diff --git a/Frank.xcodeproj/project.pbxproj b/Frank.xcodeproj/project.pbxproj index e31b649..60ad2ed 100644 --- a/Frank.xcodeproj/project.pbxproj +++ b/Frank.xcodeproj/project.pbxproj @@ -85,6 +85,8 @@ 4C1DD76D12BADFE100E10B8C /* OrientationCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C1DD76912BADFE100E10B8C /* OrientationCommand.h */; }; 4C1DD76E12BADFE100E10B8C /* AppCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1DD76A12BADFE100E10B8C /* AppCommand.m */; }; 4C1DD76F12BADFE100E10B8C /* AppCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C1DD76B12BADFE100E10B8C /* AppCommand.h */; }; + 5390A25A1A65E5B600EB436B /* DirectAppExecCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 5390A2581A65E5B600EB436B /* DirectAppExecCommand.h */; }; + 5390A25B1A65E5B600EB436B /* DirectAppExecCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 5390A2591A65E5B600EB436B /* DirectAppExecCommand.m */; }; 65DBDD7416A89CCA007D3D43 /* GCDAsyncSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = AB7947C115C4418700052B74 /* GCDAsyncSocket.m */; }; 65DBDD8D16A89CCA007D3D43 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AACBBE490F95108600F1A2B1 /* Foundation.framework */; }; 65DBDDA816A89CDC007D3D43 /* DDAbstractDatabaseLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = ABA9E4BB15C81E7900112290 /* DDAbstractDatabaseLogger.m */; }; @@ -344,6 +346,8 @@ 4C1DD76912BADFE100E10B8C /* OrientationCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OrientationCommand.h; sourceTree = ""; }; 4C1DD76A12BADFE100E10B8C /* AppCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppCommand.m; sourceTree = ""; }; 4C1DD76B12BADFE100E10B8C /* AppCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppCommand.h; sourceTree = ""; }; + 5390A2581A65E5B600EB436B /* DirectAppExecCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectAppExecCommand.h; sourceTree = ""; }; + 5390A2591A65E5B600EB436B /* DirectAppExecCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DirectAppExecCommand.m; sourceTree = ""; }; 65DBDD9216A89CCA007D3D43 /* libCocoaAsyncSocket.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libCocoaAsyncSocket.a; sourceTree = BUILT_PRODUCTS_DIR; }; 65DBDDB516A89CDC007D3D43 /* libCocoaLumberjack.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libCocoaLumberjack.a; sourceTree = BUILT_PRODUCTS_DIR; }; 65DBDDDA16A89E5B007D3D43 /* libCocoaAsyncSocketMac.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libCocoaAsyncSocketMac.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -708,6 +712,8 @@ 4C1DD76A12BADFE100E10B8C /* AppCommand.m */, 303CFCE216C80B830004BD05 /* DeviceCommand.h */, 303CFCE316C80B830004BD05 /* DeviceCommand.m */, + 5390A2581A65E5B600EB436B /* DirectAppExecCommand.h */, + 5390A2591A65E5B600EB436B /* DirectAppExecCommand.m */, D6FA01B714283C4F00576AF0 /* EnginesCommand.h */, D6FA01B714283C4F00576AEE /* EnginesCommand.m */, A91F3AA415F6E456003F434F /* ExitCommand.h */, @@ -899,6 +905,7 @@ D6FA01B714283C4F00576AF1 /* EnginesCommand.h in Headers */, A91F3AA615F6E456003F434F /* ExitCommand.h in Headers */, C9605E641606BF2900170F88 /* IOSKeyboardCommand.h in Headers */, + 5390A25A1A65E5B600EB436B /* DirectAppExecCommand.h in Headers */, C9605E6A1606BFAE00170F88 /* UIImage+Frank.h in Headers */, C18A5EF0160D4AB400DC25F6 /* ImageCaptureRoute.h in Headers */, C18A5EF5160D4AD300DC25F6 /* UIView+ImageCapture.h in Headers */, @@ -1270,6 +1277,7 @@ D6BD521F146C34BF001770B1 /* SelectorEngineRegistry.m in Sources */, 0071264714F8956700E738ED /* ViewJSONSerializer.m in Sources */, D6FA01B714283C4F00576AE1 /* FranklyProtocolHelper.m in Sources */, + 5390A25B1A65E5B600EB436B /* DirectAppExecCommand.m in Sources */, D6A1D28015A8D05E00EC056C /* UIView+Frank.m in Sources */, D6FA01B714283C4F00576AEF /* EnginesCommand.m in Sources */, A91F3AA715F6E456003F434F /* ExitCommand.m in Sources */, diff --git a/gem/lib/frank-cucumber/core_frank_steps.rb b/gem/lib/frank-cucumber/core_frank_steps.rb index 08d38ea..3907ae4 100644 --- a/gem/lib/frank-cucumber/core_frank_steps.rb +++ b/gem/lib/frank-cucumber/core_frank_steps.rb @@ -66,7 +66,11 @@ end Then /^I should see an alert view titled "([^\"]*)"$/ do |expected_mark| - values = frankly_map( 'alertView', 'title') + if frankly_os_version.to_f >= 7.0 + values = frankly_map( "view:'_UIModalItemRepresentationView' label", 'text') + else + values = frankly_map( 'alertView', 'title') + end values.should include(expected_mark) end @@ -76,7 +80,11 @@ end Then /^I should not see an alert view$/ do - check_element_does_not_exist( 'alertView' ) + if frankly_os_version.to_f >= 7.0 + check_element_does_not_exist( '_UIModalItemRepresentationView' ) + else + check_element_does_not_exist( 'alertView' ) + end end Then /^I should see an element of class "([^\"]*)" with name "([^\"]*)" with the following labels: "([^\"]*)"$/ do |className, classLabel, listOfLabels| diff --git a/src/DirectAppExecCommand.h b/src/DirectAppExecCommand.h new file mode 100644 index 0000000..9762944 --- /dev/null +++ b/src/DirectAppExecCommand.h @@ -0,0 +1,16 @@ +// +// DirectAppExecCommand.h +// Frank +// +// Created by Martin Taylor on 4-Apr-14. +// Copyright (c) 2014 Texas Instruments, Inc. All rights reserved. +// + +#import +#import "FrankCommandRoute.h" + +@interface DirectAppExecCommand : NSObject{ + +} + +@end diff --git a/src/DirectAppExecCommand.m b/src/DirectAppExecCommand.m new file mode 100644 index 0000000..0cec796 --- /dev/null +++ b/src/DirectAppExecCommand.m @@ -0,0 +1,54 @@ +// +// DirectAppExecCommand.m +// Frank +// +// Created by Martin Taylor on 4-Apr-14. +// Copyright (c) 2014 Texas Instruments, Inc. All rights reserved. +// +// NOTE: This code was copied directly from AppCommand.m. The only difference in this command is that the +// RequestRouter.m executes it on the HTTP thread rather than on the main UI thread. +// +#import +#import "DirectAppExecCommand.h" + +#import "Operation.h" +#import "ViewJSONSerializer.h" +#import "FranklyProtocolHelper.h" +#import "JSON.h" + +@implementation DirectAppExecCommand + +- (NSString *)handleCommandWithRequestBody:(NSString *)requestBody { + + NSDictionary *requestCommand = FROM_JSON(requestBody); + NSDictionary *operationDict = [requestCommand objectForKey:@"operation"]; + Operation *operation = [[[Operation alloc] initFromJsonRepresentation:operationDict] autorelease]; + +#if TARGET_OS_IPHONE + id appDelegate = [[UIApplication sharedApplication] delegate]; +#else + id appDelegate = [[NSApplication sharedApplication] delegate]; +#endif + + if( ![operation appliesToObject:appDelegate] ) + { + return [FranklyProtocolHelper generateErrorResponseWithReason:@"operation doesn't apply" andDetails:@"operation does not appear to be implemented in app delegate"]; + } + + id result; + + @try { + result = [operation applyToObject:appDelegate]; + } + @catch (NSException *e) { + NSLog( @"Exception while applying operation to app delegate:\n%@", e ); + return [FranklyProtocolHelper generateErrorResponseWithReason:@"exception while executing operation" andDetails:[e reason]]; + } + + NSMutableArray *results = [NSMutableArray new]; + [results addObject:[ViewJSONSerializer jsonify:result]]; + + return [FranklyProtocolHelper generateSuccessResponseWithResults: results]; +} + +@end diff --git a/src/FrankServer.m b/src/FrankServer.m index 7a50f2d..34df661 100644 --- a/src/FrankServer.m +++ b/src/FrankServer.m @@ -17,6 +17,7 @@ #import "DeviceCommand.h" #import "ExitCommand.h" #import "AppCommand.h" +#import "DirectAppExecCommand.h" #import "AccessibilityCheckCommand.h" #import "EnginesCommand.h" #import "VersionCommand.h" @@ -64,6 +65,7 @@ - (id) initWithStaticFrankBundleNamed:(NSString *)bundleName [frankCommandRoute registerCommand:[[[DeviceCommand alloc] init] autorelease] withName:@"device"]; [frankCommandRoute registerCommand:[[[AccessibilityCheckCommand alloc] init]autorelease] withName:@"accessibility_check"]; [frankCommandRoute registerCommand:[[[AppCommand alloc] init]autorelease] withName:@"app_exec"]; + [frankCommandRoute registerCommand:[[[DirectAppExecCommand alloc] init]autorelease] withName:@"direct_app_exec"]; [frankCommandRoute registerCommand:[[[EnginesCommand alloc] init]autorelease] withName:@"engines"]; [frankCommandRoute registerCommand:[[[VersionCommand alloc] initWithVersion:[NSString stringWithFormat:@"%s",xstr(FRANK_PRODUCT_VERSION)]]autorelease] withName:@"version"]; [frankCommandRoute registerCommand:[[[ExitCommand alloc] init] autorelease] withName:@"exit"]; diff --git a/src/OrientationCommand.m b/src/OrientationCommand.m index 1c948db..f6861e8 100644 --- a/src/OrientationCommand.m +++ b/src/OrientationCommand.m @@ -82,7 +82,7 @@ - (NSString *)getOrientationDescriptionViaDevice{ - (NSString *)handleGet{ NSDictionary *orientationDescription = [self getOrientationRepresentationViaDevice]; if( !orientationDescription ) - orientationDescription = [self getOrientationRepresentationViaDevice]; + orientationDescription = [self getOrientationRepresentationViaStatusBar]; return TO_JSON(orientationDescription); } diff --git a/src/RequestRouter.m b/src/RequestRouter.m index 38b53c1..421d6ed 100644 --- a/src/RequestRouter.m +++ b/src/RequestRouter.m @@ -64,9 +64,17 @@ - (void) registerRoute: (id) route { NSArray *pathComponents = [self pathComponentsWithPath:path]; __block NSObject *response = nil; for (id route in _routes) { - dispatch_sync(dispatch_get_main_queue(), ^{ + /* + * If the first pathComponent is "direct_app_exec" then the execution should happen in THIS thread, + * not in the main UI thread as is true for all other commands. + */ + if ([path hasSuffix:@"direct_app_exec"]) { response = [[route handleRequestForPath:pathComponents withConnection:connection] retain]; - }); + } else { + dispatch_sync(dispatch_get_main_queue(), ^{ + response = [[route handleRequestForPath:pathComponents withConnection:connection] retain]; + }); + } [response autorelease]; if( nil != response )