Вы можете сделать это sneakily † используя свойство недокументированное PHAsset.ALAssetURL
, но я ищу что-то задокументированное.
† В Objective-C это поможет
@interface PHAsset (Sneaky)
@property (nonatomic, readonly) NSURL *ALAssetURL;
@end
Вы можете сделать это sneakily † используя свойство недокументированное PHAsset.ALAssetURL
, но я ищу что-то задокументированное.
† В Objective-C это поможет
@interface PHAsset (Sneaky)
@property (nonatomic, readonly) NSURL *ALAssetURL;
@end
Создайте 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, похоже, все равно игнорируются.
Я хотел иметь возможность получить 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 для 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% от среднемесячного дохода США!
Вот расширение 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)
}
})
}
}
}
В соответствии с обсуждением 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];