WatchKitでiPhone Appとデータ共有する方法

  • 73
    Like
  • 2
    Comment
More than 1 year has passed since last update.

App Groupsを使います。

App GroupsはiOS8から追加されてApp Extensionでだいたい利用しますが、
WatchKitでも使えます。

事前準備

App Groupの登録

App Groupsを使うには事前にiOS Dev Centerで登録が必要です。

Certificates, Identifiers & Profiles > iOS Apps > Identifiers > App Groups

こちらで、App Groupの情報(App Groups Description / Identifier)を登録します。

今回の例ではIdentifierに"group.com.hoge.example"と指定したことにします。

プロジェクトの設定

App Groupsを使うことをプロジェクトに設定します。

Project > Capabilities > App GroupsをONにします。

先ほど登録したIdentifierが表示されるのでチェックします。
これをiPhone App / Watch Appの両方に対して行います。

NSUserDefaultsを使う

NSUserDefaults(suiteName:)に先ほどのIdentifierを指定します。

// 設定
var def = NSUserDefaults(suiteName: "group.com.hoge.example")
def?.setObject(123, forKey: "score")
// 取得
var def = NSUserDefaults(suiteName: "group.com.hoge.example")
let score = def?.objectForKey("score") as? Int

設定をiPhone App側、取得をWatch App(Watch Extension)側に書けば、
iPhone Appで設定した値をWatch Appで取り出せます。

逆にすればWatch Appで設定した値をiPhone Appで取り出せます。

ファイルを使う

// 設定
let fileManager = NSFileManager.defaultManager()
if let path = fileManager.containerURLForSecurityApplicationGroupIdentifier("group.com.hoge.example")?.URLByAppendingPathComponent("score.txt").path {
    // ファイルが無かったら作る
    if fileManager.fileExistsAtPath(path) == false {
        fileManager.createFileAtPath(path, contents: nil, attributes: nil)
    }

    // 書き込み
    if var fileHandle = NSFileHandle(forWritingAtPath: path) {
        var score = NSInteger(123)
        var data = NSData(bytes: &score, length: sizeof(NSInteger))
        fileHandle.writeData(data)
    }
}
// 取得
if let path = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier("group.com.hoge.example")?.URLByAppendingPathComponent("score.txt").path {
    var fileHandle = NSFileHandle(forReadingAtPath: path)
    if let data = fileHandle?.readDataOfLength(sizeof(NSInteger)) {
        var score : NSInteger = 0
        data.getBytes(&score, length: sizeof(NSInteger))
        println(score)
    }
}

CoreDataを使う

Stack Overflowにわかりやすい回答があるのでそちらが参考になります。

How to access CoreData model in today extension (iOS) -StackOverflow

まとめ

App Groupsに対応しておくとApp Extension対応だけじゃなくWatch App対応も捗る。

参考:
WatchKit app Architecture > Sharing Data with Your Containing iOS App -Apple Watch Programming Guide
How to access CoreData model in today extension (iOS) -StackOverflow

P.S.

データ共有の次はコードも共有したくなります。
そんな時はEmbedded Frameworkを作成することになります。

手順はApp Extensionで行う場合と変わらないので
Developers.IOに掲載されてる記事が参考になります。

[iOS 8] App Extension #2 – Embedded Framework を利用して共有コードを Framework 化する