Refactor most of the command queue logic into a separate class.
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/9e1aa3d5 Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/tree/9e1aa3d5 Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/diff/9e1aa3d5 Branch: refs/heads/master Commit: 9e1aa3d5400fddc19dc145c798085f79945cc031 Parents: 5c41ef6 Author: Andrew Grieve <agri...@chromium.org> Authored: Wed Oct 3 14:38:24 2012 -0400 Committer: Andrew Grieve <agri...@chromium.org> Committed: Thu Oct 4 14:57:50 2012 -0400 ---------------------------------------------------------------------- CordovaLib/Classes/CDVCommandDelegate.h | 4 + CordovaLib/Classes/CDVCommandQueue.h | 43 +++++ CordovaLib/Classes/CDVCommandQueue.m | 173 ++++++++++++++++++ CordovaLib/Classes/CDVURLProtocol.m | 7 +- CordovaLib/Classes/CDVViewController.h | 11 +- CordovaLib/Classes/CDVViewController.m | 110 +----------- CordovaLib/CordovaLib.xcodeproj/project.pbxproj | 8 + 7 files changed, 241 insertions(+), 115 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/9e1aa3d5/CordovaLib/Classes/CDVCommandDelegate.h ---------------------------------------------------------------------- diff --git a/CordovaLib/Classes/CDVCommandDelegate.h b/CordovaLib/Classes/CDVCommandDelegate.h index fce9b78..116f35c 100644 --- a/CordovaLib/Classes/CDVCommandDelegate.h +++ b/CordovaLib/Classes/CDVCommandDelegate.h @@ -26,6 +26,10 @@ - (NSString*)pathForResource:(NSString*)resourcepath; - (id)getCommandInstance:(NSString*)pluginName; - (void)registerPlugin:(CDVPlugin*)plugin withClassName:(NSString*)className; +// TODO(agrieve): Deprecate this method. Plugins should not be using this +// interface to call other plugins, since it will result in bogus callbacks +// being made. Instead, they should use getCommandInstance and call methods +// directly. - (BOOL)execute:(CDVInvokedUrlCommand*)command; @end http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/9e1aa3d5/CordovaLib/Classes/CDVCommandQueue.h ---------------------------------------------------------------------- diff --git a/CordovaLib/Classes/CDVCommandQueue.h b/CordovaLib/Classes/CDVCommandQueue.h new file mode 100644 index 0000000..cc522fe --- /dev/null +++ b/CordovaLib/Classes/CDVCommandQueue.h @@ -0,0 +1,43 @@ +/* + 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 <Foundation/Foundation.h> + +@class CDVInvokedUrlCommand; +@class CDVViewController; + +@interface CDVCommandQueue : NSObject { + @private + NSInteger _lastCommandQueueFlushRequestId; + CDVViewController* _viewController; + NSMutableArray* _queue; + BOOL _currentlyExecuting; +} + +- (id)initWithViewController:(CDVViewController*)viewController; +- (void)resetRequestId; +- (void)enqueCommandBatch:(NSString*)batchJSON; + +- (void)maybeFetchCommandsFromJs:(NSNumber*)requestId; +- (void)executeCommandsFromJson:(NSString*)queuedCommandsJSON; +- (void)fetchCommandsFromJs; +- (void)executePending; +- (BOOL)execute:(CDVInvokedUrlCommand*)command; + +@end http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/9e1aa3d5/CordovaLib/Classes/CDVCommandQueue.m ---------------------------------------------------------------------- diff --git a/CordovaLib/Classes/CDVCommandQueue.m b/CordovaLib/Classes/CDVCommandQueue.m new file mode 100644 index 0000000..f547663 --- /dev/null +++ b/CordovaLib/Classes/CDVCommandQueue.m @@ -0,0 +1,173 @@ +/* + 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 "CDV.h" +#import "CDVCommandQueue.h" +#import "CDVViewController.h" + +@implementation CDVCommandQueue + +- (id)initWithViewController:(CDVViewController*)viewController +{ + self = [super init]; + if (self != nil) { + _viewController = viewController; + _queue = [[NSMutableArray alloc] init]; + } + return self; +} + +- (void)resetRequestId +{ + _lastCommandQueueFlushRequestId = 0; +} + +- (void)enqueCommandBatch:(NSString*)batchJSON +{ + [_queue addObject:batchJSON]; +} + +/** + * Fetches the command queue and executes each command. It is possible that the + * queue will not be empty after this function has completed since the executed + * commands may have run callbacks which queued more commands. + * + * Returns the number of executed commands. + */ +- (void)executeCommandsFromJson:(NSString*)queuedCommandsJSON +{ + [self enqueCommandBatch:queuedCommandsJSON]; + [self executePending]; +} + +- (void)maybeFetchCommandsFromJs:(NSNumber*)requestId +{ + // Use the request ID to determine if we've already flushed for this request. + // This is required only because the NSURLProtocol enqueues the same request + // multiple times. + if ([requestId integerValue] > _lastCommandQueueFlushRequestId) { + _lastCommandQueueFlushRequestId = [requestId integerValue]; + [self fetchCommandsFromJs]; + } +} + +/** + * Repeatedly fetches and executes the command queue until it is empty. + */ +- (void)fetchCommandsFromJs +{ + [_viewController.webView stringByEvaluatingJavaScriptFromString: + @"cordova.commandQueueFlushing = true"]; + + // Keep executing the command queue until no commands get executed. + // This ensures that commands that are queued while executing other + // commands are executed as well. + for (;; ) { + // Grab all the queued commands from the JS side. + NSString* queuedCommandsJSON = [_viewController.webView stringByEvaluatingJavaScriptFromString: + @"cordova.require('cordova/plugin/ios/nativecomm')()"]; + + if ([@"[]" isEqualToString:queuedCommandsJSON]) { + break; + } + [self executeCommandsFromJson:queuedCommandsJSON]; + } + + [_viewController.webView stringByEvaluatingJavaScriptFromString: + @"cordova.commandQueueFlushing = false"]; +} + +- (void)executePending +{ + // Make us re-entrant-safe. + if (_currentlyExecuting) { + return; + } + @try { + _currentlyExecuting = YES; + + for (NSUInteger i = 0; i < [_queue count]; ++i) { + // Parse the returned JSON array. + NSArray* commandBatch = [[_queue objectAtIndex:i] cdvjk_mutableObjectFromJSONString]; + + // Iterate over and execute all of the commands. + for (NSArray* jsonEntry in commandBatch) { + CDVInvokedUrlCommand* command = [CDVInvokedUrlCommand commandFromJson:jsonEntry]; + if (![_viewController execute:command]) { +#ifdef DEBUG + NSString* commandJson = [jsonEntry cdvjk_JSONString]; + static NSUInteger maxLogLength = 1024; + NSString* commandString = ([commandJson length] > maxLogLength) ? + [NSString stringWithFormat:@"%@[...]", [commandJson substringToIndex:maxLogLength]] : + commandJson; + + DLog(@"FAILED pluginJSON = %@", commandString); +#endif + } + } + } + + [_queue removeAllObjects]; + } @finally + { + _currentlyExecuting = NO; + } +} + +- (BOOL)execute:(CDVInvokedUrlCommand*)command +{ + if ((command.className == nil) || (command.methodName == nil)) { + NSLog(@"ERROR: Classname and/or methodName not found for command."); + return NO; + } + + // Fetch an instance of this class + CDVPlugin* obj = [_viewController getCommandInstance:command.className]; + + if (!([obj isKindOfClass:[CDVPlugin class]])) { // still allow deprecated class, until 1.0 release + NSLog(@"ERROR: Plugin '%@' not found, or is not a CDVPlugin. Check your plugin mapping in Cordova.plist.", command.className); + return NO; + } + BOOL retVal = YES; + + // Find the proper selector to call. + NSString* methodName = [NSString stringWithFormat:@"%@:", command.methodName]; + NSString* methodNameWithDict = [NSString stringWithFormat:@"%@:withDict:", command.methodName]; + SEL normalSelector = NSSelectorFromString(methodName); + SEL legacySelector = NSSelectorFromString(methodNameWithDict); + // Test for the legacy selector first in case they both exist. + if ([obj respondsToSelector:legacySelector]) { + NSMutableArray* arguments = nil; + NSMutableDictionary* dict = nil; + [command legacyArguments:&arguments andDict:&dict]; + // [obj performSelector:legacySelector withObject:arguments withObject:dict]; + objc_msgSend(obj, legacySelector, arguments, dict); + } else if ([obj respondsToSelector:normalSelector]) { + // [obj performSelector:normalSelector withObject:command]; + objc_msgSend(obj, normalSelector, command); + } else { + // There's no method to call, so throw an error. + NSLog(@"ERROR: Method '%@' not defined in Plugin '%@'", methodName, command.className); + retVal = NO; + } + + return retVal; +} + +@end http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/9e1aa3d5/CordovaLib/Classes/CDVURLProtocol.m ---------------------------------------------------------------------- diff --git a/CordovaLib/Classes/CDVURLProtocol.m b/CordovaLib/Classes/CDVURLProtocol.m index e515a8c..3d59f1f 100644 --- a/CordovaLib/Classes/CDVURLProtocol.m +++ b/CordovaLib/Classes/CDVURLProtocol.m @@ -18,6 +18,7 @@ */ #import "CDVURLProtocol.h" +#import "CDVCommandQueue.h" #import "CDVWhitelist.h" #import "CDVViewController.h" @@ -96,10 +97,10 @@ static NSMutableSet* gRegisteredControllers = nil; BOOL hasCmds = [queuedCommandsJSON length] > 0; if (hasCmds) { SEL sel = @selector(executeCommandsFromJson:); - [viewController performSelectorOnMainThread:sel withObject:queuedCommandsJSON waitUntilDone:NO]; + [viewController.commandQueue performSelectorOnMainThread:sel withObject:queuedCommandsJSON waitUntilDone:NO]; } else { - SEL sel = @selector(maybeFlushCommandQueue:); - [viewController performSelectorOnMainThread:sel withObject:[NSNumber numberWithInteger:[requestId integerValue]] waitUntilDone:NO]; + SEL sel = @selector(maybeFetchCommandsFromJs:); + [viewController.commandQueue performSelectorOnMainThread:sel withObject:[NSNumber numberWithInteger:[requestId integerValue]] waitUntilDone:NO]; } // Returning NO here would be 20% faster, but it spams WebInspector's console with failure messages. // If JS->Native bridge speed is really important for an app, they should use the iframe bridge. http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/9e1aa3d5/CordovaLib/Classes/CDVViewController.h ---------------------------------------------------------------------- diff --git a/CordovaLib/Classes/CDVViewController.h b/CordovaLib/Classes/CDVViewController.h index 1734b84..a4aa41c 100644 --- a/CordovaLib/Classes/CDVViewController.h +++ b/CordovaLib/Classes/CDVViewController.h @@ -24,10 +24,8 @@ #import "CDVCommandDelegate.h" #import "CDVWhitelist.h" -@interface CDVViewController : UIViewController <UIWebViewDelegate, CDVCommandDelegate>{ - @private - NSInteger _lastCommandQueueFlushRequestId; -} +@class CDVCommandQueue; +@interface CDVViewController : UIViewController <UIWebViewDelegate, CDVCommandDelegate> @property (nonatomic, strong) IBOutlet CDVCordovaView* webView; @@ -44,6 +42,7 @@ @property (nonatomic, readwrite, copy) NSString* wwwFolderName; @property (nonatomic, readwrite, copy) NSString* startPage; +@property (nonatomic, readonly, strong) CDVCommandQueue* commandQueue; + (NSDictionary*)getBundlePlist:(NSString*)plistName; + (NSString*)applicationDocumentsDirectory; @@ -53,10 +52,6 @@ - (void)createGapView; - (CDVCordovaView*)newCordovaViewWithFrame:(CGRect)bounds; -- (void)maybeFlushCommandQueue:(NSNumber*)requestId; -- (int)executeCommandsFromJson:(NSString*)queuedCommandsJSON; -- (void)flushCommandQueue; - - (void)javascriptAlert:(NSString*)text; - (NSString*)appURLScheme; http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/9e1aa3d5/CordovaLib/Classes/CDVViewController.m ---------------------------------------------------------------------- diff --git a/CordovaLib/Classes/CDVViewController.m b/CordovaLib/Classes/CDVViewController.m index 9a99906..ddf9253 100644 --- a/CordovaLib/Classes/CDVViewController.m +++ b/CordovaLib/Classes/CDVViewController.m @@ -17,8 +17,9 @@ under the License. */ -#import "CDV.h" #import <objc/message.h> +#import "CDV.h" +#import "CDVCommandQueue.h" #define degreesToRadian(x) (M_PI * (x) / 180.0) @@ -48,6 +49,7 @@ - (void)__init { if ((self != nil) && !self.initialized) { + _commandQueue = [[CDVCommandQueue alloc] initWithViewController:self]; [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receivedOrientationChange) name:UIDeviceOrientationDidChangeNotification object:nil]; @@ -483,7 +485,7 @@ */ - (void)webViewDidStartLoad:(UIWebView*)theWebView { - _lastCommandQueueFlushRequestId = 0; + [_commandQueue resetRequestId]; [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPluginResetNotification object:nil]]; } @@ -532,7 +534,7 @@ * The part of the URL after gap:// is irrelevant. */ if ([[url scheme] isEqualToString:@"gap"]) { - [self flushCommandQueue]; + [_commandQueue fetchCommandsFromJs]; return NO; } @@ -793,109 +795,9 @@ BOOL gSplashScreenShown = NO; #pragma mark CordovaCommands -/** - * Fetches the command queue and executes each command. It is possible that the - * queue will not be empty after this function has completed since the executed - * commands may have run callbacks which queued more commands. - * - * Returns the number of executed commands. - */ -- (int)executeCommandsFromJson:(NSString*)queuedCommandsJSON -{ - // Parse the returned JSON array. - NSArray* queuedCommands = [queuedCommandsJSON cdvjk_mutableObjectFromJSONString]; - - // Iterate over and execute all of the commands. - for (NSArray* jsonEntry in queuedCommands) { - CDVInvokedUrlCommand* command = [CDVInvokedUrlCommand commandFromJson:jsonEntry]; - if (![self execute:command]) { -#ifdef DEBUG - NSString* commandJson = [jsonEntry cdvjk_JSONString]; - static NSUInteger maxLogLength = 1024; - NSString* commandString = ([commandJson length] > maxLogLength) ? - [NSString stringWithFormat:@"%@[...]", [commandJson substringToIndex:maxLogLength]] : - commandJson; - - DLog(@"FAILED pluginJSON = %@", commandString); -#endif - } - } - - return [queuedCommands count]; -} - -- (void)maybeFlushCommandQueue:(NSNumber*)requestId -{ - // Use the request ID to determine if we've already flushed for this request. - // This is required only because the NSURLProtocol enqueues the same request - // multiple times. - if ([requestId integerValue] > _lastCommandQueueFlushRequestId) { - _lastCommandQueueFlushRequestId = [requestId integerValue]; - [self flushCommandQueue]; - } -} - -/** - * Repeatedly fetches and executes the command queue until it is empty. - */ -- (void)flushCommandQueue -{ - [self.webView stringByEvaluatingJavaScriptFromString: - @"cordova.commandQueueFlushing = true"]; - - // Keep executing the command queue until no commands get executed. - // This ensures that commands that are queued while executing other - // commands are executed as well. - int numExecutedCommands = 0; - do { - // Grab all the queued commands from the JS side. - NSString* queuedCommandsJSON = [self.webView stringByEvaluatingJavaScriptFromString: - @"cordova.require('cordova/plugin/ios/nativecomm')()"]; - numExecutedCommands = [self executeCommandsFromJson:queuedCommandsJSON]; - } while (numExecutedCommands != 0); - - [self.webView stringByEvaluatingJavaScriptFromString: - @"cordova.commandQueueFlushing = false"]; -} - - (BOOL)execute:(CDVInvokedUrlCommand*)command { - if ((command.className == nil) || (command.methodName == nil)) { - NSLog(@"ERROR: Classname and/or methodName not found for command."); - return NO; - } - - // Fetch an instance of this class - CDVPlugin* obj = [self getCommandInstance:command.className]; - - if (!([obj isKindOfClass:[CDVPlugin class]])) { // still allow deprecated class, until 1.0 release - NSLog(@"ERROR: Plugin '%@' not found, or is not a CDVPlugin. Check your plugin mapping in Cordova.plist.", command.className); - return NO; - } - BOOL retVal = YES; - - // Find the proper selector to call. - NSString* methodName = [NSString stringWithFormat:@"%@:", command.methodName]; - NSString* methodNameWithDict = [NSString stringWithFormat:@"%@:withDict:", command.methodName]; - SEL normalSelector = NSSelectorFromString(methodName); - SEL legacySelector = NSSelectorFromString(methodNameWithDict); - // Test for the legacy selector first in case they both exist. - if ([obj respondsToSelector:legacySelector]) { - NSMutableArray* arguments = nil; - NSMutableDictionary* dict = nil; - [command legacyArguments:&arguments andDict:&dict]; - // [obj performSelector:legacySelector withObject:arguments withObject:dict]; - objc_msgSend(obj, legacySelector, arguments, dict); - } else if ([obj respondsToSelector:normalSelector]) { - // [obj performSelector:normalSelector withObject:command]; - objc_msgSend(obj, normalSelector, command); - } else { - // There's no method to call, so throw an error. - NSLog(@"ERROR: Method '%@' not defined in Plugin '%@'", methodName, command.className); - retVal = NO; - } - - return retVal; + return [_commandQueue execute:command]; } - (void)registerPlugin:(CDVPlugin*)plugin withClassName:(NSString*)className http://git-wip-us.apache.org/repos/asf/incubator-cordova-ios/blob/9e1aa3d5/CordovaLib/CordovaLib.xcodeproj/project.pbxproj ---------------------------------------------------------------------- diff --git a/CordovaLib/CordovaLib.xcodeproj/project.pbxproj b/CordovaLib/CordovaLib.xcodeproj/project.pbxproj index d89f64d..8a6d563 100644 --- a/CordovaLib/CordovaLib.xcodeproj/project.pbxproj +++ b/CordovaLib/CordovaLib.xcodeproj/project.pbxproj @@ -71,6 +71,8 @@ 88BA573E109BB46F00FB5E78 /* CDVAccelerometer.m in Sources */ = {isa = PBXBuildFile; fileRef = 88BA573C109BB46F00FB5E78 /* CDVAccelerometer.m */; }; C937A4561337599E002C4C79 /* CDVFileTransfer.h in Headers */ = {isa = PBXBuildFile; fileRef = C937A4541337599E002C4C79 /* CDVFileTransfer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 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 */; }; 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, ); }; }; @@ -156,6 +158,8 @@ AA747D9E0F9514B9006C5449 /* CordovaLib_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CordovaLib_Prefix.pch; sourceTree = SOURCE_ROOT; }; C937A4541337599E002C4C79 /* CDVFileTransfer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CDVFileTransfer.h; path = Classes/CDVFileTransfer.h; sourceTree = "<group>"; }; 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>"; }; 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>"; }; @@ -218,6 +222,8 @@ 8852C43714B65FD800F0E735 /* CDVViewController.m */, 8852C43814B65FD800F0E735 /* CDVCordovaView.h */, 8852C43914B65FD800F0E735 /* CDVCordovaView.m */, + EB3B3545161CB44D003DBE7D /* CDVCommandQueue.h */, + EB3B3546161CB44D003DBE7D /* CDVCommandQueue.m */, ); name = Cleaver; sourceTree = "<group>"; @@ -370,6 +376,7 @@ EBA3557315ABD38C00F4DE24 /* NSArray+Comparisons.h in Headers */, 30C5F1DF15AF9E950052A00D /* CDVDevice.h in Headers */, EB80C2AC15DEA63D004D9E7B /* CDVEcho.h in Headers */, + EB3B3547161CB44D003DBE7D /* CDVCommandQueue.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -459,6 +466,7 @@ EBA3557515ABD38C00F4DE24 /* NSArray+Comparisons.m in Sources */, 30C5F1E015AF9E950052A00D /* CDVDevice.m in Sources */, EB80C2AD15DEA63D004D9E7B /* CDVEcho.m in Sources */, + EB3B3548161CB44D003DBE7D /* CDVCommandQueue.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; };