WWDC 22: 照片选择器的一些更新以及追踪照片变更历史
PhotoKit
可以帮助应用深度集成系统 Photos
,提供管理、编辑、自定义相机等能力,或者为用户提供独有的照片浏览体验。使用 PHPicker
可以方便、安全的在自己的应用中访问系统相册,选择图片。
新的 filter
类型
// 已有
/// A filter that represents images, and includes Live Photos.
static let images: PHPickerFilter
/// A filter that represents video assets.
static let videos: PHPickerFilter
/// A filter that represents Live Photos.
static let livePhotos: PHPickerFilter
// 新增
/// A filter that represents screenshots.
static let screenshots: PHPickerFilter
/// A filter that represents screen recordings.
static let screenRecordings: PHPickerFilter
/// A filter that represents slow-motion videos.
static let slomoVideos: PHPickerFilter
/// A filter that represents videos with a shallow depth of field and focus transitions.
static let cinematicVideos: PHPickerFilter
/// A filter that represents photos with depth information.
static let depthEffectPhotos: PHPickerFilter
/// A filter that represents time-lapse videos.
static let timelapseVideos: PHPickerFilter
/// A filter that represents assets with multiple high-speed photos.
static let bursts: PHPickerFilter
/// A filter that represents panorama photos.
static let panoramas: PHPickerFilter
/// Creates a new filter by using the playback style you specify.
static func playbackStyle(PHAsset.PlaybackStyle) -> PHPickerFilter
也可以使用其他条件过滤器
/// Creates a new filter by combining the filters in the array.
static func any(of: [PHPickerFilter]) -> PHPickerFilter
/// Creates a new filter that includes only the filters you specify.
static func all(of: [PHPickerFilter]) -> PHPickerFilter
/// Creates a new filter that excludes the filter you specify.
static func not(PHPickerFilter) -> PHPickerFilter
所以你可以灵活的使用这些过滤器达到目的
var configuration = PHPickerConfiguration()
// iOS 15
// Shows videos and Live Photos
configuration.filter = .any(of: [.videos, .livePhotos])
// New: iOS 15
// Shows screenshots only
configuration.filter = .screenshots
// New: iOS 15
// Shows images excluding screenshots
configuration.filter = .all(of: [.images, .not(.screenshots)])
// New: iOS 16
// Shows cinematic videos
configuration.filter = .cinematicVideos
新的 picker 方法
在 iOS 15 中,新加入的 .preselectedAssetIdentifiers
设置属性允许 app 提前选中一些图片,在 iOS 16 中,新增的 .deselectAssets(withIdentifiers:)
方法,可以用来取消选择。
// 通过 identifier 取消选择
picker.deselectAssets(withIdentifiers: [identifier])
// 移动
picker.moveAsset(withIdentifier: identifier, afterAssetWithIdentifier: otherIdentifier)
注意,相册或照片的 identifier 是设备唯一的,也就是换一个设备,手机或者iPad,identifier 就会不一样,即使照片是通过 iCloud 同步的。如果要在不同设备之间同步 identifier,可以选择使用 cloud identifier,该功能甚至可以在设备没有登录 iCloud 情况下使用,参考:https://developer.apple.com/documentation/photokit/phphotolibrary/3868300-cloudidentifiermappings
追踪照片变更历史
使用新的变更历史 API,可以很方便地追踪相册的变更记录,包含插入、更新以及删除操作。所有的变更都会被呈现在同一时间轴内,这些变更可能会包含对相册、照片等的全部操作。其他应用可以通过一个持久化变更 token,在这个时间轴上很轻松的获取相册内容的变更状态,当你想获取这些变更时,只需要提供自己的 token,就可以获取到你需要的历史记录以及一个新的 token。
注意,此处仍受用户隐私保护,如果用户只允许应用访问部分相片,那返回的历史记录将只包含允许访问的内容。
变更 token 是本地设备唯一的,所有支持 PhotoKit 的系统都可以使用这个新的 API:macOS,iOS,iPadOS,tvOS。
变更历史主要针对三种 Photos 对象:asset,asset collection,collection list。
// 首先你需要获取应用自己存储的 token
// 然后用来获取 persistent changes
let persistentChanges = try! PHPhotoLibrary.shared().fetchPersistentChanges(since: self.lastStoredToken)
// 之后,通过遍历,收集变更历史的细节信息:更新、删除或者插入操作
for persistentChange in persistentChanges {
// `.changeDetails` 方法支持设置你感兴趣的对象,这里是 `.asset`,也就是照片或视频
if let changeDetails = persistentChange.changeDetails(for: PHObjectType.asset) {
let updatedIdentifiers = changeDetails.updatedLocalIdentifiers
let deletedIdentifiers = changeDetails.deletedLocalIdentifiers
let insertedIdentifiers = changeDetails.insertedLocalIdentifiers
}
}
// 更新你的 token
self.lastStoredToken = lastPersistentChange.changeToken