ndocumentedPHAsset.ALAssetURL
プロパティを使用してこっそり†できますが、文書化されているものを探しています。
†Objective-Cでは、これが役立ちます
@interface PHAsset (Sneaky)
@property (nonatomic, readonly) NSURL *ALAssetURL;
@end
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によっては、拡張子JPG
を変更する場合があります(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");
}
}];
}];
URLを取得するSwiftで記述されたPHAsset拡張機能を次に示します。
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)
}
})
}
}
}
下を読んでください!
PHImageManager.requestImageのresultHandlerは2つのオブジェクトを返します:結果と情報
PHAssetの元のファイル名(IMG_1043.JPGなど)と、次のようにしてファイルシステム上のフルパスを取得できます。
let url = info?["PHImageFileURLKey"] as! URL
これは正常に機能するはずですが、何らかの理由でAppleめちゃくちゃになっています。したがって、基本的には、イメージをファイルにコピーしてからアクセスし、削除する必要があります。
PHImageFileURLKeyを使用して元のファイル名を取得できますが、実際にはそのファイルにアクセスできません。他のアプリがファイルを削除できる一方で、バックグラウンドのコードがファイルにアクセスできるという事実に関係しています。
Apple文書化するのではなく、めちゃくちゃになっているので、それを理解するのにどれだけの時間を費やすかを考えてください。多分それは誠実かもしれません。多分彼らは理解していないし、したくない別の開発者がいたことかもしれません。ここで私は働いていますが、Appleは銀行に何千億ドルも持っていますか?
そうです、申し訳ありませんAppleしかし、私が500ドル未満で、1700人の加入者が1TBのiCloudに対して月額$ 10を払って1年未満の純資産を持っている場合は、同じことに同意しません借金から復活した期間(2001年->現在)それはオリジナルのiPhoneでしたか?確かにそれらのデータサイズを教えて、iCloudの月額料金を米国の平均の1%未満にスケーリングしています月収!