uniqueIdentifier在ios7不支持后的替代方法
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里没有头文件...)
. 加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.
. 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
uniqueIdentifier在ios7不支持后的替代方法的更多相关文章
- 让IE浏览器支持CSS3圆角的方法
如果要想在IE浏览器中实现圆角的效果,我们一般都会采用圆角图片的方式.用图片的话,基本就跟浏览器没有多大关系了,因为任何浏览器都支持这种方式.今天我们主要是讲解如果用CSS3样式表来实现圆角效果,值得 ...
- 让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap的解决方法--(转)
如有雷同,不胜荣幸,若转载,请注明 让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap的解决方法 最近做一个Web网站,之前一直觉得bootstrap非常好,这次使用了boot ...
- SCRIPT438: 对象不支持“indexOf”属性或方法
SCRIPT438: 对象不支持“indexOf”属性或方法 indexOf()的用法:返回字符中indexof(string)中字串string在父串中首次出现的位置,从0开始!没有返回-1:方便判 ...
- 不支持find_element_by_name元素定位方法,抛不支持find_element_by_name元素定位方法,会抛如下错误 org.openqa.selenium.InvalidSelectorException: Locator Strategy 'name' is not supported for this session的解决
appium1.5后不支持find_element_by_name元素定位方法,会抛如下错误 org.openqa.selenium.InvalidSelectorException: Locator ...
- bootstrap的datepicker在选择日期后调用某个方法
bootstrap的datepicker在选择日期后调用某个方法 2016-11-08 15:14 1311人阅读 评论(0) 收藏 举报 首先感谢网易LOFTER博主Ivy的博客,我才顿悟了问题所在 ...
- Lodop“对象不支持SET__LICENSES属性或方法”SET__LICENSES is not a function”
Lodop中的方法如果书写错误,就会报错:“对象不支持XXX属性或方法”调试JS会报错”SET__LICENSES is not a function” LODOP.SET_LICENSES是加注册语 ...
- jQuery 报错,对象不支持tolowercase属性或方法
泪流满面.<input>里id和name都不能是nodeName,否则跟jquery.js冲突 JQuery 实践问题 - toLowerCase 错误 在应用JQuery+easyui开 ...
- 转载------让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap的解决方法
本文是转载及收藏 让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap的解决方法 最近做一个Web网站,之前一直觉得bootstrap非常好,这次使用了bootstrap3,在c ...
- jquery autocomplete s.toLowerCase(); 对象不支持此属性或方法
今天发现了一个问题,自动提示删掉后再输入,会出现 s.toLowerCase(); 对象不支持此属性或方法的错误,后来格式化了jquery的autocomplete发现他是在matchSubset方法 ...
随机推荐
- 算法笔记_175:历届试题 蚂蚁感冒(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 长100厘米的细长直杆子上有n只蚂蚁.它们的头有的朝左,有的朝右. 每只蚂蚁都只能沿着杆子向前爬,速度是1厘米/秒. 当两只蚂蚁碰面时,它 ...
- SIT与UAT的分别
在企业级软件的测试过程中,经常会划分为三个阶段——单元测试,SIT和UAT,如果开发人员足够,通常还会在SIT之前引入代码审查机制(Code Review)来保证软件符合客户需求且流程正确.下面简单介 ...
- 【转】Asp.Net MVC4 之Url路由
MVC4常见路由的处理方式 //直接方法重载+匿名对象 routes.MapRoute( name: "Default", url: "{controller}/{act ...
- JAVA虚拟机内存架构
Java在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途.创建和销毁的时间,有一些是随虚拟机的启动而创建,随虚拟机的退出而销毁,有些则是与线程一一对应,随 ...
- LR基础学习_脚本信息函数
Action(){ //脚本信息函数. //lr_whoami:返回Vuser的ID,组名称,场景ID信息./* int id,scid; char *vuser_group; lr ...
- OpenWrt设置访客网络Guest Wi-Fi
参考 https://wiki.openwrt.org/doc/recipes/guest-wlan-webinterface 1. 在2.4GHz Wireless Controller下, 创建访 ...
- python网络编程详解
最近在看<UNIX网络编程 卷1>和<FREEBSD操作系统设计与实现>这两本书,我重点关注了TCP协议相关的内容,结合自己后台开发的经验,写下这篇文章,一方面是为了帮助有需要 ...
- php计算经纬度间的距离
<?php //根据经纬度计算距离 function getdistance($lng1,$lat1,$lng2,$lat2) { //将角度转为狐度 $radLat1=deg2rad($lat ...
- 谷歌地图地理解析和反解析geocode.geocoder详解(转)
谷歌地图地理解析和反解析geocode.geocoder详解 谷歌Geocoder服务 实例代码 地址解析就是将地址(如:贵州省贵阳市)转换为地理坐标(如经度:106.71,纬度:26.57)的过程. ...
- RabbitMQ消息队列(四):分发到多Consumer(Publish/Subscribe)[转]
上篇文章中,我们把每个Message都是deliver(提供)到某个Consumer.在这篇文章中,我们将会将同一个Message deliver(提供)到多个Consumer中.这个模式也被成为 & ...