您可以使用未记录 PHAsset.ALAssetURL
的属性偷偷摸摸地进行†,但我正在寻找有记录的东西。
† 在 Objective-C 中,这会有所帮助
@interface PHAsset (Sneaky)
@property (nonatomic, readonly) NSURL *ALAssetURL;
@end
通过利用PHAsset
. 示例:
PHAsset.localidentifier
返回91B1C271-C617-49CE-A074-E391BA7F843F/L0/001
现在使用前 32 个字符来构建assetURL,例如:
assets-library://asset/asset.JPG?id=91B1C271-C617-49CE-A074-E391BA7F843F&ext=JPG
您可能会JPG
根据资产的 UTI 更改扩展名(requestImageDataForAsset
返回 UTI),但在我的测试中,assetURL 的扩展名似乎无论如何都被忽略了。
我也希望能够获得资产的 URL。但是,我已经意识到localIdentifier
可以改为持久化并用于恢复PHAsset
.
PHAsset* asset = [PHAsset fetchAssetsWithLocalIdentifiers:@[localIdentifier] options:nil].firstObject;
可以使用以下方法转换旧资产 URL:
PHAsset* legacyAsset = [PHAsset fetchAssetsWithALAssetUrls:@[assetUrl] options:nil].firstObject;
NSString* convertedIdentifier = legacyAsset.localIdentifier;
(在该方法被淘汰之前......)
(感谢holtmann -localIdentifier
隐藏在PHObject
.)
这是在 iOS 11 模拟器和设备上测试的工作代码
PHFetchResult *result = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:nil];
[result enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
PHAsset *asset = (PHAsset *)obj;
[asset requestContentEditingInputWithOptions:nil completionHandler:^(PHContentEditingInput * _Nullable contentEditingInput, NSDictionary * _Nonnull info) {
NSLog(@"URL:%@", contentEditingInput.fullSizeImageURL.absoluteString);
NSString* path = [contentEditingInput.fullSizeImageURL.absoluteString substringFromIndex:7];//screw all the crap of file://
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL isExist = [fileManager fileExistsAtPath:path];
if (isExist)
NSLog(@"oh yeah");
else {
NSLog(@"damn");
}
}];
}];
阅读底部!
resultHandler
forPHImageManager.requestImage
返回 2 个对象:result
和info
.
您可以通过以下方式获取PHAsset
(like IMG_1043.JPG
) 的原始文件名及其在文件系统上的完整路径:
let url = info?["PHImageFileURLKey"] as! URL
这应该可以正常工作,但由于某种原因它不能。因此,基本上,您必须将图像复制到文件中,然后访问该文件,然后将其删除。
可PHImageFileURLKey
用于获取原始文件名,但您实际上无法访问该文件。这可能与后台代码可以访问该文件而其他应用程序可以删除它有关。
这是一个用 Swift 编写的 PHAsset 扩展,它将检索 URL。
extension PHAsset {
func getURL(completionHandler : @escaping ((_ responseURL : URL?) -> Void)){
if self.mediaType == .image {
let options: PHContentEditingInputRequestOptions = PHContentEditingInputRequestOptions()
options.canHandleAdjustmentData = {(adjustmeta: PHAdjustmentData) -> Bool in
return true
}
self.requestContentEditingInput(with: options, completionHandler: {(contentEditingInput: PHContentEditingInput?, info: [AnyHashable : Any]) -> Void in
completionHandler(contentEditingInput!.fullSizeImageURL as URL?)
})
} else if self.mediaType == .video {
let options: PHVideoRequestOptions = PHVideoRequestOptions()
options.version = .original
PHImageManager.default().requestAVAsset(forVideo: self, options: options, resultHandler: {(asset: AVAsset?, audioMix: AVAudioMix?, info: [AnyHashable : Any]?) -> Void in
if let urlAsset = asset as? AVURLAsset {
let localVideoUrl: URL = urlAsset.url as URL
completionHandler(localVideoUrl)
} else {
completionHandler(nil)
}
})
}
}
}