Ios8 如何从PHAsset获取ALAsset URL?

Ios8 如何从PHAsset获取ALAsset URL?,ios8,alassetslibrary,alasset,photokit,phasset,Ios8,Alassetslibrary,Alasset,Photokit,Phasset,您可以使用PHAsset.ALAssetURL属性偷偷地†完成,但我正在寻找一些文档 †在目标C中,这将有所帮助 @interface PHAsset (Sneaky) @property (nonatomic, readonly) NSURL *ALAssetURL; @end 通过利用相集的localidentifier创建assetURL。 例子: PHAsset.localidentifier返回91B1C271-C617-49CE-A074-E391BA7F843F/L0/00

您可以使用
PHAsset.ALAssetURL
属性偷偷地†完成,但我正在寻找一些文档


†在目标C中,这将有所帮助

@interface PHAsset (Sneaky)

@property (nonatomic, readonly) NSURL *ALAssetURL;

@end

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

现在使用前32个字符构建assetURL,如:

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


您可以根据资产的UTI更改扩展名
JPG
requestImageDataForAsset
返回UTI),但在我的测试中,资产的扩展名似乎被忽略了。

我也希望能够获得资产的URL。但是,我已经意识到,
localIdentifier
可以被持久化,并用于恢复
PHAsset

PHAsset* asset = [PHAsset fetchAssetsWithLocalIdentifiers:@[localIdentifier] options:nil].firstObject;
可以使用以下方式转换旧资产URL:

PHAsset* legacyAsset = [PHAsset fetchAssetsWithALAssetUrls:@[assetUrl] options:nil].firstObject;
NSString* convertedIdentifier = legacyAsset.localIdentifier;
(在该方法被淘汰之前…)


(谢谢-
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");
            }
        }];
    }];
看下面

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

您可以通过以下方式获取PHAsset的原始文件名(如IMG_1043.JPG)及其在文件系统上的完整路径:

let url = info?["PHImageFileURLKey"] as! URL
这应该是正确的,但由于某种原因,苹果把它搞砸了。所以基本上,你必须将你的图像复制到一个文件中,然后访问它,然后删除它

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

想想看,既然苹果搞砸了,你会浪费多少时间去弄清楚,而不是仅仅记录下来。也许这是真诚的,也许是因为他们有不同的开发人员,他们不理解也不想工作。但我在这里工作,苹果在银行里有几千亿美元


是的,很抱歉,苹果公司,但我不同意当1700名用户每月支付1TB iCloud@10美元,而我的净资产不到一年,而我的工作时间与你从债务中恢复过来的时间相同(2001年->现在)。这就是最初的iPhone,对吗?你肯定在教他们这些数据大小,不是吗,将iCloud的月价格调整到美国平均月收入的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)
                }
            })
        }
    }
}

没有文档记录,我看到GUID字符串是相同的,这是有意义的,因为PhotoKit和AssetLibrary在引擎盖下使用相同的CoreData对象—所以这只是CoreData对象的UUID。我更喜欢这种方法而不是使用私有API调用。我们必须这样做只是为了获取URL,这太荒谬了。请确保从localIdentifier中删除“/L0/001”,否则每次都会失败。从localIdentifier获取GUID的正确方法是在第一个/。(有些guid超过32个字符。)如果有人知道获取资产URL的更好方法,请在这里发布。这是一种黑客行为,很容易在将来的更新中被破坏。不要使用这种方法。这是黑客攻击和未记录的,苹果可能会随时更改组成资产URL的规则。此外,您无法处理某些边缘情况,例如未下载的资源。我之前尝试过,然后一些用户报告他们看不到相册中的一些图像。我在我的crash reporter中看到了很多错误报告saids AssetsLibrary在URL:assets中找不到图像-library://xxx,我花了很多时间才弄明白。更好的方法是将PHAsset提取到本地文件系统,重构代码以使用文件系统URL,或者迁移到PHAsset。您所说的可能是真的,但它似乎只与实际(我认为,明确说明)问题有间接关系。@Clay Bridges是真的。我想我意识到这一点帮助我解决了问题,并在不重新检查问题的情况下添加了答案。很抱歉,我发现创建一个单独的自答问题对于您所做的任何此类实现来说都是一个更好的格式。我做了很多,尽管他们告诉你,我还没有失明你甚至可以链接到这个问题。有没有办法获取视频URL请给出使用示例。