浏览代码

first good working flow from list to play and nowPlaying everywhere

Tobias Conradi 10 年之前
父节点
当前提交
56d4847887

+ 14 - 3
Sources/VLCAppDelegate.m

@@ -146,7 +146,7 @@
 
     [[VLCNotificationRelay sharedRelay] addRelayLocalName:NSManagedObjectContextDidSaveNotification toRemoteName:@"org.videolan.ios-app.dbupdate"];
 
-    [[VLCNotificationRelay sharedRelay] addRelayLocalName:NSManagedObjectContextDidSaveNotification toRemoteName:@"org.videolan.ios-app.nowPlayingInfoUpdate"];
+    [[VLCNotificationRelay sharedRelay] addRelayLocalName:@"nowPlayingInfoUpdate" toRemoteName:@"org.videolan.ios-app.nowPlayingInfoUpdate"];
 
     return YES;
 }
@@ -575,10 +575,21 @@
         [_movieViewController forward:nil];
     } else if ([userInfo[@"name"] isEqualToString:@"skipBackward"]) {
         [_movieViewController backward:nil];
-    }
-    else {
+    } else if ([userInfo[@"name"] isEqualToString:@"playFile"]) {
+        [self playFileFromWatch:userInfo[@"userInfo"]];
+    } else {
         NSLog(@"Did not handle request from WatchKit Extension: %@",userInfo);
     }
     reply(reponseDict);
 }
+- (void)playFileFromWatch:(NSDictionary *)userInfo {
+    MLMediaLibrary *library = [MLMediaLibrary sharedMediaLibrary];
+    NSString *uriString = userInfo[@"URIRepresentation"];
+    NSURL *uriRepresentation = [NSURL URLWithString:uriString];
+    NSManagedObjectID *objectID = [library.persistentStoreCoordinator managedObjectIDForURIRepresentation:uriRepresentation];
+    NSManagedObjectContext *moc = [(id)library managedObjectContext];
+    NSManagedObject *managedObject = [moc objectWithID:objectID];
+    [self openMediaFromManagedObject:managedObject];
+}
+
 @end

+ 32 - 7
VLC for iOS WatchKit App/Base.lproj/Interface.storyboard

@@ -35,26 +35,51 @@
             </objects>
             <point key="canvasLocation" x="221" y="216"/>
         </scene>
-        <!--nowPlaying-->
+        <!--Detail-->
+        <scene sceneID="ssu-GA-ce6">
+            <objects>
+                <controller identifier="detailInfo" title="Detail" id="iqo-j9-nlr" customClass="VLCDetailInterfaceController">
+                    <items>
+                        <imageView alignment="left" contentMode="scaleAspectFit" id="TPb-N9-Qms"/>
+                        <label alignment="left" text="title" textAlignment="left" numberOfLines="0" id="0av-IS-YI5"/>
+                        <label alignment="left" text="duration" id="eqY-Zs-PAu"/>
+                        <label alignment="left" hidden="YES" text="???" id="l0f-Nd-PHT"/>
+                        <button width="1" alignment="left" title="Play Now" enabled="NO" id="4LT-2D-Zeq">
+                            <connections>
+                                <action selector="playNow" destination="iqo-j9-nlr" id="y9K-R2-er7"/>
+                            </connections>
+                        </button>
+                    </items>
+                    <connections>
+                        <outlet property="durationLabel" destination="eqY-Zs-PAu" id="ttj-gB-C2S"/>
+                        <outlet property="imageView" destination="TPb-N9-Qms" id="epU-Re-hBk"/>
+                        <outlet property="playNowButton" destination="4LT-2D-Zeq" id="d2T-jc-gAb"/>
+                        <outlet property="titleLabel" destination="0av-IS-YI5" id="vEh-KH-Vt5"/>
+                    </connections>
+                </controller>
+            </objects>
+            <point key="canvasLocation" x="497" y="222"/>
+        </scene>
+        <!--Playing-->
         <scene sceneID="NHj-Mq-ifc">
             <objects>
-                <controller identifier="nowPlaying" id="Mzo-Y8-gdK" customClass="VLCNowPlayingInterfaceController">
+                <controller identifier="nowPlaying" title="Playing" id="Mzo-Y8-gdK" customClass="VLCNowPlayingInterfaceController">
                     <items>
