iosobjective-capple-watchwatchconnectivitywcsession

Trouble sending data from iPhone to WatchOS using Application Context


I am trying to send data from my iOS app to a companion WatchOS app using WCSession. The iOS app was created with NativeScript, thus the need for Objective-C.

When running the apps on both simulators and real devices I receive the following error message:

[WC] WCSession is missing its delegate

I've been messing around with this for a few days but unable to fix this issue.

iOS Objective-C Code (This is being called in Typescript):

#import "SendToWatch.h"
#import <WatchConnectivity/WatchConnectivity.h>

@interface SendToWatch () <WCSessionDelegate>

@end

@implementation SendToWatch

- (void)sendData: (double)value {
    if (WCSession.isSupported) {
        WCSession *session = [WCSession defaultSession];
        session.delegate = self;
        [session activateSession];

        NSError *error = nil;
        NSDictionary *applicationDict = @{@"data":[NSString stringWithFormat:@"%0.2f", value]};
        [session updateApplicationContext:applicationDict error:nil];

        if (error) {
            NSLog(@"%@", error.localizedDescription);

        }

    }
}

//MARK: - WCSessionDelegate

- (void)session:(WCSession *)session
activationDidCompleteWithState:(WCSessionActivationState)activationState
          error:(NSError *)error {
}

- (void)sessionDidBecomeInactive:(WCSession *)session {
    NSLog(@"Session Did Become Inactive");
}

- (void)sessionDidDeactivate:(WCSession *)session {
    NSLog(@"-- Session Did Deactivate --");
    [session activateSession];
}

@end

WatchOS (InterfaceController.m):

#import "InterfaceController.h"
#import <WatchConnectivity/WatchConnectivity.h>

@interface InterfaceController () <WCSessionDelegate>

@end

@implementation InterfaceController

- (void)awakeWithContext:(id)context {
    [super awakeWithContext:context];

    // Creates a WCSession to allow iPhone connectivity
    if ([WCSession isSupported]) {
        WCSession *session = [WCSession defaultSession];
        session.delegate = self;
        [session activateSession];
        NSLog(@"-- WCSession Active --");
    }
}

- (void)willActivate {
    [super willActivate];
    NSLog(@"-- Controller Activated --");
}

- (void)didDeactivate {
    [super didDeactivate];
    NSLog(@"-- Controller Deactive --");
}

//MARK: - WCSessionDelegate

// Receieves the data sent from the iPhone app
- (void)session:(nonnull WCSession *)session didReceiveApplicationContext:(nonnull NSDictionary *)applicationContext {
    NSString *receivedData = [applicationContext objectForKey:@"data"];

    NSLog(@"-- APPLICATION CONTEXT RECEIVED --");
    NSLog(@"-- Received from iOS App: %@", applicationContext);

    dispatch_async(dispatch_get_main_queue(), ^{
        [self.dataLabel setText:receivedData];
        NSLog(@"-- DATA UPDATED --");
    });
}

- (void)session:(WCSession *)session activationDidCompleteWithState:(WCSessionActivationState)activationState error:(NSError *)error {
}

@end

Solution

  • To fix this I had to re-write the Objective-C code in typescript using the tns-platform-declarations plugin. The WCSession now has a delegate and is sending data to my companion WatchOS app.