Reputation: 357
I am using PHImageManagers's requestImageDataForAsset to calculate memory size of particular photos in camera roll. It is working fine in my device but some users getting countinous crash after calculate memory size (found by analytics and crash report).
Please help.
Upvotes: 9
Views: 7642
Reputation: 289
If you want load all photos that you have in Photos.app and you didn't want iCloud. You can do:
That example works with a collection view.
@interface GalleryViewModel ()
@property (strong, nonatomic) NSMutableArray<PHAsset *> *assets;
@property (strong, nonatomic) PHImageManager *imageManager;
@property (strong, nonatomic) PHImageRequestOptions *requestOptions;
@property (strong, nonatomic) NSMutableArray<UIImage *> *imagesList;
@end
@implementation GalleryViewModel
- (instancetype) initWithContext:(ITXAppContext *)context {
self = [super initWithContext:context];
if (self) {
_assets = [[NSMutableArray alloc] init];
_imageManager = [PHImageManager defaultManager];
_requestOptions = [[PHImageRequestOptions alloc] init];
_imagesList = [[NSMutableArray alloc] init];
}
return self;
}
#pragma mark - Public methods
// ==================================================================================
// Public methods
- (void) viewModelDidLoad {
[self obtainAllPhotos];
}
#pragma mark - Private methods
// ==================================================================================
// Private methods
- (void) obtainAllPhotos {
self.requestOptions.resizeMode = PHImageRequestOptionsResizeModeExact;
self.requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
self.requestOptions.synchronous = YES;
self.requestOptions.networkAccessAllowed = NO;
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:NO]];
PHFetchResult<PHAsset *> *result = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:fetchOptions];
__weak GalleryViewModel *weakSelf = self;
[result enumerateObjectsUsingBlock:^(PHAsset * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
[weakSelf.assets addObject:obj];
if (idx >= ([result count] - 1)) {
[weakSelf.viewDelegate setupView];
}
}];
}
#pragma mark - Get data from object
// ==================================================================================
// Get data from object
- (NSInteger) sizeGallery {
if (self.assets) {
return [self.assets count];
}
return 0;
}
- (UIImage *) imagesFromList:(NSInteger) index {
__block UIImage *imageBlock;
[self.imageManager requestImageForAsset:[self.assets objectAtIndex:index] targetSize:CGSizeMake(200, 200) contentMode:PHImageContentModeAspectFit options:self.requestOptions resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
if (result) {
imageBlock = result;
}
}];
return imageBlock;
}
@end
Upvotes: 0
Reputation: 1482
I had an issue similar to this when users had their photos stored in iCloud using iCloud photo library. I was able to fix the issue by making the call asynchronous. It looks like this
let options = PHImageRequestOptions()
options.synchronous = false
options.networkAccessAllowed = true
Here is the whole function.
func getImageDataFromAsset(asset: PHAsset, completion: (data: NSData?) -> Void) {
let manager = PHImageManager.defaultManager()
let options = PHImageRequestOptions()
options.networkAccessAllowed = true
options.synchronous = false
manager.requestImageDataForAsset(asset, options: options) { (result, string, orientation, info) -> Void in
if let imageData = result {
completion(data: imageData)
} else {
completion(data: nil)
}
}
}
Upvotes: 2
Reputation: 9246
On which iOS version it is crashing, seems working fine for me in iOS 8.3 , if you are exactly using the same process to fetch image meta data or memory size:-
--------------------------------------------------------------
-- get the UIImage instance from a PHAsset
--------------------------------------------------------------
- (UIImage*)grabImageFromAsset:(PHAsset *)asset
{
__block UIImage *returnImage;
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.synchronous = YES;
[[PHImageManager defaultManager] requestImageForAsset:asset
targetSize:CGSizeMake(200, 200)
contentMode:PHImageContentModeAspectFill
options:options
resultHandler:
^(UIImage *result, NSDictionary *info) {
returnImage = result;
}];
return returnImage;
}
--------------------------------------------------------------
-- get the metadata of the image from a PHAsset
--------------------------------------------------------------
- (NSDictionary *)grabImageDataFromAsset:(PHAsset *)asset
{
__block NSMutableDictionary *imageAssetInfo = [NSMutableDictionary new];
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.synchronous = YES;
[[PHImageManager defaultManager] requestImageDataForAsset:asset
options:options
resultHandler:
^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
if ([info[@"PHImageResultIsInCloudKey"] isEqual:@YES]) {
// in the cloud
NSLog(@"in the cloud (sync grabImageDataFromAsset)");
}
imageAssetInfo = [info mutableCopy];
if (imageData) {
imageAssetInfo[@"IMAGE_NSDATA"] = imageData;
}
}];
return imageAssetInfo;
}
I am following this links for my photo kit operation:- phimagemanager and ios-8-photokit
Upvotes: 2