diff --git a/Example/WPMediaPicker/AppDelegate.m b/Example/WPMediaPicker/AppDelegate.m index 1201282f..021f9a80 100644 --- a/Example/WPMediaPicker/AppDelegate.m +++ b/Example/WPMediaPicker/AppDelegate.m @@ -35,6 +35,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( UIColor *cellBackgroundColor = [UIColor colorWithRed:243/255.0f green:246/255.0f blue:248/255.0f alpha:1.0f]; [[WPMediaCollectionViewCell appearanceWhenContainedIn:[WPMediaPickerViewController class],nil] setBackgroundColor:cellBackgroundColor]; [[WPMediaCollectionViewCell appearanceWhenContainedIn:[WPInputMediaPickerViewController class],nil] setBackgroundColor:cellBackgroundColor]; + [[UIImageView appearanceWhenContainedIn:[WPMediaGroupTableViewCell class],nil] setBackgroundColor:cellBackgroundColor]; //Configure color for activity indicator while loading media collection [[UIActivityIndicatorView appearanceWhenContainedIn:[WPMediaPickerViewController class],nil] setColor:[UIColor grayColor]]; diff --git a/Pod/Classes/WPMediaCollectionDataSource.h b/Pod/Classes/WPMediaCollectionDataSource.h index 71814a9e..fb947654 100644 --- a/Pod/Classes/WPMediaCollectionDataSource.h +++ b/Pod/Classes/WPMediaCollectionDataSource.h @@ -21,6 +21,13 @@ typedef NS_ENUM(NSInteger, WPMediaPickerErrorCode){ - (NSUInteger)to; @end +typedef NS_ENUM(NSInteger, WPMediaLoadOptions){ + WPMediaLoadOptionsGroups, + WPMediaLoadOptionsAssets, + WPMediaLoadOptionsGroupsAndAssets +}; + + @protocol WPMediaAsset; typedef void (^WPMediaChangesBlock)(BOOL incrementalChanges, NSIndexSet *removed, NSIndexSet *inserted, NSIndexSet *changed, NSArray> *moves); @@ -28,6 +35,7 @@ typedef void (^WPMediaSuccessBlock)(); typedef void (^WPMediaFailureBlock)(NSError *error); typedef void (^WPMediaAddedBlock)(id media, NSError *error); typedef void (^WPMediaImageBlock)(UIImage *result, NSError *error); +typedef void (^WPMediaCountBlock)(NSInteger result, NSError *error); typedef void (^WPMediaAssetBlock)(AVAsset *asset, NSError *error); typedef int32_t WPMediaRequestID; @@ -68,11 +76,13 @@ typedef int32_t WPMediaRequestID; - (NSString *)identifier; /** - * The numbers of assets that exist in the group - * - * @return The numbers of assets that exist in the group + The numbers of assets that exist in the group of a certain mediaType + + @param mediaType the asset type to count + @param completionHandler a block that is executed when the real number of assets is know. + @return return an estimation of the current number of assets, if no estimate is known return NSNotFound */ -- (NSInteger)numberOfAssetsOfType:(WPMediaType)mediaType; +- (NSInteger)numberOfAssetsOfType:(WPMediaType)mediaType completionHandler:(WPMediaCountBlock)completionHandler; @end @@ -250,16 +260,14 @@ typedef int32_t WPMediaRequestID; * Asks the data source to reload the data available of the media library. This should be invoked after changing the * current active group or if a change is detected. * + * @param options specifiy what type of data to load * @param successBlock a block that is invoked when the data is loaded with success. * @param failureBlock a block that is invoked when the are is any kind of error when loading the data. */ -- (void)loadDataWithSuccess:(WPMediaSuccessBlock)successBlock +- (void)loadDataWithOptions:(WPMediaLoadOptions)options + success:(WPMediaSuccessBlock)successBlock failure:(WPMediaFailureBlock)failureBlock; -- (void)loadGroupDataWithSuccess:(WPMediaSuccessBlock)successBlock - failure:(WPMediaFailureBlock)failureBlock; - - /** * Requests to the data source to add an image to the library. * diff --git a/Pod/Classes/WPMediaGroupPickerViewController.m b/Pod/Classes/WPMediaGroupPickerViewController.m index df6b8a02..53458879 100644 --- a/Pod/Classes/WPMediaGroupPickerViewController.m +++ b/Pod/Classes/WPMediaGroupPickerViewController.m @@ -42,16 +42,14 @@ - (void)viewDidLoad self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelPicker:)]; __weak __typeof__(self) weakSelf = self; self.changesObserver = [self.dataSource registerChangeObserverBlock:^(BOOL incrementalChanges, NSIndexSet *deleted, NSIndexSet *inserted, NSIndexSet *reload, NSArray *moves) { - dispatch_async(dispatch_get_main_queue(), ^{ - [weakSelf loadData]; - }); + [weakSelf loadData]; }]; [self loadData]; } - (void)loadData { - [self.dataSource loadGroupDataWithSuccess:^{ + [self.dataSource loadDataWithOptions:WPMediaLoadOptionsGroups success:^{ dispatch_async(dispatch_get_main_queue(), ^{ [self.tableView reloadData]; }); @@ -135,7 +133,11 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N }]; cell.tag = requestKey; cell.titleLabel.text = [group name]; - NSInteger numberOfAssets = [group numberOfAssetsOfType:[self.dataSource mediaTypeFilter]]; + NSInteger numberOfAssets = [group numberOfAssetsOfType:[self.dataSource mediaTypeFilter] completionHandler:^(NSInteger result, NSError *error) { + dispatch_async(dispatch_get_main_queue(), ^{ + cell.countLabel.text = [NSString stringWithFormat:@"%ld", (long)result]; + }); + }]; if (numberOfAssets != NSNotFound) { cell.countLabel.text = [NSString stringWithFormat:@"%ld", (long)numberOfAssets]; } else { diff --git a/Pod/Classes/WPMediaPickerViewController.m b/Pod/Classes/WPMediaPickerViewController.m index 924ca686..b9949b78 100644 --- a/Pod/Classes/WPMediaPickerViewController.m +++ b/Pod/Classes/WPMediaPickerViewController.m @@ -296,7 +296,7 @@ - (void)refreshDataAnimated:(BOOL)animated __weak __typeof__(self) weakSelf = self; - [self.dataSource loadDataWithSuccess:^{ + [self.dataSource loadDataWithOptions:WPMediaLoadOptionsAssets success:^{ __typeof__(self) strongSelf = weakSelf; BOOL refreshGroupFirstTime = strongSelf.refreshGroupFirstTime; strongSelf.refreshGroupFirstTime = NO; diff --git a/Pod/Classes/WPPHAssetDataSource.m b/Pod/Classes/WPPHAssetDataSource.m index 050a97b4..7f5685e3 100644 --- a/Pod/Classes/WPPHAssetDataSource.m +++ b/Pod/Classes/WPPHAssetDataSource.m @@ -101,7 +101,8 @@ - (void)photoLibraryDidChange:(PHChange *)changeInstance }); } -- (void)loadDataWithSuccess:(WPMediaSuccessBlock)successBlock +- (void)loadDataWithOptions:(WPMediaLoadOptions)options + success:(WPMediaSuccessBlock)successBlock failure:(WPMediaFailureBlock)failureBlock { PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus]; @@ -118,51 +119,31 @@ - (void)loadDataWithSuccess:(WPMediaSuccessBlock)successBlock case PHAuthorizationStatusNotDetermined: { [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) { - [self loadDataWithSuccess:successBlock failure:failureBlock]; + [self loadDataWithOptions:options success:successBlock failure:failureBlock]; }]; } case PHAuthorizationStatusAuthorized: { - dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), ^{ + dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{ if (self.activeAssetsCollection == nil) { self.activeAssetsCollection = [[PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil] firstObject]; } - if (self.refreshGroups) { - [[[self class] sharedImageManager] stopCachingImagesForAllAssets]; - [self loadGroupsWithSuccess:^{ - self.refreshGroups = NO; - } failure:nil]; + switch (options) { + case (WPMediaLoadOptionsGroups): { + [self loadGroupsWithSuccess:successBlock failure:failureBlock]; + return; + } + case (WPMediaLoadOptionsAssets): { + [self loadAssetsWithSuccess:successBlock failure:failureBlock]; + return; + } + case (WPMediaLoadOptionsGroupsAndAssets): { + [self loadGroupsWithSuccess:^{ + [self loadAssetsWithSuccess:successBlock failure:failureBlock]; + } failure:failureBlock]; + } } - [self loadAssetsWithSuccess:successBlock failure:failureBlock]; - }); - } - } -} - -- (void)loadGroupDataWithSuccess:(WPMediaSuccessBlock)successBlock - failure:(WPMediaFailureBlock)failureBlock -{ - PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus]; - switch (status) { - case PHAuthorizationStatusRestricted: - case PHAuthorizationStatusDenied: - { - if (failureBlock) { - NSError *error = [NSError errorWithDomain:WPMediaPickerErrorDomain code:WPMediaErrorCodePermissionsFailed userInfo:nil]; - failureBlock(error); - } - return; - } - case PHAuthorizationStatusNotDetermined: - { - [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) { - [self loadGroupDataWithSuccess:successBlock failure:failureBlock]; - }]; - } - case PHAuthorizationStatusAuthorized: { - dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), ^{ - [self loadGroupsWithSuccess:successBlock failure:failureBlock]; }); } } @@ -190,28 +171,21 @@ - (NSArray *)smartAlbumsToShow { - (void)loadGroupsWithSuccess:(WPMediaSuccessBlock)successBlock failure:(WPMediaFailureBlock)failureBlock { - PHFetchOptions *fetchOptions = [PHFetchOptions new]; - fetchOptions.predicate = [[self class] predicateForFilterMediaType:self.mediaTypeFilter]; NSMutableArray *collectionsArray=[NSMutableArray array]; for (NSNumber *subType in [self smartAlbumsToShow]) { PHFetchResult * smartAlbum = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:[subType intValue] options:nil]; PHAssetCollection *collection = (PHAssetCollection *)smartAlbum.firstObject; - if ([PHAsset fetchAssetsInAssetCollection:collection options:fetchOptions].count > 0 || [subType intValue] == PHAssetCollectionSubtypeSmartAlbumUserLibrary){ - [collectionsArray addObjectsFromArray:[smartAlbum objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, smartAlbum.count)]]]; - } + [collectionsArray addObject:collection]; } self.albums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAny options:nil]; - [self.albums enumerateObjectsUsingBlock:^(PHAssetCollection *collection, NSUInteger index, BOOL *stop){ - if ([PHAsset fetchAssetsInAssetCollection:collection options:fetchOptions].count > 0) { - [collectionsArray addObject:collection]; - } - }]; + [collectionsArray addObjectsFromArray:[self.albums objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.albums.count)]]]; + PHCollectionList *allAlbums = [PHCollectionList transientCollectionListWithCollections:collectionsArray title:@"Root"]; self.assetsCollections = [PHAssetCollection fetchCollectionsInCollectionList:allAlbums options:nil]; @@ -232,6 +206,10 @@ - (void)loadGroupsWithSuccess:(WPMediaSuccessBlock)successBlock } } + + self.albums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum + subtype:PHAssetCollectionSubtypeAny + options:nil]; } + (NSPredicate *)predicateForFilterMediaType:(WPMediaType)mediaType @@ -558,6 +536,7 @@ @interface PHAssetCollectionForWPMediaGroup() @property(nonatomic, strong) PHAsset *posterAsset; @property(nonatomic, assign) WPMediaType mediaType; @property(nonatomic, strong) PHFetchResult *fetchResult; +@property(nonatomic, strong) PHFetchResult *posterAssetFetchResult; @end @@ -584,7 +563,10 @@ - (NSString *)name - (WPMediaRequestID)imageWithSize:(CGSize)size completionHandler:(WPMediaImageBlock)completionHandler { - return [self.posterAsset imageWithSize:size completionHandler:completionHandler]; + dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{ + [self.posterAsset imageWithSize:size completionHandler:completionHandler]; + }); + return 0; } - (void)cancelImageRequest:(WPMediaRequestID)requestID @@ -602,18 +584,13 @@ - (NSString *)identifier return [self.collection localIdentifier]; } -- (NSInteger)numberOfAssetsOfType:(WPMediaType)mediaType +- (NSInteger)numberOfAssetsOfType:(WPMediaType)mediaType completionHandler:(WPMediaCountBlock)completionHandler { - NSInteger count = self.collection.estimatedAssetCount; - if (count != NSNotFound) { - return count; - } - - if (self.assetCount == NSNotFound) { + dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{ self.assetCount = [self.fetchResult count]; - } - - return self.assetCount; + completionHandler(self.assetCount, nil); + }); + return self.collection.estimatedAssetCount; } - (PHFetchResult *)fetchResult { @@ -626,9 +603,20 @@ - (PHFetchResult *)fetchResult { return _fetchResult; } +- (PHFetchResult *)posterAssetFetchResult { + if (!_posterAssetFetchResult) { + PHFetchOptions *fetchOptions = [PHFetchOptions new]; + fetchOptions.fetchLimit = 1; + fetchOptions.predicate = [WPPHAssetDataSource predicateForFilterMediaType:_mediaType]; + _posterAssetFetchResult = [PHAsset fetchKeyAssetsInAssetCollection:self.collection options:fetchOptions]; + } + + return _posterAssetFetchResult; +} + - (PHAsset *)posterAsset { if (!_posterAsset) { - _posterAsset = [[self fetchResult] lastObject]; + _posterAsset = [[self posterAssetFetchResult] firstObject]; } return _posterAsset;