-                        <label alignment="left" text="title" textAlignment="left" numberOfLines="0" id="H58-Y8-Tbc"/>
-                        <label alignment="left" text="duration" id="D0h-cq-wsv"/>
-                        <button width="1" alignment="left" title="playpause" id="BAZ-aC-ETt">
+                        <label alignment="left" accessibilityLabel="title" text="title" textAlignment="left" numberOfLines="0" id="H58-Y8-Tbc"/>
+                        <label alignment="left" accessibilityLabel="playback duration" text="duration" id="D0h-cq-wsv"/>
+                        <button width="1" alignment="left" accessibilityLabel="play / pause" accessibilityHint="starts playing or pauses the current playback" title="playpause" id="BAZ-aC-ETt">
                             <connections>
                                 <action selector="playPausePressed" destination="Mzo-Y8-gdK" id="6p8-JZ-0Gh"/>
                             </connections>
                         </button>
                         <group width="1" alignment="left" id="uwS-0S-Ag2">
                             <items>
-                                <button width="0.5" alignment="left" title="&lt;&lt;" id="uKa-8V-C8x">
+                                <button width="0.5" alignment="left" accessibilityLabel="backward" title="&lt;&lt;" id="uKa-8V-C8x">
                                     <connections>
                                         <action selector="skipBackward" destination="Mzo-Y8-gdK" id="aP1-vb-XwF"/>
                                     </connections>
                                 </button>
-                                <button width="0.5" alignment="left" title="&gt;&gt;" id="w8s-Mc-7oV">
+                                <button width="0.5" alignment="left" accessibilityLabel="forward" title="&gt;&gt;" id="w8s-Mc-7oV">
                                     <connections>
                                         <action selector="skipForward" destination="Mzo-Y8-gdK" id="1kf-Nh-kjr"/>
                                     </connections>

+ 3 - 1
VLC for iOS WatchKit Extension/InterfaceController.h

@@ -9,6 +9,8 @@
 #import <WatchKit/WatchKit.h>
 #import <Foundation/Foundation.h>
 
-@interface InterfaceController : WKInterfaceController
+#import "VLCBaseInterfaceController.h"
+
+@interface InterfaceController : VLCBaseInterfaceController
 @property (nonatomic, weak) IBOutlet WKInterfaceTable *table;
 @end

+ 9 - 6
VLC for iOS WatchKit Extension/InterfaceController.m

@@ -34,13 +34,11 @@ static NSString *const VLCDBUpdateNotificationRemote = @"org.videolan.ios-app.db
     mediaLibrary.libraryBasePath = groupURL.path;
     mediaLibrary.additionalPersitentStoreOptions = @{NSReadOnlyPersistentStoreOption : @YES};
 
-    self.title = NSLocalizedString(@"LIBRARY_MUSIC", nil);
+    self.title = NSLocalizedString(@"LIBRARY_ALL", nil);
     [[VLCNotificationRelay sharedRelay] addRelayRemoteName:VLCDBUpdateNotificationRemote toLocalName:VLCDBUpdateNotification];
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateData) name:VLCDBUpdateNotification object:nil];
 
     [self updateData];
-
-    [self addMenuItemWithItemIcon:WKMenuItemIconMore title:@"currently playing" action:@selector(showNowPlaying:)];
 }
 
 - (void)willActivate {
@@ -60,8 +58,13 @@ static NSString *const VLCDBUpdateNotificationRemote = @"org.videolan.ios-app.db
 }
 
 
