IDFA超频超限问题:
原因:检测机构统计IDFA
获取频率的方式,通过检测advertisingIdentifier
方法被调用次数来判定频率,每调用一次,获取频次+1。
解决思路:
1、添加ASIdentifierManager
分类。
2、交换advertisingIdentifier
方法。
3、在交换的方法中限制调用advertisingIdentifier
的次数;
代码如下:
@implementation ASIdentifierManager (GetIDFA)
+ (void)load {
GetIDFA_SwizzleMethod([self class], @selector(advertisingIdentifier), @selector(swizzled_advertisingIdentifier));
}
- (NSUUID *)swizzled_advertisingIdentifier {
NSString *idfaInfoStr = [Keychain secretForKey:@"SYSTEMIDFA"];
if ([NSObject isNotEmptyString:idfaInfoStr]) {
NSDictionary *idfaInfoDic = [idfaInfoStr JSONValue];
if (idfaInfoDic) {
NSString *idfaStr = [idfaInfoDic stringForKey:@"deviceIdfa"] ?: @"";
NSInteger getIdfaNum = [[idfaInfoDic stringForKey:@"getDeviceIdfaNum"] integerValue];
/// 这里限制一下获取的次数如果超过50次,则重新走系统方法获取,防止idfa发生改变。
if (getIdfaNum < 50 && idfaStr && idfaStr.length > 0) {
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:idfaStr];
getIdfaNum += 1;
NSDictionary *newIdfaInfoDic = @{@"deviceIdfa": idfaStr, @"getDeviceIdfaNum": [NSString stringWithFormat:@"%ld", getIdfaNum]};
[PCDKeychain saveSecret:[newIdfaInfoDic JSONRepresentation] forKey:@"SYSTEMIDFA"];
return uuid;
}
}
}
NSUUID *systemUUID = [self swizzled_advertisingIdentifier];
NSDictionary *newIdfaInfoDic = @{@"deviceIdfa": [systemUUID UUIDString], @"getDeviceIdfaNum": @"1"};
[Keychain saveSecret:[newIdfaInfoDic JSONRepresentation] forKey:@"SYSTEMIDFA"];
return systemUUID;
}
void GetIDFA_SwizzleMethod(Class class, SEL originalSelector, SEL swizzledSelector) {
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
@end
Keychain
为框架,可以自行替换。
每50次去调用一次系统获取方法,主要是为了防止IDFA
发生改变,不能及时更新到服务器。这里可以自行更改次数,只要不超过1秒/次这个频率,检测机构都不会报超频超限。