【新サービス告知】いつでもどこでもイベントを開催できる。スマホのWebカメラを利用したVRイベントスペースサービス(Meetatcube.com)
↑クリックして拡大
↑クリックして拡大
↑クリックして拡大
↑クリックして拡大

頭痛が減ったので共有です!

rebuild.fmを応援しています!

HOME > AppleWatchをNSFileCoordinatorとKeychainでデータ交換

AppleWatchをNSFileCoordinatorとKeychainでデータ交換

サンプル画像

前回の記事(ナターシャさんのサンプルデモを元に解説)の続きです。今記事はNSUserDefaultではなく、 NSFileCoordinatorとKeychain sharingを利用しての解説です。ナターシャさんのサンプルに関して前記事をご参照ください。

やってみた (NSFileCoordinator)

サンプル画像

NSUserDefaultとほぼ同じでAppGroupを利用します。(※AppGroupはそれぞれ環境に応じて設定してください。詳細は前記事をご確認ください)

↓ アプリ本体のソースです


import UIKit

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let fileCoordinator = NSFileCoordinator()
        let groupURL = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier("group.com.okko.demoAppExtensions")
        let fileURL = groupURL?.URLByAppendingPathComponent("testData.bin")
        fileCoordinator.coordinateWritingItemAtURL(fileURL!, options: nil, error: nil)
            { [unowned self] (newURL) -> Void in
                let saveData = "hogehoge"
                let dataToSave = NSKeyedArchiver.archivedDataWithRootObject(saveData)
                let ret = dataToSave.writeToURL(newURL, atomically: true)
                println(ret);//true
        }>
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

App Groupを設定して指定アプリURLにtestData.binのバイナリデータを書き込んでいます。NSUserDefaultと使い方はほぼ同じです。 使い分けとしてはNSFileCoordinatorはバイナリデータを書き込むので大きなファイルやキャッシュが必要な頻繁にアクセスするファイルを保存する場合に 利用する等、用途に応じてNSUserDefaultと使い分けすると良いのではと思います。(参考サイト:NSUserDefaults、ファイル、データベース、どれで保存するか)

↓ AppleWatch側のソースです


import WatchKit
import Foundation

class InterfaceController: WKInterfaceController {
    
    override func awakeWithContext(context: AnyObject?) {
        super.awakeWithContext(context)
        
        let fileCoordinator = NSFileCoordinator()
        let groupURL = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier("group.com.okko.demoAppExtensions")
        let fileURL = groupURL?.URLByAppendingPathComponent("testData.bin")
        fileCoordinator.coordinateReadingItemAtURL(fileURL!, options: nil, error: nil)
            { [unowned self] (newURL) -> Void in
                if let savedData = NSData(contentsOfURL: newURL) {
                     println(NSKeyedUnarchiver.unarchiveObjectWithData(savedData) as String)//Optional(hogehoge)
                }
        }
    }

    override func willActivate() {
        // This method is called when watch view controller is about to be visible to user
        super.willActivate()
    }

    override func didDeactivate() {
        // This method is called when watch view controller is no longer visible
        super.didDeactivate()
    }
}

受け取り時に上記サンプルではNSKeyedUnarchiverをString型で解凍していますが、 この箇所を画像等それぞれ切り替えてデータを受け取ってください。

(※データがアプリ本体側で変更されたイベントをWatch側で受け止めるにはNSFilePresenterNSOperationQueueを利用します。)

やってみた(Key Chain)

サンプル画像

アプリ端末とAppleWatch間のデータ送受信はBluetooth通信なので解読される可能出てきます。 セキュリティを向上させるためAPP側で暗号、AppleWatch側で複合する為にこのKeychain sharingを利用します。こちはNSUserDefault、NSFileCoordinatorと 違います。ナターシャさんのデモサンプルを触るとわかりやすいのでオススメです。以下、気づいた箇所とソースを抜粋します。

サンプル画像

TargetのCapabilityではAppGroupsを利用しません。代わりにKeychain Sharingを利用します。

↓ App側のソースです



import UIKit
import SharedDataLayer

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let username = "Swift-Salaryman"
        let password = "higegakoi"
        let keychainItem = KeychainItemWrapper(identifier: "SharingViaKeychain", accessGroup: "com.okko.SharingViaKeychain")
        keychainItem.setObject(username, forKey: kSecAttrAccount)
        keychainItem.setObject(password, forKey: kSecValueData)
    }
}

KeychainItemWrapperを利用して暗号化させます


↓ AppleWatch側のソースです


import WatchKit
import SharedDataLayer

class InterfaceController: WKInterfaceController {
    
    override func awakeWithContext(context: AnyObject?) {
        super.awakeWithContext(context)
        
        let keychainItem = KeychainItemWrapper(identifier: "SharingViaKeychain", accessGroup: "com.okko.SharingViaKeychain")
        let passwordData = keychainItem.objectForKey(kSecValueData) as NSData
        let password = NSString(data: passwordData, encoding: NSUTF8StringEncoding)
        let username = keychainItem.objectForKey(kSecAttrAccount) as? String
        println(""\(username):\(password))//Swift-Salaryman:higeganagai
    }
}

KeychainItemWrapperを利用して複合化させます。さて、KeychaninItemWrapperとはなんでしょうか? こちらはAppleから提供されているようでObjective-Cで記載されているライブラリ。 ブリッジヘッダによってObjCとSwiftを共存させます(共存方法はこちらをご参照ください。) ナターシャさんはSharedDataLayer.hを自作されてKeychainItemWrapperを利用されていました。

サンプル画像

このライブラリの説明をすると別の記事になってしまうのでここまでにします。

まとめ

Keychain Sharingの説明はなんだか中途半端で失礼しております、、、。ナターシャさんのデモ(on Github)を動作させるのが一番わかりやすいのでオススメです! 何かこの記事がお役にたてていれば感謝です。

前の記事はこちらからです!

次の記事はこちらからです!

↓こんな記事もありますよ!


2021-04-22 14:54:53

かっこいいカルーセル厳選3点!WebGLを使った渋い画像スライダー。

昨日カッコいいスライダーを探す旅にでていました。 よく使われるswiper など、シンプルで使いやすくデザインも良いのですが、何かもの足りない、、、。 そこで調べていくと、webglを使...

2021-04-20 14:46:43

Twillioとは何??skywayとは何が違うのか。webrtcを使う際に判断する情報。

先日webrtc開発で「twillio」といった名前を聞きました。 以前自分でskywayを使ってwebrtcを試していた際に調べた時には、無かったような気もするんだけと、KDDIが絡んでいる...

2021-04-19 13:58:21

先日久々にアップデートした妊娠週刊パパのAndroid版も。アカウント移管したいんだけど、注文ID見当たらないよ。

先日の妊娠、出産、育児関連のアプリ「妊娠週刊パパ」をAndroid studioで再リリースしようと思ってるんだけど、コンパイル失敗してエミュレータで動かせない。 多分sdkとかapiのバージ...
このエントリーをはてなブックマークに追加
右側のFacebookのLikeをクリック頂けると記事更新の際に通知されますので宜しければご利用下さい!