-- (void)showNowPlaying:(id)sender {
-    [self presentControllerWithName:@"nowPlaying" context:nil];
+
+
+- (void)table:(WKInterfaceTable *)table didSelectRowAtIndex:(NSInteger)rowIndex {
+    id object = self.mediaObjects[rowIndex];
+    if ([object isKindOfClass:[MLFile class]]) {
+        [self pushControllerWithName:@"detailInfo" context:object];
+    }
 }
 
 #pragma mark - data handling
@@ -92,7 +95,7 @@ static NSString *const VLCDBUpdateNotificationRemote = @"org.videolan.ios-app.db
 - (void)configureTableCellAtIndex:(NSUInteger)index withObject:(MLFile *)object {
     VLCRowController *row = [self.table rowControllerAtIndex:index];
     row.titleLabel.text = object.title;
-    row.durationLabel.text = [VLCTime timeWithNumber:object.duration].stringValue,
+    row.durationLabel.text = [VLCTime timeWithNumber:object.duration].stringValue;
     [row.group setBackgroundImage:object.computedThumbnail];
 }
 

+ 15 - 0
VLC for iOS WatchKit Extension/VLCBaseInterfaceController.h

@@ -0,0 +1,15 @@
+//
+//  VLCBaseInterfaceController.h
+//  
+//
+//  Created by Tobias Conradi on 03.04.15.
+//
+//
+
+#import <WatchKit/WatchKit.h>
+
+@interface VLCBaseInterfaceController : WKInterfaceController
+
+- (void)showNowPlaying:(id)sender;
+
+@end

+ 23 - 0
VLC for iOS WatchKit Extension/VLCBaseInterfaceController.m

@@ -0,0 +1,23 @@
+//
+//  VLCBaseInterfaceController.m
+//
+//
+//  Created by Tobias Conradi on 03.04.15.
+//
+//
+
+#import "VLCBaseInterfaceController.h"
+
+@implementation VLCBaseInterfaceController
+
+- (void)awakeWithContext:(id)context {
+    [super awakeWithContext:context];
+
+    [self addMenuItemWithItemIcon:WKMenuItemIconMore title:@"currently playing" action:@selector(showNowPlaying:)];
+}
+
+- (void)showNowPlaying:(id)sender {
+    [self presentControllerWithName:@"nowPlaying" context:nil];
+}
+
+@end

+ 20 - 0
VLC for iOS WatchKit Extension/VLCDetailInterfaceController.h

@@ -0,0 +1,20 @@
+//
+//  VLCDetailInterfaceController.h
+//  VLC for iOS
+//
+//  Created by Tobias Conradi on 03.04.15.
+//  Copyright (c) 2015 VideoLAN. All rights reserved.
+//
+
+#import <WatchKit/WatchKit.h>
+#import <Foundation/Foundation.h>
+#import "VLCBaseInterfaceController.h"
+
+@interface VLCDetailInterfaceController : VLCBaseInterfaceController
+@property (weak, nonatomic) IBOutlet WKInterfaceLabel *titleLabel;
+@property (weak, nonatomic) IBOutlet WKInterfaceLabel *durationLabel;
+@property (weak, nonatomic) IBOutlet WKInterfaceButton *playNowButton;
+@property (weak, nonatomic) IBOutlet WKInterfaceImage *imageView;
+
+- (IBAction)playNow;
+@end

+ 66 - 0
VLC for iOS WatchKit Extension/VLCDetailInterfaceController.m

@@ -0,0 +1,66 @@
+//
+//  VLCDetailInterfaceController.m
+//  VLC for iOS
+//
+//  Created by Tobias Conradi on 03.04.15.
+//  Copyright (c) 2015 VideoLAN. All rights reserved.
+//
+
+#import "VLCDetailInterfaceController.h"
+#import <MediaLibraryKit/MediaLibraryKit.h>
+#import <MobileVLCKit/MobileVLCKit.h>
+
+
+@interface VLCDetailInterfaceController ()
+@property (nonatomic, weak) MLFile *file;
+@end
+
+@implementation VLCDetailInterfaceController
+
+- (void)awakeWithContext:(id)context {
+    [super awakeWithContext:context];
+
+    if ([context isKindOfClass:[MLFile class]]) {
+        [self configureWithFile:context];
+    }
+}
+
+- (void)willActivate {
+    // This method is called when watch view controller is about to be visible to user
+    [super willActivate];
+}
+
+- (void)didDeactivate {
+    // This method is called when watch view controller is no longer visible
+    [super didDeactivate];
+}
+
+- (void)configureWithFile:(MLFile *)file {
+    self.file = file;
+
+    [self.titleLabel setText:file.title];
+    self.durationLabel.text = [VLCTime timeWithNumber:file.duration].stringValue;
+    BOOL playEnabled = file != nil;
+    self.playNowButton.enabled = playEnabled;
+    UIImage *thumbnail = file.computedThumbnail;
+    self.imageView.hidden = thumbnail == nil;
+    if (thumbnail) {
+        self.imageView.image = thumbnail;
+    }
+
+}
+
+- (IBAction)playNow {
+    NSDictionary *dict = @{@"name":@"playFile",
+                           @"userInfo":@{
+                                   @"URIRepresentation": self.file.objectID.URIRepresentation.absoluteString,
+                                   }
+                           };
+    [WKInterfaceController openParentApplication:dict reply:^(NSDictionary *replyInfo, NSError *error) {
+        [self showNowPlaying:nil];
+    }];
+}
+@end
+
+
+

+ 12 - 2
VLC for iOS WatchKit Extension/VLCNotificationRelay.m

@@ -52,10 +52,13 @@
 - (void)addRelayRemoteName:(NSString *)remoteName toLocalName:(NSString *)localName {
     CFNotificationCenterRef center = CFNotificationCenterGetDarwinNotifyCenter();
     CFNotificationCenterAddObserver(center, (__bridge  const void *)(self), notificationCallback, (__bridge CFStringRef)remoteName, NULL, CFNotificationSuspensionBehaviorHold);
+    self.remoteToLocal[remoteName] = localName;
 }
+
 - (void)removeRelayRemoteName:(NSString *)remoteName {
     CFNotificationCenterRef center = CFNotificationCenterGetDarwinNotifyCenter();
     CFNotificationCenterRemoveObserver(center, (__bridge const void *)(self), (__bridge CFStringRef)remoteName, NULL);
+    [self.remoteToLocal removeObjectForKey:remoteName];
 }
 
 #pragma mark - notification handeling
@@ -64,7 +67,8 @@
     NSString *localName = notification.name;
     NSString *remoteName = self.localToRemote[localName];
 
-    /* in current version of iOS this is ignored for the darwin center
+    /* 
+     * in current version of iOS this is ignored for the darwin center
      * nevertheless we use it to be future proof
      */
     NSDictionary *userInfo = notification.userInfo;
@@ -78,7 +82,13 @@ static void notificationCallback(CFNotificationCenterRef center, void* observer,
     VLCNotificationRelay *relay = (__bridge VLCNotificationRelay*) observer;
     NSString *remoteName = (__bridge NSString *)name;
     NSString *localName = relay.remoteToLocal[remoteName];
-    [[NSNotificationCenter defaultCenter] postNotificationName:localName object:nil userInfo:(__bridge NSDictionary *)userInfo];
+
+    /*
+     * in current version of iOS this is ignored for the darwin center
+     * nevertheless we use it to be future proof
+     */
+    NSDictionary *dict = (__bridge NSDictionary *)userInfo;
+    [[NSNotificationCenter defaultCenter] postNotificationName:localName object:nil userInfo:dict];
 }
 
 

+ 7 - 2
VLC for iOS WatchKit Extension/VLCNowPlayingInterfaceController.m

@@ -73,14 +73,19 @@
 - (void)setTitleString:(NSString *)titleString {
     if (![_titleString isEqualToString:titleString] || (_titleString==nil && titleString)) {
         _titleString = [titleString copy];
-        [self.titleLabel setText:titleString];
+        self.titleLabel.text = titleString;
     }
 }
 
 - (void)setPlayBackDurationNumber:(NSNumber *)playBackDurationNumber {
     if (![_playBackDurationNumber isEqualToNumber:playBackDurationNumber] || (_playBackDurationNumber==nil && playBackDurationNumber)) {
         _playBackDurationNumber = playBackDurationNumber;
-        [self.durationLabel setText:[VLCTime timeWithNumber:playBackDurationNumber].stringValue];
+        float duratioFloat = playBackDurationNumber.floatValue;
+        NSNumber *durationNumber = nil;
+        if (duratioFloat>0.0) {
+            durationNumber = @(playBackDurationNumber.floatValue*1000);
+        }
+        self.durationLabel.text = [VLCTime timeWithNumber:durationNumber].stringValue;
     }
 }
 

+ 12 - 0
VLC for iOS.xcodeproj/project.pbxproj

@@ -543,6 +543,8 @@
 		DD6FA7B01ACD641C006DEB2E /* VLCNowPlayingInterfaceController.m in Sources */ = {isa = PBXBuildFile; fileRef = DD6FA7AF1ACD641C006DEB2E /* VLCNowPlayingInterfaceController.m */; };
 		DDE4906C1ACDB63F00B1B5E3 /* VLCNotificationRelay.m in Sources */ = {isa = PBXBuildFile; fileRef = DDE4906B1ACDB63F00B1B5E3 /* VLCNotificationRelay.m */; };
 		DDE4906D1ACDBEA000B1B5E3 /* VLCNotificationRelay.m in Sources */ = {isa = PBXBuildFile; fileRef = DDE4906B1ACDB63F00B1B5E3 /* VLCNotificationRelay.m */; };
+		DDE490701ACE8BBC00B1B5E3 /* VLCDetailInterfaceController.m in Sources */ = {isa = PBXBuildFile; fileRef = DDE4906F1ACE8BBC00B1B5E3 /* VLCDetailInterfaceController.m */; };
+		DDE490731ACE964200B1B5E3 /* VLCBaseInterfaceController.m in Sources */ = {isa = PBXBuildFile; fileRef = DDE490721ACE964200B1B5E3 /* VLCBaseInterfaceController.m */; };
 		DDF157B11ACB162700AAFBC6 /* MediaLibrary.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 7D594CBC1A969E33004BFB17 /* MediaLibrary.xcdatamodeld */; };
 		DDF157B21ACB169600AAFBC6 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC1BBC57170493E100A20CBF /* CoreData.framework */; };
 		DDF157B41ACB169B00AAFBC6 /* WatchKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDF157B31ACB169B00AAFBC6 /* WatchKit.framework */; };
