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

Updated to use PhotoKit #141

Open
wants to merge 2 commits 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
171 changes: 98 additions & 73 deletions Classes/ELCImagePicker/ELCAlbumPickerController.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
#import "ELCImagePickerController.h"
#import "ELCAssetTablePicker.h"
#import <MobileCoreServices/UTCoreTypes.h>
#import <Photos/Photos.h>
#import "UIAlertController+Extensions.h"

@interface ELCAlbumPickerController ()

@property (nonatomic, strong) ALAssetsLibrary *library;
@interface ELCAlbumPickerController () <PHPhotoLibraryChangeObserver>

@end

Expand All @@ -36,71 +36,83 @@ - (void)viewDidLoad
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
self.assetGroups = tempArray;

ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc] init];
self.library = assetLibrary;

// Load Albums into assetGroups
dispatch_async(dispatch_get_main_queue(), ^
{
@autoreleasepool {

// Group enumerator Block
void (^assetGroupEnumerator)(ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop)
{
if (group == nil) {
return;
}

// added fix for camera albums order
NSString *sGroupPropertyName = (NSString *)[group valueForProperty:ALAssetsGroupPropertyName];
NSUInteger nType = [[group valueForProperty:ALAssetsGroupPropertyType] intValue];

if ([[sGroupPropertyName lowercaseString] isEqualToString:@"camera roll"] && nType == ALAssetsGroupSavedPhotos) {
[self.assetGroups insertObject:group atIndex:0];
}
else {
[self.assetGroups addObject:group];
}

// Reload albums
[self performSelectorOnMainThread:@selector(reloadTableView) withObject:nil waitUntilDone:YES];
};

// Group Enumerator Failure Block
void (^assetGroupEnumberatorFailure)(NSError *) = ^(NSError *error) {

if ([ALAssetsLibrary authorizationStatus] == ALAuthorizationStatusDenied) {
NSString *errorMessage = NSLocalizedString(@"This app does not have access to your photos or videos. You can enable access in Privacy Settings.", nil);
[[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Access Denied", nil) message:errorMessage delegate:nil cancelButtonTitle:NSLocalizedString(@"Ok", nil) otherButtonTitles:nil] show];

} else {
NSString *errorMessage = [NSString stringWithFormat:@"Album Error: %@ - %@", [error localizedDescription], [error localizedRecoverySuggestion]];
[[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Error", nil) message:errorMessage delegate:nil cancelButtonTitle:NSLocalizedString(@"Ok", nil) otherButtonTitles:nil] show];
}

[self.navigationItem setTitle:nil];
NSLog(@"A problem occured %@", [error description]);
};

// Enumerate Albums
[self.library enumerateGroupsWithTypes:ALAssetsGroupAll
usingBlock:assetGroupEnumerator
failureBlock:assetGroupEnumberatorFailure];

[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (status == PHAuthorizationStatusAuthorized) {
[self loadAlbums];
} else {
dispatch_async(dispatch_get_main_queue(), ^{
NSString *errorMessage = NSLocalizedString(@"This app does not have access to your photos or videos. You can enable access in Privacy Settings.", nil);
[UIAlertController showAlertWithTitle:NSLocalizedString(@"Access Denied", nil)
message:errorMessage
cancelButton:NSLocalizedString(@"Ok", nil)
fromController:self];
[self.navigationItem setTitle:nil];[self.navigationItem setTitle:nil];
});
}
});
}];

}

- (void)viewWillAppear:(BOOL)animated {

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadTableView) name:ALAssetsLibraryChangedNotification object:nil];
[super viewWillAppear:animated];
[PHPhotoLibrary.sharedPhotoLibrary registerChangeObserver:self];
[self.tableView reloadData];
}

- (void)viewWillDisappear:(BOOL)animated {

[[NSNotificationCenter defaultCenter] removeObserver:self name:ALAssetsLibraryChangedNotification object:nil];
[super viewWillDisappear:animated];
[PHPhotoLibrary.sharedPhotoLibrary unregisterChangeObserver:self];
}

- (void)photoLibraryDidChange:(PHChange *)changeInstance {
[self reloadTableView];
}

- (void)loadAlbums {
dispatch_async(dispatch_get_main_queue(), ^{
@autoreleasepool {
NSNumber *filter = [self assetFilter];
PHFetchOptions *assetsFilter = [[PHFetchOptions alloc] init];
assetsFilter.predicate = [ELCAsset slowmoFilterPredicate];
if (filter) {
NSCompoundPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[assetsFilter.predicate, [ELCAsset assetFilterPredicate:filter.integerValue]]];
assetsFilter.predicate = predicate;
}
NSArray *collectionsFetchResults;

PHFetchResult *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum
subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
PHFetchResult *syncedAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum
subtype:PHAssetCollectionSubtypeAlbumSyncedAlbum options:nil];
PHFetchResult *userCollections = [PHCollectionList fetchTopLevelUserCollectionsWithOptions:nil];

// Add each PHFetchResult to the array
collectionsFetchResults = @[smartAlbums, userCollections, syncedAlbums];

for (int i = 0; i < collectionsFetchResults.count; i ++) {

PHFetchResult *fetchResult = collectionsFetchResults[i];

for (int x = 0; x < fetchResult.count; x ++) {

PHAssetCollection *collection = fetchResult[x];
PHFetchResult *assetsFetchResult = [PHAsset fetchAssetsInAssetCollection:collection options:assetsFilter];
if (assetsFetchResult.count > 0) {
NSString *sGroupPropertyName = collection.localizedTitle;

if ([[sGroupPropertyName lowercaseString] isEqualToString:@"camera roll"] ) {
[self.assetGroups insertObject:collection atIndex:0];
}
else {
[self.assetGroups addObject:collection];
}
}

}
}
[self performSelectorOnMainThread:@selector(reloadTableView) withObject:nil waitUntilDone:YES];
}
});
}

