web-dev-qa-db-ja.com

Swift 3?を使用してバックグラウンドタスクを使用する方法

私はバックグラウンドタスクが初めてです。ツイートを取得している小さな作業があり、アプリがバックグラウンドモードの場合、ツイートも取得する必要がありますが、方法はわかりません。

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

スピーチへのテキストもありますが、アプリを閉じると話が止まります。アプリを使用していない場合は、ツイートを取得したり、テキストを音声に変換したり、バックグラウンドモードを使用することもできます。それはどれくらいの期間働きますか?

7
kishor0011

次の3つのことを行う必要があります。

  1. Info.plistでキーRequired background modesに次のエントリを追加して、バックグラウンドネットワークアクセスを許可します。

    Required background modes:App downloads content from the network

  2. 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 ) )
    }
    
  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で実際のデバイスとは大幅に異なる動作をする可能性があります。

このかなり似たトピックを見ることができます:

performFetchWithCompletionHandlerが起動されることはありません

そしてもちろん https://developer.Apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html

10

バックグラウンドタスクは、バックグラウンドスレッドを使用する必要があることを意味します。 iOSのスレッドは多すぎますが、バックグラウンドタスクのみを作成する場合は、2つのスレッドを使用する必要があります。その構造がメインとバックグラウンドのスレッド:

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

そのため、まずバックグラウンドモードでグローバルキューを初期化します。このスレッドはバックグラウンドタスクに使用でき、バックグラウンドタスクの終了時に何かを行うにはメインスレッド(必要な場合のみ)を使用する必要があります。これはオプションです。別のオプションはappDelegateのapplicationDidEnterBackgroundである必要があり、そのメソッドにコードを配置する必要があります。

10
Alfredo Luco G