iOS 基于PhotoKit 获取系统所有相册 以及所有照片 包括iCloud的处理 细节详解及实战代码
前言
最近在做一个相册的项目,一开始觉得项目没什么难度,可是真正上手做了之后,发现难度不小,苹果新推出Photokit之后,获取相册中图片对象是快的,可是在获取到具体图片个人实战比较慢,同时还有icloud的问题,那么本片博客就带你一起解决这些问题。
第一步 获取系统所有相册
import Photos
private var allAsset:[PHAsset] = [] //相册中所有的照片/*获取相机胶卷数据*/let cameraRoll = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .smartAlbumUserLibrary, options: nil)cameraRoll.enumerateObjects(options: .concurrent) { (collection, index, stop) inlet assetResult = PHAsset.fetchAssets(in: collection, options: options)for i in 0..<assetResult.count{self.allAsset.append(assetResult[i])}}/*获取用户自定义相册*/let userAlbums = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: nil)userAlbums.enumerateObjects(options: .concurrent) { (collection, index, stop) inlet assetResult = PHAsset.fetchAssets(in: collection, options: options)if collection.localizedTitle! != "最近删除"{for i in 0..<assetResult.count{self.allAsset.append(assetResult[i])}}}
讲解:self.allAsset 中全部是PHAsset对象,也就是后边我们要获取图片的对象,关于PHAsset对象的参数说明
- mediaType 四个枚举值 image video audio unknown
- pixelWidth 图片原始宽 pixelHeight 图片原始高
- creationDate 创建时间
- location 当时拍摄图片的地理坐标 可能是 nil 用的时候小心
- localIdentifier 这个非常重要 所有照片的一个唯一标识 并且还可以通过这个表示获得PHAsset对象,进而获得图片 稍后会讲如何获取图片
- duration 视频的话 会有个视频时长
第二步 通过localIdentifier 和 PHAsset如何获取图片
获取图片需要用到这几个类
- PHImageRequestOptions
- PHCachingImageManager
- PHImageManager
先说 PHImageRequestOptions 是我们请求图片时的可选配置
let option:PHImageRequestOptions = PHImageRequestOptions()
option.deliveryMode = .fastFormat
option.resizeMode = .fast
option.isSynchronous = true
option.isNetworkAccessAllowed = true
讲解PHImageRequestOptions相关配置
deliveryMode
有 opportunistic highQualityFormat fastFormat三个枚举值 其中我常用的就是fastFormat和 highQualityFormat fastFormat是系统以最快的速度给我们返回一张看起来还可以的图片当对图片的获取速度有要求时可以使用。 highQualityFormat将会返回原图 当对图片质量要求高的时候可以用。
resizeMode
有 fast exact none 跟deliveryMode差不多 都是根据对图片的要求 做尺寸的上缩减 fast 最快 exact有targetSize时使用 none 不缩减
isSynchronous
同步获取还是异步获取,这里我选择同步获取 获取图片的回调方法只会执行一次 如果设置成异步获取,那么获取图片的回调会执行多次 true是同步获取
isNetworkAccessAllowed
这个就是最蛋疼的iCloud 图片,当图片在iCloud中时 只有这个参数设置成true 才能获取到图片,每次做到这的时候 都忍不住想骂苹果。
通过PHAsset 获取图片
Photokit 框架 把 缩略图去掉了 但是直接拿图片的话 如果只有几张没问题,速度还可以,但是如果很多 那就不是1s能衡量的了 所以这里引出了 PHCachingImageManager,可以先通过PHCachingImageManager拿到一张很迷糊的图,然后再通过PHImageManager拿到相应清晰度可接受的图 具体看代码
片段一
asset 就是 PHAsset对象
拿到缓存图 这个还是比较快的
PHCachingImageManager.default().requestImage(for: asset, targetSize: CGSize(width: WIDTH-40, height: WIDTH-40), contentMode: .aspectFill, options: option, resultHandler: { (result, info) inif result != nil{completeCache(result!)}})
拿到可接受清晰度的图 速度一般
PHImageManager.default().requestImageData(for: asset, options: option) { (data, dataUi, aa, dic) inif data != nil{completeReal(data!)}}
如何根据localIdentifier获得图片呢 直接看代码
let result = PHAsset.fetchAssets(withLocalIdentifiers: idents, options: nil)
result.enumerateObjects { (asset, index, stop) in}
注意 这里的withLocalIdentifiers 是一个数组 通过enumerateObjects可以获得PHAsset 数组中有几个localIdentifier 就会回调几次 然后再用片段一中的代码获取图片
如何解决iCloud的问题
由于iCloud 是存在苹果服务器上的 需要网络下载,所以谁也没有办法像加载本地图片那样快速,只能通过一些间接的方法解决,我的方法是增加进度显示,类似相册中加载iCloud图片的进度条。那么如何获取进度
获取iCloud 下载进度
其实也很简单 还记得刚才的PHImageRequestOptions吧 只需要加上这段代码就可以了
option.progressHandler = {(pro,error,data,stop) in这里的pro 就是每张图片的进度 只需要设置一个值 定时刷新UI就好了}
进度条显示
画外圆 centerPoint 圆心 radius 半径
let path = UIBezierPath.init(arcCenter: CGPoint(x: centerPoint, y: centerPoint), radius: radius, startAngle: 0, endAngle: .pi*2, clockwise: true)
let shapeLayer = CAShapeLayer()
shapeLayer.path = path.cgPath
shapeLayer.strokeColor = UIColor.white.cgColor
shapeLayer.lineWidth = 2
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.shadowColor = UIColor.black.cgColor
shapeLayer.shadowOffset = CGSize(width: 0, height: 0)
shapeLayer.shadowRadius = 3
shapeLayer.shadowOpacity = 0.3
self.layer.addSublayer(shapeLayer)
画内圆
let subPath = UIBezierPath.init(arcCenter: CGPoint(x: centerPoint, y: centerPoint), radius: radius, startAngle: .pi*(-1/2), endAngle: CGFloat(.pi*(progress*2-1/2)), clockwise: true)
subPath.addLine(to: CGPoint(x: centerPoint, y: centerPoint))
let subLayer = CAShapeLayer()
subLayer.path = subPath.cgPath
subLayer.lineWidth = 0
subLayer.fillColor = UIColor.white.cgColor
self.layer.addSublayer(subLayer)
关于图片上传
我们公司上传图片采用的是七牛云 图片上传很简单,这里只说视频上传的一个坑 ,由于iCloud的存在 所以视频上传要分开来上传
通过let resource = PHAssetResource.assetResources(for: showAsset) showAsset是PHAsset对象
let resource = PHAssetResource.assetResources(for: model.showAsset)if resource.first != nil{let first = resource.first!if first.value(forKey: "locallyAvailable") != nil && first.value(forKey: "locallyAvailable") as? Bool != nil{let isLocal = first.value(forKey: "locallyAvailable")! as! Boolif isLocal{// 本地可用上传七牛用PHAsset的方式}else {// 本地不可用do{let data = try Data(contentsOf: model.avUrl)上传七牛用Data的方式}catch{fail()}}}}
总结
在网上找了很多例子 但是大多数都不全,都不能完全解决问题,今天就将自己整理的代码粘贴出来,关于相册的相关问题 应该可以解决95%的问题,希望对你有帮助。
iOS 基于PhotoKit 获取系统所有相册 以及所有照片 包括iCloud的处理 细节详解及实战代码相关推荐
- iOS/swift之获取系统所有相册和照片录像、封装相册多选
参考:http://www.hangge.com/blog/cache/detail_1512.html ios14 使用PHPicker获取相册(需要 import PhotosUI) 支持多选 支 ...
- android-短信验证功能,Android实现获取短信验证码的功能以及自定义GUI短信验证详解...
<Android实现获取短信验证码的功能以及自定义GUI短信验证详解>由会员分享,可在线阅读,更多相关<Android实现获取短信验证码的功能以及自定义GUI短信验证详解(8页珍藏版 ...
- Linux系统与网络、磁盘参数和日志监控等命令详解二
创作人QQ:851301776,邮箱:lfr890207@163.com, 欢迎大家一起技术交流,本博客主要是自己学习的心得体会,只为每天进步一点点! 个人座右铭: 1.没有横空出世,只要厚积一定发. ...
- android相册和拍照并裁剪图片大小,Android 拍照并对照片进行裁剪和压缩实例详解...
Android 拍照并对照片进行裁剪和压缩实例详解 本文主要介绍 Android 调用摄像头拍照并对照片进行裁剪和压缩,文中给出了主要步骤和关键代码. 调用摄像头拍照,对拍摄照片进行裁剪,代码如下. ...
- Linux系统强制位u+s、g+s、o+t 详解
Linux系统强制位u+s.g+s.o+t 详解 u+s:一个命令,给与用户s权限,则此用户暂时获得这个命令的属主权限 (例chmod u+s /usr/bin/touch或者chmod 4755 / ...
- java ear war_基于Java的打包jar、war、ear包的作用与区别详解
基于Java的打包jar.war.ear包的作用与区别详解 以最终客户的角度来看,JAR文件就是一种封装,他们不需要知道jar文件中有多少个.class文件,每个文件中的功能与作用,同样可以得到他们希 ...
- linux 文件 字符集设置,Linux字符集和系统语言设置-LANG,locale,LC_ALL,POSIX等命令及参数详解...
博文说明[前言]: 本文将通过个人口吻介绍Linux字符集和系统语言设置,包括LANG,locale,LC_ALL,POSIX等命令及参数详解的相关知识,在目前时间点[2017年6月21号]下,所掌握 ...
- 基于全生命周期的主数据管理:MDM详解与实战学习03 第三章 主数据管理的关键技术
第三章 主数据管理的关键技术 3.1 数据标准 3.1.1 数据标准的分类 3.1.2 物资类数据标准 1.国际标准 2.国内标准 3.1.3 产品数据标准 3.1.4 财务数据标准 3.2 信息分类 ...
- Android系统(96)---Android 数据交换解析框架Gson使用详解
Android 数据交换解析框架Gson使用详解 Json 是一种文本形式的数据交换格式,比 xml 更为轻量.Json 的解析和生成的方式很多,在 Android 平台上最常用的类库有 Gson 和 ...
最新文章
- 极客广州——EOS Asia郭达峰担任SegmentFault思否黑客马拉松技术顾问
- 的路由放在本地_支持双频+WiFi 6,穿墙力强,领势AX3200路由器体验
- 百练2810:完美立方
- python分词和词频统计
- SAP S/4HANA生产排期scheduling profile配置
- 有人问我,为什么1+1等于2
- Spring集成单元测试
- 有趣的html代码_千万别惹程序员,否则会在代码注释里,告诉这家公司有多坑...
- CVPR自动驾驶运动预测挑战赛:轻舟智航夺冠方案
- 机器学习 —— 概率图模型(推理:采样算法)
- Docker 容器的运行(八)
- DevExpress v18.1新版亮点——WinForms篇(六)
- IBM宣布:成功研制出了量子计算机原型机,量子计算机商业化正在加速!
- 串口通信工具android,串口调试工具手机版
- 浏览器被hao360劫持解决办法
- 互联网软件开发和传统软件开发的不同(转型互联网开发需要适应的那些事)
- IT大败局----第十章 企业公关的真谛
- 系统运维应届生面试题
- canvas教程18-刮刮乐
- 高光谱成像的传感器和相机要求