@@ -1579,6 +1581,10 @@
 		DD6FA7AF1ACD641C006DEB2E /* VLCNowPlayingInterfaceController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCNowPlayingInterfaceController.m; sourceTree = "<group>"; };
 		DDE4906A1ACDB63F00B1B5E3 /* VLCNotificationRelay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCNotificationRelay.h; sourceTree = "<group>"; };
 		DDE4906B1ACDB63F00B1B5E3 /* VLCNotificationRelay.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCNotificationRelay.m; sourceTree = "<group>"; };
+		DDE4906E1ACE8BBC00B1B5E3 /* VLCDetailInterfaceController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLCDetailInterfaceController.h; sourceTree = "<group>"; };
+		DDE4906F1ACE8BBC00B1B5E3 /* VLCDetailInterfaceController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VLCDetailInterfaceController.m; sourceTree = "<group>"; };
+		DDE490711ACE964200B1B5E3 /* VLCBaseInterfaceController.h */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = VLCBaseInterfaceController.h; sourceTree = "<group>"; tabWidth = 4; usesTabs = 0; wrapsLines = 1; };
+		DDE490721ACE964200B1B5E3 /* VLCBaseInterfaceController.m */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = VLCBaseInterfaceController.m; sourceTree = "<group>"; tabWidth = 4; usesTabs = 0; wrapsLines = 1; };
 		DDF157B31ACB169B00AAFBC6 /* WatchKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WatchKit.framework; path = System/Library/Frameworks/WatchKit.framework; sourceTree = SDKROOT; };
 		E09EACF57CDD22ABAE66CDD0 /* Pods-vlc-ios.distribution.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-vlc-ios.distribution.xcconfig"; path = "Pods/Target Support Files/Pods-vlc-ios/Pods-vlc-ios.distribution.xcconfig"; sourceTree = "<group>"; };
 		E0C04F931A25B4410080331A /* VLCDocumentPickerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCDocumentPickerController.h; path = Sources/VLCDocumentPickerController.h; sourceTree = SOURCE_ROOT; };
@@ -1792,10 +1798,14 @@
 				DD02C2FC1ACACF400026EFEE /* VLC for iOS WatchKit Extension.entitlements */,
 				DDE4906A1ACDB63F00B1B5E3 /* VLCNotificationRelay.h */,
 				DDE4906B1ACDB63F00B1B5E3 /* VLCNotificationRelay.m */,
