如何从PHAsset获取ALAsset URL?

时间:2015-03-05 21:02:22

标签: ios8 alassetslibrary alasset photokit phasset

你可以使用undocumented PHAsset.ALAssetURL属性偷偷溜溜†,但我正在寻找记录的内容。


†在Objective-C中,这将有助于

@interface PHAsset (Sneaky)

@property (nonatomic, readonly) NSURL *ALAssetURL;

@end

5 个答案:

答案 0 :(得分:43)

利用PHAsset的localidentifier创建assetURL。 例: PHAsset.localidentifier返回91B1C271-C617-49CE-A074-E391BA7F843F/L0/001

现在使用32个第一个字符来构建assetURL,如:

assets-library://asset/asset.JPG?id=91B1C271-C617-49CE-A074-E391BA7F843F&ext=JPG

您可以根据资产的UTI更改扩展名JPGrequestImageDataForAsset返回UTI),但在我的测试中,无论如何都会忽略assetURL的扩展名。

答案 1 :(得分:8)

我希望能够获得资产的URL。但是,我已经意识到localIdentifier可以保留,而是用于恢复PHAsset

PHAsset* asset = [PHAsset fetchAssetsWithLocalIdentifiers:@[localIdentifier] options:nil].firstObject;

可以使用以下方式转换旧版资产网址:

PHAsset* legacyAsset = [PHAsset fetchAssetsWithALAssetUrls:@[assetUrl] options:nil].firstObject;
NSString* convertedIdentifier = legacyAsset.localIdentifier;

(在该方法被淘汰之前......)

(感谢holtmann - localIdentifier隐藏在PHObject中。)

答案 2 :(得分:1)

这是在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");
            }
        }];
    }];

答案 3 :(得分:1)

这是用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)
                }
            })
        }
    }
}

答案 4 :(得分:0)

阅读底部!

PHImageManager.requestImage的resultHandler返回2个对象:结果和信息

您可以使用以下命令获取PHAsset的原始文件名(例如IMG_1043.JPG)以及文件系统上的完整路径:

let url = info?["PHImageFileURLKey"] as! URL

这应该正确,但是由于某种原因,Apple搞砸了。因此,基本上,您必须将图像复制到文件中,然后访问该文件然后将其删除。

PHImageFileURLKey可用于获取原始文件名,但是您实际上无法访问该文件。可能与以下事实有关:后台代码可以访问文件,而其他应用程序可以删除文件。

考虑一下,既然苹果搞砸了,而不是仅仅记录下来,您就会花多少时间弄清楚这个问题。也许是真诚的,也许是因为他们有不同的开发人员,他们不了解并且不想工作。不过我在这里工作,苹果银行里有几千亿美元?

是的,对不起Apple,但是当我的资产少于500美元且少于1年的1700位订阅者的净资产不足1年时,我需要支付1TB iCloud @ 10美元/月的费用,并在与您相同的时间里工作,我不同意从债务中恢复过来(2001年->现在)。那是原来的iPhone吗?您肯定是在教他们这些数据大小,不是,将iCloud每月价格调整为<美国平均月收入的1%!