ios 钥匙串组访问以在我现有的应用程序之间共享数据
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11793271/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Keychain group access to share data between my existing applications
提问by msk
I have many iOS applications live on AppStore. Now for next version of apps, I want to keep a piece of data for every application to share in KeyChain. As far as I know I need to provide same Keychain access group in Apple's KeychainItemWrapper class.
我在 AppStore 上有很多 iOS 应用程序。现在对于下一个版本的应用程序,我想为每个应用程序保留一段数据以在 KeyChain 中共享。据我所知,我需要在 Apple 的 KeychainItemWrapper 类中提供相同的 Keychain 访问组。
*keychain = [[KeychainItemWrapper alloc] initWithIdentifier:@"Any string" accessGroup:<string representing access group>];
I know about custom URLs and it is of no use as I want data to be persistent.
我知道自定义 URL,它没有用,因为我希望数据是持久的。
All my applications have different bundle seed ID as I can see from provisioning portal. I know that the main pre-requisite for shared keychain access is that all of the applications have a common bundle seed ID.
正如我从配置门户看到的那样,我的所有应用程序都有不同的捆绑种子 ID。我知道共享钥匙串访问的主要先决条件是所有应用程序都有一个公共包种子 ID。
Now my question is how do I make sure that in this senario I can use Keychain to share data among all these applications ?
现在我的问题是如何确保在这个场景中我可以使用 Keychain 在所有这些应用程序之间共享数据?
Is it possible to change the bundle seed ID of all applications through Provisioning profile portal without doing any harm to any functionality ( Although I want to avoid that as there are so many apps).
是否可以通过配置配置文件门户更改所有应用程序的捆绑种子 ID 而不会对任何功能造成任何损害(尽管我想避免这种情况,因为应用程序太多)。
Is there a way I can add bundle seed ID of all apps in a file and build all apps with that file in project to achieve this ? I know about "keychain-access-groups", do i need to create a plist file and add bundle seed ID of all application in it ?
有没有办法可以在文件中添加所有应用程序的捆绑种子 ID,并在项目中使用该文件构建所有应用程序以实现这一目标?我知道“钥匙串访问组”,我是否需要创建一个 plist 文件并在其中添加所有应用程序的捆绑种子 ID?
Appreciate any help in this regard.
感谢这方面的任何帮助。
回答by Constantino Tsarouhas
If you have different bundle seed IDs(the ten alphanumeric characters preceding the bundle identifier, the Xs in XXXXXXXXXX.com.company.application
), you can'tshare an access group. It's a restriction on Apple's part and circumventing it is not allowed. I suggest you find another solution of safely sharing data (possibly outside of the device, on a server, but not iCloud as it has the same restrictions).
如果您有不同的捆绑种子 ID(捆绑标识符前的十个字母数字字符, 中的 X XXXXXXXXXX.com.company.application
),则不能共享访问组。这是 Apple 方面的限制,不允许规避。我建议您找到另一种安全共享数据的解决方案(可能在设备外部,在服务器上,但不是 iCloud,因为它具有相同的限制)。
General information about keychain access groups:
关于钥匙串访问组的一般信息:
Since iPhone OS 3.0 it has been possible to share data between a family of applications. This can provide a better user experience if you follow the common path of free/premium applications or if you have a set of related applications that need to share some common account settings.
The main pre-requisite for shared keychain access is that all of the applications have a common bundle seed ID. To be clear what this means remember that an App ID consists of two parts:
<Bundle Seed ID> . <Bundle Identifier>
The bundle seed ID is a unique (within the App Store) ten character string that is generated by Apple when you first create an App ID. The bundle identifier is generally set to be a reverse domain name string identifying your app (e.g.
com.yourcompany.appName
) and is what you specify in the application Info.plist file in Xcode.So when you want to create an app that can share keychain access with an existing app you need to make sure that you use the bundle seed ID of the existing app. You do this when you create the new App ID in the iPhone Provisioning Portal. Instead of generating a new value you select the existing value from the list of all your previous bundle seed IDs.
One caveat, whilst you can create a provisioning profile with a wildcard for the bundle identifier I have never been able to get shared keychain access working between apps using it. It works fine with fully specified (no wildcard) identifiers. Since a number of other Apple services such as push notifications and in-app purchase also have this restriction maybe it should not be a surprise but I am yet to find this documented for keychain access.
Once you have your provisioning profiles setup with a common bundle seed ID the rest is pretty easy. The first thing you need to do is register the keychain access group you want to use. The keychain access group can be named pretty much anything you want as long as it starts with the bundle seed ID. So for example if I have two applications as follows:
ABC1234DEF.com.useyourloaf.amazingApp1 ABC1234DEF.com.useyourloaf.amazingApp2
I could define a common keychain access group as follows:
ABC1234DEF.amazingAppFamily
To enable the application to access this group you need to add an entitlements plist file to the project using xCode. Use Add -> New File and select the Entitlements template from the iPhone OS Code Signing section. You can name the file anything you like (e.g.
KeychainAccessGroups.plist
). In the file add a new array item named keychain-access-groups and create an item in the array with the value of our chosen keychain access group:Note: Do not change the get-task-allow item that is created by default in the entitlements file unless you are creating an Ad-Hoc distribution of your app (in which case you should uncheck this option).
This same process should be repeated for all apps that share the bundle seed ID to enable them to access the keychain group. To actually store and retrieve values from this group requires adding an additional value to the dictionary passed as an argument to the keychain services. Using the example from the previous post on simple iPhone keychain access the search dictionary gets the following additional item:
[searchDictionary setObject: @"ABC1234DEF.amazingAppFamily" forKey: (id)kSecAttrAccessGroup];
One final comment, using a shared keychain access group does not stop you from storing values in an applications private keychain as well. The Apple GenericKeychain example application builds two applications which both store data in a private and group keychain.
从 iPhone OS 3.0 开始,可以在一系列应用程序之间共享数据。如果您遵循免费/高级应用程序的通用路径,或者如果您有一组需要共享一些通用帐户设置的相关应用程序,这可以提供更好的用户体验。
共享钥匙串访问的主要先决条件是所有应用程序都有一个公共包种子 ID。要清楚这意味着什么,请记住 App ID 由两部分组成:
<Bundle Seed ID> . <Bundle Identifier>
捆绑种子 ID 是 Apple 在您第一次创建 App ID 时生成的唯一(在 App Store 内)十个字符的字符串。捆绑标识符通常设置为标识您的应用程序的反向域名字符串(例如
com.yourcompany.appName
),并且是您在 Xcode 的应用程序 Info.plist 文件中指定的内容。因此,当您想要创建一个可以与现有应用程序共享钥匙串访问权限的应用程序时,您需要确保使用现有应用程序的捆绑种子 ID。您在 iPhone Provisioning Portal 中创建新的 App ID 时执行此操作。您不是生成新值,而是从所有先前捆绑种子 ID 的列表中选择现有值。
一个警告,虽然您可以使用捆绑标识符的通配符创建配置文件,但我从未能够在使用它的应用程序之间获得共享钥匙串访问。它适用于完全指定的(无通配符)标识符。由于许多其他 Apple 服务(例如推送通知和应用内购买)也有此限制,因此这可能不足为奇,但我还没有找到有关钥匙串访问的文档。
一旦您使用公共包种子 ID 设置了配置文件,剩下的就很简单了。您需要做的第一件事是注册您要使用的钥匙串访问组。只要以捆绑种子 ID 开头,钥匙串访问组几乎可以命名为您想要的任何名称。例如,如果我有两个应用程序,如下所示:
ABC1234DEF.com.useyourloaf.amazingApp1 ABC1234DEF.com.useyourloaf.amazingApp2
我可以定义一个通用的钥匙串访问组,如下所示:
ABC1234DEF.amazingAppFamily
要使应用程序能够访问该组,您需要使用 xCode 将权利 plist 文件添加到项目中。使用 Add -> New File 并从 iPhone OS Code Signing 部分选择 Entitlements 模板。你能说出你喜欢的(如文件什么
KeychainAccessGroups.plist
)。在文件中添加一个名为 keychain-access-groups 的新数组项,并使用我们选择的钥匙串访问组的值在数组中创建一个项:注意:不要更改在权利文件中默认创建的 get-task-allow 项,除非您正在创建应用程序的 Ad-Hoc 分发(在这种情况下,您应该取消选中此选项)。
应该对共享捆绑种子 ID 的所有应用程序重复相同的过程,以使它们能够访问钥匙串组。要实际存储和检索该组中的值,需要向作为参数传递给钥匙串服务的字典添加一个附加值。使用上一篇关于简单 iPhone 钥匙串访问的示例,搜索字典将获得以下附加项目:
[searchDictionary setObject: @"ABC1234DEF.amazingAppFamily" forKey: (id)kSecAttrAccessGroup];
最后一条评论,使用共享钥匙串访问组也不会阻止您将值存储在应用程序私有钥匙串中。Apple GenericKeychain 示例应用程序构建了两个应用程序,它们都将数据存储在私有和组密钥链中。
Source: Use Your Loaf
来源:用你的面包
回答by LolaRun
Now you can use UIPasteboard
现在你可以使用 UIPasteboard
//First app, install->run->close->delete
UIPasteboard* board = [UIPasteboard pasteboardWithName:@"com.company.wtv" create:YES];
board.persistent=YES;// persistent to make what you write persist after your app closes, or gets deleted.
[board setValue:@"ccccc" forPasteboardType:@"com.company.wtv.sharedValue"];
//Second app, installed after first one is deleted and ran this one... While bundle identifier and bundle seed different (i tried it on adhoc, not really releasing the app, but i htink the same)
NSData* result=nil;
NSString*resultStr=nil;
result =[board valueForPasteboardType:@"com.company.wtv.sharedValue"];
resultStr=[[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];// I got resultStr containing ccccc
check UIPasteboard documentation for further info. I'll be coming back after using this for my store apps, in case of troubles
查看 UIPasteboard 文档以获取更多信息。如果出现问题,我会在将它用于我的商店应用程序后回来
回答by LolaRun
You can't change your app's bundle ID after it has been put into the AppStore. You also can't make an app read the info from the keychain that was put there by another app (with a different bundle ID). The solution: you'll need an entitlement with which you can access practically all the data.
将应用放入 AppStore 后,您将无法更改应用的捆绑 ID。您也不能让应用程序从另一个应用程序(具有不同的捆绑 ID)放置的钥匙串中读取信息。解决方案:您需要一个可以访问几乎所有数据的权利。