关于iOS选取相册中iCloud云上图片和视频

 推荐看:TZImagePickerController的源码,这个是一个非常靠谱的相册选择图片视频的库 。当然也可以自己写 如下遇到的问题

工作原因,需要处理接入一个视频模块,在视频选择的时候遇到了一个不太容易发现的bug,产生的原因是由于手机内存小,而用户又打开了相册同步iCloud,

 

加载中的图片

 

在这时,如果本地可用内存过小,会导致
将本地相册中的图片或视频删除只留缩略图,如果App调用的时候想要选取这种图片就需要从iCloud云中进行下载,
才能获取原图或原视频。

下面po下解决方案:

如果你之前处理过相册问题,那么对如下的代码肯定不陌生,就是很普通的两个系统级别的请求回调,获取对应的图片,视频。

// get Image
[[PHImageManager defaultManager] requestImageDataForAsset:asset options:nil resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) { }];
// get Video
[[PHImageManager defaultManager] requestPlayerItemForVideo:asset options:nil resultHandler:^(AVPlayerItem * _Nullable playerItem, NSDictionary * _Nullable info) {
if (completion) completion(playerItem,info);
}];

但是往往之前没有注意到第二个输入 options 是用来干嘛的,
其实解决方案就来自于这个 PHImageRequestOptionsPHVideoRequestOptions

这这两个 options 都有一个共同的参数就是

@property (nonatomic, assign, getter=isNetworkAccessAllowed) BOOL networkAccessAllowed;
// if necessary will download the image from iCloud (client can monitor or cancel using progressHandler). Defaults to NO (see start/stopCachingImagesForAssets)

系统的解释也很详细,如果赋值 YES ,那么允许从 iCloud 中获取图片和视频,默认是 NO

虽然这个问题解决不是很难,但是往往容易被忽略,所以记录一下。

这里非常感谢@半迟尘大大的TZImagePickerController的源码,这个是一个非常靠谱的相册选择图片视频的库,并且处于仍在维护中。感兴趣的可以链接过去看一看源码,写的很好。

博主博客@HarwordLiu

下面po一下完整的这个问题的解决代码:

/// Get Video
- (void)getVideoOutputPathWithAsset:(PHAsset *)asset completion:(void (^)(NSString *outputPath))completion {
PHVideoRequestOptions* options = [[PHVideoRequestOptions alloc] init];
options.version = PHVideoRequestOptionsVersionOriginal;
options.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic;
options.networkAccessAllowed = YES;
[[PHImageManager defaultManager] requestAVAssetForVideo:asset options:options resultHandler:^(AVAsset* avasset, AVAudioMix* audioMix, NSDictionary* info){
// NSLog(@"Info:\n%@",info);
AVURLAsset *videoAsset = (AVURLAsset*)avasset;
// NSLog(@"AVAsset URL: %@",myAsset.URL);
[self startExportVideoWithVideoAsset:videoAsset completion:completion];
}];
}
/// Get Image - (PHImageRequestID)getPhotoWithAsset:(PHAsset *)asset photoWidth:(CGFloat)photoWidth completion:(void (^)(UIImage *, NSDictionary *, BOOL isDegraded))completion { PHAsset *phAsset = (PHAsset *)asset;
CGFloat aspectRatio = phAsset.pixelWidth / (CGFloat)phAsset.pixelHeight;
CGFloat pixelWidth = photoWidth * 2.0;
CGFloat pixelHeight = pixelWidth / aspectRatio;
CGSize imageSize = CGSizeMake(pixelWidth, pixelHeight); // 修复获取图片时出现的瞬间内存过高问题
PHImageRequestOptions *option = [[PHImageRequestOptions alloc] init];
option.resizeMode = PHImageRequestOptionsResizeModeFast;
PHImageRequestID imageRequestID = [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:imageSize contentMode:PHImageContentModeAspectFill options:option resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
BOOL downloadFinined = (![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey]);
if (downloadFinined && result) {
if (completion) completion(result,info,[[info objectForKey:PHImageResultIsDegradedKey] boolValue]);
}
// Download image from iCloud / 从iCloud下载图片
if ([info objectForKey:PHImageResultIsInCloudKey] && !result) {
PHImageRequestOptions *option = [[PHImageRequestOptions alloc]init];
option.networkAccessAllowed = YES;
option.resizeMode = PHImageRequestOptionsResizeModeFast;
[[PHImageManager defaultManager] requestImageDataForAsset:asset options:option resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
UIImage *resultImage = [UIImage imageWithData:imageData scale:0.1];
if (completion) completion(resultImage,info,[[info objectForKey:PHImageResultIsDegradedKey] boolValue]); }];
}
}];
return imageRequestID;
}

