【问题标题】:iOS WatchOS2 WatchConnectivity [WCSession defaultSession] activateSession] failureiOS WatchOS2 WatchConnectivity [WCSession defaultSession] activateSession] 失败
【发布时间】:2016-04-06 16:37:21
【问题描述】:

我有 XCode 7.3,iPhone5 和 iOS 9.3,Apple Watch 和 WatchOS 2.2

我有一个公司项目想要支持 Watch App。 首先,我构建了一个空项目,以确保 watchkit 和 watchkit 扩展工作正常,并且确实工作。 我可以看到会话已建立并且手表已配对。

但是在我将相同的代码放入公司项目后,它只能工作一次:我第一次直接从Xcode运行应用程序。当我从后台杀死应用程序并再次打开它时,应用程序显示没有配对手表。 在这种情况下,我得到了以下日志: 在 iOS 应用中

paired == NO ---- watchAppInstalled=== NO---- complicationEnabled==NO  ----<WCSession:0x7ffb9a815ab0,hasDelegate:No,activationState:2>

在 watchKit 扩展中

Error Domain=WCErrorDomain Code=7004 "WatchConnectivity session has not been activated." UserInfo={NSLocalizedRecoverySuggestion=Activate the WatchConnectivity session., NSLocalizedDescription=WatchConnectivity session has not been activated., NSLocalizedFailureReason=Function activateSession has not been called.}

我关于 wcsession 的代码:

iOS APP

在AppDelegate+GC_WCSession中

 - (void)startWCSession{

    [self configSession];
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeLoginStatus:) name:GCLoginNotifyKey object:nil];

}
- (void)configSession{
    if (![WCSession isSupported]) {
        return;
    }
    _session = [WCSession defaultSession];
    [_session setDelegate:self];
    [_session activateSession];
}
- (void)session:(nonnull WCSession *)session didReceiveApplicationContext:(nonnull NSDictionary<NSString *,id> *)applicationContext {
    [self.session activateSession];
    if ([applicationContext objectForKey:k_WK_Token]) {
        [self synchronousUserInfo];
    }
}

- (void)changeLoginStatus:(NSNotification *)noti{
    ///
    [self synchronousUserInfo];
}

- (void)synchronousUserInfo{
   ///customCode
    [self.session updateApplicationContext:replayDict error:nil];
}

- (WCSession *)session{
    if (![WCSession isSupported] || ![[WCSession defaultSession] isPaired ]|| ![[WCSession defaultSession]isWatchAppInstalled] ) {
        return nil;
    }
    return  _session;
}

在 AppDelegate 中

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
     [self startWCSession]; 
}

watchKit 扩展

在 ExtensionDelegate 中

- (void)applicationDidFinishLaunching {
    // Perform any final initialization of your application.
     [self startWCSession];
}
- (void)startWCSession{

    [self configSession];
}
- (void)configSession{
    _session = [WCSession defaultSession];
    [_session setDelegate:self];
    [_session activateSession];
}

- (void)session:(nonnull WCSession *)session didReceiveApplicationContext:(nonnull NSDictionary<NSString *,id> *)applicationContext {
  ///customcode
}
- (WCSession *)session{
    return _session;
}

这是我到目前为止尝试过的:

  • 重置所有模拟器的内容和设置

  • 从手表和 iPhone 中删除了手表应用

  • 通过手机手表应用中的设置:删除手机应用的手表扩展并重新安装

  • 尝试在 AppDelegate INIT 方法中设置 iPhone WCSession

我认为代码没有错,因为它在一个空项目中工作。我想知道环境配置是否有问题。 我现在在这个问题上挣扎了很多天。因此,每一个提示都受到高度赞赏。

【问题讨论】:

  • 请发布一些实际代码,显示您在哪里设置会话委托和处理收到的消息。另外,请解释这与并发症有什么关系。
  • iPhoe app - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions watch app ExtensionDelegate applicationDidFinishLaunching
  • edit您的问题并将代码添加到您的问题中。仅向我们提供您的代码所在的方法不足以让任何人确定您的委托方法没有被调用的原因。您还需要显示设置和处理会话调用的实际代码。谢谢!
  • 您需要在此处提供minimal reproducible example,而不是在 GitHub 上。但如果问题是您的复杂功能没有更新,那是因为您在手表应用程序中设置会话,而不是手表扩展程序的 init 方法。这已经在我链接的现有问题中进行了解释。

标签: ios objective-c watchconnectivity wcsession


【解决方案1】:

正如 PetahChristian 在 cmets 中所说,在您的 ExtensionController 类中更改此方法:

- (void)applicationDidFinishLaunching {
    // Perform any final initialization of your application.
   [self startWCSession];
}

成为:

- (instancetype)init
{
    self = [super init];
    if (self) {
        [self startWCSession];
    }
    return self;
}

- (void)applicationDidFinishLaunching {
    // Perform any final initialization of your application.
}

即使您的扩展程序正在后台运行以进行复杂功能更新,您也应该能够通过 WatchConnectivity 接收内容。

【讨论】:

  • 谢谢。我发现在 mycompany 的项目中,&lt;WCSession: 0x7f8418c25f20, hasDelegate: YES, activationState: 2&gt; 配对没有
  • 对不起,我不明白你的评论。你是说我上面的建议对你有用吗?如果它不起作用,你能否提供更多关于你尝试了什么以及它是如何失败的细节?
  • 我已经更新了问题,请再次查看。谢谢!
【解决方案2】:

我解决了这个问题。代码很烂。

- (void)configSession{
    dispatch_async(dispatch_get_main_queue(), ^{
    if (![WCSession isSupported]) {
        return;
    }
    _session = [WCSession defaultSession];
    [_session setDelegate:self];
    [_session activateSession];
   });
}

但我没有看到任何需要在主线程中调用此方法的文档。而且这个方法是在主线程之前调用的,所以我认为可能是runloop的问题。

【讨论】:

  • 很奇怪!您之前在哪个线程上运行此代码?
  • 之前在主线程上运行这段代码!很奇怪!?谢谢
  • 是的,不幸的是没有意义:(
猜你喜欢
  • 1970-01-01
  • 2023-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-20
相关资源
最近更新 更多