My Favourite iOS Development Bugs

There are some things in iOS development that can really catch you out the first time you encounter them and recently I was inspired to make a list as and when I remember them. This means that I will add to this post over time as I recall things. I begin with two issues. The first is a common issue on StackOverflow.

1. NSUserDefaults not storing values

When testing something it is common to throw everything in viewDidLoad: but the problem in the case of NSUserDefaults is that it stores information asynchronously and so if you try and immediately retrieve what you have just stored then it usually isn't there. The solution is to delay the retrieval, using for example a button that triggers the retrieval later for testing purposes. Or synchronise() the user defaults.

2. UIDocumentInteractionController crashes my app when I try to open a file in another app

When using a UIDocumentInteractionController it is very important to maintain a reference to the controller instance. If released too early your app can crash. So this will crash:
class ViewController: UIViewController {
     // called when bar button item is pressed
   @IBAction func shareStuff(sender: AnyObject) {
       let fileURL = NSBundle.mainBundle().URLForResource("MyFile", withExtension: "txt")!
       // Instantiate the interaction controller
       let docController = UIDocumentInteractionController(URL: fileURL)
       if let barButton = sender as? UIBarButtonItem {
           docController.presentOptionsMenuFromBarButtonItem(barButton, animated: true)
       }
       else {
           print("not a bar button!")
       }
   }
}    
but this wouldn’t:
class ViewController: UIViewController {
   // UIDocumentInteractionController instance is a class property
   var docController: UIDocumentInteractionController!
   // called when bar button item is pressed
   @IBAction func shareStuff(sender: AnyObject) {
       let fileURL = NSBundle.mainBundle().URLForResource("MyFile", withExtension: "txt")!
       // Instantiate the interaction controller
       docController = UIDocumentInteractionController(URL: fileURL)
       if let barButton = sender as? UIBarButtonItem {
           docController.presentOptionsMenuFromBarButtonItem(barButton, animated: true)
       }
       else {
           print("not a bar button!")
       }
   }
}
The other important thing to be aware of is that testing UIDocumentInteractionController in the Simulator is really a no-go because first there is a sparsity of apps that are installed on the Simulator and second it behaves badly. You must instead test on a real device.

3. Auto Layout misbehaving

Aside from the complexities of Auto Layout which has been discussed in other posts on this blog, I have noticed a tendency to over use layoutIfNeeded() in conjunction with Auto Layout and if you are doing this for constraints where nothing but orientation is changing then you might well want to look at removing this layout-triggering code.

There are times when layout methods are required, for example on the changing and animating of constraints, but at other times Auto Layout alone is more than capable and, more than this, layoutIfNeeded() can cause issues. (Note: if you do find yourself in the situation of needing layoutIfNeeded() also investigate the less abrupt, setNeedsLayout(), which waits for the next layout cycle before making changes and this can keep things more in sync.)

Comments

  1. This comment has been removed by a blog administrator.

    ReplyDelete

Post a Comment