0

XMPPFrameworkを使用して、アプリケーションが終了する前に「10分ウィンドウ」にバックグラウンド通知を表示しようとしています。すべてのネットワークリクエストはバックグラウンドでキューに入れられておりxmppStream:didReceiveMessage:、アプリがフォアグラウンドに戻されるまで呼び出されていないようです。

Verbsのようなアプリがこの動作をサポートしていることに気づきました。彼らは明らかにVoIPアプリではないので、私は彼らがこの振る舞いをどのように達成したかについて興味があります。

4

1 に答える 1

3

他の誰かがこの問題を抱えている場合は、このコードをAppDelegateに追加することで解決できます。私の完全なソースコードは、チェックアウトしたい場合はここにあります:OTRAppDelegate.m。他の関連するコードは、OTRBuddy.mのreceiveMessage:にあります

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    NSLog(@"Application entered background state.");
    NSAssert(self.backgroundTask == UIBackgroundTaskInvalid, nil);
    self.didShowDisconnectionWarning = NO;

    self.backgroundTask = [application beginBackgroundTaskWithExpirationHandler: ^{
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"Background task expired");
            if (self.backgroundTimer) 
            {
                [self.backgroundTimer invalidate];
                self.backgroundTimer = nil;
            }
            [application endBackgroundTask:self.backgroundTask];
            self.backgroundTask = UIBackgroundTaskInvalid;
        });
    }];

    dispatch_async(dispatch_get_main_queue(), ^{
        self.backgroundTimer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(timerUpdate:) userInfo:nil repeats:YES];
    });
}

- (void) timerUpdate:(NSTimer*)timer {
    UIApplication *application = [UIApplication sharedApplication];

    NSLog(@"Timer update, background time left: %f", application.backgroundTimeRemaining);

    if ([application backgroundTimeRemaining] < 60 && !self.didShowDisconnectionWarning) 
    {
        UILocalNotification *localNotif = [[UILocalNotification alloc] init];
        if (localNotif) {
            localNotif.alertBody = EXPIRATION_STRING;
            localNotif.alertAction = OK_STRING;
            [application presentLocalNotificationNow:localNotif];
        }
        self.didShowDisconnectionWarning = YES;
    }
    if ([application backgroundTimeRemaining] < 10) 
    {
        // Clean up here
        [self.backgroundTimer invalidate];
        self.backgroundTimer = nil;
        [application endBackgroundTask:self.backgroundTask];
        self.backgroundTask = UIBackgroundTaskInvalid;
    }
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{

}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    /*
     Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
     */
    NSLog(@"Application became active");
    if (self.backgroundTimer) 
    {
        [self.backgroundTimer invalidate];
        self.backgroundTimer = nil;
    }
    if (self.backgroundTask != UIBackgroundTaskInvalid) 
    {
        [application endBackgroundTask:self.backgroundTask];
        self.backgroundTask = UIBackgroundTaskInvalid;
    }

    application.applicationIconBadgeNumber = 0;
}
于 2012-05-14T20:17:36.083 に答える