42

私のアプリでは、iPhone からサーバーに画像をアップロードしています。ユーザーがホームボタンを押すと、同期中にアプリが閉じます。

同期が完了するまでアプリをバックグラウンドで実行する必要があります。

私の質問は、現在実行中のタスクを " " で追加するにはどうすればよいbeginBackgroundTaskWithExpirationHandlerですか?

あなたのアイデアを共有してください。

4

6 に答える 6

110

その名前にもかかわらず、beginBackgroundTaskWithExpirationHandler:実際にはタスクを「開始」しません。「開始....」よりも「登録...」と考えたほうがよいかもしれません。システムに、何かを実行している途中で、それでよければ完了したいと言っているだけです。

いくつかのポイント:

  • ほとんどの場合、やりたいことbeginBackgroundTaskWithExpirationHandler:を始めたときと、やりendBackgroundTask:終わったときに電話をかけます。ユーザーがホームボタンを押した時点でこれらを呼び出すことはほとんどありません (サーバーに何かを保存するなどのタスクを開始する時点でない限り)。

  • 一度に開くことができる「バックグラウンド タスク」の数に制限はありません。彼らは何もかかりません。それらは保持カウントのようなものです。まだ 1 つ開いている限り (「開始」が「終了」に達していない場合)、システムはそれをさらに時間の要求と見なします。「begin」メソッドと「end」メソッドを呼び出すコストはほとんどないため、これらを使用して、終了までに余分な時間が必要なものをすべて囲みます。

  • 確実に同期を完了する方法はありません。これらのメソッドはリクエストを行うだけです。OS は引き続きその要求を拒否する場合があります。OSは、追加のリソースが必要なときはいつでもあなたを殺すかもしれません. OS は無限に忍耐強いわけではありません。時間がかかりすぎると (通常は約 10 分)、有効期限ハンドラーを呼び出した後、とにかくあなたを殺します。電話がオフになっているため、OSがあなたを殺す可能性があります。アプリは、完了しないことに対処できなければなりません。OS はこの機能を提供するだけで、ユーザー エクスペリエンスを向上させることができます。

于 2012-08-22T14:02:17.577 に答える
6

このページを見てください。Apple は、iOS アプリケーションがバックグラウンドにある間、一時停止しないようにする方法を説明しています。 アップルのドキュメント

そして、ここに私が実装したものがあります:

UIBackgroundTaskIdentifier bgTask;

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    NSLog(@"=== DID ENTER BACKGROUND ===");
    bgTask = [[UIApplication  sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        NSLog(@"End of tolerate time. Application should be suspended now if we do not ask more 'tolerance'");
        // [self askToRunMoreBackgroundTask]; This code seems to be unnecessary. I'll verify it.
    }];

    if (bgTask == UIBackgroundTaskInvalid) {
        NSLog(@"This application does not support background mode");
    } else {
        //if application supports background mode, we'll see this log.
        NSLog(@"Application will continue to run in background");  
    }
}

/*

- (void)askToRunMoreBackgroundTask
{
    [[UIApplication sharedApplication] endBackgroundTask:bgTask];
    NSLog(@"restart background long-running task");
    bgTask = [[UIApplication  sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        NSLog(@"End of tolerate time. Application should be suspended now if we do not ask more 'tolerance'");
        [self askToRunMoreBackgroundTask]; 
    }];

}

*/

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    NSLog(@"=== GOING BACK FROM IDLE MODE ===");
    //it’s important to stop background task when we do not need it anymore
    [[UIApplication sharedApplication] endBackgroundTask:UIBackgroundTaskInvalid];  
}
于 2014-10-24T08:33:58.257 に答える
1

beginBackgroundTaskWithExpirationHandlerアプリケーションがアプリの状態をバックグラウンドに変更した後にタスクを実行するか、通知をキャプチャしてから、現在のタスクをキャンセルして で再度実行する必要がありbeginBackgroundTaskWithExpirationHandlerます。

于 2012-08-22T11:22:36.290 に答える