Post

Replies

Boosts

Views

Activity

Reply to Trouble with @escaping Competion Handler when passing data in a shared data container
Any advice would be greatly appreciated! If you can target your app for iOS 15+ and are planning to release it after the released version of Xcode 13 is out, you may try using new async/await feature. Meet async/await in Swift Use async/await with URLSession (There are more session videos about async/await and I recommend to watch all if you have enough time.) If you need to make your app target iOS 14.x and earlier, working with completion handler would be necessary. I assume your loadInitialFireMapData is working fine in normal cases. (Hope you are not ignoring any warnings.) But it has some flaws considering error cases: It ignores some error cases without showing any debug info It does not call completion handler on errors You should better pass an Optional<Error> to the completion handler to indicate error cases. I would write it as follows: class FireDataManager { enum Errors: Error { case urlInvalid case dataIsNil } func loadInitialFireMapData(completion: @escaping (Error?) -> Void) { //<- guard let url = URL(string: "https://opendata.arcgis.com/datasets/68637d248eb24d0d853342cba02d4af7_0.geojson") else { completion(Errors.urlInvalid) return } URLSession.shared.dataTask(with: url) {data, response, error in if let error = error { print("FireMap URL Session error: ", error) //Use `error` instead of `error.localizedDescription` to show debug info completion(error) return } guard let data = data else { completion(Errors.dataIsNil) return } do { let features = try MKGeoJSONDecoder().decode(data) .compactMap { $0 as? MKGeoJSONFeature } let validWorks = features.compactMap(Fire.init) DataContainer.shared.fires.append(contentsOf: validWorks) DataContainer.shared.totalFireCount = validWorks.count print("Fire Data Manager Count of Total Fires: ", DataContainer.shared.totalFireCount) DispatchQueue.main.async { completion(nil) //<- no error here } } catch let error { print("FireMap decoding error: ", error) completion(error) } } .resume() } } In this case, meaning the type of completion is (Error?)->Void, you need to write a closure like { (error: Error?)->Void in ... } or in a simplified form { error in ... } . So, the caller side code would be something like this: class ViewController: UIViewController, CLLocationManagerDelegate { @IBOutlet weak var fireStatusLabel: UILabel! let dataContainer = DataContainer.shared let fireDataManager = FireDataManager() override func viewDidLoad() { super.viewDidLoad() //Retrieve Fire API data from Fire Data Manager fireDataManager.loadInitialFireMapData (completion: { error in if let error = error { print(error) return } self.fireStatusLabel.text = "\(DataContainer.shared.totalFireCount) fires within 100 miles of your location." }) //... } //... } (I renamed FireStatusLabel to fireStatusLabel as only type names start with Capital letter in Swift. If you have any reasons you cannot rename it, please re-interpret the lines with fireStatusLabel.) Or you can use the trailing closure notation like this: fireDataManager.loadInitialFireMapData { error in //<- no opening parenthesis here if let error = error { print(error) return } self.fireStatusLabel.text = "\(DataContainer.shared.totalFireCount) fires within 100 miles of your location." } //<- no closing parenthesis Please try.
Topic: Programming Languages SubTopic: Swift Tags:
Jun ’21
Reply to Priority queue in Swift
Is a collection like this available in Swift? I do not think so. At lease, not now. If you want to discuss about some future of Swift, you should better visit swift.org . You can find Get Involved! part at the bottom of this article. Introducing Swift Collections
Topic: Programming Languages SubTopic: Swift Tags:
Jun ’21
Reply to FPS App crashes when compiling, “Thread 1: Swift runtime failure: Range requires lowerBound <= upperBound” error
FPS App crashes when compiling  I see the following when the compiler runs the line The compiler is a tool to generate a binary, and it is not something to run a code. As far as I know, the error you find is a runtime error which would not be shown in compile-time. Ignoring such terminology problems, it is clear why you see that error: min Engine.Vector x = (Double) 51.75 y = (Double) 0 max Engine.Vector x = (Double) 2 y = (Double) 51.75 The left hand side of the range operator ..< cannot be greater than the right hand side. In your case shown, 51.75 (and Int value of it) is clearly greater than 2. You may need to find all the places you create such Rects in your project and fix them to fulfill the requirement of Range. Or create some sort of extension: public extension Rect { var minX: Double {Swift.min(min.x, max.x)} var maxX: Double {Swift.max(min.x, max.x)} var minY: Double {Swift.min(min.y, max.y)} var maxY: Double {Swift.max(min.y, max.y)} } And use it like this: for y in Int(rect.minY) ..< Int(rect.maxY) { for x in Int(rect.minX) ..< Int(rect.maxX) { self[x, y] = color } }
Topic: Programming Languages SubTopic: Swift Tags:
Jun ’21
Reply to objc_getAssociatedObject and Runtime attributes
it's not being called during the XIB decoding process,  Sorry, I had not noticed the image was an example of storyboard settings. (You should better have mentioned it explicitly.) But I cannot reproduce the getters were always returning nil. I got this: Failed to set (imgAttribute) user defined inspected property on (UIImageView): [<UIImageView 0x7ff072e080f0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key imgAttribute. Not always returning nil. The User Defined Runtime Attributes uses Key Value Coding, which is one of the dynamic feature of Objective-C. Since Swift 4 (not Swift 5), you need to add an explicit annotation @objc for such methods and properties. extension UIImageView { @objc var imgAttribute: String? { get { return objc_getAssociatedObject(self, &imgAttributeKey) as? String } set { objc_setAssociatedObject(self, &imgAttributeKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN) } } } With this change, I can get the value shown in the User Defined Runtime Attributes: Optional("someAttr") What do you get with this change?
Topic: Programming Languages SubTopic: Swift Tags:
Jun ’21
Reply to Show UIImageView for 1 second and hide again
In your animation, you set alpha to 0, but there's no code to reset it to 1. func showIcon() { statusField.isHidden = false UIView.animate(withDuration: 1, delay: 0.5, options: UIView.AnimationOptions.transitionFlipFromTop, animations: { self.statusField.alpha = 0 }, completion: { finished in self.statusField.isHidden = true self.statusField.alpha = 1 //<- }) } In your shown code, showIcon() looks like it is nested inside viewDidLoad(), but it is odd and I assumed it is not nested.
Topic: UI Frameworks SubTopic: UIKit Tags:
Jun ’21
Reply to Thread 1: Swift runtime failure: Unexpectedly found nil while unwrapping an Optional value
look at the Debug navigator Debug Navigator is quite useless when finding which is being nil and you may need to modify your code: private func loadTextures() -> Textures { return Textures(loader: { name in guard let image = UIImage(named: name) else { fatalError("UIImage for \(name) cannot be created") } guard let bitmap = Bitmap(image: image) else { fatalError("Bitmap for \(name) (image: \(image)) cannot be created") } return bitmap }) } Generally, you use toooo.... many forced unwrappings (!) in your code. I recommend you to learn safe ways to work with Optionals.
Topic: Programming Languages SubTopic: Swift Tags:
Jun ’21
Reply to getting Error While using Date picker class ActionSheetDatePicker.init
Thanks for showing your code. But codes in comments cannot be properly formatted and hard to read. Can you use Your Answer to show your code? (Please format it as Code Block, not Add Text.)
Topic: Programming Languages SubTopic: Swift Tags:
Replies
Boosts
Views
Activity
Jun ’21
Reply to AttributedString with Markdown in UILabel doesn't render any attributes?
Please include code as text, do not use image.
Topic: App & System Services SubTopic: General Tags:
Replies
Boosts
Views
Activity
Jun ’21
Reply to AttributedString with Markdown in UILabel doesn't render any attributes?
The parameter label markdown: is missing in your code.
Topic: App & System Services SubTopic: General Tags:
Replies
Boosts
Views
Activity
Jun ’21
Reply to Cannot convert value of type 'EventsTrigger' to expected argument type 'String?
Unless any clarification about what you want to do, there is no clue to find what will be needed.
Topic: Programming Languages SubTopic: Swift Tags:
Replies
Boosts
Views
Activity
Jun ’21
Reply to Trouble with @escaping Competion Handler when passing data in a shared data container
Any advice would be greatly appreciated! If you can target your app for iOS 15+ and are planning to release it after the released version of Xcode 13 is out, you may try using new async/await feature. Meet async/await in Swift Use async/await with URLSession (There are more session videos about async/await and I recommend to watch all if you have enough time.) If you need to make your app target iOS 14.x and earlier, working with completion handler would be necessary. I assume your loadInitialFireMapData is working fine in normal cases. (Hope you are not ignoring any warnings.) But it has some flaws considering error cases: It ignores some error cases without showing any debug info It does not call completion handler on errors You should better pass an Optional<Error> to the completion handler to indicate error cases. I would write it as follows: class FireDataManager { enum Errors: Error { case urlInvalid case dataIsNil } func loadInitialFireMapData(completion: @escaping (Error?) -> Void) { //<- guard let url = URL(string: "https://opendata.arcgis.com/datasets/68637d248eb24d0d853342cba02d4af7_0.geojson") else { completion(Errors.urlInvalid) return } URLSession.shared.dataTask(with: url) {data, response, error in if let error = error { print("FireMap URL Session error: ", error) //Use `error` instead of `error.localizedDescription` to show debug info completion(error) return } guard let data = data else { completion(Errors.dataIsNil) return } do { let features = try MKGeoJSONDecoder().decode(data) .compactMap { $0 as? MKGeoJSONFeature } let validWorks = features.compactMap(Fire.init) DataContainer.shared.fires.append(contentsOf: validWorks) DataContainer.shared.totalFireCount = validWorks.count print("Fire Data Manager Count of Total Fires: ", DataContainer.shared.totalFireCount) DispatchQueue.main.async { completion(nil) //<- no error here } } catch let error { print("FireMap decoding error: ", error) completion(error) } } .resume() } } In this case, meaning the type of completion is (Error?)->Void, you need to write a closure like { (error: Error?)->Void in ... } or in a simplified form { error in ... } . So, the caller side code would be something like this: class ViewController: UIViewController, CLLocationManagerDelegate { @IBOutlet weak var fireStatusLabel: UILabel! let dataContainer = DataContainer.shared let fireDataManager = FireDataManager() override func viewDidLoad() { super.viewDidLoad() //Retrieve Fire API data from Fire Data Manager fireDataManager.loadInitialFireMapData (completion: { error in if let error = error { print(error) return } self.fireStatusLabel.text = "\(DataContainer.shared.totalFireCount) fires within 100 miles of your location." }) //... } //... } (I renamed FireStatusLabel to fireStatusLabel as only type names start with Capital letter in Swift. If you have any reasons you cannot rename it, please re-interpret the lines with fireStatusLabel.) Or you can use the trailing closure notation like this: fireDataManager.loadInitialFireMapData { error in //<- no opening parenthesis here if let error = error { print(error) return } self.fireStatusLabel.text = "\(DataContainer.shared.totalFireCount) fires within 100 miles of your location." } //<- no closing parenthesis Please try.
Topic: Programming Languages SubTopic: Swift Tags:
Replies
Boosts
Views
Activity
Jun ’21
Reply to Cannot convert value of type 'EventsTrigger' to expected argument type 'String?
Please share the solution you have found.
Topic: Programming Languages SubTopic: Swift Tags:
Replies
Boosts
Views
Activity
Jun ’21
Reply to Priority queue in Swift
Is a collection like this available in Swift? I do not think so. At lease, not now. If you want to discuss about some future of Swift, you should better visit swift.org . You can find Get Involved! part at the bottom of this article. Introducing Swift Collections
Topic: Programming Languages SubTopic: Swift Tags:
Replies
Boosts
Views
Activity
Jun ’21
Reply to FPS App crashes when compiling, “Thread 1: Swift runtime failure: Range requires lowerBound <= upperBound” error
FPS App crashes when compiling  I see the following when the compiler runs the line The compiler is a tool to generate a binary, and it is not something to run a code. As far as I know, the error you find is a runtime error which would not be shown in compile-time. Ignoring such terminology problems, it is clear why you see that error: min Engine.Vector x = (Double) 51.75 y = (Double) 0 max Engine.Vector x = (Double) 2 y = (Double) 51.75 The left hand side of the range operator ..< cannot be greater than the right hand side. In your case shown, 51.75 (and Int value of it) is clearly greater than 2. You may need to find all the places you create such Rects in your project and fix them to fulfill the requirement of Range. Or create some sort of extension: public extension Rect { var minX: Double {Swift.min(min.x, max.x)} var maxX: Double {Swift.max(min.x, max.x)} var minY: Double {Swift.min(min.y, max.y)} var maxY: Double {Swift.max(min.y, max.y)} } And use it like this: for y in Int(rect.minY) ..< Int(rect.maxY) { for x in Int(rect.minX) ..< Int(rect.maxX) { self[x, y] = color } }
Topic: Programming Languages SubTopic: Swift Tags:
Replies
Boosts
Views
Activity
Jun ’21
Reply to objc_getAssociatedObject and Runtime attributes
the getters were always returning nil. I cannot reproduce the same issue, iOS 14.5 simulator/Xcode 12.5. A simple code like print(imageView.imgAttribute) has output: Optional("Test") Can you clarify how have you tested it?
Topic: Programming Languages SubTopic: Swift Tags:
Replies
Boosts
Views
Activity
Jun ’21
Reply to objc_getAssociatedObject and Runtime attributes
it's not being called during the XIB decoding process,  Sorry, I had not noticed the image was an example of storyboard settings. (You should better have mentioned it explicitly.) But I cannot reproduce the getters were always returning nil. I got this: Failed to set (imgAttribute) user defined inspected property on (UIImageView): [<UIImageView 0x7ff072e080f0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key imgAttribute. Not always returning nil. The User Defined Runtime Attributes uses Key Value Coding, which is one of the dynamic feature of Objective-C. Since Swift 4 (not Swift 5), you need to add an explicit annotation @objc for such methods and properties. extension UIImageView { @objc var imgAttribute: String? { get { return objc_getAssociatedObject(self, &imgAttributeKey) as? String } set { objc_setAssociatedObject(self, &imgAttributeKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN) } } } With this change, I can get the value shown in the User Defined Runtime Attributes: Optional("someAttr") What do you get with this change?
Topic: Programming Languages SubTopic: Swift Tags:
Replies
Boosts
Views
Activity
Jun ’21
Reply to Show UIImageView for 1 second and hide again
In your animation, you set alpha to 0, but there's no code to reset it to 1. func showIcon() { statusField.isHidden = false UIView.animate(withDuration: 1, delay: 0.5, options: UIView.AnimationOptions.transitionFlipFromTop, animations: { self.statusField.alpha = 0 }, completion: { finished in self.statusField.isHidden = true self.statusField.alpha = 1 //<- }) } In your shown code, showIcon() looks like it is nested inside viewDidLoad(), but it is odd and I assumed it is not nested.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
Boosts
Views
Activity
Jun ’21
Reply to Semaphore Wait After Creating UIButton
With creating a semaphore with value 1, wait(timeout:) never waits. If you change it to 0, wait(timeout:) freezes until timeout UI and signal() would not be called until timeout. Conclusion, you should not use semaphore for your purpose.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
Boosts
Views
Activity
Jun ’21
Reply to Thread 1: Swift runtime failure: Unexpectedly found nil while unwrapping an Optional value
If the line is causing Unexpectedly found nil, UIImage(named: name) is nil or Bitmap(image: UIImage(named: name)!) is nil. Have you checked which is returning nil?
Topic: Programming Languages SubTopic: Swift Tags:
Replies
Boosts
Views
Activity
Jun ’21
Reply to Semaphore Wait After Creating UIButton
Never call wait is one clear principle in iOS programming (or in many other GUI programming). If you understand you cannot use DispatchSemaphore here, you may know what to use.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
Boosts
Views
Activity
Jun ’21
Reply to Thread 1: Swift runtime failure: Unexpectedly found nil while unwrapping an Optional value
look at the Debug navigator Debug Navigator is quite useless when finding which is being nil and you may need to modify your code: private func loadTextures() -> Textures { return Textures(loader: { name in guard let image = UIImage(named: name) else { fatalError("UIImage for \(name) cannot be created") } guard let bitmap = Bitmap(image: image) else { fatalError("Bitmap for \(name) (image: \(image)) cannot be created") } return bitmap }) } Generally, you use toooo.... many forced unwrappings (!) in your code. I recommend you to learn safe ways to work with Optionals.
Topic: Programming Languages SubTopic: Swift Tags:
Replies
Boosts
Views
Activity
Jun ’21