PHPickerViewControllerで動画ファイルを選択した後、Task内だと動かない
現在開発してるiOSアプリで、iPhoneのライブラリから動画ファイルを選択する処理を作ってた。
最近PHPickerControllerというのがあるみたいで試してたんだが、ユーザーに許可を得なくてもいいらしく、こりゃいいや!と試してたんだが、、、
PHPickerViewControllerDelegateのメソッドである
func picker(PHPickerViewController, didFinishPicking: [PHPickerResult])
でurl: URLを取得まではOK。その後続けて処理をしていくんだが、例えば動画が記録された日付を得るとする。
↑これは意図通りに動く。
問題はasync/awaitを使うために以下のように書き換えた場合だ。
↑これだとabortで処理が止まる。urlは有効で、assetは一応できてるっぽい。
Task内の処理にtry await someFunction(…とかあるんだがそこまで辿り着かない。orz
困ったなあ、、、
試しにUIImagePickerController(PHPickerControllerが出る前はこれを使ってたよね)でやってみるとこれが動いたんだわ。
でもUIImagePickerControllerのUIってあまり好きじゃないしなあ。
ユーザーに許可を求める必要あるし(できればない方がいい)。
せっかく苦労してasync/await実装できたのに、元に戻してcompletionHandler使うか?うーん、、、
と思ってたところ試しに得たファイルをdocumentDirectoryにコピーしてから、それに対して処理をするようにしたらasync/await使ってても動いた!
めでたし、めでたし。
おおよそのコードはこんな感じ。
最近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
https://ringsbell.blog.fc2.com/tb.php/1373-abc4ac04