Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add command for saving screenshots in the camera roll #237

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Frank.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@
30E82E3417128AB500E5BC7C /* ResolutionCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 30E82E3117128AB500E5BC7C /* ResolutionCommand.m */; };
30E82E3517128AB500E5BC7C /* ResolutionCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 30E82E3117128AB500E5BC7C /* ResolutionCommand.m */; };
387BFA7D17036DDA007B9F17 /* UISlider+PublicAutomation.m in Sources */ = {isa = PBXBuildFile; fileRef = 387BFA7C17036DDA007B9F17 /* UISlider+PublicAutomation.m */; };
400632C717C61767005BAE46 /* SaveScreenshotInCameraRollCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 400632C517C61767005BAE46 /* SaveScreenshotInCameraRollCommand.h */; };
400632C817C61767005BAE46 /* SaveScreenshotInCameraRollCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 400632C617C61767005BAE46 /* SaveScreenshotInCameraRollCommand.m */; };
4C1DD76C12BADFE100E10B8C /* OrientationCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1DD76812BADFE100E10B8C /* OrientationCommand.m */; };
4C1DD76D12BADFE100E10B8C /* OrientationCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C1DD76912BADFE100E10B8C /* OrientationCommand.h */; };
4C1DD76E12BADFE100E10B8C /* AppCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1DD76A12BADFE100E10B8C /* AppCommand.m */; };
Expand Down Expand Up @@ -313,6 +315,8 @@
30E82E3017128AB500E5BC7C /* ResolutionCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResolutionCommand.h; sourceTree = "<group>"; };
30E82E3117128AB500E5BC7C /* ResolutionCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ResolutionCommand.m; sourceTree = "<group>"; };
387BFA7C17036DDA007B9F17 /* UISlider+PublicAutomation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UISlider+PublicAutomation.m"; sourceTree = "<group>"; };
400632C517C61767005BAE46 /* SaveScreenshotInCameraRollCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SaveScreenshotInCameraRollCommand.h; sourceTree = "<group>"; };
400632C617C61767005BAE46 /* SaveScreenshotInCameraRollCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SaveScreenshotInCameraRollCommand.m; sourceTree = "<group>"; };
4C1DD76812BADFE100E10B8C /* OrientationCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OrientationCommand.m; sourceTree = "<group>"; };
4C1DD76912BADFE100E10B8C /* OrientationCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OrientationCommand.h; sourceTree = "<group>"; };
4C1DD76A12BADFE100E10B8C /* AppCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppCommand.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -699,6 +703,8 @@
C189EF1D16BB5A8000F8236D /* VersionCommand.m */,
30E82E3017128AB500E5BC7C /* ResolutionCommand.h */,
30E82E3117128AB500E5BC7C /* ResolutionCommand.m */,
400632C517C61767005BAE46 /* SaveScreenshotInCameraRollCommand.h */,
400632C617C61767005BAE46 /* SaveScreenshotInCameraRollCommand.m */,
);
name = Commands;
sourceTree = "<group>";
Expand Down Expand Up @@ -866,6 +872,7 @@
303CFCE416C80B830004BD05 /* DeviceCommand.h in Headers */,
30E82E3217128AB500E5BC7C /* ResolutionCommand.h in Headers */,
0626BFAE174300240020B33B /* DumpCommandRoute.h in Headers */,
400632C717C61767005BAE46 /* SaveScreenshotInCameraRollCommand.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -1240,6 +1247,7 @@
387BFA7D17036DDA007B9F17 /* UISlider+PublicAutomation.m in Sources */,
0626BFAF174300240020B33B /* DumpCommandRoute.m in Sources */,
3078E33C175417AE0016889C /* NSObject+FrankAutomation.m in Sources */,
400632C817C61767005BAE46 /* SaveScreenshotInCameraRollCommand.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
4 changes: 4 additions & 0 deletions gem/lib/frank-cucumber/core_frank_steps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@
element_exists_and_is_not_hidden.should be_false
end

# -- Save screenshots in the camera roll -- #
Given /^the device saves (\d+) screenshot(s)? in the camera roll$/ do |number,_|
frankly_save_screenshot_in_camera_roll number
end

# -- Rotate -- #
Given /^the device is in (a )?(landscape|portrait) orientation$/ do |_,orientation|
Expand Down
8 changes: 8 additions & 0 deletions gem/lib/frank-cucumber/frank_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,14 @@ def frankly_set_orientation(orientation)
return Gateway.evaluate_frankly_response( res, "set_orientation #{orientation}" )
end

# takes an screenshot and saves it an specific number of times in the camera roll.
# @param number the number of times the screenshot will be saved.
# @return always success, because there is no way of knowing wether the screenshots were succesfully saved or not.
def frankly_save_screenshot_in_camera_roll(number)
res = frank_server.send_post( 'save_screenshot_in_camera_roll', number )
return Gateway.evaluate_frankly_response( res, "save_screenshot_in_camera_roll #{number}" )
end

# @return [Boolean] Does the device running the application have accessibility enabled.
# If accessibility is not enabled then a lot of Frank functionality will not work.
def frankly_is_accessibility_enabled
Expand Down
2 changes: 2 additions & 0 deletions src/FrankServer.m
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#import "OrientationCommand.h"
#import "LocationCommand.h"
#import "IOSKeyboardCommand.h"
#import "SaveScreenshotInCameraRollCommand.h"
#else
#import "OSXKeyboardCommand.h"
#endif
Expand Down Expand Up @@ -73,6 +74,7 @@ - (id) initWithStaticFrankBundleNamed:(NSString *)bundleName
[frankCommandRoute registerCommand:[[[OrientationCommand alloc]init]autorelease] withName:@"orientation"];
[frankCommandRoute registerCommand:[[[LocationCommand alloc]init]autorelease] withName:@"location"];
[frankCommandRoute registerCommand:[[[IOSKeyboardCommand alloc] init]autorelease] withName:@"type_into_keyboard"];
[frankCommandRoute registerCommand:[[[SaveScreenshotInCameraRollCommand alloc] init]autorelease] withName:@"save_screenshot_in_camera_roll"];
#else
[frankCommandRoute registerCommand:[[[SuccessCommand alloc]init]autorelease] withName:@"orientation"];
[frankCommandRoute registerCommand:[[[SuccessCommand alloc]init]autorelease] withName:@"location"];
Expand Down
15 changes: 15 additions & 0 deletions src/SaveScreenshotInCameraRollCommand.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// SaveScreenshotInCameraRollCommand.h
// Frank
//
// Created by Sergio Padrino on 22/08/13.
//
//

#import <Foundation/Foundation.h>

#import "FrankCommandRoute.h"

@interface SaveScreenshotInCameraRollCommand : NSObject <FrankCommand>

@end
62 changes: 62 additions & 0 deletions src/SaveScreenshotInCameraRollCommand.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//
// SaveScreenshotInCameraRollCommand.m
// Frank
//
// Created by Sergio Padrino on 22/08/13.
//
//

#import "SaveScreenshotInCameraRollCommand.h"

#import "FranklyProtocolHelper.h"
#import "UIImage+Frank.h"

@interface SaveScreenshotInCameraRollCommand ()

@property (nonatomic, assign) NSUInteger numberOfPhotos;
@property (nonatomic, retain) UIImage *screenshot;

@end

@implementation SaveScreenshotInCameraRollCommand

- (void)dealloc
{
[_screenshot release];

[super dealloc];
}

- (NSString *)handleCommandWithRequestBody:(NSString *)requestBody {
self.numberOfPhotos = [requestBody integerValue];

self.screenshot = [UIImage imageFromApplication:YES
resultInPortrait:UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation])];

// This code is running in the main thread and UIImageWriteToSavedPhotosAlbum also calls its callback in the main
// thread. Therefore, it's impossible to make this process completely synchronous as needed (waiting for all the
// images to be saved and then return the results), so all we can do is start a chain of calls for saving the images
// and hope for the app to live long enough so that all the images are written in the camera roll.
[self saveScreenshotInPhotosAlbum];

return [FranklyProtocolHelper generateSuccessResponseWithoutResults];
}

- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
self.numberOfPhotos -= 1;

// Continue saving images until all have been saved
if (self.numberOfPhotos > 0) {
[self saveScreenshotInPhotosAlbum];
}
else {
self.screenshot = nil;
}
}

- (void)saveScreenshotInPhotosAlbum
{
UIImageWriteToSavedPhotosAlbum(self.screenshot, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
}

@end