苹果推荐的就是使用IDFA、IDFV
idfa: 适用于对外:例如广告推广,换量等跨应用的用户追踪等
idfv: 适用于对内:例如分析用户在应用内的行为等
idfa:主要用于广告,可能会获取不到,iOS用户也可以--> 设置|隐私|广告追踪,里重置此id的值,虽然玩家一般不会重置,但是上述理由已经不足以把idfa作为账号了
idfv: 顾名思义,是给Vendor标识用户用的,每个设备在所属同一个Vender的应用里,都有相同的值。其中的Vender是指应用提供商,但准确点说,是通过BundleID的DNS反转的前两部分进行匹配,如果相同就是同一个Vender,例如对于
com.company.appone,
com.company.apptwo
这两个BundleID来说,就属于同一个Vendor,共享同一个idfv的值。和idfa不同的是,idfv的值是一定能取到的,所以非常适合于作为内部用户行为分析的主id,来标识用户,替代OpenUDID。
转载:http://www.myexception.cn/ai/1985348.html
idfv(identifierForVendor)是CFBundleIdentifier(反转DNS格式)的前两部分。比如某个应用的bundle id 是com.companyName.appname,那么idfv就是com.companyName。来自同一个运营商的应用运行在同一个设备上,此属性的值是相同的;不同的运营商应用运行在同一个设备上值不同,或者同一个运营商的应用运行在不同的设备上值不同。
经测试,只要设备上有一个tencent的app,重新安装后的identifierForVendor值不变,如果tencent的app全部删除,重新安装后的identifierForVendor值改变。
肯定不能将idfv存入NSUserDefaults,因为一旦应用被卸载,那么数据将不复存在,idfv有可能就会改变。keychain不会这样。那么介绍下keychain:
我们可以把KeyChain理解为一个Dictionary,所有数据都以key-value的形式存储,可以对这个Dictionary进行add、update、get、delete这四个操作。对于每一个应用来说,KeyChain都有两个访问区,私有区和公共区。私有区是一个sandbox,本程序存储的任何数据都对其他程序不可见。而要想在将存储的内容放在公共区,需要先声明公共区的名称,官方文档管这个名称叫“keychain access group”,声明的方法是新建一个plist文件,名字随便起,内容如下:
“yourAppID.com.yourCompany.whatever”就是你要起的公共区名称,除了whatever字段可以随便定之外,其他的都必须如实填写。这个文件的路径要配置在 Project->build setting->Code Signing Entitlements里,否则公共区无效,配置好后,须用你正式的证书签名编译才可通过,否则xcode会弹框告诉你code signing有问题。所以,苹果限制了你只能同公司的产品共享KeyChain数据,别的公司访问不了你公司产品的KeyChain。
iOS的keychain服务提供了一种安全的保存私密信息(密码,序列号,证书等)的方式,每个ios程序都有一个独立的keychain存储。相对于NSUserDefaults、文件保存等一般方式,keychain保存更为安全,而且keychain里保存的信息不会因App被删除而丢失,所以在重装App后,keychain里的数据还能使用。
在应用里使用使用keyChain,我们需要导入Security.framework ,keychain的操作接口声明在头文件SecItem.h里。直接使用SecItem.h里方法操作keychain,需要写的代码较为复杂,为减轻咱们程序员的开发,我们可以使用一些已经封装好了的工具类,apple官方提出了两个工具类:KeychainItemWrapper和SFHFKeychainUtils。
1.使用KeychainItemWrapper
把KeychainItemWrapper下载下来,然后将“KeychainItemWrapper.h”和“KeychainItemWrapper.m”拷贝到我们项目,并导入Security.framework
下面是我在appDelegate.m中的代码:因为我不需要在应用间共享keychain中的内容,所以accessGroup设置为nil
- (NSString *)getIdfv
{
NSString *str;
KeychainItemWrapper *keychainItem = [[KeychainItemWrapperalloc]initWithIdentifier:@"UUID"accessGroup:nil];
MYLog(@"%@",[keychainItem objectForKey:(__bridgeid)kSecValueData]);
NSString *uuidStr = [keychainItemobjectForKey:(__bridgeid)kSecValueData];
MYLog(@"%@",[[UIDevice currentDevice] identifierForVendor]);
if ([uuidStrisKindOfClass:[NSDictionaryclass]])
{ //代表里面还没有存值
NSString *myUUIDStr = [[[UIDevicecurrentDevice] identifierForVendor]UUIDString];
[keychainItem setObject:myUUIDStrforKey:(__bridgeid)kSecValueData];
str = myUUIDStr;
}
else{
str = [keychainItem objectForKey:(__bridgeid)kSecValueData];
}
MYLog(@"======%@",str);
return str;
}
2.SSKeyChains
SSKeyChains对苹果安全框架API进行了简单封装,支持对存储在钥匙串中密码、账户进行访问,包括读取、删除和设置。SSKeyChain的作者是大名鼎鼎的SSToolkit的作者samsoffes。
项目地址:https://github.com/samsoffes/sskeychain
在工程中加入SSKeyChain
在工程中加入Security.framework框架。
把SSKeychain.h和SSKeychain.m加到项目文件夹。
使用SSKeyChain
通过以下类方法来使用SSKeyChain(请查看SSKeyChain.h):
- (NSArray *)allAccounts;
- (NSArray *)accountsForService:(NSString *)serviceName;
- (NSString *)passwordForService:(NSString *)serviceNameaccount:(NSString *)account;
- (BOOL)deletePasswordForService:(NSString *)serviceNameaccount:(NSString *)account;
- (BOOL)setPassword:(NSString )password forService:(NSString)serviceName account:(NSString *)account;
文档
在Xcode中安装SSKeyChain的帮助文档需要以下步骤:
打开菜单 Xcode -> Preferences
选择 Downloads
选择 Documentation
点击底部的加号按钮,并输入以下URL: http://docs.samsoff.es/com.samsoffes.sskeychain.atom
点击”SSKeyChain Documentation”旁边的install按钮。 (如果你看不到它,也没有提示任何错误,请重启Xcode)
确保在Organizer中可选的docset中能够看到SSKeychain。
此外,可以在线查看SSKeychain Documentation。
调试
如果无法保存钥匙串,请使用SSKeychain.h中提供的错误代码,例如:
NSError *error = nil;
NSString *password = [SSKeychainpasswordForService:@"MyService" account:@"samsoffes"error:&error];
if ([error code] == SSKeychainErrorNotFound) {
NSLog(@"Passwordnot found");
}
显然,你对做这个应该很熟悉了。访问钥匙串是件痛苦的事情,你要随时检查它的每个错误和失败。SSKeychain并没有使它(钥匙串)变得更稳定,它仅仅是繁琐的C APIs封装。
示例代码
保存一个UUID字符串到钥匙串:
CFUUIDRef uuid = CFUUIDCreate(NULL);assert(uuid != NULL);CFStringRef uuidStr = CFUUIDCreateString(NULL, uuid);
[SSKeychain setPassword: [NSString stringWithFormat:@"%@", uuidStr]
forService:@"com.yourapp.yourcompany"account:@"user"];
然后,从钥匙串读取UUID:
NSString *retrieveuuid = [SSKeychainpasswordForService:@"com.yourapp.yourcompany"account:@"user"];
注意: setPassword和passwordForSevice方法中的services 和 accounts 参数应该是一致的。
3.SFHFKeychainUtils
SFHFKeychainUtils密码保护,使用方法很简单
下载地址:https://github.com/ldandersen/scifihifi-iphone/tree/master/security
1、引入Security.frameWork框架。
2、引入头文件:SFHKeychainUtils.h.
3、存密码:
[SFHFKeychainUtils storeUsername:@"dd"
andPassword:@"aa"
forServiceName:SERVICE_NAME
updateExisting:1
error:nil];
[SFHFKeychainUtils deleteItemForUsername:@"dd"
andServiceName:SERVICE_NAME
error:nil];
4、取密码:
NSString *passWord = [SFHFKeychainUtils getPasswordForUsername:@"dd"
andServiceName:SERVICE_NAME
error:nil];