+				DDE490711ACE964200B1B5E3 /* VLCBaseInterfaceController.h */,
+				DDE490721ACE964200B1B5E3 /* VLCBaseInterfaceController.m */,
 				4173AEA41ABF1B850004101D /* InterfaceController.h */,
 				4173AEA51ABF1B850004101D /* InterfaceController.m */,
 				DD6FA7AE1ACD641C006DEB2E /* VLCNowPlayingInterfaceController.h */,
 				DD6FA7AF1ACD641C006DEB2E /* VLCNowPlayingInterfaceController.m */,
+				DDE4906E1ACE8BBC00B1B5E3 /* VLCDetailInterfaceController.h */,
+				DDE4906F1ACE8BBC00B1B5E3 /* VLCDetailInterfaceController.m */,
 				DD02C30C1ACAF4A50026EFEE /* VLCRowController.h */,
 				DD02C30D1ACAF4A50026EFEE /* VLCRowController.m */,
 				4173AEA71ABF1B850004101D /* Images.xcassets */,
@@ -3555,8 +3565,10 @@
 			files = (
 				DD6FA7B01ACD641C006DEB2E /* VLCNowPlayingInterfaceController.m in Sources */,
 				DDF157B11ACB162700AAFBC6 /* MediaLibrary.xcdatamodeld in Sources */,
+				DDE490731ACE964200B1B5E3 /* VLCBaseInterfaceController.m in Sources */,
 				DDE4906C1ACDB63F00B1B5E3 /* VLCNotificationRelay.m in Sources */,
 				DD02C30E1ACAF4A50026EFEE /* VLCRowController.m in Sources */,
+				DDE490701ACE8BBC00B1B5E3 /* VLCDetailInterfaceController.m in Sources */,
 				4173AEA61ABF1B850004101D /* InterfaceController.m in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;