広告

iPhone にダウンロードした MP4 ビデオファイルを WatchConnectivity で Apple Watch に転送し、そして見る

!!! 半年以上も前に書かれた古い情報です !!!
!!! 半年以上も前に書かれた古い情報です !!!
!!! 半年以上も前に書かれた古い情報です !!!
!!! 半年以上も前に書かれた古い情報です !!!
!!! 半年以上も前に書かれた古い情報です !!!

WatchOS 2 以降、Apple Watch で MP4 のビデオファイルが再生できるのは既に確かめていたのですが・・・、

iPhone でダウンロードしたビデオを Watch Connectivity で Apple Watch に転送して見る件
https://hirooka.pro/?p=8477

基本的な部分は変わりはないのですが、どうも iOS 11 では WatchConnectivity で iPhone から Apple Watch にビデオファイルを転送する部分の仕様が若干変更された?と思わしき現象が。実は iOS 11 ベータの頃から発生していて、バグ?と思っていたのですが、リリース版でも変わらずでした。

Apple Developer Forums でも同じ内容で悩んでいる投稿がありました。

iOS11 / watchOS4 cannot transfer images anymore (WCErrorCodeFileAccessDenied)
https://forums.developer.apple.com/thread/85406

今までは iPhone 側の ViewController にてビデオファイルをダウンロードし、App Groups の領域に watch.m4v として保存し、WCSession.default().transferFile… で Apple Watch に転送していました。しかし、iOS 11 では WCErrorCodeFileAccessDenied になってしまいます。回避策としては、ビデオファイルを Temporary フォルダに移した上で転送します。

func completeDownloading() {
        
        let savedFile = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.pro.hirooka.mogmog")?.appendingPathComponent("watch.m4v")
        
        let tempDirURL = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("watch.m4v")
        let manager = FileManager()
        do {
            try manager.removeItem(at: tempDirURL!)
        } catch let error {
            
        }
        do {
            try FileManager.default.copyItem(at: savedFile!, to: tempDirURL!)
        } catch let error {
            NSLog("Unable to copy file: \(error)")
        }
        if FileManager.default.fileExists(atPath: (tempDirURL?.path)!) {
            print("trasfer ---> ")
            WCSession.default().transferFile(tempDirURL!, metadata: ["key" : "value"])
        }
    }

Apple Watch 側の InterfaceController では、受信したファイルを App Groups の領域に違うファイル名 watch_playback.m4v として保存し、WKInterfaceMovie にビデオファイルの URL をセットすることでビデオファイルの再生を行います。

ただ、果たしてこれが正しいビデオファイルの転送と再生のやり方なのか分からず・・・。WatchConnectivity でビデオファイルを転送して Apple Watch の小さな画面で動画を見ようなんて人は世界にもいないのか、と。

func session(_ session: WCSession,
                   didReceive file: WCSessionFile){
        
        print(file.fileURL.absoluteString)

        let sharedContainer = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.pro.hirooka.mogmog")
        let sharedFile = sharedContainer?.appendingPathComponent("watch_playback.m4v")
        do{
            if FileManager.default.fileExists(atPath: (sharedFile?.path)!) {
                print("file exists")
            }
            try FileManager.default.removeItem(at: sharedFile!)
        }catch{
            
        }
        
        do {
            try FileManager.default.copyItem(at: file.fileURL, to: sharedFile!) // TODO: copy or move ?
            print("\(file.fileURL.absoluteString) ---> \(sharedFile?.absoluteString ?? "")")
            let savedFile = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.pro.hirooka.chukasa-ios")?.appendingPathComponent("watch_playback.m4v")
            
            let fileAttributes = try FileManager.default.attributesOfItem(atPath: (savedFile?.path)!)
            let fileSize = fileAttributes[FileAttributeKey.size]
            print(fileSize ?? 0)
            
            DispatchQueue.main.async(execute: {
                self.movie.setMovieURL((savedFile?.absoluteURL)!)
                self.label.setText("Ready!")
                WKInterfaceDevice().play(.notification)
            })
            
        }catch{
            print("fail to move item")
        }
    }

広告

Apple Watch

Posted by admin