Commit 368887bd authored by Carola Nitz's avatar Carola Nitz

Remove Watchcode and adjust related files

parent 311679fb
......@@ -13,7 +13,9 @@ def shared_pods
pod 'SwiftLint', '~> 0.25.0'
end
def iOS_pods
target 'VLC-iOS' do
platform :ios, '9.0'
shared_pods
pod 'OBSlider', '1.1.0'
pod 'InAppSettingsKit', :git => 'git://github.com/fkuehne/InAppSettingsKit.git', :commit => '415ea6bb' #tvOS fix
pod 'HockeySDK', '~>5.1.2', :subspecs => ['CrashOnlyLib']
......@@ -25,18 +27,6 @@ def iOS_pods
pod 'GTMAppAuth'
end
target 'VLC-iOS' do
platform :ios, '9.0'
shared_pods
iOS_pods
end
target 'VLC-iOS-no-watch' do
platform :ios, '9.0'
shared_pods
iOS_pods
end
target 'VLC-tvOS' do
platform :tvos, '10.2'
shared_pods
......@@ -47,27 +37,13 @@ target 'VLC-tvOS' do
pod 'TVVLCKit', '3.0.2'
end
target 'VLC-watchOS-Extension' do
platform :watchos, '2.0'
pod 'MediaLibraryKit-unstable'
end
post_install do |installer_representation|
installer_representation.pods_project.targets.each do |target|
if target.name == 'VLC-watchOS-Extension'
installer_representation.pods_project.build_configurations.each do |config|
config.build_settings['SKIP_INSTALL'] = 'YES'
config.build_settings['CLANG_CXX_LIBRARY'] = 'libc++'
config.build_settings['VALID_ARCHS'] = 'armv7 armv7s arm64 i386 armv7k'
config.build_settings['ARCHS'] = 'armv7 armv7s arm64 i386 armv7k'
end
else
installer_representation.pods_project.build_configurations.each do |config|
config.build_settings['SKIP_INSTALL'] = 'YES'
config.build_settings['VALID_ARCHS'] = 'armv7 armv7s arm64 i386 armv7k'
config.build_settings['ARCHS'] = 'armv7 armv7s arm64 i386 armv7k'
config.build_settings['CLANG_CXX_LIBRARY'] = 'libc++'
end
end
installer_representation.pods_project.build_configurations.each do |config|
config.build_settings['SKIP_INSTALL'] = 'YES'
config.build_settings['VALID_ARCHS'] = 'armv7 armv7s arm64 i386 armv7k'
config.build_settings['ARCHS'] = 'armv7 armv7s arm64 i386 armv7k'
config.build_settings['CLANG_CXX_LIBRARY'] = 'libc++'
end
end
end
......@@ -38,8 +38,6 @@ PODS:
- InAppSettingsKit (2.2.2)
- MediaLibraryKit-prod (2.6.5):
- MobileVLCKit (~> 3.0.1)
- MediaLibraryKit-unstable (2.6.5):
- MobileVLCKit-unstable (~> 3.0.0a8)
- MetaDataFetcherKit (0.3.1):
- AFNetworking (= 3.1.0)
- OROpenSubtitleDownloader
......@@ -71,7 +69,6 @@ DEPENDENCIES:
- HockeySDK/CrashOnlyLib (~> 5.1.2)
- InAppSettingsKit (from `git://github.com/fkuehne/InAppSettingsKit.git`, commit `415ea6bb`)
- MediaLibraryKit-prod
- MediaLibraryKit-unstable
- MetaDataFetcherKit (~> 0.3.1)
- MobileVLCKit (= 3.0.2)
- ObjectiveDropboxOfficial (from `git://github.com/carolanitz/dropbox-sdk-obj-c.git`)
......@@ -130,7 +127,6 @@ SPEC CHECKSUMS:
HockeySDK-tvOS: 6b2a69f86419ebaf23225f59a64e5761ed3a0d8a
InAppSettingsKit: 76d5cfbaa3e3f8aa53fe3628516da7eb1aa6a5cb
MediaLibraryKit-prod: 095dce5faa59e2bb0a537646ac09fe57eaf3fbdf
MediaLibraryKit-unstable: aaf147005a2e024ed2f4c45440bfcc19225ca776
MetaDataFetcherKit: d1d61b061bf74268aaffb6bf08a70396672163df
MobileVLCKit: a9e06de53e7a7fd43d7b04bcab4f2e68868f768a
NSData+Base64: 4e84902c4db907a15673474677e57763ef3903e4
......@@ -147,6 +143,6 @@ SPEC CHECKSUMS:
XKKeychain: 852ef663c56a7194c73d3c68e8d9d4f07b121d4f
xmlrpc: 109bb21d15ed6d108b2c1ac5973a6a223a50f5f4
PODFILE CHECKSUM: c8dbb4c0b180876fb032d297e7e1ca3dbf736b6b
PODFILE CHECKSUM: 1db4a441715ef12947bbe7bfdcfdbb86d52919fb
COCOAPODS: 1.4.0
......@@ -200,7 +200,6 @@
"BWD_BUTTON" = "Jump Backwards";
"FWD_BUTTON" = "Jump Forwards";
"PLAY_BUTTON" = "Play";
"PAUSE_BUTTON" = "Pause";
"PLAY_ALL_BUTTON" = "Play all";
"VERSION_FORMAT" = "Version: %@";
......@@ -257,36 +256,15 @@
"WEBINTF_URL_INVALID" = "Not a valid URL.";
"NOW_PLAYING" = "Now Playing";
"PLAY_NOW" = "Play Now";
"PLAYING" = "Playing";
"DETAIL" = "Detail";
"VOLUME" = "Volume";
"DURATION" = "Duration";
"TITLE" = "Title";
// strings from VLCKit
"%ld hours %ld minutes remaining" = "%1$ld hours %2$ld minutes remaining";
"%ld hours %ld minutes" = "%1$ld hours %2$ld minutes";
"%ld minutes remaining" = "%ld minutes remaining";
"%ld minutes" = "%ld minutes";
"%ld minutes %ld seconds remaining" = "%1$ld minutes %2$ld seconds remaining";
"%ld minutes %ld seconds" = "%1$ld minutes %2$ld seconds";
"%ld seconds remaining" = "%ld seconds remaining";
"%ld seconds" = "%ld seconds";
// accessibility labels for the playlist
"OBJECT_TYPE_SHOW" = "Show";
"OBJECT_TYPE_SHOW_EPISODE" = "Show episode";
"OBJECT_TYPE_LABEL" = "Folder";
"OBJECT_TYPE_ALBUM" = "Album";
"OBJECT_TYPE_ALBUM_TRACK" = "Album track";
"OBJECT_TYPE_FILE" = "File";
"OBJECT_TYPE_FILE_AUDIO" = "Audio file";
"NOT_CONNECTED_TO_PHONE_TITLE" = "Not connected to iPhone";
"NOT_CONNECTED_TO_PHONE_MESSAGE" = "Please connect your iPhone to perform remote control actions.";
"LONGPRESS_TO_STOP" = "Long-press to stop playback.";
......
//
// VLCWatchMessage.h
// VLC for iOS
//
// Created by Tobias Conradi on 02.05.15.
// Copyright (c) 2015 VideoLAN. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
extern NSString *const VLCWatchMessageNameGetNowPlayingInfo;
extern NSString *const VLCWatchMessageNamePlayPause;
extern NSString *const VLCWatchMessageNameSkipForward;
extern NSString *const VLCWatchMessageNameSkipBackward;
extern NSString *const VLCWatchMessageNamePlayFile;
extern NSString *const VLCWatchMessageNameSetVolume;
extern NSString *const VLCWatchMessageNameNotification;
extern NSString *const VLCWatchMessageNameRequestThumbnail;
extern NSString *const VLCWatchMessageNameRequestDB;
extern NSString *const VLCWatchMessageKeyURIRepresentation;
@interface VLCWatchMessage : NSObject
@property (nonatomic, readonly) NSString *name;
@property (nonatomic, readonly, nullable) id<NSObject,NSCoding> payload;
@property (nonatomic, readonly) NSDictionary *dictionaryRepresentation;
- (instancetype)initWithName:(NSString *)name payload:(nullable id<NSObject,NSCoding>)payload;
- (instancetype)initWithDictionary:(NSDictionary *)dictionary;
+ (NSDictionary *)messageDictionaryForName:(NSString *)name payload:(nullable id<NSObject,NSCoding>)payload;
+ (NSDictionary *)messageDictionaryForName:(NSString *)name;
@end
NS_ASSUME_NONNULL_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";
NSString *const VLCWatchMessageNameNotification = @"notification";
NSString *const VLCWatchMessageNameRequestThumbnail = @"requestThumbnail";
NSString *const VLCWatchMessageNameRequestDB = @"requestDB";
NSString *const VLCWatchMessageKeyURIRepresentation = @"URIRepresentation";
static NSString *const VLCWatchMessageNameKey = @"name";
static NSString *const VLCWatchMessagePayloadKey = @"payload";
@implementation VLCWatchMessage
@synthesize dictionaryRepresentation = _dictionaryRepresentation;
- (instancetype)initWithName:(NSString *)name payload:(nullable 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:(nullable 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
......@@ -2,7 +2,7 @@
* VLCAppDelegate.h
* VLC for iOS
*****************************************************************************
* Copyright (c) 2013-2015 VideoLAN. All rights reserved.
* Copyright (c) 2013-2018 VideoLAN. All rights reserved.
* $Id$
*
* Authors: Felix Paul Kühne <fkuehne # videolan.org>
......@@ -14,15 +14,12 @@
* Refer to the COPYING file of the official project for license.
*****************************************************************************/
#import "VLCWatchCommunication.h"
#import <AppAuth/AppAuth.h>
extern NSString *const VLCDropboxSessionWasAuthorized;
@interface VLCAppDelegate : UIResponder <UIApplicationDelegate>
@property (nonatomic, readonly) VLCWatchCommunication *watchCommunication;
@property (nonatomic, strong) UIWindow *window;
@property (atomic, strong) id<OIDAuthorizationFlowSession> currentGoogleAuthorizationFlow;
......
......@@ -44,7 +44,6 @@ NSString *const VLCDropboxSessionWasAuthorized = @"VLCDropboxSessionWasAuthorize
{
BOOL _isRunningMigration;
BOOL _isComingFromHandoff;
VLCWatchCommunication *_watchCommunication;
VLCKeychainCoordinator *_keychainCoordinator;
AppCoordinator *appCoordinator;
UITabBarController *rootViewController;
......@@ -156,13 +155,6 @@ NSString *const VLCDropboxSessionWasAuthorized = @"VLCDropboxSessionWasAuthorize
setupBlock();
}
if ([VLCWatchCommunication isSupported]) {
_watchCommunication = [VLCWatchCommunication sharedInstance];
// TODO: push DB changes instead
// [_watchCommunication startRelayingNotificationName:NSManagedObjectContextDidSaveNotification object:nil];
[_watchCommunication startRelayingNotificationName:VLCPlaybackControllerPlaybackMetadataDidChange object:nil];
}
/* add our static shortcut items the dynamic way to ease l10n and dynamic elements to be introduced later */
if (@available(iOS 9, *)) {
if (application.shortcutItems == nil || application.shortcutItems.count < 4) {
......@@ -481,14 +473,4 @@ didFailToContinueUserActivityWithType:(NSString *)userActivityType
[vpc playMediaList:mediaList firstIndex:0 subtitlesFilePath:nil];
}
#pragma mark - watch stuff
- (void)application:(UIApplication *)application
handleWatchKitExtensionRequest:(NSDictionary *)userInfo
reply:(void (^)(NSDictionary *))reply
{
if ([VLCWatchCommunication isSupported]) {
[self.watchCommunication session:[WCSession defaultSession] didReceiveMessage:userInfo replyHandler:reply];
}
}
@end
......@@ -16,7 +16,6 @@
#import "VLCThumbnailsCache.h"
#import <CommonCrypto/CommonDigest.h>
#import "UIImage+Blur.h"
#import <WatchKit/WatchKit.h>
#import <CoreData/CoreData.h>
#import <MediaLibraryKit/MediaLibraryKit.h>
#import <MediaLibraryKit/UIImage+MLKit.h>
......@@ -36,14 +35,11 @@
#define MAX_CACHE_SIZE_IPHONE 21 // three times the number of items shown on iPhone 5
#define MAX_CACHE_SIZE_IPAD 27 // three times the number of items shown on iPad
#define MAX_CACHE_SIZE_WATCH 15 // three times the number of items shown on 42mm Watch
- (instancetype)init
{
self = [super init];
if (self) {
// TODO: correct for watch
#if TARGET_OS_IOS
_currentDeviceIdiom = [[UIDevice currentDevice] userInterfaceIdiom];
MaxCacheSize = 0;
......@@ -54,14 +50,7 @@
case UIUserInterfaceIdiomPhone:
MaxCacheSize = MAX_CACHE_SIZE_IPHONE;
break;
default:
MaxCacheSize = MAX_CACHE_SIZE_WATCH;
break;
}
#else
MaxCacheSize = MAX_CACHE_SIZE_WATCH;
#endif
_thumbnailCache = [[NSCache alloc] init];
_thumbnailCacheMetadata = [[NSCache alloc] init];
[_thumbnailCache setCountLimit: MaxCacheSize];
......@@ -278,8 +267,6 @@
{
UIImage *clusterThumb;
CGSize imageSize = CGSizeZero;
// TODO: correct for watch
#ifndef TARGET_OS_WATCH
if (_currentDeviceIdiom == UIUserInterfaceIdiomPad) {
if ([UIScreen mainScreen].scale==2.0)
imageSize = CGSizeMake(682., 384.);
......@@ -290,13 +277,6 @@
imageSize = CGSizeMake(480., 270.);
else
imageSize = CGSizeMake(720., 405.);
} else
#endif
{
if (WKInterfaceDevice.currentDevice != nil) {
CGRect screenRect = WKInterfaceDevice.currentDevice.screenBounds;
imageSize = CGSizeMake(screenRect.size.width * WKInterfaceDevice.currentDevice.screenScale, 120.);
}
}
UIGraphicsBeginImageContext(imageSize);
......@@ -324,12 +304,7 @@
if (!blurImage)
return clusterThumb;
// TODO: When we move to watch os 4.0 we can include the blurcategory and remove the if else block
#ifndef TARGET_OS_WATCH
return [UIImage applyBlurOnImage:clusterThumb withRadius:0.1];
#else
return clusterThumb;
#endif
}
@end
/*****************************************************************************
* VLCWatchCommunication.h
* VLC for iOS
*****************************************************************************
* Copyright (c) 2015 VideoLAN. All rights reserved.
* $Id$
*
* Author: Tobias Conradi <videolan # tobias-conradi.de>
*
* Refer to the COPYING file of the official project for license.
*****************************************************************************/
#import <Foundation/Foundation.h>
#import <WatchConnectivity/WatchConnectivity.h>
NS_ASSUME_NONNULL_BEGIN
@interface VLCWatchCommunication : NSObject <WCSessionDelegate>
+ (BOOL)isSupported;
+ (instancetype)sharedInstance;
- (void)startRelayingNotificationName:(nullable NSString *)name object:(nullable id)object;
- (void)stopRelayingNotificationName:(nullable NSString *)name object:(nullable id)object;
@end
NS_ASSUME_NONNULL_END
\ No newline at end of file
/*****************************************************************************
* VLCWatchCommunication.m
* VLC for iOS
*****************************************************************************
* Copyright (c) 2015 VideoLAN. All rights reserved.
* $Id$
*
* Author: Tobias Conradi <videolan # tobias-conradi.de>
*
* Refer to the COPYING file of the official project for license.
*****************************************************************************/
#import "VLCWatchCommunication.h"
#import "VLCWatchMessage.h"
#import "VLCPlaybackController+MediaLibrary.h"
#import <MediaPlayer/MediaPlayer.h>
#import <MediaLibraryKit/UIImage+MLKit.h>
#import <WatchKit/WatchKit.h>
#import "VLCThumbnailsCache.h"
@interface VLCWatchCommunication()
@property (nonatomic, strong) NSOperationQueue *thumbnailingQueue;
@end
@implementation VLCWatchCommunication
+ (BOOL)isSupported {
return @available(iOS 9, *) && [WCSession isSupported];
}
- (instancetype)init
{
self = [super init];
if (self) {
if ([VLCWatchCommunication isSupported]) {
WCSession *session = [WCSession defaultSession];
session.delegate = self;
[session activateSession];
_thumbnailingQueue = [NSOperationQueue new];
_thumbnailingQueue.name = @"org.videolan.vlc.watch-thumbnailing";
}
}
return self;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:nil];
}
static VLCWatchCommunication *_singeltonInstance = nil;
+ (VLCWatchCommunication *)sharedInstance
{
@synchronized(self) {
static dispatch_once_t pred;
dispatch_once(&pred, ^{
_singeltonInstance = [[self alloc] init];
});
}
return _singeltonInstance;
}
- (void)playFileFromWatch:(VLCWatchMessage *)message
{
NSManagedObject *managedObject = nil;
NSString *uriString = (id)message.payload;
if ([uriString isKindOfClass:[NSString class]]) {
NSURL *uriRepresentation = [NSURL URLWithString:uriString];
managedObject = [[MLMediaLibrary sharedMediaLibrary] objectForURIRepresentation:uriRepresentation];
}
if (managedObject == nil) {
APLog(@"%s file not found: %@",__PRETTY_FUNCTION__,message);
return;
}
VLCPlaybackController *vpc = [VLCPlaybackController sharedInstance];
[vpc playMediaLibraryObject:managedObject];
}
#pragma mark - WCSessionDelegate
- (NSDictionary *)handleMessage:(nonnull VLCWatchMessage *)message {
UIApplication *application = [UIApplication sharedApplication];
/* dispatch background task */
__block UIBackgroundTaskIdentifier taskIdentifier = [application beginBackgroundTaskWithName:nil
expirationHandler:^{
[application endBackgroundTask:taskIdentifier];
taskIdentifier = UIBackgroundTaskInvalid;
}];
NSString *name = message.name;
NSDictionary *responseDict = @{};
if ([name isEqualToString:VLCWatchMessageNameGetNowPlayingInfo]) {
responseDict = [self nowPlayingResponseDict];
} else if ([name isEqualToString:VLCWatchMessageNamePlayPause]) {
[[VLCPlaybackController sharedInstance] playPause];
responseDict = @{@"playing": @([VLCPlaybackController sharedInstance].isPlaying)};
} else if ([name isEqualToString:VLCWatchMessageNameSkipForward]) {
[[VLCPlaybackController sharedInstance] next];
} else if ([name isEqualToString:VLCWatchMessageNameSkipBackward]) {
[[VLCPlaybackController sharedInstance] previous];
} else if ([name isEqualToString:VLCWatchMessageNamePlayFile]) {
[self playFileFromWatch:message];
} else if ([name isEqualToString:VLCWatchMessageNameSetVolume]) {
[self setVolumeFromWatch:message];
} else if ([name isEqualToString:VLCWatchMessageNameRequestThumbnail]) {
[self requestThumnail:message];
} else if([name isEqualToString:VLCWatchMessageNameRequestDB]) {
[self copyCoreDataToWatch];
} else {
APLog(@"Did not handle request from WatchKit Extension: %@",message);
}
return responseDict;
}
- (void)session:(nonnull WCSession *)session didReceiveMessage:(nonnull NSDictionary<NSString *,id> *)userInfo replyHandler:(nonnull void (^)(NSDictionary<NSString *,id> * _Nonnull))replyHandler {
VLCWatchMessage *message = [[VLCWatchMessage alloc] initWithDictionary:userInfo];
NSDictionary *responseDict = [self handleMessage:message];
replyHandler(responseDict);
}
- (void)session:(nonnull WCSession *)session didReceiveMessage:(nonnull NSDictionary<NSString *,id> *)messageDict {
VLCWatchMessage *message = [[VLCWatchMessage alloc] initWithDictionary:messageDict];
[self handleMessage:message];
}
- (void)sessionWatchStateDidChange:(WCSession *)session {
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center removeObserver:self name:NSManagedObjectContextDidSaveNotification object:nil];
[center removeObserver:self name:MLFileThumbnailWasUpdated object:nil];
if ([[WCSession defaultSession] isPaired] && [[WCSession defaultSession] isWatchAppInstalled]) {
[center addObserver:self selector:@selector(savedManagedObjectContextNotification:) name:NSManagedObjectContextDidSaveNotification object:nil];
[center addObserver:self selector:@selector(didUpdateThumbnail:) name:MLFileThumbnailWasUpdated object:nil];
}
}
#pragma mark -
- (void)setVolumeFromWatch:(VLCWatchMessage *)message
{
NSNumber *volume = (id)message.payload;
if ([volume isKindOfClass:[NSNumber class]]) {
/*
* Since WatchKit doesn't provide something like MPVolumeView we use deprecated API.
* rdar://20783803 Feature Request: WatchKit equivalent for MPVolumeView
*/
[MPMusicPlayerController applicationMusicPlayer].volume = volume.floatValue;
}
}
- (NSDictionary *)nowPlayingResponseDict {
NSMutableDictionary *response = [NSMutableDictionary new];
NSMutableDictionary *nowPlayingInfo = [[MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo mutableCopy];
NSNumber *playbackTime = [[VLCPlaybackController sharedInstance] playbackTime];
if (playbackTime) {
nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = @(playbackTime.floatValue/1000);
}
if (nowPlayingInfo) {
response[@"nowPlayingInfo"] = nowPlayingInfo;
}
VLCMedia *currentFile = [VLCPlaybackController sharedInstance].currentlyPlayingMedia;
MLFile *mediaFile = [MLFile fileForURL:currentFile.url].firstObject;
NSString *URIString = mediaFile.objectID.URIRepresentation.absoluteString;
if (URIString) {
response[VLCWatchMessageKeyURIRepresentation] = URIString;
}
response[@"volume"] = @([MPMusicPlayerController applicationMusicPlayer].volume);
return response;
}
- (void)requestThumnail:(VLCWatchMessage *)message {
NSAssert([message.payload isKindOfClass:[NSDictionary class]], @"the payload needs to be an NSDictionary");
if (![message.payload isKindOfClass:[NSDictionary class]]) return;
NSDictionary *payload = (NSDictionary *)message.payload;
NSString *uriString = payload[VLCWatchMessageKeyURIRepresentation];
NSURL *url = [NSURL URLWithString:uriString];
NSManagedObject *object = [[MLMediaLibrary sharedMediaLibrary] objectForURIRepresentation:url];
if (object) {
[self transferThumbnailForObject:object refreshCache:NO];
}
}
#pragma mark - Notifications
- (void)startRelayingNotificationName:(nullable NSString *)name object:(nullable id)object {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(relayNotification:) name:name object:object];
}
- (void)stopRelayingNotificationName:(nullable NSString *)name object:(nullable id)object {
[[NSNotificationCenter defaultCenter] removeObserver:self name:name object:object];
}
- (void)relayNotification:(NSNotification *)notification {
NSMutableDictionary *payload = [NSMutableDictionary dictionary];
payload[@"name"] = notification.name;
if (notification.userInfo) {
payload[@"userInfo"] = notification.userInfo;
}
NSDictionary *dict = [VLCWatchMessage messageDictionaryForName:VLCWatchMessageNameNotification
payload:payload];
if ([WCSession isSupported] && [[WCSession defaultSession] isWatchAppInstalled] && [[WCSession defaultSession] isReachable]) {
[[WCSession defaultSession] sendMessage:dict replyHandler:nil errorHandler:nil];
}
}
#pragma mark - Copy CoreData to Watch
- (void)savedManagedObjectContextNotification:(NSNotification *)notification {
NSManagedObjectContext *moc = notification.object;
if (moc.persistentStoreCoordinator == [[MLMediaLibrary sharedMediaLibrary] persistentStoreCoordinator]) {
[self copyCoreDataToWatch];
}
}
- (void)copyCoreDataToWatch {
if (![[WCSession defaultSession] isPaired] || ![[WCSession defaultSession] isWatchAppInstalled]) return;
MLMediaLibrary *library = [MLMediaLibrary sharedMediaLibrary];
NSPersistentStoreCoordinator *libraryPSC = [library persistentStoreCoordinator];
NSPersistentStore *persistentStore = [libraryPSC persistentStoreForURL:[library persistentStoreURL]];
NSURL *tmpDirectoryURL = [[WCSession defaultSession] watchDirectoryURL];
NSURL *tmpURL = [tmpDirectoryURL URLByAppendingPathComponent:persistentStore.URL.lastPathComponent];
NSMutableDictionary *destOptions = [persistentStore.options mutableCopy] ?: [NSMutableDictionary new];
destOptions[NSSQLitePragmasOption] = @{@"journal_mode": @"DELETE"};
NSError *error;
bool success = [libraryPSC replacePersistentStoreAtURL:tmpURL destinationOptions:destOptions withPersistentStoreFromURL:persistentStore.URL sourceOptions:persistentStore.options storeType:NSSQLiteStoreType error:&error];
if (!success) {
NSLog(@"%s failed to copy persistent store to tmp location for copy to watch with error %@",__PRETTY_FUNCTION__,error);
}
// cancel old transfers
NSArray<WCSessionFileTransfer *> *outstandingtransfers = [[WCSession defaultSession] outstandingFileTransfers];
[outstandingtransfers enumerateObjectsUsingBlock:^(WCSessionFileTransfer * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([obj.file.metadata[@"filetype"] isEqualToString:@"coredata"]) {
[obj cancel];
}
}];
NSDictionary *metadata = @{@"filetype":@"coredata"};