iOS开发获取设备基础信息

收集了iOS获取设备基础信息的一些方法,可以根据需要自己扩展
#ifndef DeviceInfoDefine_h
#define DeviceInfoDefine_h


/** 唯一ID */
#define XC_UNIQUE_ID            [XC_DeviceInfo getUniqueId]

/** idfa */
#define XC_IDFA                 [XC_DeviceInfo idfaString]

/** idfv */
#define XC_IDFV                 [XC_DeviceInfo idfvString]

/**  mac 地址 */
#define XC_MAC_ADDRESS          [XC_DeviceInfo macAddress]

/** ipv4 地址 */
#define XC_IPV4_ADDRESS         [XC_DeviceInfo getIPAddress:YES]

/** ipv6 地址 */
#define XC_IPV6_ADDRESS         [XC_DeviceInfo getIPAddress:NO]

/** 设备型号名称 如:iPhone10,1 */
#define XC_MODEL_NAME           [XC_DeviceInfo modelName]

/** 浏览器 User-Agent */
#define XC_USER_AGENT           [XC_DeviceInfo userAgent]

/** 设备宽高,如 750.0,1334.0 */
#define XC_SCREEN_SIZE          [XC_DeviceInfo screenSize]

/** 应用名称 */
#define XC_APP_NAME             [XC_DeviceInfo appName]

/** 应用包名 */
#define XC_APP_PACKAGE_NAME     [XC_DeviceInfo appPackageName]

/** bundle id */
#define XC_BUNDLE_ID            [XC_DeviceInfo appBundleId]

/**  app version */
#define XC_APP_VERSION          [XC_DeviceInfo appVersion]

/**  device version */
#define XC_DEVICE_VERSION       [XC_DeviceInfo deviceVersion]

/** 手机磁盘空间使用情况,如:6.8/64.0 */
#define XC_DISK_USAGE           [XC_DeviceInfo diskUsage]

/** 手机磁盘总空间,如:63989469184 (64G) */
#define XC_DEVICE_TOTAL_SPACE   [XC_DeviceInfo deviceStorageSpace:YES]

/** 手机磁盘剩余空间 */
#define XC_DEVICE_FREE_SPACE    [XC_DeviceInfo deviceStorageSpace:NO]



#endif /* DeviceInfoDefine_h */





//自定义log输出
#ifdef DEBUG
    #define XC_LOG(param,...) NSLog((@"\n-------------- XC_LOG ↓ --------------\n" @"log info:" param @"\nlog at line: %d\n" @"log at file: %@\n" @"log at function: %@" @"\n-------------- XC_LOG ↑ --------------\n"),##__VA_ARGS__,__LINE__,[NSString stringWithUTF8String:__FILE__],[NSString stringWithUTF8String:__PRETTY_FUNCTION__])
#else
    #define XC_LOG(...)
#endif



XC_DeviceInfo.h
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface XC_DeviceInfo : NSObject

/** 获取唯一标识 */
+ (nonnull NSString *)getUniqueId;

/** idfa 广告标识 */
+ (nonnull NSString *)idfaString;


/** idfv */
+ (nonnull NSString *)idfvString;

/** mac地址 */
+ (nonnull NSString *)macAddress;

/** 获取设备当前网络IP地址 */
+ (nonnull NSString *)getIPAddress:(BOOL)preferIPv4;

/** 设备机型名称 如:iPhone10,1 */
+ (nonnull NSString *)modelName;

/** 浏览器userAgent */
+ (nonnull NSString *)userAgent;

/** 屏幕尺⼨ */
+ (nonnull NSString *)screenSize;

/** app名 */
+ (nonnull NSString *)appName;

/** 应用包名 */
+ (nonnull NSString *)appPackageName;

/** 应用 bundleID */
+ (nonnull NSString *)appBundleId;

/** APP版本号 */
+ (nonnull NSString *)appVersion;

/** 设备系统版本 */
+ (nonnull NSString *)deviceVersion;

/** 磁盘使用情况 */
+ (nonnull NSString *)diskUsage;

/** 当前手机磁盘空间大小 ,totalSpace:YES:磁盘空间总大小,NO:磁盘剩余可用空间 */
+ (long long)deviceStorageSpace:(BOOL)totalSpace;

@end

NS_ASSUME_NONNULL_END


XC_DeviceInfo.m

#import "XC_DeviceInfo.h"

#import "SFHFKeychainUtils.h"

#include <sys/types.h>
#include <sys/sysctl.h>
#include <sys/utsname.h>
#import  <arpa/inet.h>

#import <ifaddrs.h>
#import <sys/sockio.h>
#import <sys/ioctl.h>

#import <AdSupport/AdSupport.h>

