Цель c WatchKit WKInterfaceController openParentApplication вызывает блоки бесконечно

Я использую следующий код, чтобы "просто" определить состояние приложения родительского приложения из моего приложения наблюдения:

Расширение WatchKit:

[WKInterfaceController openParentApplication:[NSDictionary dictionary] reply:^(NSDictionary *replyInfo, NSError *error)
    {
        UIApplicationState appState =  UIApplicationStateBackground;
        if(nil != replyInfo)
            appState = (UIApplicationState)[((NSNumber*)[replyInfo objectForKey:kAppStateKey]) integerValue];

        //handle app state
    }];

Основное приложение:

- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *replyInfo))reply
{
    __block UIBackgroundTaskIdentifier realBackgroundTask;

    realBackgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{

        reply([NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:[[UIApplication sharedApplication] applicationState]], kAppStateKey, nil]);
        [[UIApplication sharedApplication] endBackgroundTask:realBackgroundTask];
    }];

    reply([NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:[[UIApplication sharedApplication] applicationState]], kAppStateKey, nil]);

    [[UIApplication sharedApplication] endBackgroundTask:realBackgroundTask];
}

Когда приложение находится на переднем плане, это работает 100% времени. Когда приложение "свернуто" или "закрыто", это может работать 50% времени (может быть, меньше). Когда это не работает, кажется, блокируется на неопределенный срок. Например, если через 1 минуту я запускаю родительское приложение, вызов (openParentApplication) немедленно возвращается с состоянием "UIApplicationStateBackground" (состояние, в котором оно находилось до запуска приложения, поскольку очевидно, что приложение не находится в фоновом состоянии, если я запустил его).

Кстати: я тестирую на реальном оборудовании.

Что я делаю неправильно? Почему iOS переводит мое основное приложение в спящий режим сразу же после получения вызова, даже если я создаю фоновую задачу? Это полный шоу-стоппер.

Любые мысли или предложения будут с благодарностью!

1 ответ

После некоторого исследования это кажется известной проблемой. Например, следующая ссылка идентифицирует эту проблему и предоставляет решение:

http://www.fiveminutewatchkit.com/blog/2015/3/11/one-weird-trick-to-fix-openparentapplicationreply

Однако это решение не сработало для меня. В результате я реализовал следующее решение (оно немного неаккуратное, но оно намеренно поможет сжать решение):

//start the timeout timer
timeoutTimer = [NSTimer scheduledTimerWithTimeInterval:kTimeOutTime target:self selector:@selector(onTimeout) userInfo:nil repeats:NO];

//make the call
messageSent = [WKInterfaceController openParentApplication:[NSDictionary dictionary] reply:^(NSDictionary *replyInfo, NSError *error)
{
  if(nil != _stateDelegate)
  {     
    UIApplicationState appState =  UIApplicationStateBackground;
    if(nil != replyInfo)
      appState = (UIApplicationState)[((NSNumber*)[replyInfo objectForKey:kAppStateKey]) integerValue];

    [_stateDelegate onOperationComplete:self timeout:false applicationState:appState];
    _stateDelegate = nil;
   }
}];

//if the message wasn't sent, then this ends now
if(!messageSent)
{
   if(nil != _stateDelegate)
   {
      //just report that the main application is inactive
      [_stateDelegate onOperationComplete:self timeout:false applicationState:UIApplicationStateInactive];
   }
   _stateDelegate = nil;
}


-(void)onTimeout
{
    timeoutTimer = nil;
    if(nil != _stateDelegate)
    {
        [_stateDelegate onOperationComplete:self timeout:true applicationState:UIApplicationStateInactive];
    }
    _stateDelegate = nil;
}

Короче говоря, если таймер сработает до того, как я получу ответ от основного приложения, я в основном предположу, что основное приложение было переведено в спящий режим. Имейте в виду, что все ожидающие вызовы в какой-то момент будут успешными (например, состояние приложения восстанавливается до активного), и, таким образом, вам нужно будет обработать этот сценарий (при необходимости).

Другие вопросы по тегам