Use newer Photos API for screenshots, when available

AssetsLibrary is deprecated. We now use the newer Photos API to fetch the screenshots.
This commit is contained in:
Lukas Spieß
2015-09-14 17:01:53 +02:00
parent 3ec882fa04
commit 608e12f255
7 changed files with 84 additions and 18 deletions

View File

@@ -32,6 +32,7 @@
#if HOCKEYSDK_FEATURE_FEEDBACK
#import <AssetsLibrary/AssetsLibrary.h>
#import <Photos/Photos.h>
#import "HockeySDKPrivate.h"
@@ -55,6 +56,8 @@
NSString *const kBITFeedbackUpdateAttachmentThumbnail = @"BITFeedbackUpdateAttachmentThumbnail";
typedef void (^BITLatestImageFetchCompletionBlock)(UIImage *latestImage);
@interface BITFeedbackManager()<UIGestureRecognizerDelegate>
@property (nonatomic, strong) UITapGestureRecognizer *tapRecognizer;
@@ -1153,25 +1156,83 @@ NSString *const kBITFeedbackUpdateAttachmentThumbnail = @"BITFeedbackUpdateAttac
}
-(void)extractLastPictureFromLibraryAndLaunchFeedback {
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[self requestLatestImageWithCompletionHandler:^(UIImage *latestImage) {
[self showFeedbackComposeViewWithPreparedItems:@[latestImage]];
}];
}
- (void)requestLatestImageWithCompletionHandler:(BITLatestImageFetchCompletionBlock)completionHandler {
if (!completionHandler) { return; }
// Only available from iOS 8 up
id phimagemanagerClass = NSClassFromString(@"PHImageManager");
if (phimagemanagerClass) {
[self fetchLatestImageUsingPhotoLibraryWithCompletionHandler:completionHandler];
} else {
[self fetchLatestImageUsingAssetsLibraryWithCompletionHandler:completionHandler];
}
}
- (void)fetchLatestImageUsingAssetsLibraryWithCompletionHandler:(BITLatestImageFetchCompletionBlock)completionHandler {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
[group setAssetsFilter:[ALAssetsFilter allPhotos]];
[group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *alAsset, NSUInteger index, BOOL *innerStop) {
[group setAssetsFilter:[ALAssetsFilter allPhotos]];
[group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *alAsset, NSUInteger index, BOOL *innerStop) {
if (alAsset) {
ALAssetRepresentation *representation = [alAsset defaultRepresentation];
UIImage *latestPhoto = [UIImage imageWithCGImage:[representation fullScreenImage]];
completionHandler(latestPhoto);
*stop = YES;
*innerStop = YES;
}
}];
} failureBlock: nil];
#pragma clang diagnostic pop
}
- (void)fetchLatestImageUsingPhotoLibraryWithCompletionHandler:(BITLatestImageFetchCompletionBlock)completionHandler {
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if ((status == PHAuthorizationStatusDenied) || (status == PHAuthorizationStatusRestricted)) {
BITHockeyLog(@"INFO: The latest image could not be fetched, not permissions.");
completionHandler(nil);
if (alAsset) {
ALAssetRepresentation *representation = [alAsset defaultRepresentation];
UIImage *latestPhoto = [UIImage imageWithCGImage:[representation fullScreenImage]];
*stop = YES;
*innerStop = YES;
[self showFeedbackComposeViewWithPreparedItems:@[latestPhoto]];
} else if (status == PHAuthorizationStatusAuthorized) {
PHImageManager *imageManager = PHImageManager.defaultManager;
PHFetchOptions *fetchOptions = [PHFetchOptions new];
fetchOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];
PHFetchResult *fetchResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:fetchOptions];
if (fetchResult.count > 0) {
PHAsset *latestImageAsset = (PHAsset *)fetchResult.lastObject;
if (latestImageAsset) {
PHImageRequestOptions *options = [PHImageRequestOptions new];
options.version = PHImageRequestOptionsVersionCurrent;
options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
options.resizeMode = PHImageRequestOptionsResizeModeNone;
[imageManager requestImageDataForAsset:latestImageAsset options:options resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
if (imageData) {
completionHandler([UIImage imageWithData:imageData]);
return;
}
}];
}
} else {
BITHockeyLog(@"INFO: The latest image could not be fetched, the fetch result was empty.");
}
}];
} failureBlock: nil];
completionHandler(nil);
}
}];
}
- (void)screenshotTripleTap:(UITapGestureRecognizer *)tapRecognizer {

View File

@@ -22,7 +22,7 @@ Pod::Spec.new do |s|
s.source_files = 'Classes'
s.requires_arc = true
s.frameworks = 'AssetsLibrary', 'CoreGraphics', 'CoreTelephony', 'CoreText', 'MobileCoreServices', 'QuartzCore', 'QuickLook', 'Security', 'SystemConfiguration', 'UIKit'
s.frameworks = 'AssetsLibrary', 'CoreGraphics', 'CoreTelephony', 'CoreText', 'MobileCoreServices', 'Photos', 'QuartzCore', 'QuickLook', 'Security', 'SystemConfiguration', 'UIKit'
s.libraries = 'c++', 'z'
s.ios.vendored_frameworks = 'Vendor/CrashReporter.framework'
s.pod_target_xcconfig = {'GCC_PREPROCESSOR_DEFINITIONS' => %{$(inherited) BITHOCKEY_VERSION="@\\"#{s.version}\\"" BITHOCKEY_C_VERSION="\\"#{s.version}\\"" BITHOCKEY_BUILD="@\\"51\\"" BITHOCKEY_C_BUILD="\\"51\\""} }

View File

@@ -42,7 +42,7 @@ Pod::Spec.new do |s|
s.subspec 'AllFeaturesLib' do |ss|
ss.resource_bundle = { 'HockeySDKResources' => ['HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDK.framework/Versions/A/Resources/HockeySDKResources.bundle/*.png', 'HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDK.framework/Versions/A/Resources/HockeySDKResources.bundle/*.lproj'] }
ss.frameworks = 'AssetsLibrary', 'CoreGraphics', 'CoreText', 'CoreTelephony', 'MobileCoreServices', 'QuartzCore', 'QuickLook', 'UIKit'
ss.frameworks = 'AssetsLibrary', 'CoreGraphics', 'CoreText', 'CoreTelephony', 'MobileCoreServices', 'Photos,'QuartzCore', 'QuickLook', 'UIKit'
ss.libraries = 'z'
ss.vendored_frameworks = 'HockeySDK-iOS/HockeySDK.embeddedframework/HockeySDK.framework'
end

View File

@@ -148,10 +148,12 @@ If you are working with an older project which doesn't support clang modules yet
+ `MobileCoreServices`
+ `QuartzCore`
+ `QuickLook`
+ `Photos`
+ `Security`
+ `SystemConfiguration`
+ `UIKit`
+ `libc++`
+ `libz`
2. Crash reporting only:
+ `Foundation`
+ `Security`

View File

@@ -1,3 +1,3 @@
OTHER_LDFLAGS=$(inherited) -framework CrashReporter -framework CoreTelephony -framework CoreText -framework CoreGraphics -framework Foundation -framework QuartzCore -framework SystemConfiguration -framework UIKit -framework Security -framework AssetsLibrary -framework MobileCoreServices -framework QuickLook -lc++ -lz
OTHER_LDFLAGS=$(inherited) -framework CrashReporter -framework AssetsLibrary -framework CoreTelephony -framework CoreText -framework CoreGraphics -framework Foundation -framework MobileCoreServices -framework Photos -framework QuartzCore -framework QuickLook -framework Security -framework SystemConfiguration -framework UIKit -lc++ -lz
HOCKEYSDK_DOCSET_NAME=HockeySDK-iOS
GCC_PREPROCESSOR_DEFINITIONS=$(inherited) CONFIGURATION_$(CONFIGURATION)

View File

@@ -10,6 +10,7 @@ framework module HockeySDK {
link framework "CoreGraphics"
link framework "Foundation"
link framework "MobileCoreServices"
link framework "Photos"
link framework "QuartzCore"
link framework "QuickLook"
link framework "Security"

View File

@@ -130,12 +130,14 @@ If you are working with an older project which doesn't support clang modules yet
+ `CoreGraphics`
+ `Foundation`
+ `MobileCoreServices`
+ `Photos`
+ `QuartzCore`
+ `QuickLook`
+ `Security`
+ `SystemConfiguration`
+ `UIKit`
+ `libc++`
+ `libz`
2. Crash reporting only:
+ `Foundation`
+ `Security`