判断是否是iCloud视频或图片的方法

https://stackoverflow.com/questions/31966571/check-given-phasset-is-icloud-asset

第一种方法

[cloudAlbums enumerateObjectsUsingBlock:^(PHAssetCollection *collection, NSUInteger idx, BOOL *stop)
{
PHFetchResult *result = [PHAsset fetchAssetsInAssetCollection:collection options:fetchOptions];
[result enumerateObjectsUsingBlock:^(PHAsset *asset, NSUInteger idx, BOOL *stop)
{
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.resizeMode = PHImageRequestOptionsResizeModeFast;
options.synchronous = YES;
__block BOOL isICloudAsset = NO;
[[PHImageManager defaultManager] requestImageForAsset:asset targetSize:imageSize contentMode:PHImageContentModeAspectFit options:options resultHandler:^(UIImage *result, NSDictionary *info)
{
//根据请求会调中的参数重 NSDictionary *info 是否有cloudKey 来判断是否是 iCloud
if ([info objectForKey: PHImageResultIsInCloudKey].boolValue)
{
isICloudAsset = YES;
}
}];
}];
}];

第二种方法(其实是同一种)

__block BOOL isPhotoInICloud = NO;
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.networkAccessAllowed = YES;
options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
// 下载iCloud 图片的进度回调 只要图片是在icloud中 然后去请求图片就会走这个回调 如果图片没有在iCloud中不回走这个回调
//里面的会调中的参数重 NSDictionary *info 是否有cloudKey 来判断是否是 iCloud 处理UI放到主线程
options.progressHandler = ^(double progress, NSError *error, BOOL *stop, NSDictionary *info){ isPhotoInICloud = YES;
});

//上面的进度下载完了之后才会掉用resultHandler 回调
[[PHImageManager defaultManager] requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeAspectFit options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) { if (isPhotoInICloud) {
// Photo is in iCloud.
}
});

 

