主页 DeviceCheck
Post
Cancel

DeviceCheck

前言

iOS11 苹果改动了一个比较引开发者关注的亮点

UDID之类的写到系统 keychain 的唯一标识会随着 app 删除而删除

这个问题在微博上已经争论好几天

iOS11新的设备唯一标识 DCDevice

介绍 API

我们首先看看DCDevice类都有啥

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

NS_ASSUME_NONNULL_BEGIN

API_AVAILABLE(ios(11.0), tvos(11.0)) API_UNAVAILABLE(watchos, macos)
@interface DCDevice : NSObject
//当前设备
@property (class, readonly) DCDevice *currentDevice;

//是否支持
@property (getter=isSupported, readonly) BOOL supported;

//生成唯一标识的 token 注意:每call一次就会生成一个新的 token(和前边不同)
- (void)generateTokenWithCompletionHandler:(void(^)(NSData * _Nullable token, NSError * _Nullable error))completion;

@end

NS_ASSUME_NONNULL_END

接口简直不能再简单了 创建实例调方法

使用 API

下面我们来看下如何使用DCDevice

导入头文件

1
#import <DeviceCheck/DeviceCheck.h>

check 是否支持 如果支持 的话会在回调以后返回 token(NSData)

1
2
3
4
5
6
7
8
9
10
11
- (void)viewDidLoad {
    [super viewDidLoad];
    
    //下面是调用代码
    if([DCDevice currentDevice].supported){
        [[DCDevice currentDevice] generateTokenWithCompletionHandler:^(NSData * _Nullable token, NSError * _Nullable error) {
            NSLog(@"%@",token);
        }];
    }
}

token 是个 2188字节(2k 多点)的二进制流,很小

我尝试各种字符串编码最终也不知道里面是啥 没能成功打印出来

谁要是打印出来烦请 share 一下

删除/重装App 如何处理

DeviceCheck 允许你通过你的服务器与 Apple 服务器通讯,并为单个设备设置2k左右 的数据。 在设备上用 DeviceCheck API 生成一个 2字节的 token (00, 01,10,11),然后将这个 token 发给自己的服务器,再由自己的服务器与 Apple 的 API 进行通讯,来更新或者查询该设备的值。这两字节 的数据用来追踪用户。比如。借助两个自己的数据,你可以得知用户究竟使用了该 App 多久。 该 API 可以成为:反欺诈领域: 试用7天 Uber、滴滴司机被封号后,防止重新注册账号接单 该用户是否已经领取过首次注册红包 APP防多开 因为传输的是 flag 级别的数据,并不会定位到该设备的使用者,所以相对安全。

但是对于购买了二手手机的使用场景,可能会出现一些边界情况,这个在业务中也需要考虑进去。

引自iOS11开发新特性之实用小tips

首先要明白我们 的 token 需要发给谁

  1. token 需要发送给我们自己公司的server做记录
  2. 我们公司自己的serverAppleserver查询token是否有效,从而来更新或者查询该设备值.
  3. 2k 左右的 token不会因为设备删除 app 而删除 会一直存在苹果的 server(其实我觉得就是苹果自己去获取的设备唯一标识).

那么 怎么查询和更新呢

查询接口

https://api.development.devicecheck.apple.com/v1/query_two_bits

可以用终端自己模拟一下 就当作你自己是自己的服务器访问Apple 的服务器

1
2
3
4
curl -i --verbose -H "Authorization: Bearer <GeneratedJWT>" \
-X POST --data-binary @ValidQueryRequest.json \ 
https://api.development.devicecheck.apple.com/v1/query_two_bits 

json 的定义如下:

字段 key类型说明必须
device_tokenString设备唯一标识 token
transaction_idString服务器产生的一个ID
timestampLong服务器生成的UTC时间戳

它会 返回 如下格式

1
2
3
4
5
{
   "device_token" : "wlkCDA2Hy/CfrMqVAShs1BAR/0sAiuRIUm5jQg0a..."
   "transaction_id" : "5b737ca6-a4c7-488e-b928-8452960c4be9",
   "timestamp" : 1487716472000 
}
更新接口

https://api.development.devicecheck.apple.com/v1/update_two_bits

1
2
3
curl -i --verbose -H "Authorization: Bearer <GeneratedJWT>" \
-X POST --data-binary @ValidUpdateRequest.json \
https://api.development.devicecheck.apple.com/v1/update_two_bits 

json 的定义如下:

字段 key类型说明必须
device_tokenString设备唯一标识 token
transaction_idString服务器产生的一个ID
timestampLong服务器生成的UTC时间戳
bit0Boolean新的布尔值1
bit1Boolean新的布尔值2

json 的示例:

1
2
3
4
5
6
7
{
   "device_token" : "wlkCDA2Hy/CfrMqVAShs1BAR/0sAiuRIUm5jQg0a..."
   "transaction_id" : "5b737ca6-a4c7-488e-b928-8452960c4be9",
   "timestamp" : 1487716472000,
   "bit0" : true,
   "bit1" : false 
}

最终的方案

  1. iOS11以前版本暂且才用 UUID 等 keychian 方式
  2. iOS11尽量才用新的 api 来适配解决

对于 server 来讲可以 把 token 搞成新的附属字段 比如一个账号下登录多少个设备

那么 一个 UID 下面 就要附属 iOS 版本+ token

相信过不了多久 很成熟的 token方案会脱颖而出

如果本文有误之处还请各路大神指教

全文完

该博客文章由作者通过 CC BY 4.0 进行授权。