sc1*_*c13 5 background-process ios completionhandler appdelegate swift
我具有以下功能,可以在我的SeachVC(UIViewController)中下载JSON数据,它可以完美运行。
func downloadJSON(){
guard let url = URL(string: "myURL") else { return }
URLSession.shared.dataTask(with: url) { (data, response, err) in
guard let data = data else { return }
do {
let downloadedCurrencies = try JSONDecoder().decode([Currency].self, from: data)
// Adding downloaded data into Local Array
Currencies = downloadedCurrencies
} catch let jsonErr {
print("Here! Error serializing json", jsonErr)
}
}.resume()
}
Run Code Online (Sandbox Code Playgroud)
为了实现后台应用刷新,我在App Delegate中添加了以下功能;
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
// Background App Refresh Config
UIApplication.shared.setMinimumBackgroundFetchInterval(UIApplicationBackgroundFetchIntervalMinimum)
return true
}
func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
if let VC = window?.rootViewController as? SearchVC {
// Update JSON data
VC.downloadJSON()
completionHandler(.newData)
}
}
Run Code Online (Sandbox Code Playgroud)
但是,当我在模拟器上模拟Background App Refresh时,我得到警告:
警告:应用程序委托收到了对-application:performFetchWithCompletionHandler:的调用,但从未调用完成处理程序。
我将在哪里实现完成处理程序,以及如何实现?
谢谢
您将需要将下载的代码从视图控制器移到另一个类中,或者至少在需要时修改当前的后台刷新方法以实例化视图控制器。当您的应用尚未在前台启动时,可以触发后台刷新,因此if let会失败。
考虑问题中的代码:
func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
if let VC = window?.rootViewController as? SearchVC {
// Update JSON data
VC.downloadJSON()
completionHandler(.newData)
}
}
Run Code Online (Sandbox Code Playgroud)
如果if let...没有通过,则您不调用即可退出该函数completionHandler,因此会收到运行时警告,提示未调用完成处理程序。
您可以修改代码以completionHandler在else情况下包含对的调用,但在这种情况下,将不会进行提取:
func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
if let VC = window?.rootViewController as? SearchVC {
// Update JSON data
VC.downloadJSON()
completionHandler(.newData)
} else {
completionHandler(.noData)
}
Run Code Online (Sandbox Code Playgroud)
或者如果需要,您可以实例化视图控制器(或者我建议另一个数据获取类):
func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
let vc = (window?.rootViewController as? SearchVC) ?? SearchVC()
// Update JSON data
vc.downloadJSON()
completionHandler(.newData)
}
Run Code Online (Sandbox Code Playgroud)
您还应该修改downloadJSON函数以包含完成处理程序参数,当JSON下载完成时调用该参数。实际下载数据后,这将使您调用后台提取完成处理程序:
func downloadJSON(completion: ((Bool,Error?) -> Void )? = nil)) {
guard let url = URL(string: "myURL") else {
completion?(false, nil)
return
}
URLSession.shared.dataTask(with: url) { (data, response, err) in
guard nil == err else {
completion?(false, err)
return
}
guard let data = data else {
completion?(false, nil)
return
}
do {
let downloadedCurrencies = try JSONDecoder().decode([Currency].self, from: data)
// Adding downloaded data into Local Array
Currencies = downloadedCurrencies
completion(true,nil)
} catch let jsonErr {
print("Here! Error serializing json", jsonErr)
completion?(false,jsonErr)
}
}.resume()
}
func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
let vc = (window?.rootViewController as? SearchVC) ?? SearchVC()
// Update JSON data
vc.downloadJSON() { (newData,error) in
if let err = error {
NSLog("Background fetch error: \(err.localizedDescription)")
completionHandler(.fail)
} else {
completionHandler(newData ? .newData:.noData)
}
}
}
Run Code Online (Sandbox Code Playgroud)
2019年9月更新
请注意,iOS 13引入了新的后台获取和处理功能。有关更多详细信息,请参考此WWDC会话
| 归档时间: |
|
| 查看次数: |
6965 次 |
| 最近记录: |