Цель 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;
}
Короче говоря, если таймер сработает до того, как я получу ответ от основного приложения, я в основном предположу, что основное приложение было переведено в спящий режим. Имейте в виду, что все ожидающие вызовы в какой-то момент будут успешными (например, состояние приложения восстанавливается до активного), и, таким образом, вам нужно будет обработать этот сценарий (при необходимости).