iOS - 选取相册中iCloud云上图片和视频的处理的更多相关文章

  1. iOS swift 启动页加载广告(图片广告+视频广告)

    一般app在启动的时候都会有广告页,广告页用来加载自己的或者第三方的广告,广告的展示形式也多种多样,最近在看swift相关的东西,这里将提供支持加载图片广告和视频广告的解决方案 思路: 我们知道在加载 ...

  2. iOS 删除相册中照片--来自简书

    来自:http://www.jianshu.com/p/ac18aa3f28c2 最近公司的app有一个新功能是在app中删除相册的照片 ,本来是一个比较简单地功能,在做的过程中却发现AssetsLi ...

  3. iOS 从相册中拿到 图片名 ,截取后缀,图片名

    //从路径中获得完整的文件名 (带后缀) 对从相册中取出的图片,视频都有效. NSString *fileName = [filePath lastPathComponent]; //获得文件名 (不 ...

  4. Android 获取SDCard上图片和视频的缩略图

    获取图片缩略图和视频缩略图的方法: Java代码: import java.io.File; import android.app.Activity; import android.graphics. ...

  5. iOS遍历相册中的图片

    //获取相册的所有图片 - (void)reloadImagesFromLibrary { self.images = [[NSMutableArray alloc] init]; dispatch_ ...

  6. iOS 获取相册中图片的名字 url

    __block NSString *imageFileName; NSURL *imageURL = [info valueForKey:UIImagePickerControllerReferenc ...

  7. IOS 在IOS6中设置navigationBar背景图片 会有一条 黑色阴影 --- 解决方案

    //给navigationBar设置背景图片 if ([self.navigationController.navigationBar respondsToSelector:@selector(set ...

  8. ios选取相册视频,过滤掉所有图片!

    imagePicker = [[UIImagePickerController alloc]init]; imagePicker.mediaTypes = [NSArray arrayWithObje ...

  9. Android将view保存为图片并放在相册中

    在Android中,可以将view保存为图片并放在相册中,步骤为 view->bitmap->file,即先将view转化为bitmap,再将bitmap保存到相册中. 需要将红框标注的v ...

随机推荐

  1. C++ 结构体和枚举

    共同体 共同体(union) 是一种数据格式, 它能够存储不同的数据类型, 但只能同时存储其中的一种类型.也就是说, 结构可以同时存储int.long 和 double, 共同体只能存储int.lon ...

  2. SAP FI 财务模块 关键用户 考试练习 问卷

    FI概念部分课后练习:(20题, 开卷,本周五内完毕) PC端自我测试: http://www.xiaocar.net/index.php?s=/addon/Exam/Exam/show/exam_i ...

  3. 【Html】网页获取屏幕宽高

    <html> <script> function size(){ document.write( "屏幕分辨率为:"+screen.width+" ...

  4. NPOI 2.1.1 系列(2) 使用NPOI读取List或者datatable数据生成 Excel文档 ;Npoi生成 xlsx 2007以上文档

    结合上一篇文章  NPOI 2.1.1 系列(1) 使用NPOI读取 Excel文档 ;NpoiExcelHelper 导入导出 2003格式 2007格式的 Excel; Npoi 导出 xlsx ...

  5. PD 15.1 安装 破解 , 简单使用 (一对多,多对多关系生成sql脚本) , CDM 和 PDM 的区别;PD15.1 生成sql2008 无FK外键约束的解决方法

    CDM是概念模型,在概念模型上没有具体数据库产品的概念,反映的是实体和联系.PDM是物理模型,是依赖具体数据库产品的模型,比如可以指定具体的数据类型和约束等等.在PowerDesigner中两个模型之 ...

  6. zookeeper ACL使用

    生产环境中,经常会有多个项目使用zookeeper,例如多个hbase集群.每个项目搭建一套独立的zookeeper,无论从机器成本,还是运维成本,都是一笔额外的开销. 然而多项目,多集群共用zook ...

  7. T4生成实体,单张表和多张表

    # 使用说明 . 把T4目录放在项目的根目录 . 配置连接字符串,在tt文件的最底部 . generateAllEntity.tt生成全部的实体类 . generateSingleEntityByNa ...

  8. 精选10款超酷的HTML5/CSS3菜单

    今天向大家精选了10款超酷的HTML5/CSS3菜单,给你的网页添加不一样的精彩,一起来围观一下吧. 1.CSS3手风琴菜单 下拉展开带弹性动画 利用CSS3技术可以实现各种各样的网页菜单,我们之前也 ...

  9. Ubuntu14.04下安装Libsvm,并使用Libsvm

    (1)Ubuntu14.04下安装Libsvm 转载:https://blog.csdn.net/katrinawj/article/details/78915874 一.下载: 网址:http:// ...

  10. 如何在Sql Server中读取最近一段时间的记录,比如取最近3天的或最近3个月的记录。

    如何在Sql Server中读取最近一段时间的记录,比如取最近3天的或最近3个月的记录. 主要用到DATEADD函数,下面是详细语句 取最近3天 select * from 表名where rq> ...