Keychain Access GroupとTeam ID
iOSのKeychainを使えば、同じTeam ID(AppIdentifierPrefix)を持つアプリ間でアカウント情報を共有したりできますね。それについては、例えば、以下のサイトが詳しいです。
[iOS] 複数アプリケーション間でのデータ共有 〜 Keychain Services を使った第三の方法 - Cocoaの日々
ここで問題になるのが、Keychain Access Groupの名前です。
デフォルトのAccess Group以外のグループを使おうとすると、Access Group名として、Team IDを含んだ文字列を kSecAttrAccessGroup
に指定する必要があります。
[attributes setObject:@"GFDZH8PXXX.share" forKey:(id)kSecAttrAccessGroup];
別に気にせず、Team IDまでを含めた文字列をソースコードに書けばそれでいいわけですが、
- ロジックを書くべきソースコードに、ビルド時のProvisioning Profileによって変化するTeam IDを入れてしまうのが生理的にイヤ
- ストア申請用ビルドと、社内利用のためのEnterprise(In-House)ビルドの両方をビルドするので、ビルドによってTeam IDが変わる
- 最終的に顧客のアプリを開発するのだが、開発中は自社で契約しているTeamを使っている
- オープンソースなので特定のTeam IDに依存させたくない
などの理由で、ソースコード中にTeam IDを含めたくないことがあります。
これで解決
Info.plist ファイルにアプリ独自の情報を埋めておけば、プログラムでそれを読み出すことができます。その情報を含める際に $(AppIdentifierPrefix)
と書けば、ビルド時にその部分はTeam ID + .
に置き換えられます。
つまり、Info.plist ファイルをOpen As→Source Codeで開いて、
<key>AppIdentifierPrefix</key>
<string>$(AppIdentifierPrefix)</string>
というような記述をしておけば、プログラムで次のようにして、Team IDを取得することができます。
NSString *appIdentifierPrefix =
[[NSBundle mainBundle] objectForInfoDictionaryKey:@"AppIdentifierPrefix"];
ここで得た appIdentifierPrefix
には最後にピリオド .
が付いていることにだけ注意が必要です。
または、
<key>SharedAccessGroup</key>
<string>$(AppIdentifierPrefix)share</string>
のような感じで、あらかじめAccess Group名そのものを Info.plist から取得するように記述しておいてもいいでしょう。
実はこのネタ‥‥
以前、Stack Overflowに解答として投稿したものです。
Access App Identifier Prefix programmatically - Stack Overflow
質問自体は古くて、ちょっと無理やり感のある解答が付いていたんですが、そっちはぼくにとって気に入った方法じゃなかったので、別の方法もあるよ、という気分で解答したのです。すると、どうも、古い解答のやり方はiOS 8で使えなくなっていたらしく、こちらの方法も徐々にVoteされ始め、気分がよくなったので、もとい、需要があるんだなあと思ったので、Qiitaにも共有してみました。