相册选择库PhotoAlbum遇到iCloud的BUG修改

在开发过程中,涉及了相册图片和视频的选择,根据易用性和产品方面,我们选择了PhotoAlbum这个第三方库去选择图片和视频。

在使用过程中,并没有发现什么问题,但是当涉及到iCloud的相册和视频选取的时候,虽然能选取,但是在最后的使用过程中,会出现空值,所以针对库的问题和我们产品的要求,做了下面几个调整。

1、点击选择视频而非播放

这个修改就是修改collection的点击事件了,在ZQAlbumVC.m中的点击函数中修改

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath

修改为点击选择,不是点击播放

if (self.type == ZQAlbumTypeVideo) {
        //Damon 不使用播放,点击直接选择
//        ZQVideoPlayVC *vc = [[ZQVideoPlayVC alloc] init];
//        vc.model = self.models[indexPath.row];
//        [self.navigationController pushViewController:vc animated:YES];
        ZQPhotoModel* model = self.models[indexPath.row];
        NSTimeInterval maxDur = ((ZQAlbumNavVC *)self.navigationController).maxVideoDurationInSeconds;
        if (maxDur > 0.01 && model.asset.duration > maxDur) {
            
            NSString* message = [NSString stringWithFormat:_LocalizedString(@"VIDEO_CHOICE_LIMIT"), (NSInteger)maxDur/60];
            UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:message preferredStyle:(UIAlertControllerStyleAlert)];
            UIAlertAction *ok = [UIAlertAction actionWithTitle:_LocalizedString(@"OPERATION_OK") style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {
                
            }];
            [alert addAction:ok];
            [self presentViewController:alert animated:NO completion:nil];
            return;
        }
        [ProgressHUD show];
        
        ______WS();
        
        __block UIImage * exportImage;
        [ZQPhotoFetcher getPhotoFastWithAssets:model.asset photoWidth:kTPScreenWidth completionHandler:^(UIImage * _Nullable image, NSDictionary * _Nullable info) {
            ZQAlbumNavVC *nav = (ZQAlbumNavVC *)wSelf.navigationController;
            exportImage = image;//先存小图,再存大图
            dispatch_async(dispatch_get_main_queue(), ^{
                if (nav.updateUIFinishVideoPicking) {
                    nav.updateUIFinishVideoPicking(image);
                }
            });
        }];
        
        [ZQPhotoFetcher exportVideoDegradedWithAssets:model.asset progress:^(CGFloat progress) {
            //在progressHUD上加一个progress label
            [ProgressHUD sharedInstance].progress = progress;
        } completionHandler:^(AVAsset * _Nullable playerAsset, NSDictionary * _Nullable info, NSURL * _Nullable url) {
            ZQAlbumNavVC *nav = (ZQAlbumNavVC *)wSelf.navigationController;
            dispatch_async(dispatch_get_main_queue(), ^{
                [ProgressHUD hide];
                if ([nav.albumDelegate isKindOfClass:[UIViewController class]]) {
                    [((UIViewController*)nav.albumDelegate).navigationController setNavigationBarHidden:YES animated:NO];
                }
                [nav dismissViewControllerAnimated:NO completion:nil];
                if (nav.didFinishPickingVideoHandle) {
                    nav.didFinishPickingVideoHandle(url, exportImage, playerAsset);
                }
                
            });
        }];
        //end
    }

2、选取使用iCloud视频

通过这个库,能显示iCloud的视频,但是在点击之后,会卡在处理中,或者0%不会动的情况,之前以为是视频问题,通过查看代码,发现原来是作者在库里面把iCloud视频的模式给注销了,所以在该ZQPhotoFetcher.m文件中的下面这个函数,修改选择视频的模式

+ (void)exportVideoDegradedWithAssets:(PHAsset *_Nonnull)asset progress:(void(^)(CGFloat progress))progressBlock completionHandler:(void(^_Nullable)(AVAsset* _Nullable playerAsset, NSDictionary* _Nullable info, NSURL* _Nullable url))completion