#import  "sys/utsname.h"
#include <sys/socket.h> // Per msqr
#include <net/if.h>
#include <net/if_dl.h>
#include <sys/types.h>


#define IOS_CELLULAR    @"pdp_ip0"
#define IOS_WIFI        @"en0"
//#define IOS_VPN       @"utun0"
#define IP_ADDR_IPv4    @"ipv4"
#define IP_ADDR_IPv6    @"ipv6"


NSString *const UUID_USER_NAME = @"com.xiaocan._uuid";
NSString *const UUID_SERVICE = @"com.xiaocan._uuid_service";

@implementation XC_DeviceInfo


/** 获取唯一标识 */
+ (nonnull NSString *)getUniqueId{
    NSString * strUUID = (NSString *)[SFHFKeychainUtils getPasswordForUsername:UUID_USER_NAME andServiceName:UUID_SERVICE error:nil];
    
    //首次执行该方法时,uuid为空
    if ([strUUID isEqualToString:@""] || !strUUID){
        
        //生成一个uuid的方法
        CFUUIDRef uuidRef = CFUUIDCreate(kCFAllocatorDefault);
        strUUID = (NSString *)CFBridgingRelease(CFUUIDCreateString (kCFAllocatorDefault,uuidRef));
        
        //将该uuid保存到keychain
        [SFHFKeychainUtils storeUsername:UUID_USER_NAME andPassword:strUUID forServiceName:UUID_SERVICE updateExisting:YES error:nil];
        
    }
    return strUUID;
}

/** idfa 广告标识 */
+ (nonnull NSString *)idfaString{
    return [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
}


/** idfv */
+ (nonnull NSString *)idfvString{
    return [[[UIDevice currentDevice] identifierForVendor] UUIDString];
}

/** mac地址 */
+ (nonnull NSString *)macAddress{
    int mib[6];
    size_t len;
    char *buf;
    unsigned char *ptr;
    struct if_msghdr *ifm;
    struct sockaddr_dl *sdl;
    
    mib[0] = CTL_NET;
    mib[1] = AF_ROUTE;
    mib[2] = 0;
    mib[3] = AF_LINK;
    mib[4] = NET_RT_IFLIST;
    
    if ((mib[5] = if_nametoindex("en0")) == 0) {
        printf("Error: if_nametoindex error/n");
        return NULL;
    }
    
    if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
        printf("Error: sysctl, take 1/n");
        return NULL;
    }
    
    if ((buf = malloc(len)) == NULL) {
        printf("Could not allocate memory. error!/n");
        return NULL;
    }
    
    if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
        printf("Error: sysctl, take 2");
        return NULL;
    }
    
    ifm = (struct if_msghdr *)buf;
    sdl = (struct sockaddr_dl *)(ifm + 1);
    ptr = (unsigned char *)LLADDR(sdl);
    
    NSString *outstring = [NSString stringWithFormat:@"%02x:%02x:%02x:%02x:%02x:%02x", *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)];
    free(buf);
    
    return [outstring uppercaseString];
}

/** 获取设备当前网络IP地址 */
+ (nonnull NSString *)getIPAddress:(BOOL)preferIPv4{
    NSArray *searchArray = preferIPv4 ?
    @[ /*IOS_VPN @"/" IP_ADDR_IPv4, IOS_VPN @"/" IP_ADDR_IPv6,*/ IOS_WIFI @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6 ] :
    @[ /*IOS_VPN @"/" IP_ADDR_IPv6, IOS_VPN @"/" IP_ADDR_IPv4,*/ IOS_WIFI @"/" IP_ADDR_IPv6, IOS_WIFI @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4 ] ;
    
    NSDictionary *addresses = [self getIPAddresses];
    //    NSLog(@"addresses: %@", addresses);
    
    __block NSString *address;
    [searchArray enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop)
     {
         address = addresses[key];
         if(address) *stop = YES;
     } ];
    return address ? address : @"0.0.0.0";
}

