作者:这个汤圆没有馅,iOS / 前端 开发者。
Session:https://developer.apple.com/videos/play/wwdc2020/10652/
在今年的WWDC
中,PhotoKit
有了新变化,其中一个就是PHPicker
。
什么是 PHPicker
PHPicker
是由系统提供的选择器,可以访问用户相册里的照片和视频。它内置了搜索功能,支持网格中的流体缩放,以及经常会被用到的照片多选功能。
简而言之,PHPicker
是应用程序从相册中获取照片和视频数据的最佳方式。它有一个全新的设计,易于使用的新 API,支持多选功能,同时应用程序可以指定可选择的类型。
另一个非常重要的特性是 PHPicker
的隐私方面。默认情况下,它有内置的隐私。
不需要直接访问用户相册
不会提示访问相册
仅为用户提供可选择的照片和视频
这是如何做到的?
PHPicker
运行在应用程序的进程之外,尽管它看起来像是在应用程序内部运行。它实际上是在一个独立的进程中运行,而不是在它上面呈现的宿主应用。但是该应用不能直接访问选择器,甚至不能截屏选择器内容。只有用户实际选择的内容才会传递回主机应用程序。
New API
1.声明一个PHPickerConfiguration
。PHPickerConfiguration
有两个可选属性 selectionLimit
和 filter
。selectionLimit
默认值为 1,表示单选。若要多选,则设置为 0;filter
指定相册显示类型,可单独设置,也可用数组形式显示多种类型。
2.初始化PHPickerViewController
,设置代理。
3.实现代理方法。
这里要注意的是,在代理方法中,首先要 dismiss
掉选择器。选择完毕后我们拿到的 results
打印结果如下,拿到数据后我们要先判断itemProvider
是否可加载为想要的对象类型,再处理后续逻辑。另外itemProvider.loadObject
是一个异步的方法,若出现错误也需要处理。
代码展示(import PhotoUI
)
- 单选 直接在首页展示选中的图片
@IBAction func pickerImageAct(_ sender: Any) { var config = PHPickerConfiguration() config.filter = .images config.selectionLimit = 1 let picker = PHPickerViewController(configuration: config) picker.delegate = self present(picker, animated: true) }
`extension ViewController: PHPickerViewControllerDelegate {
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
dismiss(animated: true, completion: nil)
if let itemProvider = results.first?.itemProvider, itemProvider.canLoadObject(ofClass: UIImage.self) {
let previousImg = imgView.image
itemProvider.loadObject(ofClass: UIImage.self) { [weak self] image, error in
DispatchQueue.main.async {
guard let self = self, let image = image as? UIImage, self.imgView.image == previousImg else {return}
self.imgView.image = image
}
}
}
}
}
`
- 多选 将选中的多张图片展示在首页,点击时切换图片
var itemProviders: [NSItemProvider] = [] //存储选择的所有照片的itemProviders var iterator: IndexingIterator<[NSItemProvider]>? //标记当前显示的图片
func displayNextImage() { if let itemProvider = iterator?.next(), itemProvider.canLoadObject(ofClass: UIImage.self) { let previousImg = imgView.image itemProvider.loadObject(ofClass: UIImage.self) { [weak self] image, error in DispatchQueue.main.async { guard let self = self, let image = image as? UIImage, self.imgView.image == previousImg else {return} self.imgView.image = image } } } }
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { displayNextImage() }
extension ViewController: PHPickerViewControllerDelegate { func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) { dismiss(animated: true, completion: nil) itemProviders = results.map(\.itemProvider) print(itemProviders) iterator = itemProviders.makeIterator() displayNextImage() } }
- Using PHPicker with PhotoKit
实际上,对于大多数只需要照片和视频数据的应用程序,根本不需要使用PhotoKit
。那么哪些情况需要使用PhotoKit
呢?一是 非破坏性图像编辑,二是 相册管理。
若应用程序需要使用PhotoKit
,一定要确保仅在必要时请求相册访问,并处理用户拒绝相册访问的情况。首先用PHPhotoLibrary
对象初始化configuration
,然后在代理方法中获取asset
标识符,并通过PhotoKit
的API方法用标识符来获取PHAssets
。
在iOS 14中,我们还引入了“Limited Photos Library”的新功能。如果应用程序没有使用PhotoKit
,则无需为此担心。对于要求访问相册的应用,除了现有的允许访问和拒绝访问选项外,还将在用户提示中显示第三个选项。新选项将仅允许应用程序访问用户相册的部分PHAsset
。它可以使用户更好地控制隐私,有关更多信息,请参阅 [Handle the Limited Photos Library in your app]
写在最后
AssetsLibrary
在几年前已被弃用,现在仍被弃用。如果应用程序需要访问AssetsLibrary
,请切换到到PhotoKit
。AssetsLibrary
最终将消失。UIImagePickerController
正在被弃用,不建议继续使用,可改为PHPickerViewController
。在显示选择器之前,不要提示访问图片库,也别要求用户授予访问权限。没有必要做这些。如果应用程序使用了
PhotoKit
来访问图片库,重新考虑它是否真的需要访问该库,或者是否可以使用PHPicker
来代替。
推荐阅读
如何使用原生 Diff 能力优化 UICollectionView 性能
关注我们
我们是「老司机技术周报」,每周会发布一份关于 iOS 的周报,也会定期分享一些和 iOS 相关的技术。欢迎关注。
关注有礼,关注【老司机技术周报】,回复「2019」,领取学习大礼包。
支持作者
这篇文章的内容来自于 《WWDC20 内参》。在这里给大家推荐一下这个专栏,专栏目前已经创作了 105 篇文章,只需要 29.9 元。点击【阅读原文】,就可以购买继续阅读 ~
WWDC 内参 系列是由老司机周报、知识小集合以及 SwiftGG 几个技术组织发起的。已经做了几年了,口碑一直不错。 主要是针对每年的 WWDC 的内容,做一次精选,并号召一群一线互联网的 iOS 开发者,结合自己的实际开发经验、苹果文档和视频内容做二次创作。
本文分享自微信公众号 - 老司机技术周报(LSJCoding)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。