Updated Branches: refs/heads/master 15f8a5d9a -> afb673b76
Adds CDVCommandDelegateImpl. It's tidier to have the APIs exposed to plugins implemented as a separate class from the CDVViewController. Makes it much easier to add helper functions to it without bloating CDVViewController. Project: http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/commit/afb673b7 Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/tree/afb673b7 Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/diff/afb673b7 Branch: refs/heads/master Commit: afb673b765e29f67dc7eb3ae12fa63c88b67f3c9 Parents: 88302e1 Author: Andrew Grieve <agri...@chromium.org> Authored: Fri Oct 5 15:36:39 2012 -0400 Committer: Andrew Grieve <agri...@chromium.org> Committed: Fri Oct 5 15:36:39 2012 -0400 ---------------------------------------------------------------------- CordovaLib/CDVCommandDelegateImpl.h | 32 +++++ CordovaLib/CDVCommandDelegateImpl.m | 113 ++++++++++++++++++ CordovaLib/Classes/CDVCommandQueue.m | 2 +- CordovaLib/Classes/CDVViewController.h | 11 ++- CordovaLib/Classes/CDVViewController.m | 79 ++----------- CordovaLib/CordovaLib.xcodeproj/project.pbxproj | 8 ++ 6 files changed, 173 insertions(+), 72 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/afb673b7/CordovaLib/CDVCommandDelegateImpl.h ---------------------------------------------------------------------- diff --git a/CordovaLib/CDVCommandDelegateImpl.h b/CordovaLib/CDVCommandDelegateImpl.h new file mode 100644 index 0000000..f850dc6 --- /dev/null +++ b/CordovaLib/CDVCommandDelegateImpl.h @@ -0,0 +1,32 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ + +#import <UIKit/UIKit.h> +#import "CDVCommandDelegate.h" + +@class CDVViewController; +@class CDVCommandQueue; + +@interface CDVCommandDelegateImpl : NSObject <CDVCommandDelegate>{ + @private + __unsafe_unretained CDVViewController* _viewController; + __unsafe_unretained CDVCommandQueue* _commandQueue; +} +- (id)initWithViewController:(CDVViewController*)viewController; +@end http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/afb673b7/CordovaLib/CDVCommandDelegateImpl.m ---------------------------------------------------------------------- diff --git a/CordovaLib/CDVCommandDelegateImpl.m b/CordovaLib/CDVCommandDelegateImpl.m new file mode 100644 index 0000000..342ea79 --- /dev/null +++ b/CordovaLib/CDVCommandDelegateImpl.m @@ -0,0 +1,113 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + */ + +#import "CDVCommandDelegateImpl.h" + +#import "CDVCommandQueue.h" +#import "CDVPluginResult.h" +#import "CDVViewController.h" + +@implementation CDVCommandDelegateImpl + +- (id)initWithViewController:(CDVViewController*)viewController +{ + self = [super init]; + if (self != nil) { + _viewController = viewController; + _commandQueue = _viewController.commandQueue; + } + return self; +} + +- (NSString*)pathForResource:(NSString*)resourcepath +{ + NSBundle* mainBundle = [NSBundle mainBundle]; + NSMutableArray* directoryParts = [NSMutableArray arrayWithArray:[resourcepath componentsSeparatedByString:@"/"]]; + NSString* filename = [directoryParts lastObject]; + + [directoryParts removeLastObject]; + + NSString* directoryPartsJoined = [directoryParts componentsJoinedByString:@"/"]; + NSString* directoryStr = _viewController.wwwFolderName; + + if ([directoryPartsJoined length] > 0) { + directoryStr = [NSString stringWithFormat:@"%@/%@", _viewController.wwwFolderName, [directoryParts componentsJoinedByString:@"/"]]; + } + + return [mainBundle pathForResource:filename ofType:@"" inDirectory:directoryStr]; +} + +- (void)evalJsHelper:(NSString*)js +{ + void (^doIt)() = ^{ + NSString* commandsJSON = [_viewController.webView stringByEvaluatingJavaScriptFromString:js]; + [_commandQueue enqueCommandBatch:commandsJSON]; + }; + + // Cycle the run-loop before executing the JS. + // This works around a bug where sometimes alerts() within callbacks can cause + // dead-lock. + // If the commandQueue is currently executing, then we know that it is safe to + // execute the callback immediately. + if (![NSThread isMainThread] || !_commandQueue.currentlyExecuting) { + dispatch_async (dispatch_get_main_queue (), doIt); + } else { + doIt (); + } +} + +- (void)sendPluginResult:(CDVPluginResult*)result callbackId:(NSString*)callbackId +{ + int status = [result.status intValue]; + BOOL keepCallback = [result.keepCallback boolValue]; + id message = result.message == nil ? [NSNull null] : result.message; + + // Use an array to encode the message as JSON. + message = [NSArray arrayWithObject:message]; + NSString* encodedMessage = [message cdvjk_JSONString]; + // And then strip off the outer []s. + encodedMessage = [encodedMessage substringWithRange:NSMakeRange (1, [encodedMessage length] - 2)]; + NSString* js = [NSString stringWithFormat:@"cordova.require('cordova/exec').nativeCallback('%@',%d,%@,%d)", + callbackId, status, encodedMessage, keepCallback]; + + [self evalJsHelper:js]; +} + +- (void)evalJs:(NSString*)js +{ + js = [js stringByAppendingString:@";cordova.require('cordova/exec').nativeFetchMessages()"]; + [self evalJsHelper:js]; +} + +- (BOOL)execute:(CDVInvokedUrlCommand*)command +{ + return [_commandQueue execute:command]; +} + +- (id)getCommandInstance:(NSString*)pluginName +{ + return [_viewController getCommandInstance:pluginName]; +} + +- (void)registerPlugin:(CDVPlugin*)plugin withClassName:(NSString*)className +{ + [_viewController registerPlugin:plugin withClassName:className]; +} + +@end http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/afb673b7/CordovaLib/Classes/CDVCommandQueue.m ---------------------------------------------------------------------- diff --git a/CordovaLib/Classes/CDVCommandQueue.m b/CordovaLib/Classes/CDVCommandQueue.m index cec5afd..73ee1aa 100644 --- a/CordovaLib/Classes/CDVCommandQueue.m +++ b/CordovaLib/Classes/CDVCommandQueue.m @@ -91,7 +91,7 @@ // Iterate over and execute all of the commands. for (NSArray* jsonEntry in commandBatch) { CDVInvokedUrlCommand* command = [CDVInvokedUrlCommand commandFromJson:jsonEntry]; - if (![_viewController execute:command]) { + if (![self execute:command]) { #ifdef DEBUG NSString* commandJson = [jsonEntry cdvjk_JSONString]; static NSUInteger maxLogLength = 1024; http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/afb673b7/CordovaLib/Classes/CDVViewController.h ---------------------------------------------------------------------- diff --git a/CordovaLib/Classes/CDVViewController.h b/CordovaLib/Classes/CDVViewController.h index 6f723a3..c27286b 100644 --- a/CordovaLib/Classes/CDVViewController.h +++ b/CordovaLib/Classes/CDVViewController.h @@ -25,7 +25,12 @@ #import "CDVWhitelist.h" @class CDVCommandQueue; -@interface CDVViewController : UIViewController <UIWebViewDelegate, CDVCommandDelegate> +@class CDVCommandDelegateImpl; + +@interface CDVViewController : UIViewController <UIWebViewDelegate>{ + @private + CDVCommandDelegateImpl* _commandDelegate; +} @property (nonatomic, strong) IBOutlet CDVCordovaView* webView; @@ -43,6 +48,7 @@ @property (nonatomic, readwrite, copy) NSString* wwwFolderName; @property (nonatomic, readwrite, copy) NSString* startPage; @property (nonatomic, readonly, strong) CDVCommandQueue* commandQueue; +@property (nonatomic, readonly, strong) CDVCommandDelegateImpl* commandDelegate; + (NSDictionary*)getBundlePlist:(NSString*)plistName; + (NSString*)applicationDocumentsDirectory; @@ -57,4 +63,7 @@ - (NSArray*)parseInterfaceOrientations:(NSArray*)orientations; - (BOOL)supportsOrientation:(UIInterfaceOrientation)orientation; +- (id)getCommandInstance:(NSString*)pluginName; +- (void)registerPlugin:(CDVPlugin*)plugin withClassName:(NSString*)className; + @end http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/afb673b7/CordovaLib/Classes/CDVViewController.m ---------------------------------------------------------------------- diff --git a/CordovaLib/Classes/CDVViewController.m b/CordovaLib/Classes/CDVViewController.m index 8573112..f253a2f 100644 --- a/CordovaLib/Classes/CDVViewController.m +++ b/CordovaLib/Classes/CDVViewController.m @@ -20,6 +20,7 @@ #import <objc/message.h> #import "CDV.h" #import "CDVCommandQueue.h" +#import "CDVCommandDelegateImpl.h" #define degreesToRadian(x) (M_PI * (x) / 180.0) @@ -45,11 +46,13 @@ @synthesize settings, loadFromString; @synthesize imageView, activityView, useSplashScreen; @synthesize wwwFolderName, startPage, invokeString, initialized; +@synthesize commandDelegate = _commandDelegate; - (void)__init { if ((self != nil) && !self.initialized) { _commandQueue = [[CDVCommandQueue alloc] initWithViewController:self]; + _commandDelegate = [[CDVCommandDelegateImpl alloc] initWithViewController:self]; [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receivedOrientationChange) name:UIDeviceOrientationDidChangeNotification object:nil]; @@ -157,7 +160,7 @@ { [super viewDidLoad]; - NSString* startFilePath = [self pathForResource:self.startPage]; + NSString* startFilePath = [_commandDelegate pathForResource:self.startPage]; NSURL* appURL = nil; NSString* loadErr = nil; @@ -617,24 +620,6 @@ return resource; } -- (NSString*)pathForResource:(NSString*)resourcepath -{ - NSBundle* mainBundle = [NSBundle mainBundle]; - NSMutableArray* directoryParts = [NSMutableArray arrayWithArray:[resourcepath componentsSeparatedByString:@"/"]]; - NSString* filename = [directoryParts lastObject]; - - [directoryParts removeLastObject]; - - NSString* directoryPartsJoined = [directoryParts componentsJoinedByString:@"/"]; - NSString* directoryStr = self.wwwFolderName; - - if ([directoryPartsJoined length] > 0) { - directoryStr = [NSString stringWithFormat:@"%@/%@", self.wwwFolderName, [directoryParts componentsJoinedByString:@"/"]]; - } - - return [mainBundle pathForResource:filename ofType:@"" inDirectory:directoryStr]; -} - + (NSString*)applicationDocumentsDirectory { NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); @@ -769,52 +754,6 @@ BOOL gSplashScreenShown = NO; } #pragma mark CordovaCommands -- (void)evalJsHelper:(NSString*)js -{ - void (^doIt)() = ^{ - NSString* commandsJSON = [webView stringByEvaluatingJavaScriptFromString:js]; - [_commandQueue enqueCommandBatch:commandsJSON]; - }; - - // Cycle the run-loop before executing the JS. - // This works around a bug where sometimes alerts() within callbacks can cause - // dead-lock. - // If the commandQueue is currently executing, then we know that it is safe to - // execute the callback immediately. - if (![NSThread isMainThread] || !_commandQueue.currentlyExecuting) { - dispatch_async (dispatch_get_main_queue (), doIt); - } else { - doIt (); - } -} - -- (void)sendPluginResult:(CDVPluginResult*)result callbackId:(NSString*)callbackId -{ - int status = [result.status intValue]; - BOOL keepCallback = [result.keepCallback boolValue]; - id message = result.message == nil ? [NSNull null] : result.message; - - // Use an array to encode the message as JSON. - message = [NSArray arrayWithObject:message]; - NSString* encodedMessage = [message cdvjk_JSONString]; - // And then strip off the outer []s. - encodedMessage = [encodedMessage substringWithRange:NSMakeRange (1, [encodedMessage length] - 2)]; - NSString* js = [NSString stringWithFormat:@"cordova.require('cordova/exec').nativeCallback('%@',%d,%@,%d)", - callbackId, status, encodedMessage, keepCallback]; - - [self evalJsHelper:js]; -} - -- (void)evalJs:(NSString*)js -{ - js = [js stringByAppendingString:@";cordova.require('cordova/exec').nativeFetchMessages()"]; - [self evalJsHelper:js]; -} - -- (BOOL)execute:(CDVInvokedUrlCommand*)command -{ - return [_commandQueue execute:command]; -} - (void)registerPlugin:(CDVPlugin*)plugin withClassName:(NSString*)className { @@ -823,7 +762,7 @@ BOOL gSplashScreenShown = NO; } if ([plugin respondsToSelector:@selector(setCommandDelegate:)]) { - [plugin setCommandDelegate:self]; + [plugin setCommandDelegate:_commandDelegate]; } [self.pluginObjects setObject:plugin forKey:className]; @@ -859,7 +798,7 @@ BOOL gSplashScreenShown = NO; if ((obj != nil) && [obj isKindOfClass:[CDVPlugin class]]) { [self registerPlugin:obj withClassName:className]; } else { - NSLog (@"CDVPlugin class %@ (pluginName: %@) does not exist.", className, pluginName); + NSLog(@"CDVPlugin class %@ (pluginName: %@) does not exist.", className, pluginName); } } return obj; @@ -896,9 +835,9 @@ BOOL gSplashScreenShown = NO; NSString* plistPath = [[NSBundle mainBundle] pathForResource:plistName ofType:@"plist"]; NSData* plistXML = [[NSFileManager defaultManager] contentsAtPath:plistPath]; NSDictionary* temp = (NSDictionary*)[NSPropertyListSerialization -propertyListFromData: plistXML -mutabilityOption: NSPropertyListMutableContainersAndLeaves -format: &format errorDescription : &errorDesc]; + propertyListFromData:plistXML + mutabilityOption:NSPropertyListMutableContainersAndLeaves + format:&format errorDescription:&errorDesc]; return temp; } http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/afb673b7/CordovaLib/CordovaLib.xcodeproj/project.pbxproj ---------------------------------------------------------------------- diff --git a/CordovaLib/CordovaLib.xcodeproj/project.pbxproj b/CordovaLib/CordovaLib.xcodeproj/project.pbxproj index 8a6d563..8cd78a5 100644 --- a/CordovaLib/CordovaLib.xcodeproj/project.pbxproj +++ b/CordovaLib/CordovaLib.xcodeproj/project.pbxproj @@ -73,6 +73,8 @@ C937A4571337599E002C4C79 /* CDVFileTransfer.m in Sources */ = {isa = PBXBuildFile; fileRef = C937A4551337599E002C4C79 /* CDVFileTransfer.m */; }; EB3B3547161CB44D003DBE7D /* CDVCommandQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = EB3B3545161CB44D003DBE7D /* CDVCommandQueue.h */; }; EB3B3548161CB44D003DBE7D /* CDVCommandQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = EB3B3546161CB44D003DBE7D /* CDVCommandQueue.m */; }; + EB3B357C161F2A45003DBE7D /* CDVCommandDelegateImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = EB3B357A161F2A44003DBE7D /* CDVCommandDelegateImpl.h */; }; + EB3B357D161F2A45003DBE7D /* CDVCommandDelegateImpl.m in Sources */ = {isa = PBXBuildFile; fileRef = EB3B357B161F2A45003DBE7D /* CDVCommandDelegateImpl.m */; }; EB80C2AC15DEA63D004D9E7B /* CDVEcho.h in Headers */ = {isa = PBXBuildFile; fileRef = EB80C2AA15DEA63D004D9E7B /* CDVEcho.h */; }; EB80C2AD15DEA63D004D9E7B /* CDVEcho.m in Sources */ = {isa = PBXBuildFile; fileRef = EB80C2AB15DEA63D004D9E7B /* CDVEcho.m */; }; EBA3557315ABD38C00F4DE24 /* NSArray+Comparisons.h in Headers */ = {isa = PBXBuildFile; fileRef = EBA3557115ABD38C00F4DE24 /* NSArray+Comparisons.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -160,6 +162,8 @@ C937A4551337599E002C4C79 /* CDVFileTransfer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDVFileTransfer.m; path = Classes/CDVFileTransfer.m; sourceTree = "<group>"; }; EB3B3545161CB44D003DBE7D /* CDVCommandQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDVCommandQueue.h; path = Classes/CDVCommandQueue.h; sourceTree = "<group>"; }; EB3B3546161CB44D003DBE7D /* CDVCommandQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDVCommandQueue.m; path = Classes/CDVCommandQueue.m; sourceTree = "<group>"; }; + EB3B357A161F2A44003DBE7D /* CDVCommandDelegateImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CDVCommandDelegateImpl.h; sourceTree = "<group>"; }; + EB3B357B161F2A45003DBE7D /* CDVCommandDelegateImpl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CDVCommandDelegateImpl.m; sourceTree = "<group>"; }; EB80C2AA15DEA63D004D9E7B /* CDVEcho.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDVEcho.h; path = Classes/CDVEcho.h; sourceTree = "<group>"; }; EB80C2AB15DEA63D004D9E7B /* CDVEcho.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CDVEcho.m; path = Classes/CDVEcho.m; sourceTree = "<group>"; }; EBA3557115ABD38C00F4DE24 /* NSArray+Comparisons.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSArray+Comparisons.h"; path = "Classes/NSArray+Comparisons.h"; sourceTree = "<group>"; }; @@ -246,6 +250,8 @@ 3034979B1513D56A0090E688 /* CDVLocalStorage.m */, 30392E4D14F4FCAB00B9E0B8 /* CDVAvailability.h */, 30F5EBA914CA26E700987760 /* CDVCommandDelegate.h */, + EB3B357A161F2A44003DBE7D /* CDVCommandDelegateImpl.h */, + EB3B357B161F2A45003DBE7D /* CDVCommandDelegateImpl.m */, 30C684921407044A004C1A8E /* CDVURLProtocol.h */, 30C684931407044A004C1A8E /* CDVURLProtocol.m */, 30C6847E1406CB38004C1A8E /* CDVWhitelist.h */, @@ -377,6 +383,7 @@ 30C5F1DF15AF9E950052A00D /* CDVDevice.h in Headers */, EB80C2AC15DEA63D004D9E7B /* CDVEcho.h in Headers */, EB3B3547161CB44D003DBE7D /* CDVCommandQueue.h in Headers */, + EB3B357C161F2A45003DBE7D /* CDVCommandDelegateImpl.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -467,6 +474,7 @@ 30C5F1E015AF9E950052A00D /* CDVDevice.m in Sources */, EB80C2AD15DEA63D004D9E7B /* CDVEcho.m in Sources */, EB3B3548161CB44D003DBE7D /* CDVCommandQueue.m in Sources */, + EB3B357D161F2A45003DBE7D /* CDVCommandDelegateImpl.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; };