0

バックグラウンド モード (最小化) で動作するアプリケーションを作成しており、サーバー上の情報をチェックする特定のメソッドを 90 秒ごとに実行しています。コードは次のとおりです。

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
...
[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
...
}

-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{

    MyFristViewController *viewController = (MyFristViewController *)self.window.rootViewController;

    [viewController checkData:^(UIBackgroundFetchResult result) {
        completionHandler(result);
    }];

}

MyFristViewController.m

-(void)checkData:(void (^)(UIBackgroundFetchResult))completionHandler{
...
NSURLSessionDataTask * dataTask =[defaultSession dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

        if(error == nil){   
            completionHandler(UIBackgroundFetchResultNewData);

        }else{
             completionHandler(UIBackgroundFetchResultNoData);
        }
    }];

    [dataTask resume];

    [self performSelector:@selector(checkData:) withObject:nil afterDelay:90.0];
...
}

私のコードはうまく機能しますが、前に述べたように、90 秒ごとにコマンドを数回実行する必要があります。

[self performSelector:@selector(checkData:) withObject:nil afterDelay:90.0];

このコードの問題は、最初は完全に機能することです。彼が 90 秒を期待して同じコードを 2 回目に実行すると、次のコード行のエラー メッセージEXEC_BAD_ACCESSが表示されます。

completionHandler(UIBackgroundFetchResultNewData);

このコード行を削除すると、メッセージが表示され、アプリは正常に動作します (クラッシュすることはありません)。

アプリケーション デリゲートが -application:performFetchWithCompletionHandler: への呼び出しを受け取りましたが、完了ハンドラーが呼び出されませんでした。

このメッセージを受け取るのは良くないと思います。要するに、私がやりたいことは、アプリケーションが最小化されているときに、このコマンドを 90 秒ごとに永久に実行することです。私はそれを正しい方法でやっていますか?

4

2 に答える 2

2

バックグラウンドで永久に実行することはできません。iOS にはその機能がありません。

現在のクラッシュは、完了ハンドラーを複数回呼び出していて、無効化された後に発生しています。

基本的に、アプローチを変更し、おそらく要件を変更し、Apple の規定に従ってバックグラウンド処理を使用する必要があります (明示的な期間ではなく、ユーザーの使用状況に基づいて)。

于 2015-02-16T23:22:50.817 に答える