如何使用 Swift 3 使用后台任务?

Posted

技术标签:

【中文标题】如何使用 Swift 3 使用后台任务?【英文标题】:How to use background task using Swift 3? 【发布时间】:2017-07-19 13:41:11 【问题描述】:

我是后台任务的新手。我有一个小工作正在获取推文,如果我的应用程序处于后台模式,那么它也应该获取推文,但我不知道如何。

我在 Appdelegate didFinishLaunchOption 方法中使用了简单的 Timer。当我关闭应用程序时,它就不起作用了。我是新来的,所以请提出任何建议。下面是我的代码:

Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(getTweets), userInfo: nil, repeats: true). 

func getTweets() 

    let locationName = Helper.sharedInstance.userDefault.value(forKey: ModelKey.currentLocation) as? String

    let accessToken = Helper.sharedInstance.userDefault.value(forKey: ModelKey.twitterAccessToken) as? String

    if (locationName == "Bengaluru" && nil != accessToken) || (locationName == "Bangalore" && nil != accessToken)
        tweetModel.getTweets(accessToken: accessToken!, city: ModelKey.blrcitytraffic, cityName: "Bengaluru")
    

文本到语音也在那里,但是当我关闭应用程序时,它会停止说话。如果我不使用应用程序,那么它也可以获取推文和文本到语音应该使用后台模式工作。多久有效?

【问题讨论】:

相关:developer.apple.com/library/content/documentation/iPhone/… 【参考方案1】:

后台任务意味着您需要使用后台线程。 ios的线程太多了,但是如果你只想做后台任务,你应该使用两个线程;它们的结构是主线程和后台线程:

DispatchQueue.global(qos: .background).async 
    //background code
    DispatchQueue.main.async 
        //your main thread
        

所以,你首先用后台模式初始化全局队列。该线程可用于后台任务,然后您必须在后台任务完成时使用主线程(仅当您需要时)才能执行某些操作。这可以是一个选项。另一个选项应该是 appDelegate 中的applicationDidEnterBackground,您只能将代码放入该方法中。

【讨论】:

我不知道为什么投反对票。这就是我来这里寻找的东西。 也帮助了我。 + 1 票 DispatchQueue.global 自己睡了吗? 这对我有帮助。但是当应用程序进入后台模式时,这个线程会在 10 分钟内停止。知道为什么吗?【参考方案2】:

你需要做三件事:

    在您的 Info.plist 中为密钥 Required background modes 添加以下条目以允许后台网络访问:

    Required background modes:App downloads content from the network

    在您的 AppDelegate 中添加到您的 applicationDidEnterBackground():

    func applicationDidEnterBackground(_ application: UIApplication) 
        // Fetch no sooner than every (60) seconds which is thrillingly short actually. 
        // Defaults to Infinite if not set. 
        UIApplication.shared.setMinimumBackgroundFetchInterval( 60 ) )
    
    

    也在AppDelegate中实现

    func application(application: UIApplication, performFetchWithCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) 
      var fetchResult: UIBackgroundFetchResult!
    
    
      if doingYourStuffActuallyCreatesNetworkTraffic() 
        fetchResult = UIBackgroundFetchResult.newData
       else if thereWasAnError()  
        fetchResult = UIBackgroundFetchResult.failed
       else 
        fetchResult = UIBackgroundFetchResult.noData
                 
      completionHandler( fetchResult )
    
      return    
    
    

仍有一些陷阱,例如没有保证的最大获取间隔,后台执行在 XCode/Simulator 中的行为可能与在真实设备上大不相同。

你可以看看这个非常相似的话题:

performFetchWithCompletionHandler never gets fired

当然还有 https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html

【讨论】:

以上是关于如何使用 Swift 3 使用后台任务?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 中将任务发送到后台队列?

Swift • 如何从视图的初始化程序启动后台任务?

ios - 如何在 ios swift 中正确实现后台获取

如何使用关系 Swift 3 显示 UITableView

Swift 3:如何在后台扫描外围设备?

如何通过 API 使用后台任务?