- (void)reloadTableView
Expand All @@ -124,19 +136,19 @@ - (void)selectedAssets:(NSArray*)assets
[_parent selectedAssets:assets];
}

- (ALAssetsFilter *)assetFilter
- (NSNumber *)assetFilter
{
if([self.mediaTypes containsObject:(NSString *)kUTTypeImage] && [self.mediaTypes containsObject:(NSString *)kUTTypeMovie])
{
return [ALAssetsFilter allAssets];
return nil;
}
else if([self.mediaTypes containsObject:(NSString *)kUTTypeMovie])
{
return [ALAssetsFilter allVideos];
return @(PHAssetMediaTypeVideo);
}
else
{
return [ALAssetsFilter allPhotos];
return @(PHAssetMediaTypeImage);
}
}

Expand Down Expand Up @@ -167,17 +179,30 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}

NSNumber *filter = [self assetFilter];
PHFetchOptions *assetsFilter = [[PHFetchOptions alloc] init];
assetsFilter.predicate = [ELCAsset slowmoFilterPredicate];
if (filter) {
NSCompoundPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[assetsFilter.predicate, [ELCAsset assetFilterPredicate:filter.integerValue]]];
assetsFilter.predicate = predicate;
}

// Get count
ALAssetsGroup *g = (ALAssetsGroup*)[self.assetGroups objectAtIndex:indexPath.row];
[g setAssetsFilter:[self assetFilter]];
NSInteger gCount = [g numberOfAssets];
PHAssetCollection *g = (PHAssetCollection*)[self.assetGroups objectAtIndex:indexPath.row];
PHFetchResult *assetsFetchResult = [PHAsset fetchAssetsInAssetCollection:g options:assetsFilter];
NSInteger gCount = assetsFetchResult.count;

PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.resizeMode = PHImageRequestOptionsResizeModeExact;
[[PHImageManager defaultManager] requestImageForAsset:assetsFetchResult.firstObject targetSize:CGSizeMake(156,156) contentMode:PHImageContentModeAspectFill options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
cell.imageView.contentMode = UIViewContentModeScaleAspectFill;
cell.imageView.clipsToBounds = YES;
[cell.imageView setImage:result];
}];

cell.textLabel.text = [NSString stringWithFormat:@"%@ (%ld)",g.localizedTitle, (long)gCount];
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];

cell.textLabel.text = [NSString stringWithFormat:@"%@ (%ld)",[g valueForProperty:ALAssetsGroupPropertyName], (long)gCount];
UIImage* image = [UIImage imageWithCGImage:[g posterImage]];
image = [self resize:image to:CGSizeMake(78, 78)];
[cell.imageView setImage:image];
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];

return cell;
}

Expand All @@ -202,7 +227,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
picker.parent = self;

picker.assetGroup = [self.assetGroups objectAtIndex:indexPath.row];
[picker.assetGroup setAssetsFilter:[self assetFilter]];
[picker setAssetsFilter:[self assetFilter]];

picker.assetPickerFilterDelegate = self.assetPickerFilterDelegate;

Expand Down
13 changes: 8 additions & 5 deletions Classes/ELCImagePicker/ELCAsset.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//

#import <UIKit/UIKit.h>
#import <AssetsLibrary/AssetsLibrary.h>
#import <Photos/PHAsset.h>

@class ELCAsset;

Expand All @@ -22,11 +22,14 @@

@interface ELCAsset : NSObject

@property (nonatomic, strong) ALAsset *asset;
@property (nonatomic, strong) PHAsset *asset;
@property (nonatomic, weak) id<ELCAssetDelegate> parent;
@property (nonatomic, assign) BOOL selected;
@property (nonatomic,assign) int index;
@property (nonatomic,assign) NSUInteger index;

- (id)initWithAsset:(ALAsset *)asset;
- (id)initWithAsset:(PHAsset *)asset;
- (NSComparisonResult)compareWithIndex:(ELCAsset *)_ass;
@end

+ (NSPredicate*)assetFilterPredicate:(NSInteger)filter;
+ (NSPredicate*)slowmoFilterPredicate;
@end
12 changes: 10 additions & 2 deletions Classes/ELCImagePicker/ELCAsset.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ @implementation ELCAsset
//Using auto synthesizers
- (NSString *)description
{
return [NSString stringWithFormat:@"ELCAsset index:%d",self.index];
return [NSString stringWithFormat:@"ELCAsset index:%lu",(unsigned long)self.index];
}

