Подтвердить что ты не робот

Как получить URL-адрес ALAsset из PHAsset?

Вы можете сделать это sneakily † используя свойство недокументированное PHAsset.ALAssetURL, но я ищу что-то задокументированное.


† В Objective-C это поможет

@interface PHAsset (Sneaky)

@property (nonatomic, readonly) NSURL *ALAssetURL;

@end
4b9b3361

Ответ 1

Создайте assetURL, используя локальный идентификатор 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 в зависимости от ИМП актива (requestImageDataForAsset возвращает UTI), но в моем тестировании расширения objectURL, похоже, все равно игнорируются.

Ответ 2

Я хотел иметь возможность получить 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.)

Ответ 3

Вот рабочий код, протестированный на 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");
            }
        }];
    }];

Ответ 4

Читайте дно!

ResultHandler для PHImageManager.requestImage возвращает 2 объекта: результат и информация

Вы можете получить исходное имя файла для PHAsset (например, IMG_1043.JPG), а также его полный путь в файловой системе с помощью:

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

Это должно работать правильно, но по какой-то причине Apple все испортила. Таким образом, вы должны скопировать свое изображение в файл, затем получить доступ к нему, а затем удалить его.

PHImageFileURLKey можно использовать для получения исходного имени файла, но вы не можете получить к нему доступ. Вероятно, это связано с тем, что фоновый код может получить доступ к файлу, а другие приложения могут его удалить.

Подумайте, сколько времени вы потратили бы на то, чтобы понять это с тех пор, как Apple облажалась, а не просто документировали это. Может быть, это искренне, может быть, у них были разные разработчики, которые не понимали и не хотели работать. Здесь я работаю, а у Apple сколько сотен миллиардов в банке?

Да, извините, Apple, но я не согласен, когда у меня есть & lt; 500 долларов и чистая стоимость менее чем 1 года для 1700 абонентов, которые платят iCloud по 1 ТБ @10 долларов в месяц за работу в течение того же периода времени, что вы были возвращены из долгов (2001 → сейчас). Это был оригинальный iPhone, верно? Вы уверены, что обучаете их этим размерам данных, хотя не так ли, масштабируя месячные цены iCloud & lt; 1% от среднемесячного дохода США!

Ответ 5

Вот расширение PHAsset, написанное на Swift, которое будет извлекать 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)
                }
            })
        }
    }
}

Ответ 6

В соответствии с обсуждением holtmann && Clay Bridges, я сделал добавление ссылки следующим образом: Это предварительный ответ, но для экономии времени я снова отправлю его

UPVote Here ссылка

PHAsset *asset = self.allPhotos[indexPath.item];
    NSLog(@"this is local assets =%@",asset.localIdentifier);
    NSString *localStr=asset.localIdentifier;
    NSRange range = [localStr rangeOfString:@"/"];
    NSString *newString = [localStr substringToIndex:range.location];
    NSString *appendedString=[NSString stringWithFormat:@"%@%@%@",@"assets-library://asset/asset.JPG?id=",newString,@"&ext=JPG"];
    name=[NSURL URLWithString:appendedString];