UIActivityViewControllerで動画をシェアする

Xcode Version 12.5.1 

カメラロール内の動画をUIActivityViewControllerでシェアできるようにしました。
３日詰まりました。。

<img width="200" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758221/beb72086-374f-52d1-9213-5bcf428d0abb.png">

ImageはこんなかんじでactivityItemsにそのまま渡してやれば良いので、簡単です。

```swift
import SwiftUI
import PhotosUI //忘れずに

struct ImageShareSheet: UIViewControllerRepresentable {
    @State var image: UIImage
    
    func makeUIViewController(context: Context) -> UIActivityViewController {
        let text = "Image"
        let activityItems: [Any] = [image, text]
        let controller = UIActivityViewController(
            activityItems: activityItems,
            applicationActivities: nil)
        return controller
    }
    
    func updateUIViewController(_ vc: UIActivityViewController, context: Context) {
    }
}
```
問題は動画です。
動画はURLで渡すのですが、そのまま渡すと「サンドボックス拡張機能の発行に失敗しました」というようなエラーが出ました。
私は元ファイルのURLを@StateでStringで受けとって使用していましたが、なんだろう、揮発するのかな？上手くいきませんでした。
正確に言うと、AirDropとMessageアプリでは送れるのに、メールやLINEで送れませんでした。（写真は送れたけど動画が送れず）


元になるPHAssetファイルのURLをstruct MovieShareSheet内で改めて取得し、fileManager.copyItemでTempディレクトリにコピーしてから、コピーしたファイルに対して操作を実行することで、うまく行くようになりました。やったー！

```swift
struct MovieShareSheet: UIViewControllerRepresentable {
    @State var photo: PHAsset
    
    func makeURLandCopy() -> URL {
        let fileURL = photo.getURL(ofPhotoWith: photo)
        print("fileURL(元): \(String(describing: fileURL))")
        let temporaryDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
        let temporaryFileURL = temporaryDirectoryURL.appendingPathComponent(fileURL!.lastPathComponent)
        print("temporaryFileURL（コピー先）:\(temporaryFileURL)")
        copyToTmp(fileURL: fileURL!, temporaryFileURL: temporaryFileURL)
        return temporaryFileURL
    }
    
    func copyToTmp(fileURL: URL, temporaryFileURL: URL){
        let fileManager = FileManager.default
        do{try fileManager.copyItem(at: fileURL, to: temporaryFileURL)}
        catch{}
        return
    }
    
    
    func makeUIViewController(context: Context) -> UIActivityViewController {
        let fileURL = makeURLandCopy()
        let activityItems: [Any] = [fileURL]
        let controller = UIActivityViewController(
            activityItems: activityItems,
            applicationActivities: nil)
        return controller
    }
    
    func updateUIViewController(_ vc: UIActivityViewController, context: Context) {
    }
}

extension PHAsset{
    func getURL(ofPhotoWith mPhasset: PHAsset) -> URL?{
        var url = URL(string:"test")
        let semaphore = DispatchSemaphore(value: 0)
        let options=PHVideoRequestOptions()
        
        options.version = .current
        options.isNetworkAccessAllowed = true
        PHImageManager.default().requestAVAsset(forVideo: mPhasset,                                                 options: options)
        {(asset:AVAsset?,audioMix, info:[AnyHashable:Any]?) -> Void in
            
            if let urlAsset = asset as? AVURLAsset{
                let localURL = urlAsset.url as URL
                url = localURL
                print(url!)
            }else{
                print("url asset nil")
            }
            do   {semaphore.signal() }
        }
        if semaphore.wait(timeout: DispatchTime.distantFuture) == .success {
            print("url success")
            return url!
        }else{
            print("url timeout")
            return url!
        }
    }

}


```

（Tmpファイルは自分で消さなくて大丈夫なのかな…？気になっています）
お役に立てれば幸いです！
もっと良い美しい方法があればぜひご教示ください！

参考
https://try2explore.com/questions/12413739
https://stackoverflow.com/questions/57798968/didfinishpickingmediawithinfo-returns-different-url-in-ios-13