Как использовать фоновую задачу с помощью Swift 3?

Я новичок в фоновых задачах. У меня есть небольшая работа, я получаю твиты, и если мое приложение работает в фоновом режиме, оно также должно получать твиты, но я не знаю, как.

Я использую просто таймер в Appdelegate didFinishLaunchOption Method. Когда я закрою приложение, оно не будет работать. Я новичок в этом, поэтому, пожалуйста, любое предложение. Здесь ниже мой код:

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

Текст в речь тоже есть, но когда я закрою приложение, оно перестает говорить. Если я не пользуюсь приложением, оно также может извлекать твиты, а текст в речь должен работать в фоновом режиме. Как долго это работает?

2 ответа

Фоновая задача означает, что вам нужно использовать фоновые потоки. Потоков в iOS слишком много, но если вы хотите сделать только фоновое задание, вы должны использовать два потока; основной и фоновый поток, что их структура:

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

Итак, вы сначала инициализируете глобальную очередь в фоновом режиме. Этот поток можно использовать для фоновой задачи, а затем вы должны использовать основной поток (только если вы хотите) для выполнения каких-либо действий после завершения фоновой задачи. Это может быть вариантом. Другой вариант должен быть applicationDidEnterBackground в appDelegate, и вы можете только поместить свой код в этот метод.

Вам нужно сделать три вещи:

  1. В вашем Info.plist добавьте следующую запись для ключа Required background modes чтобы разрешить фоновый доступ к сети:

    Required background modes:App downloads content from the network

  2. В вашем AppDelegate добавьте в ваше приложение DidEnterBackground():

    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. Также в 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, чем на реальных устройствах.

Вы могли бы взглянуть на эту довольно похожую тему:

executeFetchWithCompletionHandler никогда не будет уволен

и, конечно, https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html

Другие вопросы по тегам