ios使用PhAsset

作者: 一只努力的猿 | 来源:发表于2018-07-13 11:44 被阅读5684次

    本篇只讨论PhAsset,关于ALAsset,网上很多资料。这里就不再讨论。
    曾几何时,项目中访问IPhone的系统相册,选中需要上传的照片或视频,使用webdav上传到自己的私有云中的需求。

    从ios8开始,苹果推出了PhAsset,ios9以后ALAsset就不能在使用。我相信大家都用惯了ALAsset,里面的方法特别的好用,尤其是获取相册中没有照片的路径的时候,更是怀恋。
    PhAsset获取照片、视频在相册中的路径的时候,就没有那么的方便。


    访问相册一般就是以下几个步骤:
    无非就是申请访问相册的权限,获取相册分组
    获取相册中的相册组
    点击进入到具体的相册中组中,选中需要上传的图片进行上传

    马上想到去找度娘、简书。但是,不知道是我搜索的姿势不对,还是什么原因,并没有找到获取该对象在相册中的路径、要不然就是不能用的方法。

    好了废话少说,进入正题,具体分以下几个步骤:
    1)申请访问相册的权限(每次进入去访问系统相册的时候,都是需要去查看权限)
    2)获取相册中的所有的照片、视频
    3)获取具体某一个对象的路径

    一:申请权限

    [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {        
            //没有授权
            if(status== PHAuthorizationStatusRestricted) {
                complate(nil);
            }
            else if (status==PHAuthorizationStatusDenied) {
                complate(nil);
            }
            else {//已经授权
                
            }
    }];
    

    1)如果没有授权,需要提示用户去授权,否则访问不了相册

      NSDictionary *info = [[NSBundle mainBundle] infoDictionary];
      NSString *appName  = [info objectForKey:@"CFBundleDisplayName"];
      appName            = appName ? appName : [info objectForKey:@"CFBundleName"];                        
      NSString *message  = [NSString stringWithFormat:@"请在系统设置中允许“%@”访问照片!", appName];
      [[[UIAlertView alloc]initWithTitle:@"无法访问照片" message:message delegate:self   cancelButtonTitle:@"我知道了!" otherButtonTitles:nil] show];
    

    二)允许访问后,获取相册中的资源

    NSMutableArray<PHAsset *> *assets = [NSMutableArray array];
              
    PHFetchOptions *option = [[PHFetchOptions alloc] init];
    //ascending 为YES时,按照照片的创建时间升序排列;为NO时,则降序排列
    option.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:ascending]];
    PHAssetMediaType type = self.type==5 ? PHAssetMediaTypeImage:PHAssetMediaTypeVideo;
             
    PHFetchResult *result = [PHAsset fetchAssetsWithMediaType:type options:option];
    __weak typeof(self) weakSelf= self;
    __strong typeof(weakSelf) strongSelf=weakSelf;
              
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                    
              [result enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                       
             PHAsset *asset = (PHAsset *)obj;
             NSInteger type = asset.mediaType;                    
              //照片
             if(strongSelf.type==5&&type==1){
                            
                            [assets addObject:asset];
             }
             else if (strongSelf.type==2&&type==2){
                            
                        [assets addObject:asset];
                    }
             }];
             dispatch_async(dispatch_get_main_queue(), ^{
                        complate(assets);
           });
      });
    

    获取到相册中的资源,接下来就是获取到具体某一个对象,显示到界面上
    三)获取具体某一个asset的对象,如果是视频,那么直接获取首帧的图像

      PHImageRequestOptions *option = [[PHImageRequestOptions alloc] init];
        /**
         resizeMode:对请求的图像怎样缩放。有三种选择:None,默认加载方式;Fast,尽快地提供接近或稍微大于要求的尺寸;Exact,精准提供要求的尺寸。
         deliveryMode:图像质量。有三种值:Opportunistic,在速度与质量中均衡;HighQualityFormat,不管花费多长时间,提供高质量图像;FastFormat,以最快速度提供好的质量。
         这个属性只有在 synchronous 为 true 时有效。
         */
        option.resizeMode = resizeMode;//控制照片尺寸
        //option.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;//控制照片质量
        //option.synchronous = YES;
        option.networkAccessAllowed = YES;
        //param:targetSize 即你想要的图片尺寸,若想要原尺寸则可输入PHImageManagerMaximumSize
        [[PHCachingImageManager defaultManager] requestImageForAsset:asset targetSize:size contentMode:PHImageContentModeAspectFit options:option resultHandler:^(UIImage * _Nullable image, NSDictionary * _Nullable info) {
            completion(image);
        }];
    

    获取到需要上传的文件后,那就是需要上传文件
    那么上传文件就有两种方法:
    1)把需要上传的文件读成data去上传
    2)获取在相册中的路径,根据路径去上传

    读成data,是比较方便。我们知道,data是需要占我们的运行内存。如果文件比较大的时候,有可能app就因为收到内存警告,占用内存再大,就会导致app奔溃。还要就是,data比较大的时候,上传也是一个比较繁琐的事情。
    利用路径去上传文件的话,就不会出现上面说的那种情况,只需要跑一个线程去进行这个任务,我并不用太关心内存的开销。但是,比较麻烦的是,怎么去获取在相册中的路径。网上一直没有找到具体的方法。

    解决思路:
    1)首先想到了alasset的获取照片思路:

    ALAssetRepresentation * representation = [(ALAsset *)asset defaultRepresentation];
                    
    model.URLInPotoes = [representation url];
    model.imageName=[representation filename];
    [photos addObject:model];
    

    在phasset中,并没有找到这样的方法。

    2)反向获取url
    1.获取照片的url

          [[PHImageManager defaultManager] requestImageForAsset:phAsset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeDefault options:nil resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
                
                NSURL * url = [info objectForKey:@"PHImageFileURLKey"];
                complate(url);
            }];
    

    2.获取视频的地址

    [[PHImageManager defaultManager] requestAVAssetForVideo:phAsset options:nil resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
                
           NSString * url = [[[info objectForKey:@"PHImageFileSandboxExtensionTokenKey"]componentsSeparatedByString:@";"] lastObject];            
           complate(url);
      }];
    

    注意:相册中Icloud类型的照片、视频只是相当于是一个链接,所以并不能获取该类型文件的链接

    如果,有好的方法,请联系我。

    相关文章

      网友评论

        本文标题:ios使用PhAsset

        本文链接:https://www.haomeiwen.com/subject/tccjpftx.html