AppGroupsでデータ共有


はじめに

AppGroupsでデータ共有 (準備編)の続きです。

AppGroupsを用いてアプリ間で文字列、画像の共有をしてみます。

UserDefaultsで文字列を共有

UserDefaults(suiteName:)を使用します。
suiteNameには、プロジェクトファイルのCapabilitiesで選択したAppGroupsのidentifierを設定します。

コードはこんな感じにしてみました。

AppGroupsManager.swift
class AppGroupsManager: NSObject {
    private static let groupID = "group.co.jp.foo"

    /// 保存するメッセージ、キーを指定してメッセージを保存
    class func saveMessage(message: String, key: String) {
        let userDefaults = UserDefaults(suiteName: groupID)
        userDefaults?.set(message, forKey: key)
    }

    /// キーを指定してメッセージを呼び出す
    class func loadMessage(key: String) -> String? {
        let userDefaults = UserDefaults(suiteName: groupID)
        return userDefaults?.object(forKey: key) as! String?
    }
}

同一のAppGroupにあるアプリ間で共有できます。

// アプリA側でメッセージを保存
let message = "bar"
AppGroupsManager.saveMessage(message: message, key: "sampleKey")

// アプリB側でメッセージを呼び出す
if let savedMessage = AppGroupsManager.loadMessage(key: "sampleKey") {
    debugPrint("\(savedMessage)") //"bar"
}

FileManagerで画像を共有

FileManager.default.containerURL(forSecurityApplicationGroupIdentifier:)を使用します。
こちらも、UserDefaultsと同様に
プロジェクトファイルのCapabilitiesで選択したAppGroupsのidentifierを設定します。

コードはこんな感じにしてみました。
(上記のsaveMessage, loadMessageも使用しています。)

AppGroupsManager.swift
class AppGroupsManager: NSObject {
    private static let groupID = "group.co.jp.foo"


    class func saveMessage(message: String, key: String) {
        let userDefaults = UserDefaults(suiteName: groupID)
        userDefaults?.set(message, forKey: key)
    }

    class func loadMessage(key: String) -> String? {
        let userDefaults = UserDefaults(suiteName: groupID)
        return userDefaults?.object(forKey: key) as! String?
    }


    /// 保存する画像、画像名、画像名用のキーを指定して画像を保存
    class func saveImage(imageData: Data, imageName: String, imageNameKey: String) {

        let fileManager = FileManager.default
        let url = fileManager.containerURL(forSecurityApplicationGroupIdentifier: groupID)
        if let url = url?.appendingPathComponent(imageName) {
            self.saveMessage(message: imageName, key: imageNameKey)
            try! imageData.write(to: url)
        }
    }

    /// 画像名用のキーを指定して画像を呼び出す
    class func loadImage(imageNameKey: String) -> UIImage? {
        if let savedImageName = AppGroupsManager.loadMessage(key: imageNameKey) {
            let fileManager = FileManager.default
            let url = fileManager.containerURL(forSecurityApplicationGroupIdentifier: groupID)
            if let url = url?.appendingPathComponent(savedImageName) {
                return UIImage.init(contentsOfFile: url.path)
            }
        }
        return nil
    }
}

こちらも同一のAppGroupにあるアプリ間で共有できます。

// アプリA側で画像を保存
let fileName = "test.png"
if let imageData = UIImagePNGRepresentation(image) {
    AppGroupsManager.saveImage(imageData: imageData, imageName: fileName, imageNameKey: "testImageName")
}

// アプリB側で画像を呼び出す
if let savedImage = AppGroupsManager.loadImage(imageNameKey: "testImageName") {
    // 呼び出した画像をImageViewにセットする
    imageView.image = savedImage
}

さいごに

AppGroupsの使い方を勉強しました。

アプリ間で共有のkeyを管理するのが大変そうだなーと思いました。