So I am doing a background fetch, and after I want to update the UI. The background fetching itself (database) works, but when I want to update the UI, I get a crash unexpectedly found nil while unwrapping an Optional value
According to my xCode self.newestPublicationsCollectionView.reloadData()
is where the crash occurs in the updateCollections() function.
func updateCollections() {
// get latest data from Database
latestPublications = getNewestPublications()
self.newestPublicationsCollectionView.reloadData()
self.newestPublicationsCollectionView.layoutIfNeeded()
// fix wrong content height
self.newestPublicationsCollectionViewHeight.constant = self.newestPublicationsCollectionView.collectionViewLayout.collectionViewContentSize().height
}
Other code in the AppDelegate:
func application(application: UIApplication, performFetchWithCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
let fetchViewController = PublicationOverviewController()
fetchViewController.fetch {
dispatch_async(dispatch_get_main_queue()) {
fetchViewController.updateCollections()
}
completionHandler(.NewData)
}
}
The .fetch in my PublicationOverviewController
func fetch(completion: () -> Void) {
PublicationFetcher.shared.fetchAllPublications()
completion()
}
I thought the crash was because I needed the UI on the main thread, but that didn't help. Any input would be nice.
DETAILS:
In my PublicationFetcher.shared.fetchAllPublications() I do the following:
dispatch_async(dispatch_get_main_queue()) { () -> Void in NSNotificationCenter.defaultCenter().postNotificationName("RELOAD_NOTIFICATION", object: nil) }
and under that Reload Notification I do a updateCollections()
DispatchQueue.global(attributes: .qosBackground).async {
print("This is run on the background queue")
DispatchQueue.main.async {
print("This is run on the main queue, after the previous code in outer block")
}
}
Don't initialize PublicationOverviewController()
again because it will give you new instance of that view and you would not get your referenced collectionView
. Also you will get all UI controls nil before viewDidLoad:
get calls.
Example:
let *controller : PublicationOverviewController = PublicationOverviewController()
// controller.collectionView will be nil here because view hasn't loaded yet
What you can do Post a notification in applicationDidBecomeActive:
method and observe
it in PublicationOverviewController
then reload your collectionView
in respective method.