0

I have XCode 7.3, iPhone5 with iOS 9.3, Apple Watch with WatchOS 2.2

I have a company project which wants to support Watch App. Firstly, I built an empty project to make sure the watchkit and watchkit extension is working, and it does work. I can see the session is established and the watch is paired.

But after i put the same code into the company project, it can only work for once:the first time I RUN the app directly from Xcode.When I kill the app from background and open it again, the app shows no paired watch. In this condition , I got the log below: In iOS app

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

in watchKit Extension

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.}

my code about wcsession :

iOS APP

in 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;
}

in AppDelegate

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

watchKit Extension

in 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;
}

This is what I've tried up to now:

  • reset content and settings of all simulators

  • deleted watch app from watch &from iPhone

  • via settings in Watch App on Phone: Removed Watch Extension for Phone App and reinstalled it

  • Tried setting up the iPhone WCSession in AppDelegate INIT Method

I don't think the code is wrong, because it's working in an empty project.I wonder if the environment config has problems. I am struggling with this issue for many days now. So every hint is highly appreciated.

Alien
  • 31
  • 1
  • 5
  • Please post some actual code showing where you setup your session delegate and handle received messages. Also, please explain what this has to do with complications. –  Apr 06 '16 at 16:55
  • iPhoe app - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions watch app ExtensionDelegate applicationDidFinishLaunching – Alien Apr 06 '16 at 17:02
  • Please [edit] your question and add the code to your question. Only providing us the method where your code resides is not enough for anyone to determine why your delegate method isn't being called. You also need to show your actual code which sets up and handles the session calls. Thanks! –  Apr 06 '16 at 17:08
  • Possible duplicate of [Keeping my WatchKit complications up to date when not running](http://stackoverflow.com/questions/33198326/keeping-my-watchkit-complications-up-to-date-when-not-running) –  Apr 06 '16 at 17:13
  • You need to provide a [mcve] here, not on GitHub. But if the problem is that your complication isn't being updated, it's because you're setting up your session in your watch app instead of the watch extension init method. That's already explaining in the existing question I linked. –  Apr 06 '16 at 17:47

2 Answers2

1

As PetahChristian was saying in the comments, in your ExtensionController class change this method:

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

to be:

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

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

You should then be able to receive content via WatchConnectivity even if your extension is running in the background for a complication update.

Community
  • 1
  • 1
ccjensen
  • 4,578
  • 2
  • 23
  • 25
  • Thanks. I find that In mycompany's project the `` paired no – Alien Apr 08 '16 at 06:10
  • I'm sorry, I don't understand your comment. Are you saying my suggestion above worked for you, or not? If it didn't work, can you supply a bit more details about what you tried and how it failed? – ccjensen Apr 08 '16 at 06:14
  • I have updated the question,please check again.Thanks! – Alien Apr 08 '16 at 07:54
-1

I Solved this issue. The code is blow.

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

But I don't see any documents that need to call this method in the main thread. Moreover, this method is called before is in the main thread.So I think it might be the runloop problem.

Alien
  • 31
  • 1
  • 5