gpt4 book ai didi

ios - 如何使用 Swift 配置后台应用刷新?

转载 作者:搜寻专家 更新时间:2023-10-30 22:31:48 43 4
gpt4 key购买 nike

我有以下功能可以在我的 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()
}

为了实现后台应用刷新,我在 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)
}
}

但是,当我在模拟器上模拟 Background App Refresh 时,我收到警告:

警告:应用程序委托(delegate)收到对 -application:performFetchWithCompletionHandler: 的调用,但从未调用完成处理程序。

我要在哪里实现完成处理程序以及如何实现?

谢谢

最佳答案

您需要将下载代码从 View Controller 移到另一个类中,或者至少修改当前的后台刷新方法以在需要时实例化 View Controller 。当您的应用程序尚未在前台启动时,可以触发后台刷新,因此 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)
}
}

如果 if let... 没有通过,那么您退出函数而不调用 completionHandler,这样您就得到了运行时 警告未调用完成处理程序。

您可以修改您的代码以在 else 情况下包含对 completionHandler 的调用,但在这种情况下不会发生任何提取:

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)
}

或者如果需要,您可以实例化 View Controller (或者我建议使用另一个数据获取类):

func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
let vc = (window?.rootViewController as? SearchVC) ?? SearchVC()
// Update JSON data
vc.downloadJSON()
completionHandler(.newData)
}

您还应该修改您的 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)
}
}
}

2019 年 9 月更新

请注意,iOS 13 引入了新的后台获取和处理功能。引用这个WWDC session了解更多详情

关于ios - 如何使用 Swift 配置后台应用刷新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47045022/

43 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com