Commit 6c10703b authored by Tobias's avatar Tobias Committed by Felix Paul Kühne
Browse files

first step of formalizing of Watch -> App communication

parent 219932af
//
// VLCWatchMessage.h
// VLC for iOS
//
// Created by Tobias Conradi on 02.05.15.
// Copyright (c) 2015 VideoLAN. All rights reserved.
//
#import <Foundation/Foundation.h>
extern NSString *const VLCWatchMessageNameGetNowPlayingInfo;
extern NSString *const VLCWatchMessageNamePlayPause;
extern NSString *const VLCWatchMessageNameSkipForward;
extern NSString *const VLCWatchMessageNameSkipBackward;
extern NSString *const VLCWatchMessageNamePlayFile;
extern NSString *const VLCWatchMessageNameSetVolume;
@interface VLCWatchMessage : NSObject
@property (nonatomic, readonly) NSString *name;
@property (nonatomic, readonly) id<NSObject,NSCoding> payload;
@property (nonatomic, readonly) NSDictionary *dictionaryRepresentation;
- (instancetype)initWithName:(NSString *)name payload:(id<NSObject,NSCoding>)payload;
- (instancetype)initWithDictionary:(NSDictionary *)dictionary;
+ (NSDictionary *)messageDictionaryForName:(NSString *)name payload:(id<NSObject,NSCoding>)payload;
+ (NSDictionary *)messageDictionaryForName:(NSString *)name;
@end
//
// VLCWatchMessage.m
// VLC for iOS
//
// Created by Tobias Conradi on 02.05.15.
// Copyright (c) 2015 VideoLAN. All rights reserved.
//
#import "VLCWatchMessage.h"
NSString *const VLCWatchMessageNameGetNowPlayingInfo = @"getNowPlayingInfo";
NSString *const VLCWatchMessageNamePlayPause = @"playpause";
NSString *const VLCWatchMessageNameSkipForward = @"skipForward";
NSString *const VLCWatchMessageNameSkipBackward = @"skipBackward";
NSString *const VLCWatchMessageNamePlayFile = @"playFile";
NSString *const VLCWatchMessageNameSetVolume = @"setVolume";
static NSString *const VLCWatchMessageNameKey = @"name";
static NSString *const VLCWatchMessagePayloadKey = @"payload";
@implementation VLCWatchMessage
@synthesize dictionaryRepresentation = _dictionaryRepresentation;
- (instancetype)initWithName:(NSString *)name payload:(id<NSObject, NSCoding>)payload
{
self = [super init];
if (self) {
_name = [name copy];
_payload = payload;
}
return self;
}
- (instancetype)initWithDictionary:(NSDictionary *)dictionary
{
NSString *name = dictionary[VLCWatchMessageNameKey];
id<NSObject> payloadObject = dictionary[VLCWatchMessagePayloadKey];
id payload = [self payloadFromPayloadObject:payloadObject];
return [self initWithName:name payload:payload];
}
- (NSDictionary *)dictionaryRepresentation
{
if (!_dictionaryRepresentation) {
_dictionaryRepresentation = [self.class messageDictionaryForName:self.name payload:self.payload];
}
return _dictionaryRepresentation;
}
- (id)payloadFromPayloadObject:(id<NSObject>)payloadObject {
id payload;
if ([payloadObject isKindOfClass:[NSData class]]) {
@try {
payload = [NSKeyedUnarchiver unarchiveObjectWithData:(NSData *)payloadObject];
}
@catch (NSException *exception) {
NSLog(@"%s Failed to decode payload with exception: %@",__PRETTY_FUNCTION__,exception);
}
} else {
payload = payloadObject;
}
return payload;
}
+ (NSDictionary *)messageDictionaryForName:(NSString *)name payload:(id<NSObject,NSCoding>)payload
{
id payloadObject;
BOOL noArchiving = [payload isKindOfClass:[NSNumber class]] || [payload isKindOfClass:[NSString class]];
if (noArchiving) {
payloadObject = payload;
} else if (payload != nil) {
payloadObject = [NSKeyedArchiver archivedDataWithRootObject:payload];
}
// we use nil termination so when payloadData is nil payload is not set
return [NSDictionary dictionaryWithObjectsAndKeys:
name,VLCWatchMessageNameKey,
payloadObject, VLCWatchMessagePayloadKey,
nil];
}
+ (NSDictionary *)messageDictionaryForName:(NSString *)name
{
return [self messageDictionaryForName:name payload:nil];
}
- (NSString *)debugDescription
{
return [NSString stringWithFormat:@"<%@: %p name=%@, payload=%@>",NSStringFromClass(self.class), self, _name, _payload];
}
@end
......@@ -32,6 +32,7 @@
#import "VLCNotificationRelay.h"
#import "VLCPlaybackController.h"
#import "VLCNavigationController.h"
#import "VLCWatchMessage.h"
#define HAVE_FABRIC 0
......@@ -662,45 +663,47 @@
taskIdentifier = UIBackgroundTaskInvalid;
}];
VLCWatchMessage *message = [[VLCWatchMessage alloc] initWithDictionary:userInfo];
NSString *name = message.name;
NSDictionary *responseDict = nil;
if ([userInfo[@"name"] isEqualToString:@"getNowPlayingInfo"]) {
if ([name isEqualToString:VLCWatchMessageNameGetNowPlayingInfo]) {
responseDict = [self nowPlayingResponseDict];
} else if ([userInfo[@"name"] isEqualToString:@"playpause"]) {
} else if ([name isEqualToString:VLCWatchMessageNamePlayPause]) {
[[VLCPlaybackController sharedInstance] playPause];
responseDict = @{@"playing": @([VLCPlaybackController sharedInstance].isPlaying)};
} else if ([userInfo[@"name"] isEqualToString:@"skipForward"]) {
} else if ([name isEqualToString:VLCWatchMessageNameSkipForward]) {
[[VLCPlaybackController sharedInstance] forward];
} else if ([userInfo[@"name"] isEqualToString:@"skipBackward"]) {
} else if ([name isEqualToString:VLCWatchMessageNameSkipBackward]) {
[[VLCPlaybackController sharedInstance] backward];
} else if ([userInfo[@"name"] isEqualToString:@"playFile"]) {
[self playFileFromWatch:userInfo[@"userInfo"]];
} else if ([userInfo[@"name"] isEqualToString:@"setVolume"]) {
[self setVolumeFromWatch:userInfo[@"userInfo"]];
} else if ([name isEqualToString:VLCWatchMessageNamePlayFile]) {
[self playFileFromWatch:message];
} else if ([name isEqualToString:VLCWatchMessageNameSetVolume]) {
[self setVolumeFromWatch:message];
} else {
NSLog(@"Did not handle request from WatchKit Extension: %@",userInfo);
}
reply(responseDict);
}
- (void)playFileFromWatch:(NSDictionary *)userInfo
- (void)playFileFromWatch:(VLCWatchMessage *)message
{
NSManagedObject *managedObject = nil;
NSString *uriString = userInfo[@"URIRepresentation"];
if (uriString) {
NSString *uriString = (id)message.payload;
if ([uriString isKindOfClass:[NSString class]]) {
NSURL *uriRepresentation = [NSURL URLWithString:uriString];
managedObject = [[MLMediaLibrary sharedMediaLibrary] objectForURIRepresentation:uriRepresentation];
}
if (managedObject == nil) {
NSLog(@"%s file not found: %@",__PRETTY_FUNCTION__,userInfo);
NSLog(@"%s file not found: %@",__PRETTY_FUNCTION__,message);
return;
}
[self openMediaFromManagedObject:managedObject];
}
- (void)setVolumeFromWatch:(NSDictionary *)userInfo
- (void)setVolumeFromWatch:(VLCWatchMessage *)message
{
NSNumber *volume = userInfo[@"volume"];
NSNumber *volume = (id)message.payload;
if ([volume isKindOfClass:[NSNumber class]]) {
/*
* Since WatchKit doen't provide something like MPVolumeView we use deprecated API.
......
......@@ -15,6 +15,7 @@
#import <MobileVLCKit/MobileVLCKit.h>
#import "VLCThumbnailsCache.h"
#import "WKInterfaceObject+VLCProgress.h"
#import "VLCWatchMessage.h"
@interface VLCDetailInterfaceController ()
@property (nonatomic, weak) NSManagedObject *managedObject;
......@@ -86,12 +87,12 @@
}
- (IBAction)playNow {
NSDictionary *dict = @{@"name":@"playFile",
@"userInfo":@{
@"URIRepresentation": self.managedObject.objectID.URIRepresentation.absoluteString,
}
};
id payload = self.managedObject.objectID.URIRepresentation.absoluteString;
NSDictionary *dict = [VLCWatchMessage messageDictionaryForName:@"playFile"
payload:payload];
[self updateUserActivity:@"org.videolan.vlc-ios.playing" userInfo:@{@"playingmedia":self.managedObject.objectID.URIRepresentation} webpageURL:nil];
[WKInterfaceController openParentApplication:dict reply:^(NSDictionary *replyInfo, NSError *error) {
[self showNowPlaying:nil];
}];
......
......@@ -17,6 +17,7 @@
#import "VLCNotificationRelay.h"
#import "VLCThumbnailsCache.h"
#import "WKInterfaceObject+VLCProgress.h"
#import "VLCWatchMessage.h"
@interface VLCNowPlayingInterfaceController ()
{
......@@ -71,7 +72,7 @@
}
- (void)requestNowPlayingInfo {
[WKInterfaceController openParentApplication:@{@"name": @"getNowPlayingInfo"} reply:^(NSDictionary *replyInfo, NSError *error) {
[WKInterfaceController openParentApplication:[VLCWatchMessage messageDictionaryForName:VLCWatchMessageNameGetNowPlayingInfo] reply:^(NSDictionary *replyInfo, NSError *error) {
MLFile *file = nil;
NSString *uriString = replyInfo[@"URIRepresentation"];
if (uriString) {
......@@ -123,7 +124,8 @@
}
- (IBAction)playPausePressed {
[WKInterfaceController openParentApplication:@{@"name": @"playpause"} reply:^(NSDictionary *replyInfo, NSError *error) {
NSDictionary *dict = [VLCWatchMessage messageDictionaryForName:VLCWatchMessageNamePlayPause];
[WKInterfaceController openParentApplication:dict reply:^(NSDictionary *replyInfo, NSError *error) {
NSNumber *playing = replyInfo[@"playing"];
if ([playing isKindOfClass:[NSNumber class]]) {
self.playing = playing.boolValue;
......@@ -136,14 +138,18 @@
}
- (IBAction)skipForward {
[WKInterfaceController openParentApplication:@{@"name": @"skipForward"} reply:^(NSDictionary *replyInfo, NSError *error) {
NSDictionary *dict = [VLCWatchMessage messageDictionaryForName:VLCWatchMessageNameSkipForward];
[WKInterfaceController openParentApplication:dict reply:^(NSDictionary *replyInfo, NSError *error) {
if (error)
NSLog(@"skipForward failed with reply %@ error: %@",replyInfo,error);
}];
}
- (IBAction)skipBackward {
[WKInterfaceController openParentApplication:@{@"name": @"skipBackward"} reply:^(NSDictionary *replyInfo, NSError *error) {
NSDictionary *dict = [VLCWatchMessage messageDictionaryForName:VLCWatchMessageNameSkipBackward];
[WKInterfaceController openParentApplication:dict reply:^(NSDictionary *replyInfo, NSError *error) {
if (error)
NSLog(@"skipBackward failed with reply %@ error: %@",replyInfo,error);
}];
......@@ -151,11 +157,8 @@
- (IBAction)volumeSliderChanged:(float)value {
_volume = value;
NSDictionary *dict = @{@"name" : @"setVolume",
@"userInfo" : @{
@"volume" : @(value)
},
};
NSDictionary *dict = [VLCWatchMessage messageDictionaryForName:VLCWatchMessageNameSetVolume
payload:@(value)];
[WKInterfaceController openParentApplication:dict reply:^(NSDictionary *replyInfo, NSError *error) {
if (error)
NSLog(@"setVolume failed with reply %@ error: %@",replyInfo,error);
......
......@@ -552,6 +552,8 @@
DD02C30B1ACAF0370026EFEE /* libstdc++.6.0.9.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DD02C30A1ACAF0370026EFEE /* libstdc++.6.0.9.dylib */; };
DD02C30E1ACAF4A50026EFEE /* VLCRowController.m in Sources */ = {isa = PBXBuildFile; fileRef = DD02C30D1ACAF4A50026EFEE /* VLCRowController.m */; };
DD1542121ACFF76400AFD4EC /* VLCWatchTableController.m in Sources */ = {isa = PBXBuildFile; fileRef = DD1542111ACFF76400AFD4EC /* VLCWatchTableController.m */; };
DD3EA6311AF50CFE007FF096 /* VLCWatchMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = DD3EA6301AF50CFE007FF096 /* VLCWatchMessage.m */; };
DD3EA6321AF50D01007FF096 /* VLCWatchMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = DD3EA6301AF50CFE007FF096 /* VLCWatchMessage.m */; };
DD6FA7B01ACD641C006DEB2E /* VLCNowPlayingInterfaceController.m in Sources */ = {isa = PBXBuildFile; fileRef = DD6FA7AF1ACD641C006DEB2E /* VLCNowPlayingInterfaceController.m */; };
DD7110F01AF38B2B00854776 /* MLMediaLibrary+playlist.m in Sources */ = {isa = PBXBuildFile; fileRef = DD7110EF1AF38B2B00854776 /* MLMediaLibrary+playlist.m */; };
DD7110F11AF38B2B00854776 /* MLMediaLibrary+playlist.m in Sources */ = {isa = PBXBuildFile; fileRef = DD7110EF1AF38B2B00854776 /* MLMediaLibrary+playlist.m */; };
......@@ -1621,6 +1623,8 @@
DD02C30D1ACAF4A50026EFEE /* VLCRowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCRowController.m; sourceTree = "<group>"; };
DD1542101ACFF76400AFD4EC /* VLCWatchTableController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCWatchTableController.h; sourceTree = "<group>"; };
DD1542111ACFF76400AFD4EC /* VLCWatchTableController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCWatchTableController.m; sourceTree = "<group>"; };
DD3EA62F1AF50CFE007FF096 /* VLCWatchMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCWatchMessage.h; sourceTree = "<group>"; };
DD3EA6301AF50CFE007FF096 /* VLCWatchMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCWatchMessage.m; sourceTree = "<group>"; };
DD6FA7AE1ACD641C006DEB2E /* VLCNowPlayingInterfaceController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCNowPlayingInterfaceController.h; sourceTree = "<group>"; };
DD6FA7AF1ACD641C006DEB2E /* VLCNowPlayingInterfaceController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCNowPlayingInterfaceController.m; sourceTree = "<group>"; };
DD7110EE1AF38B2B00854776 /* MLMediaLibrary+playlist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MLMediaLibrary+playlist.h"; sourceTree = "<group>"; };
......@@ -3025,6 +3029,8 @@
children = (
DD7110EE1AF38B2B00854776 /* MLMediaLibrary+playlist.h */,
DD7110EF1AF38B2B00854776 /* MLMediaLibrary+playlist.m */,
DD3EA62F1AF50CFE007FF096 /* VLCWatchMessage.h */,
DD3EA6301AF50CFE007FF096 /* VLCWatchMessage.m */,
);
path = SharedSources;
sourceTree = "<group>";
......@@ -3650,6 +3656,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
DD3EA6321AF50D01007FF096 /* VLCWatchMessage.m in Sources */,
DD6FA7B01ACD641C006DEB2E /* VLCNowPlayingInterfaceController.m in Sources */,
7DE715ED1AD2DAE50075E716 /* VLCThumbnailsCache.m in Sources */,
7D298F451AD58A0700A0BF68 /* UIImage+Blur.m in Sources */,
......@@ -3740,6 +3747,7 @@
7D50903218F41C7900180139 /* VLCAlertView.m in Sources */,
7DBBF182183AB3B80009A339 /* VLCAppDelegate.m in Sources */,
7D3784C0183A9938009EE944 /* VLCLinearProgressIndicator.m in Sources */,
DD3EA6311AF50CFE007FF096 /* VLCWatchMessage.m in Sources */,
41CD695D1A29D72600E60BCE /* VLCBoxTableViewController.m in Sources */,
7D3784C1183A9938009EE944 /* VLCMenuButton.m in Sources */,
41CD695C1A29D72600E60BCE /* VLCBoxController.m in Sources */,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment