2017-08-08 4 views
2

私のアプリで有限長バックグラウンドタスクを実行しようとしています。しかし、今のところ私のコードは、アプリケーションが中断される前に実行されていません。アプリケーションがサスペンド状態に入る前のバックグラウンドタスクの実行

私は、以下のことを主張する多くのチュートリアルに従ってきましたが、明らかに何か間違っています。

class Manager { 

    private var backgroundTask: UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid 

    init(){ 
     // Add observer able of detecting when app will go to background 
     NotificationCenter.default.addObserver(self, selector: #selector(self.didEnterBackground(_:)), name: .UIApplicationDidEnterBackground, object: nil) 
    } 

    deinit { 
     // Observers removed when view controller is dismissed/deallocated 
     NotificationCenter.default.removeObserver(self) 
    } 

     // Routine performed when app will resign from active 
@objc private func didEnterBackground(_ notification: Notification){ 

    registerBackgroundTask() 

    // Code that needs to be executed before app is suspended ------ 
    DispatchQueue.global().sync { 

     self.isBackgrounding = true 

     self.shutdownSession() 


     self.isConnected = false 
     self.isActivated = false 
     self.activate = false 

     self.connectionManager.closeConnectionToPeripherals() 

    } 
    // ----------------------------------------------------- 
    self.endBackgroundTask() 

} 

func registerBackgroundTask() { 
    backgroundTask = UIApplication.shared.beginBackgroundTask { [weak self] in 
     self?.endBackgroundTask() 
    } 
    assert(backgroundTask != UIBackgroundTaskInvalid) 
} 

func endBackgroundTask() { 
    print("\n\n\nBackground task ended.\n\n\n") 
    UIApplication.shared.endBackgroundTask(backgroundTask) 
    backgroundTask = UIBackgroundTaskInvalid 
} 

} 

私はバックグラウンドタスクは、常にコードを実行する前に終了しているように見える問題に直面しています:関連するコードは(私は何かが欠けていた場合だけで任意の明確化のためにお問い合わせください)の下に掲示しなければなりません。アプリが停止する前に同期ブロックのコードが実行されるようにするにはどうすればよいですか?

endBackgroundTask()を呼び出すときに、インターネットがこのように実装することを主張しているにもかかわらず、 "registerBackgroundTask()"のどちらかをよく理解していません。

答えて

1

self.connectionManager.closeConnectionToPeripherals()の直後にself.endBackgroundTask()コールをDispatchQueueブロックに移動する必要があります。

registerBackgroundTaskメソッドは、self.endBackgroundTask()を直接呼び出すのではなく、バックグラウンドタスクが期限切れになった場合にのみ呼び出されます。通常、これはアプリがバックグラウンドで約30秒後にタスクを完了しない場合に発生します。

+0

提案にコードを再配置しましたが、「バックグラウンドタスクが終了しました。」すぐに実行されます。私は仕事がおよそかかることを知っている。合計で7秒なので何かが間違っています。 私は関数を呼び出しているので、実行/開始されますが内部的には終了していないという事実とは関係がありますか? – matiastofteby

+1

はい。呼び出している関数が非同期処理を行っている場合、システムはアプリケーションが戻る前にアプリケーションをフリーズすることがあります。これらの関数を非同期にする必要がある場合は、完了ブロックを渡してそれらを修正し、すべてが返されるとすぐに 'endBackgroundTask'を実行する必要があります。 – ersjoh

関連する問題