- (id)initWithAsset:(ALAsset*)asset
- (id)initWithAsset:(PHAsset*)asset
{
self = [super init];
if (self) {
Expand Down Expand Up @@ -70,5 +70,13 @@ - (NSComparisonResult)compareWithIndex:(ELCAsset *)_ass
return NSOrderedSame;
}

+ (NSPredicate*)assetFilterPredicate:(NSInteger)filter {
return [NSPredicate predicateWithFormat:@"mediaType = %d", filter];
}

+ (NSPredicate*)slowmoFilterPredicate {
return [NSPredicate predicateWithFormat:@"!((mediaSubtype & %d) == %d)", PHAssetMediaSubtypeVideoHighFrameRate, PHAssetMediaSubtypeVideoHighFrameRate];
}

@end

18 changes: 13 additions & 5 deletions Classes/ELCImagePicker/ELCAssetCell.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#import "ELCAsset.h"
#import "ELCConsole.h"
#import "ELCOverlayImageView.h"
#import <Photos/PHImageManager.h>

@interface ELCAssetCell ()

Expand Down Expand Up @@ -49,6 +50,8 @@ - (void)setAssets:(NSArray *)assets
for (ELCOverlayImageView *view in _overlayViewArray) {
[view removeFromSuperview];
}
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.resizeMode = PHImageRequestOptionsResizeModeExact;
//set up a pointer here so we don't keep calling [UIImage imageNamed:] if creating overlays
UIImage *overlayImage = nil;
for (int i = 0; i < [_rowAssets count]; ++i) {
Expand All @@ -57,24 +60,29 @@ - (void)setAssets:(NSArray *)assets

if (i < [_imageViewArray count]) {
UIImageView *imageView = [_imageViewArray objectAtIndex:i];
imageView.image = [UIImage imageWithCGImage:asset.asset.thumbnail];
[[PHImageManager defaultManager] requestImageForAsset:asset.asset targetSize:CGSizeMake(156,156) contentMode:PHImageContentModeAspectFill options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
imageView.image = result;
}];
} else {
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageWithCGImage:asset.asset.thumbnail]];
UIImageView *imageView = [[UIImageView alloc] init];
[[PHImageManager defaultManager] requestImageForAsset:asset.asset targetSize:CGSizeMake(156,156) contentMode:PHImageContentModeAspectFill options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
imageView.image = result;
}];
[_imageViewArray addObject:imageView];
}

if (i < [_overlayViewArray count]) {
ELCOverlayImageView *overlayView = [_overlayViewArray objectAtIndex:i];
overlayView.hidden = asset.selected ? NO : YES;
overlayView.labIndex.text = [NSString stringWithFormat:@"%d", asset.index + 1];
overlayView.labIndex.text = [NSString stringWithFormat:@"%lu", asset.index + 1];
} else {
if (overlayImage == nil) {
overlayImage = [UIImage imageNamed:@"Overlay.png"];
}
ELCOverlayImageView *overlayView = [[ELCOverlayImageView alloc] initWithImage:overlayImage];
[_overlayViewArray addObject:overlayView];
overlayView.hidden = asset.selected ? NO : YES;
overlayView.labIndex.text = [NSString stringWithFormat:@"%d", asset.index + 1];
overlayView.labIndex.text = [NSString stringWithFormat:@"%lu", asset.index + 1];
}
}
}
Expand Down Expand Up @@ -107,7 +115,7 @@ - (void)cellTapped:(UITapGestureRecognizer *)tapRecognizer
}
else
{
int lastElement = [[ELCConsole mainConsole] numOfSelectedElements] - 1;
NSUInteger lastElement = [[ELCConsole mainConsole] numOfSelectedElements] - 1;
[[ELCConsole mainConsole] removeIndex:lastElement];
}
break;
Expand Down
5 changes: 3 additions & 2 deletions Classes/ELCImagePicker/ELCAssetTablePicker.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@
@interface ELCAssetTablePicker : UITableViewController <ELCAssetDelegate>

@property (nonatomic, weak) id <ELCAssetSelectionDelegate> parent;
@property (nonatomic, strong) ALAssetsGroup *assetGroup;
@property (nonatomic, strong) PHAssetCollection *assetGroup;
@property (nonatomic, strong) NSMutableArray *elcAssets;
@property (nonatomic, strong) IBOutlet UILabel *selectedAssetsLabel;
@property (nonatomic, assign) BOOL singleSelection;
@property (nonatomic, assign) BOOL immediateReturn;
@property (nonatomic, assign) NSNumber *assetsFilter;

// optional, can be used to filter the assets displayed
@property(nonatomic, weak) id<ELCAssetPickerFilterDelegate> assetPickerFilterDelegate;
Expand All @@ -28,4 +29,4 @@

- (void)doneAction:(id)sender;

@end
@end
Loading