如何通过PHFetchOptions仅获取iPhone相机拍摄的照片?
当然可以实现!要只筛选iPhone原生相机拍摄的照片,我们可以结合照片的元数据特征和相册来源两种思路,下面给你具体的实现方案:
方法1:通过EXIF元数据精准筛选
iPhone原生相机拍摄的照片会带有独特的EXIF标记,比如制造商是Apple,设备型号包含iPhone,我们可以把这些条件加入到NSPredicate中,同时保留你原来排除截图的逻辑:
let options = PHFetchOptions() // 排除截图 let excludeScreenshotPredicate = NSPredicate(format: "NOT (mediaSubtype & %d != 0)", PHAssetMediaSubtype.photoScreenshot.rawValue) // 筛选Apple设备拍摄的照片(制造商为Apple) let makePredicate = NSPredicate(format: "%K == %@", "{Exif}.Make", "Apple") // 筛选iPhone型号拍摄的照片(设备型号包含iPhone) let modelPredicate = NSPredicate(format: "%K CONTAINS %@", "{Exif}.Model", "iPhone") // 合并所有条件 options.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [excludeScreenshotPredicate, makePredicate, modelPredicate]) // 执行查询 var fetchResult: PHFetchResult<PHAsset> = PHAsset.fetchAssets(with: .image, options: options)
补充说明:
{Exif}.Make和{Exif}.Model是照片EXIF元数据中的标准字段,原生相机拍摄的照片一定会包含这些信息- 如果想更严格地限定为原生相机应用拍摄的,还可以添加对
{TIFF}.Software的筛选(原生相机的该字段通常是Camera或者对应iOS版本号,比如17.0,你可以根据实际测试调整):let softwarePredicate = NSPredicate(format: "%K == %@", "{TIFF}.Software", "Camera")
方法2:从相机胶卷相册直接获取
原生相机拍摄的照片默认都会存入「相机胶卷」(也就是系统的"User Library"智能相册),我们可以先定位到这个相册,再从中获取照片,同时结合排除截图的条件:
// 获取相机胶卷相册 guard let cameraRollCollection = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .smartAlbumUserLibrary, options: nil).firstObject else { // 相机胶卷不存在的异常处理 return } let options = PHFetchOptions() // 排除截图 options.predicate = NSPredicate(format: "NOT (mediaSubtype & %d != 0)", PHAssetMediaSubtype.photoScreenshot.rawValue) // 按拍摄时间倒序(可选,符合用户浏览习惯) options.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)] // 从相机胶卷中获取照片 var fetchResult: PHFetchResult<PHAsset> = PHAsset.fetchAssets(in: cameraRollCollection, options: options)
注意点:
- 这种方法的好处是简单直接,但要注意:部分第三方应用也可能将保存的照片写入相机胶卷,如果需要完全排除这类照片,建议结合方法1的元数据筛选,进一步缩小范围。
内容的提问来源于stack exchange,提问作者Paul T.
相关产品推荐
相关产品推荐

