uniqueIdentifier在ios7不支持后的替代方法
来源:互联网 发布:外国人看中国网络支付 编辑:程序博客网 时间:2024/04/29 04:11
UIDevice的uniqueIdentifier方法在ios7就不支持了, 为了获得设备相关的唯一标识符,
参考了这里:https://github.com/Itayber/UIDevice-uniqueID
但是改了部分代码(下面会贴上代码). 另外,真机编译会出问题,解决记录如下:
1. 把我修改了的UIDevice-uniqueID.h/m(见下面代码)加到工程里.
2. 加IOKit.framework:
把IOKit.framework(在/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/System/Library/Frameworks/IOKit.framework) 拖到 编译选项-Build Phases-Link Binary With Libraries里.(注意到这个framework里没有头文件...)
3. 加IOKit的头文件:
在工程目录下的源文件目录里新建IOKit文件夹,
把/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.0.sdk/System/Library/Frameworks/IOKit.framework/Headers里的文件都拷贝到该目录里.
同时添加好头文件搜索路径:
在编译选项-Build Settings-Header Search Paths添加$SRCROOT,并且可递归遍历:recursive.
4. done.
注意:这个方法虽然算出了设备相关的唯一标识符,但其结果和原uniqueIdentifier函数结果是不一样的,且如果上appStore很有可能会被苹果审核为不通过.
--------------------------------------------贴代码:--------------------------------------------
UIDevice-uniqueID.h
/** * @brief 计算设备相关唯一标识符. * @note 来自https://github.com/Itayber/UIDevice-uniqueID, 但是修改了部分算法.by xiaoU. **/#import <UIKit/UIDevice.h>@interface UIDevice (uniqueID)- (NSString *) uniqueID;- (NSString *) wifiMAC;- (NSString *) bluetoothMAC;- (NSString *) serialNumber;- (NSString *) deviceIMEI;- (NSString *)deviceECID;@end
UIDevice-uniqueID.m
#import "UIDevice-uniqueID.h"#include <arpa/inet.h>#include <net/if.h>#include <net/if_dl.h>#include <arpa/inet.h>#include <ifaddrs.h>#import <mach/mach_port.h>#import <CommonCrypto/CommonDigest.h>#import <IOKit/IOKitLib.h> // add by U.NSArray *getValue(NSString *iosearch);// thanks Erica Sadun! // (spent time on this without realizing you had already wrote what I was looking for!)NSArray *getValue(NSString *iosearch){ mach_port_t masterPort; CFTypeID propID = (CFTypeID) NULL; unsigned int bufSize; kern_return_t kr = IOMasterPort(MACH_PORT_NULL, &masterPort); if (kr != noErr) return nil; io_registry_entry_t entry = IORegistryGetRootEntry(masterPort); if (entry == MACH_PORT_NULL) return nil; CFTypeRef prop = IORegistryEntrySearchCFProperty(entry, kIODeviceTreePlane, (CFStringRef) iosearch, nil, kIORegistryIterateRecursively); if (!prop) return nil; propID = CFGetTypeID(prop); if (!(propID == CFDataGetTypeID())) {mach_port_deallocate(mach_task_self(), masterPort);return nil;} CFDataRef propData = (CFDataRef) prop; if (!propData) return nil; bufSize = CFDataGetLength(propData); if (!bufSize) return nil; NSString *p1 = [[[NSString alloc] initWithBytes:CFDataGetBytePtr(propData) length:bufSize encoding:1] autorelease]; mach_port_deallocate(mach_task_self(), masterPort); return [p1 componentsSeparatedByString:@"\0"];}@implementation UIDevice (uniqueID)// UDID = SHA1(SerialNumber + IMEI + WiFiAddress + BluetoothAddress) // http://iphonedevwiki.net/index.php/Lockdownd /** add by U: 这网址里说了, iphone4之后,公示应该是:SHA1(SerialNumber + ECID + WiFiAddress + BluetoothAddress). 而实际真机测试发现- deviceIMEI函数获取不到IMEI. 所以修改了这函数. */- (NSString *) uniqueID{ // Returns a random hash if run in the simulator#if TARGET_IPHONE_SIMULATOR return [[[[[NSProcessInfo processInfo] globallyUniqueString] stringByReplacingOccurrencesOfString:@"-" withString:@""] substringToIndex:40] lowercaseString]; #endif NSString *concat = [NSString stringWithFormat:@"%@%@%@%@", [self serialNumber], [self deviceECID],//[self deviceIMEI], [self wifiMAC], [self bluetoothMAC]]; const char *cconcat = [concat UTF8String]; unsigned char result[20]; CC_SHA1(cconcat,strlen(cconcat),result); NSMutableString *hash = [NSMutableString string]; int i; for (i=0; i < 20; i++) { [hash appendFormat:@"%02x",result[i]]; } return [hash lowercaseString];}- (NSString *) wifiMAC{ struct ifaddrs *interfaces; const struct ifaddrs *tmpaddr; if (getifaddrs(&interfaces)==0) { tmpaddr = interfaces; while (tmpaddr != NULL) { if (strcmp(tmpaddr->ifa_name,"en0")==0) { struct sockaddr_dl *dl_addr = ((struct sockaddr_dl *)tmpaddr->ifa_addr); uint8_t *base = (uint8_t *)&dl_addr->sdl_data[dl_addr->sdl_nlen]; NSMutableString *s = [NSMutableString string]; int i; for (i=0; i < dl_addr->sdl_alen; i++) { [s appendFormat:(i!=0)?@":%02x":@"%02x",base[i]]; } return s; } tmpaddr = tmpaddr->ifa_next; } freeifaddrs(interfaces); } return @"00:00:00:00:00:00";}// I hope someone will find a better way to do this- (NSString *) bluetoothMAC{ mach_port_t port; IOMasterPort(MACH_PORT_NULL,&port); CFMutableDictionaryRef bt_dict = IOServiceNameMatching("bluetooth"); mach_port_t btservice = IOServiceGetMatchingService(port, bt_dict); CFDataRef bt_data = (CFDataRef)IORegistryEntrySearchCFProperty(btservice,"IODevicTree",(CFStringRef)@"local-mac-address", kCFAllocatorDefault, 1); NSString *string = [((NSData *)bt_data) description]; string = [string stringByReplacingOccurrencesOfString:@"<" withString:@""]; string = [string stringByReplacingOccurrencesOfString:@">" withString:@""]; string = [string stringByReplacingOccurrencesOfString:@" " withString:@""]; NSMutableString *btAddr = [NSMutableString string]; int x=0; while (x<12) { x++; [btAddr appendFormat:((x!=12&&x%2==0)?@"%C:":@"%C"),[string characterAtIndex:(x-1)]]; } return btAddr;}- (NSString *) serialNumber{ return [getValue(@"serial-number") objectAtIndex:0];}- (NSString *) deviceIMEI{ return [getValue(@"device-imei") objectAtIndex:0];}/// add by U://- (NSString *)deviceECID{ NSString * res = nil; if (CFMutableDictionaryRef dict = IOServiceMatching("IOPlatformExpertDevice")) { if (io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, dict)) { if (CFTypeRef ecid = IORegistryEntrySearchCFProperty(service, kIODeviceTreePlane, CFSTR("unique-chip-id"), kCFAllocatorDefault, kIORegistryIterateRecursively)) { NSData *data((NSData *) ecid); size_t length([data length]); uint8_t bytes[length]; [data getBytes:bytes]; char string[length * 2 + 1]; for (size_t i(0); i != length; ++i) sprintf(string + i * 2, "%.2X", bytes[length - i - 1]); printf("%s", string); res = [[[NSString alloc] initWithCString:string encoding:NSASCIIStringEncoding] autorelease]; CFRelease(ecid); } IOObjectRelease(service); } } return res;}@end
<script type="text/javascript"><!--google_ad_client = "ca-pub-1944176156128447";/* cnblogs 首页横幅 */google_ad_slot = "5419468456";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
- uniqueIdentifier在ios7不支持后的替代方法
- uniqueIdentifier在ios7不支持后的替代方法 (未验证)
- 获取UIDevice的uniqueIdentifier替代方法
- iOS5:[UIDevice uniqueIdentifier]的替代方案
- iOS5:[UIDevice uniqueIdentifier]的替代方案
- 苹果UDID(uniqueIdentifier)的替代方案
- iOS5:[UIDevice uniqueIdentifier]的替代方案
- iOS5:[UIDevice uniqueIdentifier]的替代方案
- 苹果UDID(uniqueIdentifier)的替代方案
- ios7之后替代label高度自适应的方法
- iOS开发笔记 --iOS7 API 对sizeWithFont的替代方法
- 为什么子类在重写父类的方法后,会替代原有方法?
- singleLine过期,淘汰后的替代方法
- 代替[UIDevice uniqueIdentifier]获取UDID的方法
- 在HQL语句中,替代?的方法
- Context#getResources().getDrawable()方法过时后的替代方法
- Context#getResources().getDrawable()方法过时后的替代方法
- getResources().getDrawable()方法过时后的替代方法
- Apache MINA 快速入门
- [csharp] view plaincopyprint?DateTimePicker dtp = new DateTimePicker();
- continue && break
- 中国合伙人
- 求yoord U N9至尊版刷机资料
- uniqueIdentifier在ios7不支持后的替代方法
- C# 在WinForm中按钮响应回车事件的简单方法
- poj 3070 Fibonacci(矩阵快速幂)
- 题目1503:二叉搜索树与双向链表
- java通用分页(SSH2框架下)和基于Hibernate的BaseDao接口
- 模版方法模式
- assert用法总结
- C#中使用DataGridView显示二维数组中的内容
- 用正则表达式匹配邮箱地址