WWDC 22: 照片选择器的一些更新以及追踪照片变更历史

发布
更新
字数 962
阅读 5 分钟
阅读量 897

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