
别让头像上传卡在权限坑:用 AI + PhotosPicker 给 iOS 接上相册选择
这一技教你用 SwiftUI PhotosPicker 给头像上传、反馈截图、晒单配图这类入口接上系统照片选择器,并用 AI 缺陷单和 6 步真机清单验收权限、取消、多选和加载失败边界。
用户要换头像、上传晒单图、提交反馈截图时,最怕的不是没有入口,而是一点入口就弹出一大串相册权限。很多人看到「允许访问所有照片」会犹豫,PM 也很难解释:我明明只想让用户选一张图,为什么像是在要整本相册?
这招可以交给 AI 补:用 SwiftUI 的
PhotosPicker 接系统照片选择器。Apple 文档把它定义为一个用于从照片图库选择资源的视图。1 Hacking with Swift 的 SwiftUI 示例也标明,PhotosPicker 是 iOS 16 开始可用的能力。2 如果你的 App 还要支持更老系统,先让 AI 检查 deployment target,再决定是不是需要旧方案兜底。先判断:哪些入口适合接 PhotosPicker
PhotosPicker 适合「用户主动挑几张媒体交给 App」的场景。它不是给 App 扫描整本相册用的,也不是给后台自动读照片用的。你可以先让 AI 帮你做一张照片入口表:
| 场景 | 推荐选择 | AI 要写清楚什么 | 验收重点 |
|---|---|---|---|
| 头像上传 | 单选图片 | 只允许选图片,选完后更新头像预览 | 取消后旧头像还在 |
| 反馈截图 | 单选或最多 3 张 | 优先允许截图,必要时限制数量 | 大图加载时有等待状态 |
| 晒单 / 发布动态 | 多选图片 | 写清最多能选几张,选完后按顺序展示 | 超过上限不能继续加 |
| 视频封面 | 单选图片 | 不要误让用户选视频 | 选错类型时有提示 |
这一步别直接让 AI 写代码。先把产品规则说清楚:用户能选什么、最多选几张、选完放在哪里、失败时怎么提示。
原理:系统负责选,App 只拿用户选中的那几张
PhotosPicker 的好处是把「浏览相册」这件事交给系统。WWDC22 里 Apple 说,系统照片选择器在 App 进程外运行,使用它不需要 App 请求照片图库访问权限。3 对 PM 来说,这句话可以翻译成:不要为了选一张头像,就把用户吓到像是在授权整本相册。但选完照片不等于照片已经进了你的页面。Apple 在同一个视频里提醒,SwiftUI binding 收到的选择结果只是 placeholder objects,App 还要按需加载真实资源数据。3 Apple 文档也把
PhotosPickerItem 定义为和 Photos picker 搭配使用的选中项类型。4真实加载通常交给
loadTransferable。Apple 文档说,它会尝试加载你指定类型的实例。5 Swift with Majid 的示例也展示了常见写法:用 matching: .images 限制图片,用数组绑定开启多选,再用 loadTransferable 读取选中的内容。6翻成产品语言,就是三步:先让系统打开相册,用户选中后拿到一个「选择结果」,最后再把结果加载成页面能显示的图片。
直接给 AI 的缺陷单
你可以把下面这段交给 Cursor、Claude Code 或 Xcode 里的 AI 助手:
请给这个 SwiftUI 页面增加系统照片选择入口,只做最小改动,不重写页面结构。
- 使用
PhotosPicker,不要自制相册页面。- 如果这是头像、封面或反馈截图,只允许选择图片,不要让用户选视频。
- 如果是多图上传,请把最大选择数量写成明确参数,并在 UI 上保留已选顺序。
- 用户取消选择时,不要清空原来的头像、草稿或已选图片。
- 选中后用
loadTransferable加载图片,并给加载中、加载失败各留一个可见状态。- 不要为了普通选图额外请求整本相册权限;如果代码里新增了照片权限说明,请解释为什么必须要。
- 大图或 iCloud 照片加载慢时,不要卡住整个页面,只在对应图片位置显示等待状态。
最后一条很容易被忽略。Apple 在 WWDC22 里提到,某些资源不会立刻加载;如果设备没联网,iCloud Photos 里的内容也可能加载失败;大视频这类文件还可能需要较长时间,所以建议做单项 inline loading UI,而不是一个挡住全页面的加载圈。3
两个容易被 AI 写错的地方
第一,AI 可能会把「选照片」写成「申请相册权限」。如果你的需求只是让用户主动选一张头像,先让 AI 解释新增权限的必要性。解释不出来,就要求它改回系统 PhotosPicker。普通选图入口应该尽量少打扰用户。
第二,AI 可能只做了打开选择器,没有处理选中后的加载。Hacking with Swift 的教程就把流程拆成几步:导入
PhotosUI,用 @State 保存 PhotosPickerItem,放置 PhotosPicker,再在选择变化后调用加载方法。7 如果你点完照片页面没变化,多半是这一步没接上。还有一个小坑:多图不是「一次性全塞进内存」。如果页面允许选 9 张大图,你要让 AI 逐张加载、逐张显示状态,失败的那张可以重试,不要让一张图失败拖垮整次发布。
真机验收:6 个动作就够
改完后不要只在模拟器里点一下。按这 6 步验收:
- 首次打开:点入口后出现系统照片选择界面,不要先弹整本相册权限。
- 取消路径:打开后直接取消,原头像、原草稿和已选图片都不应被清空。
- 单选路径:选一张图片,页面能显示预览,返回后入口仍然可再次选择。
- 类型限制:头像、封面、截图这类入口只能选图片,不能误选视频。
- 多选上限:如果允许多选,连续选择到上限后不能再继续加。
- 弱网 / iCloud 图:选一张可能需要下载的大图,页面要有加载中和失败提示,不要整页卡死。
如果你做的是反馈截图入口,再多测一步:选择截图后,用户能不能删除其中一张再重新选。这个动作比「一次选对」更接近真实使用。
今天最小可行动作
先别全 App 改。选一个最简单的图片入口,比如头像上传或反馈截图,写下三行:
- 用户最多能选几张?
- 只能选图片,还是也允许视频?
- 用户取消或加载失败时,页面要保留什么?
把这三行和上面的缺陷单一起交给 AI。今天的目标不是做完整媒体库,而是把一个「看起来要很多权限」的上传入口,改成用户主动选择、页面能稳稳接住的系统流程。
参考ソース
- 1PhotosPicker | Apple Developer Documentation
- 2How to let users select pictures using PhotosPicker - a free SwiftUI by Example tutorial
- 3What's new in the Photos picker - WWDC22 - Videos - Apple Developer
- 4PhotosPickerItem | Apple Developer Documentation
- 5loadTransferable(type:) | Apple Developer Documentation
- 6PhotosPicker in SwiftUI | Swift with Majid
- 7Importing an image into SwiftUI using PhotosPicker - a free Hacking with iOS: SwiftUI Edition tutorial
関連コンテンツ
- ログインするとコメントできます。
More from this channel›
- 别让图片加载只剩空白:用 AI + AsyncImage 补齐加载和失败状态
- 别让 iPad 版只是放大 iPhone:用 AI + NavigationSplitView 做双栏界面
- 别让页面跳转像迷宫:用 AI + NavigationStack 给 iOS 流程搭清楚路径
- 别让设置每次重置:用 AI + AppStorage 给 iOS 偏好做本地保存
- 别让误触删掉成果:用 AI + confirmationDialog 给 iOS 危险操作加二次确认
- 别让列表像没更新:用 AI + refreshable 给 iOS 页面加下拉刷新
- 别让用户只会截图:用 AI + ShareLink 给 iOS 页面接上系统分享
- 别让按钮像没反应:用 AI + sensoryFeedback 给 iOS 操作加触感
