ios-唯一标识符及Keychain共享

ios-唯一标识符及Keychain共享


前篇

iOS7中已经完全的禁用了 UDID, 推荐使用 [IDFA & IDFV ](#IDFA & IDFV )

结合 Keychain 持久化的特性, 达到 唯一标识符 的持久可用性.


唯一标识符


UDID

UDID(Unique Device Identifier Description)是苹果IOS设备的唯一识别码,由40个字符的字母和数字组成。

在很多需要限制一台设备一个账号的应用中经常会用到。在iOS5中可以获取到设备的UDID,但在iOS7中已经完全的禁用了它。因此系统的 UDID 已经不可用.


IDFA & IDFV

  • IDFA - Identifier For Advertising(广告标识符)

    • 同一手机获取该值都相同
    • 重装应用, 不会改变
    • 用户可手动重置这个值. 重置广告 id: 设置 -> 隐私 -> 广告 -> 重置广告 id (中国区的可能看不到这个, 模拟器可以看到)
  • IDFV - Identifier For Vendor(应用开发商标识符)

    • 重装应用, 会改变.

使用代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#import <UIKit/UIKit.h>
#import <AdSupport/AdSupport.h>

+(NSString*)getDeviceId{
// IDFA - Identifier For Advertising(广告标识符)
BOOL isOk = [[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled];
NSLog(@"--- ad TrackingEnabled: %d", isOk);
if (isOk) {
NSString *idfa = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
NSLog(@"--- idfa: %@", idfa);
return idfa;
}

// IDFV - Identifier For Vendor(应用开发商标识符)
NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
NSLog(@"--- idfv: %@", idfv);
return @"sdfsdf";
}

Keychain

Keychain的特点

  • 数据并不存放在App的Sanbox中,即使删除了App,资料依然保存在keychain中。如果重新安装了app,还可以从keychain获取数据。
  • keychain的数据可以通过group方式,让程序可以在App间共享。不过得要相同TeamID
  • keychain的数据是经过加密的

网上找到的 大部分使用的是 KeychainItemWrapper, 需要将 KeychainItemWrapper 的头文件和实现文件 (传送门) 拷入项目, 发现很多编译报错, 已经不适用了.

使用第三方库 UICKeyChainStore, https://github.com/kishikawakatsumi/UICKeyChainStore

  1. 模块引入 Security.framework 系统动态库

  2. Podfile 文件中引入 UICKeyChainStore

    1
    pod 'UICKeyChainStore'
  3. cd 到 Podfile 文件所在目录, 安装

    1
    2
    3
    $ pod install --verbose
    -> Installing UICKeyChainStore (2.2.1)
    ...
  4. 打开 Pods.xcodeproj 工程, 构建所需 cpu 架构的 静态库, 丢到能被项目引入的地方

  5. 代码使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #import <UICKeyChainStore/UICKeyChainStore.h>

    NSString* key = @"name";
    NSString* value = @"hi, wilker";

    // set key value
    [UICKeyChainStore setString:kc.value forKey:kc.key service:@"you bundle id"];

    // get value by key
    NSString* value02 = [UICKeyChainStore stringForKey:key service:@"you bundle id"];
    NSLog(@"--- value02: %@", value02);

多 app 共享 keychain 数据

前置条件:

  1. app 都要使用同一个 TeamID 构建出来.
  2. Keychain Groups 相同.

流程

  1. 添加 Keychain Sharing, 会生成 .entitlements 文件, 并添加一个 group (点 + 号默认添加的 group 自动拼上了 bundle id )

    生成的 .entitlements 文件内容, 绘制动拼上 $(AppIdentifierPrefix)

    • 内容格式

      1
      2
      3
      4
      5
      6
      默认生成如下:
      $(AppIdentifierPrefix) + 你的 Bundle ID

      可以自定义用于创建独立组,自定义格式为:
      自定义内容 //但是如果需要分享的组格式需要如下:
      $(AppIdentifierPrefix) + 自定义内容
    • 关于 $(AppIdentifierPrefix)

      AppIdentifierPrefix 就是 team帐号

      有相同的 Team ID,这个是应用间共享 Keychain 数据的前提条件。一个 App ID 分两部分:

      • Apple 为你生成的 Team ID
      • 开发者注册的 Bundle ID

      一个典型的 App ID 如:659823F3DC53.com.apple.oneappleapp。

      659823F3DC53 即为你的 Team ID,是 Apple 为你生成的。一个开发者账号可以有不同的几个 Team ID。但 Apple 不会为不同的开发者生成一样的 Team ID。这样,不同的开发者账号发布的应用想共享 keychain 数据,在现在来看是无法实现的。而要做到 keychain 数据共享,要求是同一个开发账号开发的,同时选择了相同的 Team ID。

  2. 把这个 .entitlements 文件丢到 同一个 TeamId 的其他 app 下 (或者 其他 app 下新建包含相同 group 名的 .entitlements 文件也行) , 就可以共享数据了.