Alright, so I've been trying really hard to get the answer to this but I still can't get Alamofire to do its magic when I simulate a background refresh via Xcode.
This is what my said function in app delegate looks like
func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
let vc = ViewController()
vc.fetchData()
vc.sendNoti(currentFlightRules: currentFlightRules)
completionHandler(.newData)
print("Background Fetch Complete! UP")
}
fetchData() is the one that has the API request via Alamofire and it doesn't run whereas the sendNoti() does. I know that this implementation is running as when I simulate the background refresh the print statement executes.
I'd really appreciate some help with this as I'm not familiar with how to do tasks in the background and especially networking tasks in the background. Thanks in advance.
Your problem is that fetchData
will complete asynchronously. This means that sendNotification
and the completionHandler
will be called before the network operation has been completed.
You need your fetchData
function to accept and invoke a completion handler when it has the data. You then invoke the notification method and the background fetch completionHandler
from that closure:
func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
let vc = ViewController()
vc.fetchData { (error, data) in
guard error == nil else {
print("There was an error \(error!.localizedDescription)")
completionHandler(.failed)
return
}
if let newData = data {
vc.sendNoti(currentFlightRules: newData)
completionHandler(.newData)
} else {
completionHandler(.noData)
}
}
}
I would also suggest that you refactor so that your fetch and notification operations are not included in a view controller; they should be separated out into their own classes.