Как мне получить имя файла изображения из UIImagePickerController - PullRequest
0 голосов
/ 17 июня 2020

Я пытаюсь получить имя файла из ссылки PHAsset, предоставленной UIImagePickerController. Как мне получить имя файла изображения при выборе из библиотеки и сделать снимок с помощью камеры?

Я использую Xcode 11.4 и Swift 5.

Ответы [ 2 ]

0 голосов
/ 18 июня 2020

Учитывая, что у вас уже есть объект PHAsset, PHAssetResource - это то, что вам нужно, чтобы получить имя файла.

let assetResources = PHAssetResource.assetResources(for: asset)

Это вернет вам массив из PHAssetResource экземпляров, среди которых одно из них - текущее изображение.

Просматривая экземпляры PHAssetResource в отладчике, вы можете увидеть, что он содержит несколько файлов. Это может включать данные настройки, представленные .plist, и одну или несколько фотографий.

Чтобы получить файл, который в данный момент доступен, вам нужно найти ключ isCurrent. Apple не предоставила этот ключ как переменную для PHAssetResource, однако они не прилагают никаких усилий, чтобы скрыть значение. И я предполагаю, что запрос этого значения не приводит к отклонению приложения.

Вы можете запросить это значение напрямую или сделать это более аккуратно, расширив PHAssetResource.

extension PHAssetResource {
    var isCurrent: Bool? {
        self.value(forKey: "isCurrent") as? Bool
    }
}

Теперь, вы можете задать [PHAssetResource], для первого элемента, который isCurrent, а также фото или видео.

let resourceTypes: [PHAssetResourceType] = [.photo, .video, .audio, .fullSizePhoto]
let currentAssetResource = assetResources.first(
   where: { $0.isCurrent == true && resourceTypes.contains($0.type)
})

И, наконец, имя файла.

let fileName = currentAssetResource?.originalFilename

Примечание

PhotoKit ожидает, что разработчик будет работать с абстрактным ресурсом актива, а не с базовыми файлами или данными. Использование isCurrent кажется разрешенным. Однако это значение можно изменить или удалить с помощью обновления iOS. Делайте это только в том случае, если у вас есть надежный пример использования для извлечения имени файла.

0 голосов
/ 17 июня 2020

Существует два подхода:

  1. Вы можете получить URL-адрес временного файла, который UIImagePickerController создает для вас, используя info[.imageURL]. Если вам нужно, например, только расширение ресурса, этого достаточно.

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
    
        // url of temporary file provided by image picker
    
        if let url = info[.imageURL] as? URL {
            print("temp URL", url)                         // file:///private/var/mobile/Containers/Data/Application/.../tmp/FAC0D82B-85A9-4C7A-B69C-58BB53F74CDC.jpeg
        }
    
        dismiss(animated: true)
    }
    

    Но само имя файла не имеет отношения к исходному активу.

  2. Вы можете получить исходный URL ресурса из структуры Photos. Раньше мы могли использовать PHImageManager, вызывать requestImageDataForAsset, а затем использовать "PHImageFileURLKey" в итоговом информационном словаре, но это больше не работает.

    Но как предлагается в другом месте , вы можете asset.requestContentEditingInput, включая URL-адрес ресурса:

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
    
        // url of the original asset
    
        if let asset = info[.phAsset] as? PHAsset {
            asset.requestContentEditingInput(with: nil) { input, info in
                if let fileURL = input?.fullSizeImageURL {
                    print("original URL", fileURL)         // file:///var/mobile/Media/DCIM/100APPLE/IMG_0135.HEIC
                }
            }
        }
    
        dismiss(animated: true)
    }
    

    Если вы это сделаете, вам, очевидно, потребуется запросить разрешения для библиотеки фотографий, в частности:

    if PHPhotoLibrary.authorizationStatus() == .notDetermined {
        PHPhotoLibrary.requestAuthorization { granted in
            print(granted)
        }
    }
    

    И вам нужно указать строку использования NSPhotoLibraryUsageDescription в вашем Info.plist.

    Лично мне кажется неправильным запрашивать ввод для редактирования содержимого, когда вам действительно не нужно редактировать, но, НАВЕРНУТЬСЯ, в настоящее время это единственный способ получить исходное имя актива. (Должен быть способ получше: если вы просматриваете PHAsset в отладчике, имя актива фактически скрыто там, но не отображается ... возможно, они сделали это, чтобы избежать путаницы с расширением HEIC.)

Итог, это просто зависит от того, для чего вам нужно имя. Если вам просто нужен путь к временному файлу, используйте .imageURL. Если вам нужна информация об исходном активе, используйте .phAsset и фреймворк Photos / PhotoKit .

...