欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS 获取设备唯一标示符的方法详解

程序员文章站 2023-12-21 08:01:51
在开发中会遇到应用需要记录设备标示,即使应用卸载后再安装也可重新识别的情况,在这写一种实现方式——读取设备的uuid(universally unique identifi...

在开发中会遇到应用需要记录设备标示,即使应用卸载后再安装也可重新识别的情况,在这写一种实现方式——读取设备的uuid(universally unique identifier)并通过keychain记录。

首先ios中获取设备唯一标示符的方法一直随版本的更新而变化。ios 2.0版本以后uidevice提供一个获取设备唯一标识符的方法uniqueidentifier,通过该方法我们可以获取设备的序列号,这个也是目前为止唯一可以确认唯一的标示符。好景不长,因为该唯一标识符与手机一一对应,苹果觉得可能会泄露用户隐私,所以在 ios 5.0之后该方法就被废弃掉了;ios 6.0系统新增了两个用于替换uniqueidentifier的接口,分别是:identifierforvendor,advertisingidentifier,但这两个接口会在应用重新安装时改变数值,并不是唯一的标示符,所以开发者改为使用wifi的mac地址来取代;ios 7中苹果又封杀mac地址,所以开发者再次改变思路使用keychain来保存获取到的udid,这样以后即使app删了再装回来,也可以从keychain中读取回来。

首先保存设备的uuid,可以使用类方法+ (id)uuid 是一个类方法,调用该方法可以获得一个uuid。通过下面的代码可以获得一个uuid字符串:

 nsstring *uuid = [[nsuuid uuid] uuidstring];

也可以保存在ios 6中新增的vindor标示符 (idfv-identifierforvendor),获取这个idfv的新方法被添加在已有的uidevice类中。跟advertisingidentifier一样,该方法返回的是一个nsuuid对象。

nsstring *idfv = [[[uidevice currentdevice] identifierforvendor] uuidstring];

如果用户卸载了同一个vendor对应的所有程序,然后在重新安装同一个vendor提供的程序,此时identifierforvendor会被重置,所以这里要用到keychain来保存。

keychain(钥匙串)是使用苹果设备经常使用的,通常要调试的话,都得安装证书之类的,这些证书就是保存在keychain中,还有我们平时浏览网页记录的账号密码也都是记录在keychain中。ios中的keychain相比os x比较简单,整个系统只有一个keychain,每个程序都可以往keychain中记录数据,而且只能读取到自己程序记录在keychain中的数据。ios中security.framework框架提供了四个主要的方法来操作keychain:

  • secitemcopymatching(cfdictionaryref query, cftyperef *result);//查询osstatus
  • secitemadd(cfdictionaryref attributes, cftyperef *result); //添加osstatus
  • secitemupdate(cfdictionaryref query, cfdictionaryref attributestoupdate);//更新keychain中的itemosstatus
  • secitemdelete(cfdictionaryref query)//删除keychain中的itemosstatus

这四个方法参数比较复杂,一旦传错就会导致操作keychain失败,文档中介绍的比较详细,大家可以查查官方文档。而苹果提供的keychain使用起来略麻烦,所以这里推荐一个第三方库samkeychains.samkeychains对苹果安全框架api进行了简单封装,支持对存储在钥匙串中密码、账户进行访问,包括读取、删除和设置。samkeychains使用简单,通过实例代码便可掌握。

//保存一个uuid字符串到钥匙串:
cfuuidref uuid = cfuuidcreate(null);
assert(uuid != null);
cfstringref uuidstr = cfuuidcreatestring(null, uuid);
 [samkeychain setpassword: [nsstring stringwithformat:@"%@", uuidstr]
 forservice:@"com.yourapp.yourcompany"account:@"user"];

//从钥匙串读取uuid:
nsstring *retrieveuuid = [samkeychain passwordforservice:@"com.yourapp.yourcompany"account:@"user"];

**注意: setpassword和passwordforsevice方法中的**services 和 accounts 参数应该是一致的。

更多详细用法说明可以看samkeychains documentation

基本的实现思路便是这样,下面是具体的一种具体实现代码,仅供参考。

+ (nsstring *)getdeviceid
{
  nsstring * currentdeviceuuidstr = [samkeychain passwordforservice:@" "account:@"uuid"];
  if (currentdeviceuuidstr == nil || [currentdeviceuuidstr isequaltostring:@""])
  {
    nsuuid * currentdeviceuuid = [uidevice currentdevice].identifierforvendor;
    currentdeviceuuidstr = currentdeviceuuid.uuidstring;
    currentdeviceuuidstr = [currentdeviceuuidstr stringbyreplacingoccurrencesofstring:@"-" withstring:@""];
    currentdeviceuuidstr = [currentdeviceuuidstr lowercasestring];
    [samkeychain setpassword: currentdeviceuuidstr forservice:@" "account:@"uuid"];
  }
  return currentdeviceuuidstr;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。、

上一篇:

下一篇: