Search code examples
iosswiftbackgroundbackground-processtweets

How to use background task using Swift 3?


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?


Solution

  • 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