A local network connection from the Apple Watch app to another device works on the simulator, but not on the Watch

I am trying to create an app for my Apple Watch to remotely control a media player (omxplayer) on a Raspberry Pi.

I got it in a simulator in Xcode, but it doesn't work on the actual clock.

On a Raspberry Pi, I have a simple python script that starts a TCP server and listens for commands.

In the InterfaceController.m file of the WatchKit renewal project, I have the following code:

- (IBAction)playPauseButtonPressed {    
    [self initNetworkCommunication];
    [self sendNetworkCommand:@"play"];
    [self closeNetworkCommunication];
}

-(void)initNetworkCommunication {
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;

    CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"192.168.10.116", 10010, &readStream, &writeStream);

    if(!CFWriteStreamOpen(writeStream)) {
        NSLog(@"Error, writeStream not open");

        return;
    }

    inputStream = (NSInputStream *)CFBridgingRelease(readStream);
    outputStream = (NSOutputStream *)CFBridgingRelease(writeStream);

    [inputStream setDelegate:self];
    [outputStream setDelegate:self];

    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

    [inputStream open];
    [outputStream open];
}

-(void)sendNetworkCommand:(NSString *) command {    
    NSData *data = [[NSData alloc] initWithData:[command dataUsingEncoding:NSASCIIStringEncoding]];
    [outputStream write:[data bytes] maxLength:[data length]];
}

-(void)closeNetworkCommunication {        
    [inputStream close];
    [outputStream close];

    [inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

    [inputStream setDelegate:nil];
    [outputStream setDelegate:nil];

    inputStream = nil;
    outputStream = nil;
}

      

When I click a button in the My Watch app, "playPauseButtonPressed" is called. This connection initiates a network connection to the Raspberry Pi and sends a string.

As I said, it works on the Watch simulator, but not on a real device.

Please note that the same code works in an iOS app on a real device.

Any help would be appreciated!

+3


source to share


1 answer


Ok, I started working. In the meantime, I have upgraded to WatchKit 2.0 SDK. Here is my code (still needs work) in case anyone is interested:

ExtensionDelegate.m clock extensions:

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

    if ([WCSession isSupported]) {
        WCSession *session = [WCSession defaultSession];
        session.delegate = self;
        [session activateSession];
    }
}

      

InterfaceController.m clock extensions:



- (IBAction)playPauseButtonPressed
{
    [self sendCommandToPhone:@"pause"];
}

- (IBAction)seekBackwardButtonPressed
{
    [self sendCommandToPhone:@"seek_backward"];
}

- (IBAction)seekForwardButtonPressed
{
    [self sendCommandToPhone:@"seek_forward"];
}

- (IBAction)subtitleButtonPressed
{
    [self sendCommandToPhone:@"subtitle"];
}

- (void)sendCommandToPhone:(NSString *)command
{
    NSLog(@"sendCommandToPhone called");

    NSDictionary *dict = [[NSDictionary alloc] initWithObjectsAndKeys:command, @"command", nil];
    [[WCSession defaultSession] sendMessage:dict
                               replyHandler:^(NSDictionary *replyHandler) {
                               }
                               errorHandler:^(NSError *error) {
                                   NSLog(@"%@", [error localizedDescription]);
                               }
    ];
}

      

ViewController.m iPhone app:

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Init communication with watch
    if ([WCSession isSupported]) {
        WCSession *session = [WCSession defaultSession];
        session.delegate = self;
        [session activateSession];

        NSLog(@"WCSession initialized");
    }
}

// Message received from the watch
- (void)session:(WCSession * _Nonnull)session didReceiveMessage:(NSDictionary<NSString *, id> * _Nonnull)message
{
    NSLog(@"didReceiveMessage called");
    [self sendCommandToPlayerAndCloseConnection:message[@"command"]];
}

- (IBAction)connectButtonPressed:(id)sender
{
    [self sendCommandToPlayer:@"list_dir"];
    [self performSegueWithIdentifier:@"toFileTableViewController" sender:self];
}

- (IBAction)seekBackwardButtonPressed:(id)sender
{
    [self sendCommandToPlayerAndCloseConnection:@"seek_backward"];
}

- (IBAction)seekForwardButtonPressed:(id)sender
{
    [self sendCommandToPlayerAndCloseConnection:@"seek_forward"];
}

- (IBAction)stopButtonPressed:(id)sender
{
    [self sendCommandToPlayerAndCloseConnection:@"stop"];
}

- (IBAction)playPauseButtonPressed:(id)sender
{
    [self sendCommandToPlayerAndCloseConnection:@"pause"];
}

- (void)sendCommandToPlayer:(NSString *) command
{
    NSLog(@"%@", [NSString stringWithFormat:@"Sending command to player : %@", command]);

    [self initNetworkCommunication];

    NSData *data = [[NSData alloc] initWithData:[command dataUsingEncoding:NSASCIIStringEncoding]];
    [outputStream write:[data bytes] maxLength:[data length]];
}

- (void)sendCommandToPlayerAndCloseConnection:(NSString *) command
{
    [self sendCommandToPlayer:command];
    [self closeNetworkCommunication];
}

-(void)initNetworkCommunication
{
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;

    CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"192.168.10.116", 10023, &readStream, &writeStream);

    if(!CFWriteStreamOpen(writeStream)) {
        NSLog(@"Error, writeStream not open");

        return;
    }

    inputStream = (__bridge NSInputStream *) readStream;
    outputStream = (__bridge NSOutputStream *) writeStream;

    [inputStream setDelegate:self];
    [outputStream setDelegate:self];

    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

    [inputStream open];
    [outputStream open];
}

-(void)closeNetworkCommunication
{    
    [inputStream close];
    [outputStream close];

    [inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

    [inputStream setDelegate:nil];
    [outputStream setDelegate:nil];

    inputStream = nil;
    outputStream = nil;
}

      

Now I can control omxplayer from my phone and my watch;)

+3


source







All Articles