//获取所有相关IP信息
+ (NSDictionary *)getIPAddresses{
    NSMutableDictionary *addresses = [NSMutableDictionary dictionaryWithCapacity:8];
    
    // retrieve the current interfaces - returns 0 on success
    struct ifaddrs *interfaces;
    if(!getifaddrs(&interfaces)) {
        // Loop through linked list of interfaces
        struct ifaddrs *interface;
        for(interface=interfaces; interface; interface=interface->ifa_next) {
            if(!(interface->ifa_flags & IFF_UP) /* || (interface->ifa_flags & IFF_LOOPBACK) */ ) {
                continue; // deeply nested code harder to read
            }
            const struct sockaddr_in *addr = (const struct sockaddr_in*)interface->ifa_addr;
            char addrBuf[ MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) ];
            if(addr && (addr->sin_family==AF_INET || addr->sin_family==AF_INET6)) {
                NSString *name = [NSString stringWithUTF8String:interface->ifa_name];
                NSString *type;
                if(addr->sin_family == AF_INET) {
                    if(inet_ntop(AF_INET, &addr->sin_addr, addrBuf, INET_ADDRSTRLEN)) {
                        type = IP_ADDR_IPv4;
                    }
                } else {
                    const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*)interface->ifa_addr;
                    if(inet_ntop(AF_INET6, &addr6->sin6_addr, addrBuf, INET6_ADDRSTRLEN)) {
                        type = IP_ADDR_IPv6;
                    }
                }
                if(type) {
                    NSString *key = [NSString stringWithFormat:@"%@/%@", name, type];
                    addresses[key] = [NSString stringWithUTF8String:addrBuf];
                }
            }
        }
        // Free memory
        freeifaddrs(interfaces);
    }
    return [addresses count] ? addresses : nil;
}

/** 设备机型名称 */
+ (nonnull NSString *)modelName{
    struct utsname systemInfo;
    uname(&systemInfo);
    NSString *platform = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
    return platform?platform:@"unknow";
}

/** 浏览器userAgent */
+ (nonnull NSString *)userAgent{
    NSString *ua = [[NSUserDefaults standardUserDefaults] objectForKey:@"navigator.userAgent"];
    if (!ua) {
        if ([NSThread isMainThread]) {
            UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectZero];
            NSString *useAgent = [webView stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
            [[NSUserDefaults standardUserDefaults] setObject:useAgent forKey:@"navigator.userAgent"];
        }else{
            dispatch_sync(dispatch_get_main_queue(), ^{
                UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectZero];
                NSString *useAgent = [webView stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
                [[NSUserDefaults standardUserDefaults] setObject:useAgent forKey:@"navigator.userAgent"];
            });
        }
    }
    if (ua) {
        return ua;
    }
    return @"";
}

/** 屏幕尺⼨ */
+ (nonnull NSString *)screenSize{
    CGFloat width = [UIScreen mainScreen].bounds.size.width * [UIScreen mainScreen].scale;
    CGFloat height = [UIScreen mainScreen].bounds.size.height * [UIScreen mainScreen].scale;
    NSString *size = @"";
    if (width > height) {
        size = [NSString stringWithFormat:@"%.01f,%.01f",height,width];
    }else{
        size = [NSString stringWithFormat:@"%.01f,%.01f",width,height];
    }
    return size;
}

/** app名 */
+ (nonnull NSString *)appName{
    NSString *appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"];
    if (!appName) {
        appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
    }
    if (!appName) {
        appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleExecutable"];
    }
    if (!appName) {
        appName = @"";
    }
    return appName;
}

/** 应用包名 */
+ (nonnull NSString *)appPackageName{
    NSString *appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
    
    if (!appName) {
        appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleExecutable"];
    }
    if (!appName) {
        appName = @"";
    }
    return appName;
}

/** 应用 bundleID */
+ (nonnull NSString *)appBundleId{
    NSString *bundleId = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
    if (!bundleId) {
        bundleId = @"";
    }
    return bundleId;
}

/** APP版本号 */
+ (nonnull NSString *)appVersion{
    return [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
}

/** 设备系统版本 */
+ (nonnull NSString *)deviceVersion{
    return [UIDevice currentDevice].systemVersion;
}

/** 磁盘使用情况 */
+ (nonnull NSString *)diskUsage{
    return [NSString stringWithFormat:@"%.01lf/%.01lf",[self deviceStorageSpace:NO] / 1000.0 / 1000.0 / 1000.0,[self deviceStorageSpace:YES] / 1000.0 / 1000.0 / 1000.0];
}

/** 当前手机磁盘空间大小 ,totalSpace:YES:磁盘空间总大小,NO:磁盘剩余可用空间 */
+ (long long)deviceStorageSpace:(BOOL)totalSpace{
    //剩余空间
    NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask , YES) objectAtIndex:0];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSDictionary *fileSysAttributes = [fileManager attributesOfFileSystemForPath:path error:nil];
    NSNumber *freeSpaces = (NSNumber *)[fileSysAttributes objectForKey:NSFileSystemFreeSize];
    NSNumber *totalSpaces = (NSNumber *)[fileSysAttributes objectForKey:NSFileSystemSize];
    if (totalSpace) {
        return totalSpaces.longLongValue;
    }
    return freeSpaces.longLongValue;
}

@end

使用了keychain存储 SFHFKeychainUtils
GitHub地址iOS_DeviceInfo

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容