2016-05-31 14:50:30 +03:00
|
|
|
//
|
|
|
|
// CKGallery.m
|
|
|
|
// ReactNativeCameraKit
|
|
|
|
//
|
|
|
|
// Created by Ran Greenberg on 30/05/2016.
|
|
|
|
// Copyright © 2016 Wix. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#import "CKGalleryManager.h"
|
|
|
|
#import <Photos/Photos.h>
|
|
|
|
#import "RCTConvert.h"
|
|
|
|
|
2016-06-07 18:42:59 +03:00
|
|
|
typedef void (^AlbumsBlock)(NSDictionary *albums);
|
|
|
|
|
|
|
|
@interface CKGalleryManager ()
|
|
|
|
|
|
|
|
@property (nonatomic, strong) PHFetchResult *allPhotos;
|
|
|
|
@property (nonatomic, strong) PHFetchResult *smartAlbums;
|
|
|
|
@property (nonatomic, strong) PHFetchResult *topLevelUserCollections;
|
|
|
|
|
|
|
|
|
|
|
|
@end
|
2016-05-31 14:50:30 +03:00
|
|
|
|
|
|
|
@implementation CKGalleryManager
|
|
|
|
|
|
|
|
RCT_EXPORT_MODULE();
|
|
|
|
|
2016-06-07 18:42:59 +03:00
|
|
|
-(instancetype)init {
|
|
|
|
self = [super init];
|
|
|
|
|
|
|
|
[self initAlbums];
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2016-05-31 14:50:30 +03:00
|
|
|
|
2016-06-07 18:42:59 +03:00
|
|
|
-(void)initAlbums {
|
|
|
|
|
|
|
|
PHFetchOptions *allPhotosOptions = [[PHFetchOptions alloc] init];
|
|
|
|
allPhotosOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];
|
2016-05-31 14:50:30 +03:00
|
|
|
|
2016-06-07 18:42:59 +03:00
|
|
|
PHFetchOptions *albumsOptions = [[PHFetchOptions alloc] init];
|
|
|
|
albumsOptions.predicate = [NSPredicate predicateWithFormat:@"estimatedAssetCount > 0"];
|
2016-05-31 14:50:30 +03:00
|
|
|
|
2016-06-07 18:42:59 +03:00
|
|
|
self.allPhotos = [PHAsset fetchAssetsWithOptions:allPhotosOptions];
|
2016-06-14 18:12:50 +03:00
|
|
|
// self.smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAlbumMyPhotoStream options:nil];
|
2016-06-07 18:42:59 +03:00
|
|
|
self.topLevelUserCollections = [PHCollectionList fetchTopLevelUserCollectionsWithOptions:nil];
|
2016-05-31 14:50:30 +03:00
|
|
|
|
2016-06-02 14:08:06 +03:00
|
|
|
}
|
|
|
|
|
2016-06-07 18:42:59 +03:00
|
|
|
|
|
|
|
|
|
|
|
-(void)getAllAlbumsNameAndThumbnails:(AlbumsBlock)block {
|
|
|
|
|
|
|
|
PHImageRequestOptions *cropToSquare = [[PHImageRequestOptions alloc] init];
|
|
|
|
cropToSquare.resizeMode = PHImageRequestOptionsResizeModeExact;
|
|
|
|
cropToSquare.synchronous = YES;
|
|
|
|
NSInteger retinaScale = [UIScreen mainScreen].scale;
|
|
|
|
CGSize retinaSquare = CGSizeMake(100*retinaScale, 100*retinaScale);
|
|
|
|
|
|
|
|
NSMutableDictionary *albumsDict = [[NSMutableDictionary alloc] init];
|
2016-06-02 14:08:06 +03:00
|
|
|
|
2016-06-07 18:42:59 +03:00
|
|
|
NSInteger smartAlbumsCount = self.smartAlbums.count;
|
2016-06-02 14:08:06 +03:00
|
|
|
|
2016-05-31 14:50:30 +03:00
|
|
|
|
2016-06-02 14:08:06 +03:00
|
|
|
|
2016-06-07 18:42:59 +03:00
|
|
|
|
|
|
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
2016-06-02 14:08:06 +03:00
|
|
|
|
2016-06-07 18:42:59 +03:00
|
|
|
if (smartAlbumsCount) {
|
|
|
|
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
|
|
|
|
|
|
|
|
[self.smartAlbums enumerateObjectsUsingBlock:^(PHAssetCollection *collection, NSUInteger idx, BOOL * _Nonnull stop) {
|
|
|
|
|
|
|
|
NSInteger collectionCount = [PHAsset fetchAssetsInAssetCollection:collection options:nil].count;
|
|
|
|
|
|
|
|
if (collectionCount > 0){
|
|
|
|
|
|
|
|
NSString *albumName = collection.localizedTitle;
|
|
|
|
albumName = [NSString stringWithFormat:@"%@", albumName];
|
|
|
|
|
|
|
|
PHFetchResult *fetchResult = [PHAsset fetchKeyAssetsInAssetCollection:collection options:nil];
|
|
|
|
PHAsset *thumbnail = [fetchResult firstObject];
|
|
|
|
|
|
|
|
NSMutableDictionary *albumInfo = [[NSMutableDictionary alloc] init];
|
|
|
|
albumInfo[@"albumName"] = albumName;
|
2016-06-14 18:12:50 +03:00
|
|
|
albumInfo[@"imagesCount"] = [NSNumber numberWithInteger:collectionCount];
|
2016-06-07 18:42:59 +03:00
|
|
|
|
|
|
|
albumsDict[albumName] = albumInfo;
|
|
|
|
|
|
|
|
[[PHImageManager defaultManager]
|
|
|
|
requestImageForAsset:thumbnail
|
|
|
|
targetSize:retinaSquare
|
|
|
|
contentMode:PHImageContentModeAspectFit
|
|
|
|
options:cropToSquare
|
|
|
|
resultHandler:^(UIImage *result, NSDictionary *info) {
|
|
|
|
|
|
|
|
if (!albumInfo[@"image"]) {
|
|
|
|
|
|
|
|
albumInfo[@"image"] = [UIImageJPEGRepresentation(result, 1.0) base64Encoding];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (idx == smartAlbumsCount-1) {
|
|
|
|
|
|
|
|
dispatch_semaphore_signal(sem);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
else if (idx == smartAlbumsCount-1) {
|
|
|
|
dispatch_semaphore_signal(sem);
|
|
|
|
}
|
|
|
|
|
|
|
|
}];
|
|
|
|
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
|
|
|
|
}
|
2016-06-02 14:08:06 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
2016-06-07 18:42:59 +03:00
|
|
|
NSInteger topLevelAlbumsCount = self.topLevelUserCollections.count;
|
2016-06-02 14:08:06 +03:00
|
|
|
|
2016-06-07 18:42:59 +03:00
|
|
|
[self.topLevelUserCollections enumerateObjectsUsingBlock:^(PHAssetCollection *collection, NSUInteger idx, BOOL * _Nonnull stop) {
|
|
|
|
NSInteger collectionCount = [PHAsset fetchAssetsInAssetCollection:collection options:nil].count;
|
|
|
|
|
|
|
|
if (collectionCount > 0){
|
|
|
|
|
|
|
|
NSString *albumName = collection.localizedTitle;
|
|
|
|
albumName = [NSString stringWithFormat:@"%@", albumName];
|
|
|
|
|
|
|
|
PHFetchResult *fetchResult = [PHAsset fetchKeyAssetsInAssetCollection:collection options:nil];
|
|
|
|
PHAsset *thumbnail = [fetchResult firstObject];
|
|
|
|
|
|
|
|
NSMutableDictionary *albumInfo = [[NSMutableDictionary alloc] init];
|
|
|
|
albumInfo[@"albumName"] = [NSString stringWithFormat:@"%@", albumName];
|
2016-06-14 18:12:50 +03:00
|
|
|
albumInfo[@"imagesCount"] = [NSNumber numberWithInteger:collectionCount];
|
2016-06-07 18:42:59 +03:00
|
|
|
|
|
|
|
albumsDict[albumName] = albumInfo;
|
|
|
|
|
|
|
|
|
|
|
|
// __block BOOL isInvokeBlock = NO;
|
|
|
|
|
|
|
|
[[PHImageManager defaultManager]
|
|
|
|
requestImageForAsset:thumbnail
|
|
|
|
targetSize:retinaSquare
|
|
|
|
contentMode:PHImageContentModeAspectFit
|
|
|
|
options:cropToSquare
|
|
|
|
resultHandler:^(UIImage *result, NSDictionary *info) {
|
|
|
|
|
|
|
|
if (!albumInfo[@"image"]) {
|
|
|
|
albumInfo[@"image"] = [UIImageJPEGRepresentation(result, 1.0) base64Encoding];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (idx == topLevelAlbumsCount-1) {
|
|
|
|
|
2016-06-14 18:12:50 +03:00
|
|
|
// if (block) {
|
|
|
|
//
|
|
|
|
// block(albumsDict);
|
|
|
|
// }
|
2016-06-07 18:42:59 +03:00
|
|
|
}
|
|
|
|
}];
|
2016-05-31 14:50:30 +03:00
|
|
|
}
|
2016-06-07 18:42:59 +03:00
|
|
|
}];
|
2016-06-02 14:08:06 +03:00
|
|
|
|
2016-06-14 18:12:50 +03:00
|
|
|
NSInteger allPhotosCount = self.allPhotos.count;
|
|
|
|
|
|
|
|
// NSInteger collectionCount = [PHAsset fetchAssetsInAssetCollection:collection options:nil].count;
|
|
|
|
|
|
|
|
if (allPhotosCount > 0){
|
2016-06-07 18:42:59 +03:00
|
|
|
|
2016-06-14 18:12:50 +03:00
|
|
|
NSString *albumName = @"All Photos";
|
|
|
|
albumName = [NSString stringWithFormat:@"%@", albumName];
|
|
|
|
|
|
|
|
// PHFetchResult *fetchResult = [PHAsset fetchKeyAssetsInAssetCollection:self.allPhotos options:nil];
|
|
|
|
PHAsset *thumbnail = [self.allPhotos firstObject];
|
|
|
|
|
|
|
|
NSMutableDictionary *albumInfo = [[NSMutableDictionary alloc] init];
|
|
|
|
albumInfo[@"albumName"] = [NSString stringWithFormat:@"%@", albumName];
|
|
|
|
albumInfo[@"imagesCount"] = [NSNumber numberWithInteger:allPhotosCount];
|
|
|
|
|
|
|
|
albumsDict[albumName] = albumInfo;
|
|
|
|
|
|
|
|
|
|
|
|
// __block BOOL isInvokeBlock = NO;
|
|
|
|
|
|
|
|
[[PHImageManager defaultManager]
|
|
|
|
requestImageForAsset:thumbnail
|
|
|
|
targetSize:retinaSquare
|
|
|
|
contentMode:PHImageContentModeAspectFit
|
|
|
|
options:cropToSquare
|
|
|
|
resultHandler:^(UIImage *result, NSDictionary *info) {
|
|
|
|
|
|
|
|
if (!albumInfo[@"image"]) {
|
|
|
|
albumInfo[@"image"] = [UIImageJPEGRepresentation(result, 1.0) base64Encoding];
|
|
|
|
}
|
|
|
|
|
|
|
|
// if (idx == topLevelAlbumsCount-1) {
|
|
|
|
|
|
|
|
if (block) {
|
|
|
|
|
|
|
|
block(albumsDict);
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
}];
|
2016-06-07 18:42:59 +03:00
|
|
|
}
|
2016-06-14 18:12:50 +03:00
|
|
|
|
|
|
|
});
|
2016-06-07 18:42:59 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-06-14 18:12:50 +03:00
|
|
|
-(void)getThumbnial:(PHFetchResult*)albums
|
|
|
|
albumName:(NSString*)albumName
|
|
|
|
cropToSquare:(PHImageRequestOptions*)cropToSquare
|
|
|
|
retinaSquare:(CGSize)retinaSquare block:(CallbackGalleryBlock)block {
|
|
|
|
|
2016-06-07 18:42:59 +03:00
|
|
|
[albums enumerateObjectsUsingBlock:^(PHAssetCollection *collection, NSUInteger idx, BOOL *stop) {
|
2016-06-02 14:08:06 +03:00
|
|
|
|
|
|
|
if ([albumName isEqualToString:collection.localizedTitle]) {
|
|
|
|
*stop = YES;
|
|
|
|
|
2016-06-07 18:42:59 +03:00
|
|
|
PHFetchResult *fetchResult = [PHAsset fetchKeyAssetsInAssetCollection:collection options:nil];
|
2016-06-02 14:08:06 +03:00
|
|
|
PHAsset *asset = [fetchResult firstObject];
|
|
|
|
|
|
|
|
CGFloat cropSideLength = MIN(asset.pixelWidth, asset.pixelHeight);
|
|
|
|
CGRect square = CGRectMake(0, 0, cropSideLength, cropSideLength);
|
|
|
|
CGRect cropRect = CGRectApplyAffineTransform(square,
|
|
|
|
CGAffineTransformMakeScale(1.0 / asset.pixelWidth,
|
|
|
|
1.0 / asset.pixelHeight));
|
|
|
|
|
2016-06-07 18:42:59 +03:00
|
|
|
|
2016-06-02 14:08:06 +03:00
|
|
|
// make sure resolve call only once
|
|
|
|
__block BOOL isInvokeResolve = NO;
|
|
|
|
|
|
|
|
[[PHImageManager defaultManager]
|
2016-06-07 18:42:59 +03:00
|
|
|
requestImageForAsset:asset
|
2016-06-02 14:08:06 +03:00
|
|
|
targetSize:retinaSquare
|
|
|
|
contentMode:PHImageContentModeAspectFit
|
|
|
|
options:cropToSquare
|
|
|
|
resultHandler:^(UIImage *result, NSDictionary *info) {
|
2016-06-07 18:42:59 +03:00
|
|
|
|
|
|
|
|
|
|
|
NSData *imageData = [UIImagePNGRepresentation(result) base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
|
|
|
|
|
|
|
|
|
|
|
|
if (!imageData) {
|
|
|
|
imageData = UIImagePNGRepresentation(result);
|
|
|
|
|
|
|
|
if (!imageData) {
|
|
|
|
CGDataProviderRef provider = CGImageGetDataProvider(result.CGImage);
|
|
|
|
imageData = (id)CFBridgingRelease(CGDataProviderCopyData(provider));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-06-02 14:08:06 +03:00
|
|
|
NSString *encodedString = [imageData base64Encoding];
|
|
|
|
|
2016-06-07 18:42:59 +03:00
|
|
|
|
|
|
|
// NSString *encodedString = [data base64Encoding];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (block && !isInvokeResolve) {
|
2016-06-02 14:08:06 +03:00
|
|
|
isInvokeResolve = YES;
|
2016-06-07 18:42:59 +03:00
|
|
|
block(YES, encodedString);
|
2016-06-02 14:08:06 +03:00
|
|
|
}
|
2016-06-07 18:42:59 +03:00
|
|
|
|
2016-06-02 14:08:06 +03:00
|
|
|
}];
|
|
|
|
}
|
2016-06-07 18:42:59 +03:00
|
|
|
else {
|
|
|
|
if (block) {
|
|
|
|
block(NO, nil);
|
|
|
|
}
|
|
|
|
}
|
2016-05-31 14:50:30 +03:00
|
|
|
}];
|
|
|
|
}
|
|
|
|
|
2016-06-14 18:12:50 +03:00
|
|
|
|
|
|
|
|
|
|
|
RCT_EXPORT_METHOD(getAlbumsWithThumbnails:(RCTPromiseResolveBlock)resolve
|
|
|
|
reject:(__unused RCTPromiseRejectBlock)reject)
|
|
|
|
{
|
|
|
|
|
|
|
|
[self getAllAlbumsNameAndThumbnails:^(NSDictionary *albums) {
|
|
|
|
if (resolve) {
|
|
|
|
|
|
|
|
NSDictionary *ans = @{[NSString stringWithFormat:@"albums"]: albums};
|
|
|
|
resolve(ans);
|
|
|
|
}
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
RCT_EXPORT_METHOD(getImagesForAlbumName:(NSInteger)numberOfImages
|
|
|
|
albumName:(NSString*)albumName
|
|
|
|
resolve:(RCTPromiseResolveBlock)resolve
|
|
|
|
reject:(__unused RCTPromiseRejectBlock)reject)
|
|
|
|
{
|
|
|
|
// [self.imageManager requestImageForAsset:asset
|
|
|
|
// targetSize:AssetGridThumbnailSize
|
|
|
|
// contentMode:PHImageContentModeAspectFill
|
|
|
|
// options:nil
|
|
|
|
// resultHandler:^(UIImage *result, NSDictionary *info) {
|
|
|
|
// // Set the cell's thumbnail image if it's still showing the same asset.
|
|
|
|
// if ([cell.representedAssetIdentifier isEqualToString:asset.localIdentifier]) {
|
|
|
|
// cell.thumbnailImage = result;
|
|
|
|
// }
|
|
|
|
// }];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-05-31 14:50:30 +03:00
|
|
|
@end
|