这个函数中,修改opt,允许网络下载,否则会停留在处理中,0%不会动

 PHVideoRequestOptions *opt = [[PHVideoRequestOptions alloc] init];
    opt.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic;
    opt.networkAccessAllowed = YES;
    
    ______WS();
    PHAsset *videoAsset = assets;
    [[PHImageManager defaultManager] requestAVAssetForVideo:videoAsset options:opt resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {

3、选取使用iCloud图片

刚开头说了,这个库虽然能显示iCloud的图片,但是在点击之后回调里面,偶尔会出现空值,这里除了修改图片的选择模式,还要修改后面第四条里面说的 dispatch_group_leave(group);的时机。

首先在ZQPhotoFetcher.m中的

+ (PHImageRequestID)getPhotoWithAssets:(PHAsset *)asset photoWidth:(CGFloat)photoWidth completionHandler:(void(^)(UIImage *image, NSDictionary *info))completion option:(PHImageRequestOptions *)option

从iCloud选取图片的时候,修改PHImageRequestOptions的选项,改为同步模式

if ([info objectForKey:PHImageResultIsInCloudKey] && !result) {
            PHImageRequestOptions *option = [[PHImageRequestOptions alloc]init];
            option.networkAccessAllowed = YES;
            option.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
            option.synchronous = YES;

4、iCloud图片为空,选择顺序和输出顺序不一致

在ZQBottomToolbarView.m中,因为想要选择的顺序和输出的顺序是一致的,并且避免icloud选择图片不跳出的情况,所以修改下面的完成函数

- (void)finish

在这个函数中

- (void)finish {
    [ProgressHUD show];
    ______WS();
    if (self.bSingleSelection) {
        UIViewController *pvc = [self firstViewController];
        if ([pvc isKindOfClass:[ZQPhotoPreviewVC class]]) {
            [[pvc.view subviews] enumerateObjectsUsingBlock:^(UIView *view, NSUInteger idx, BOOL * _Nonnull stop) {
                if ([view isKindOfClass:[UICollectionView class]]) {
                    UICollectionView *cv = (UICollectionView *)view;
                    ZQPreviewCell *cell = [cv.visibleCells firstObject];
                    wSelf.selections = @[cell.mPhoto];
                }
            }];
        }
    }
    NSMutableDictionary *results = [[NSMutableDictionary alloc] init];
    //Damon fix
    NSMutableArray *fetchArray = [NSMutableArray array];    //为了排序
    NSMutableDictionary *fetchResultDic = [[NSMutableDictionary alloc] init];  //为了排序
    NSMutableArray *images = [NSMutableArray array];
    //end
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        __block dispatch_group_t group = dispatch_group_create();
        for (int i=0; i<wSelf.selections.count; i++) {
            dispatch_group_enter(group);
            ZQPhotoModel *model = wSelf.selections[i];
            //Damon fix 选择照片排序
            NSString *requestId = [NSString stringWithFormat:@"%d",model.requestID];
            [fetchArray addObject:requestId];
            //end
            [ZQPhotoFetcher getPhotoWithAssets:model.asset photoWidth:kTPScreenWidth completionHandler:^(UIImage *image, NSDictionary *info) {
                if (info) {
                    if ([[info objectForKey:PHImageResultIsDegradedKey] integerValue] == 1) {
                        if (image) {
                            //Damon fix
//                            [results setObject:image forKey:[info objectForKey:PHImageResultRequestIDKey]];
                            [fetchResultDic setObject:image forKey:requestId];
                            //end
                        }
                        
                    }
                    else if ([[info objectForKey:PHImageResultIsDegradedKey] integerValue] == 0) {
                        if (image) {//可能为nil
                            //Damon fix
//                            [results setObject:image forKey:[info objectForKey:PHImageResultRequestIDKey]];
                            [fetchResultDic setObject:image forKey:requestId];
                            dispatch_group_leave(group);//图片不为空时再离开
                            //end
                        }
                    }
                }
                else {
                    //info也没有是什么情况
                    //如果没有回调大图,group出不去,就悲剧了
                }
            }];

        }
        dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
        dispatch_async(dispatch_get_main_queue(), ^{
            [ProgressHUD hide];
            UIViewController *vc = [wSelf firstViewController];
            ZQAlbumNavVC *nav = (ZQAlbumNavVC *)vc.navigationController;
            [nav dismissViewControllerAnimated:NO completion:^{
                if (nav.didFinishPickingPhotosHandle) {
//                    NSArray *images = [results allValues];
                    for (int i = 0; i<fetchArray.count; i++) {
                        [images addObject:[fetchResultDic objectForKey:[fetchArray objectAtIndex:i]]];
                    }
                    NSLog(@"%@",images);
                    if (images.count == 0) {
                        NSString *msg = _LocalizedString(@"FETCH_PHOTO_ERROR");
                        UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:msg preferredStyle:(UIAlertControllerStyleAlert)];
                        UIAlertAction *ok = [UIAlertAction actionWithTitle:_LocalizedString(@"OPERATION_OK") style:(UIAlertActionStyleDefault) handler:nil];
                        [alert addAction:ok];
                        [[ZQTools rootViewController] presentViewController:alert animated:YES completion:nil];
                    }
                    nav.didFinishPickingPhotosHandle(images);
                }
            }];
            
            
        });
    });
}

5、demo下载

这个库是一个挺好用的库,但是这几个小问题影响了使用,晚点会提交给库的作者一封邮件说一下。下面这个demo是用cocopod继承过0.5.0版本,然后把上面说的几个地方给修改替换过的demo,如果有人在使用iCloud的图片和视频出问题的时候,不妨看下。

GitHub下载地址:PhotoAlbum相册Demo

Gitosc下载地址:PhotoAlbum相册Demo

Last modification:July 7th, 2017 at 01:54 pm
如果看了这个文章可以让你少加会班,可以请我喝杯可乐
已打赏名单
微信公众号

Leave a Comment