ios使用PhAsset

本篇只讨论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 *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)