You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Camera App使用.addOnly级PHPhotoLibrary创建新相册的方案咨询

解决方案

可以在仅申请.addOnly级PHAccessLevel权限的前提下完成自定义相册创建操作,无需申请.readWrite全量相册权限

原理说明

iOS 14推出的.addOnly权限的核心限制是禁止应用读取全局相册列表、访问非本App创建的相册/资源,但允许以下操作:

  • 创建新的自定义相册
  • 向本App创建的相册中添加照片资源
  • 通过指定localIdentifier查询本App创建的相册资源

你原有代码报错的核心原因是fetchAssetCollectionForAlbum方法采用了按相册名全局遍历筛选的逻辑,该操作属于读取用户全量相册列表的行为,被.addOnly权限限制。

实现步骤

  1. 放弃全局按相册名查询的逻辑,改为持久化存储本App创建的相册的唯一标识localIdentifier(可存储在UserDefaults中)
  2. 每次需要获取自定义相册时,优先用本地存储的localIdentifier直接查询相册,该操作在.addOnly权限下合法
  3. 若本地无存储的标识、或标识对应的相册已被用户删除,再走新建相册逻辑,创建时直接记录返回的相册标识
  4. 相册创建失败时清理本地存储的无效标识,避免后续查询异常

修正后代码实现

import Photos

// 自定义相册名称
private let albumName = "AppName"
// 本地存储相册唯一标识的Key
private let kCustomAlbumIdentifier = "AppSavedAlbumID"
// 缓存的相册实例
var customAlbum: PHAssetCollection?

// 通过本地存储的标识查询相册
private func fetchCustomAlbum() -> PHAssetCollection? {
    guard let albumID = UserDefaults.standard.string(forKey: kCustomAlbumIdentifier) else {
        return nil
    }
    // 仅查询指定标识的相册,addOnly权限下允许
    let fetchResult = PHAssetCollection.fetchAssetCollections(withLocalIdentifiers: [albumID], options: nil)
    return fetchResult.firstObject
}

// 校验相册存在性,不存在则自动创建
func prepareCustomAlbum(completion: @escaping (Bool, PHAssetCollection?) -> Void) {
    // 优先读取已有的相册
    if let existingAlbum = fetchCustomAlbum() {
        customAlbum = existingAlbum
        completion(true, existingAlbum)
        return
    }
    
    // 无有效相册则创建新相册
    PHPhotoLibrary.shared().performChanges({
        // 发起创建相册请求
        let createRequest = PHAssetCollectionChangeRequest.creationRequestForAssetCollection(withTitle: albumName)
        // 提前记录新建相册的临时标识
        let placeholderID = createRequest.placeholderForCreatedAssetCollection.localIdentifier
        UserDefaults.standard.set(placeholderID, forKey: kCustomAlbumIdentifier)
    }) { [weak self] success, error in
        guard let self = self else { return }
        if success, let newAlbum = self.fetchCustomAlbum() {
            self.customAlbum = newAlbum
            completion(true, newAlbum)
        } else {
            // 创建失败清理无效标识
            UserDefaults.standard.removeObject(forKey: kCustomAlbumIdentifier)
            completion(false, nil)
            print("相册创建失败: \(error?.localizedDescription ?? "未知错误")")
        }
    }
}

注意事项

  • 该方案仅支持iOS 14及以上系统,与PHAccessLevel的适配最低版本一致
  • 由于.addOnly权限限制无法读取全局相册列表,若用户手动创建了同名相册,无法复用该相册,系统会自动为新建的同名相册添加序号后缀区分,不影响正常使用
  • 向该自定义相册中添加照片的操作在.addOnly权限下完全合法,无需额外申请权限

内容的提问来源于stack exchange,提问作者xellos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 13:06:04