頭と尻尾はくれてやる!

iOSアプリなどの開発日記です


PHPickerViewControllerで動画ファイルを選択した後、Task内だと動かない

現在開発してるiOSアプリで、iPhoneのライブラリから動画ファイルを選択する処理を作ってた。
最近PHPickerControllerというのがあるみたいで試してたんだが、ユーザーに許可を得なくてもいいらしく、こりゃいいや!と試してたんだが、、、
PHPickerViewControllerDelegateのメソッドである
func picker(PHPickerViewController, didFinishPicking: [PHPickerResult])
でurl: URLを取得まではOK。その後続けて処理をしていくんだが、例えば動画が記録された日付を得るとする。

//上記メソッド内
let asset = AVURLAsset(url: url)
guard let creationDate = asset.creationDate?.value as? Date else { abort() }
print(creationDate)

↑これは意図通りに動く。
問題はasync/awaitを使うために以下のように書き換えた場合だ。

Task {
let asset = AVURLAsset(url: url)
guard let creationDate = asset.creationDate?.value as? Date else { abort() }
print(creationDate)
}

↑これだとabortで処理が止まる。urlは有効で、assetは一応できてるっぽい。
Task内の処理にtry await someFunction(…とかあるんだがそこまで辿り着かない。orz

困ったなあ、、、
試しにUIImagePickerController(PHPickerControllerが出る前はこれを使ってたよね)でやってみるとこれが動いたんだわ。
でもUIImagePickerControllerのUIってあまり好きじゃないしなあ。
ユーザーに許可を求める必要あるし(できればない方がいい)。
せっかく苦労してasync/await実装できたのに、元に戻してcompletionHandler使うか?うーん、、、

と思ってたところ試しに得たファイルをdocumentDirectoryにコピーしてから、それに対して処理をするようにしたらasync/await使ってても動いた!

めでたし、めでたし。

おおよそのコードはこんな感じ。
    @IBAction func tappedSelectVideoButton() {

var configuration = PHPickerConfiguration()
configuration.selectionLimit = 1//default
configuration.filter = .videos
configuration.preferredAssetRepresentationMode = .current

let pickerViewController = PHPickerViewController(configuration: configuration)
pickerViewController.delegate = self
self.present(pickerViewController, animated: true)
}

func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {

picker.dismiss(animated: true)

guard let provider = results.first?.itemProvider else { return }
guard let typeIdentifier = provider.registeredTypeIdentifiers.first else { return }

if provider.hasItemConformingToTypeIdentifier(typeIdentifier) {
provider.loadFileRepresentation(forTypeIdentifier: typeIdentifier) { [weak self] (url, error) in
if let url = url {
let copiedFileURL = self?.copyFile(url)//詳細略
assert(copiedFileURL != nil, "copiedFileURL is nil")

Task {
do {
let r = try await analyzer.start(copiedFileURL!)
print(r)
} catch {
//以下略

スポンサーサイト




<< マイクラのCycleButton.builderの最小実装  TopPage  iOSアプリが「バイナリが無効」でApp Store Connectにuploadできない >>

コメント


管理者にだけ表示を許可する
 

トラックバック

トラックバックURL
https://ringsbell.blog.fc2.com/tb.php/1373-abc4ac04




Copyright ©頭と尻尾はくれてやる!. Powered by FC2 Blog. Template by eriraha.