31678


iOS側のRealmデータをApple Watchにデータ転送したいのですが、うまくいきません。

環境は以下の通りです。

  * Xcode 8.2.1
  * DevelopmentTarget：iOS 10.0 / watchOS 3.0
  * Realm / RealmSwift (2.1.2)

以下のリンクに記載されているような形式で実行してみましたが、iOS側とApple
Watch側とでは取得するURLが異なってしまい、Realmのデータが共有できないようでした。

<https://stackoverflow.com/questions/39644579/share-realm-data-with-watchos>  
<https://realm.io/news/tutorial-sharing-data-between-watchkit-and-your-app/>

**iOS側 / watchOS側**

[code]

    let directory : URL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: jp.co.example.app)!
    let realmPath : URL = directory.appendingPathComponent("default.realm")
    
    var config = Realm.Configuration()
    config.fileURL = realmPath
    let realm = try! Realm(configuration: config)
    
[/code]

調べてみると、以下の様な方法がありました。

<http://qiita.com/hsylife/items/986a47a173a4b8ad5672>

Realmのデータが置いてある箇所のデータをWCSessionで送るというものでした。

**iOS側**

[code]

    let directory : URL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: jp.co.example.app)!
    let realmPath : URL = directory.appendingPathComponent("default.realm")
    WCSession.default().transferFile(realmPath, metadata: nil)
    
[/code]

**watchOS側**

[code]

    func session(_ session: WCSession, didReceive file: WCSessionFile) {
        var config = Realm.Configuration()
        config.fileURL = file.fileURL
    
        let realm = try! Realm(configuration: config)
    }
    
[/code]

しかし、上記の場合だとiOS側からのURLが正常に送られていない(?)のか、Realmの取得するところでエラーとなってしまいます。  
（なぜかシミュレーターでは落ちずに正常に取得・Realmデータ共有出来ますが、実機だとエラーとなります）

いろいろと調べましたが、他の方法が見当たらずに困っています。  
わかる方がいらっしゃいましたら、ご教授いただけますでしょうか。

よろしくお願いいたします。


CC BY-SA 3.0
2017-01-06T03:12:41.667
31655
2017-01-06T16:39:00.590
2017-05-23T12:38:55.307
-1
20124
question
swift ios realm watchkit
Apple WatchにRealmのデータを転送できない


下記の記事はwatchOS 1.0の頃に書かれたものなので、watchOS 2.0以降では意図した挙動になりません。

<https://realm.io/news/tutorial-sharing-data-between-watchkit-and-your-app/>

watchOS
1.0ではWatchアプリはiPhoneデバイス上に存在し、iPhoneデバイス上で動作していました。つまり、本体iOSアプリとWatchアプリは同じiPhoneデバイスに存在していたので、AppGroupの共有コンテナを通じて同じファイルを読み書きすることができました。  
しかしながら、watchOS 2.0以降ではWatchアプリはApple Watch上に存在し、Apple
Watch上で動作するので、iPhone側の共有コンテナにファイルをおいてもWatchアプリからはアクセスすることができません。

こちらのStackOverflowの回答は、最初はwatchOS 1.0の場合について書かれていましたが、アップデートされて、watchOS
2.0でも動く方法が書かれています。そちらを参考にすれば動いたと思います。

<https://stackoverflow.com/questions/39644579/share-realm-data-with-watchos>

下記の記事は上記のアップデート後の内容と同等です。サンプルコードもあるので、まずはこちらを見るのが良いと思います。

<http://qiita.com/hsylife/items/986a47a173a4b8ad5672>

要するに、watchOS 2.0以降ではWatchアプリは物理的に別のデバイスで動作しているので、ファイルを共有するにはWatch
Connectivityを使ってファイルを送る必要があります。  
（もしくはRealm Mobile Platformの同期機能を利用するという手もあります。）

Watch
Connectivityで転送されたファイルは一旦システムが管理する特別なディレクトリに保存されます。そこでは、Realmが必要とする管理ファイルの作成が許可されていないため、読み取り専用でなければ、直接ファイルを開くことはできません。

次のように転送されたファイルを、Documentディレクトリなど書き込み可能な場所にコピーしてから開けばいいです。

[code]

    // When the file was received
    func session(_ session: WCSession, didReceive file: WCSessionFile) {
        //set the recieved file to default Realm file
        var config = Realm.Configuration()
    
        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        let documentsDirectory = paths[0]
        let realmURL = documentsDirectory.appendingPathComponent("data.realm")
        try! FileManager.default.copyItem(at: file.fileURL, to: realmURL)
    
        config.fileURL = realmURL
        Realm.Configuration.defaultConfiguration = config
    
        // display the first of realm objects
        let realm = try! Realm()
        if let firstField = realm.objects(Field.self).first{
            realmLabel.setText(firstField.text)
        }
    }
    
[/code]


CC BY-SA 3.0
2017-01-06T16:39:00.590
31678
2017-01-06T16:39:00.590
2017-05-23T12:38:55.250
-1
5519
31655
answer