私はバックグラウンドタスクが初めてです。ツイートを取得している小さな作業があり、アプリがバックグラウンドモードの場合、ツイートも取得する必要がありますが、方法はわかりません。
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")
}
}
スピーチへのテキストもありますが、アプリを閉じると話が止まります。アプリを使用していない場合は、ツイートを取得したり、テキストを音声に変換したり、バックグラウンドモードを使用することもできます。それはどれくらいの期間働きますか?
次の3つのことを行う必要があります。
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で実際のデバイスとは大幅に異なる動作をする可能性があります。
このかなり似たトピックを見ることができます:
バックグラウンドタスクは、バックグラウンドスレッドを使用する必要があることを意味します。 iOSのスレッドは多すぎますが、バックグラウンドタスクのみを作成する場合は、2つのスレッドを使用する必要があります。その構造がメインとバックグラウンドのスレッド:
DispatchQueue.global(qos: .background).async {
//background code
DispatchQueue.main.async {
//your main thread
}
}
そのため、まずバックグラウンドモードでグローバルキューを初期化します。このスレッドはバックグラウンドタスクに使用でき、バックグラウンドタスクの終了時に何かを行うにはメインスレッド(必要な場合のみ)を使用する必要があります。これはオプションです。別のオプションはappDelegateのapplicationDidEnterBackground
である必要があり、そのメソッドにコードを配置する必要があります。