How to use background task using Swift 3?

徘徊边缘 提交于 2019-12-21 12:18:52

问题


I am new in background tasks. I have a small work that I am fetching tweets and If my app is in background mode then also it should fetch tweets, but I don't know how.

I am using simply Timer in Appdelegate didFinishLaunchOption Method. When I will close the app then it's not working. I am new in that so please any suggestion. Here below is my code:

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

Text to speech is also there but when I will close the app then it stops speaking. If I am not using app then also it can fetch tweets and text to speech should work using a background mode. How long does that work?


回答1:


You need to do three things:

  1. In your Info.plist add the following entry for key Required background modes to allow background network access:

    Required background modes: App downloads content from the network

  2. In your AppDelegate add to your 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 ) )
    }
    
  3. Also in AppDelegate implement

    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    
    }
    

There are still some pitfalls, e.g. there is no guaranteed maximum fetch interval, and background execution might behave substantially different in XCode/Simulator than on real devices.

You could take a look at this pretty similiar topic:

performFetchWithCompletionHandler never gets fired

and of course https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html




回答2:


A background task means you need to use background threads. Threads in iOS are too many, but if you want to make only background task, you should use two threads; the main and background thread that their structure is:

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

So, you firstly initialize the global queue with background mode. This thread can be used for background task and then you must use main thread (only if you want) for doing something when the background task is finished. This can be an option. Another option should be applicationDidEnterBackground in appDelegate and you can only must put your code in that method.



来源:https://stackoverflow.com/questions/45192402/how-to-use-background-task-using-swift-3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!