APP在開發(fā)的過程中,有時(shí)候?yàn)榱薭ug的跟蹤汪拥,需要收集用戶使用手機(jī)的設(shè)備达传,手機(jī)系統(tǒng)版本,手機(jī)型號,以及應(yīng)用版本宪赶,應(yīng)用信息等等宗弯。這些的信息便于開發(fā)者診斷問題,是能夠通過開發(fā)api可以獲取到的搂妻,iOS的SDK中提供了三種方式來獲取APP的信息,他們分別是UIDevice,NSBundle,NSLocale.
一蒙保、UIDevice 幫助我們?nèi)轿坏牧私馑褂玫脑O(shè)備的信息
//手機(jī)名稱
NSString *userPhoneNameStr = [[UIDevice currentDevice] name];
//手機(jī)系統(tǒng)名稱
NSString *deviceNameStr = [[UIDevice currentDevice] systemName];
//手機(jī)系統(tǒng)版本號
NSString *systemVersionStr = [[UIDevice currentDevice] systemVersion];
//類型 是模擬器還是真機(jī)
NSString *phoneModelStr = [[UIDevice currentDevice] model];
//電池電量
CGFloat batteryLevel = [[UIDevice currentDevice] batteryLevel];
//地方型號 (國際化區(qū)域名稱)
NSString* localPhoneModel = [[UIDevice currentDevice] localizedModel];
二、NSBundle 欲主,這是一個(gè)目錄邓厕,我們稱之為程序的main bundle,通過這個(gè)目錄獲取應(yīng)用的信息扁瓢,比如說應(yīng)用的名稱详恼,版本號,應(yīng)用軟件的版本
這里總共有29個(gè),我在這里挑選了幾個(gè)比較常用的
//app 應(yīng)用信息的獲取字典類型引几,
NSDictionary * dicInfo =[[NSBundle mainBundle] infoDictionary];
//當(dāng)前應(yīng)用名稱
NSString * appNameStr =[dicInfo objectForKey:@"CFBundleName"];
//當(dāng)前應(yīng)用版本號
NSString * appVersionStr =[dicInfo objectForKey:@"CFBundleShortVersionString"];
//當(dāng)前應(yīng)用構(gòu)建版本號(build號)
NSString * appBuildStr =[dicInfo objectForKey:@"CFBundleVersion"];
//獲取build號另一種方式
NSString *version = [[[NSBundle mainBundle]infoDictionary]objectForKey:(NSString *)kCFBundleVersionKey];
//Xcode 版本號
NSString * appXcodeStr =[dicInfo objectForKey:@"DTXcode"];
//模擬器系統(tǒng)版本號
NSString * appSDKNameStr = [dicInfo objectForKey:@"DTSDKName"];
三昧互、NSLocale 可以獲取用戶的本地化信息的設(shè)置,比如說:國家伟桅,語言敞掘,日期的格式。
四楣铁、磁盤空間
// 獲取磁盤總空間
- (int64_t)getTotalDiskSpace {
NSError *error = nil;
NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:&error];
if (error) return -1;
int64_t space = [[attrs objectForKey:NSFileSystemSize] longLongValue];
if (space < 0) space = -1;
return space;
}
// 獲取未使用的磁盤空間
- (int64_t)getFreeDiskSpace {
NSError *error = nil;
NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:&error];
if (error) return -1;
int64_t space = [[attrs objectForKey:NSFileSystemFreeSize] longLongValue];
if (space < 0) space = -1;
return space;
}
// 獲取已使用的磁盤空間
- (int64_t)getUsedDiskSpace {
int64_t totalDisk = [self getTotalDiskSpace];
int64_t freeDisk = [self getFreeDiskSpace];
if (totalDisk < 0 || freeDisk < 0) return -1;
int64_t usedDisk = totalDisk - freeDisk;
if (usedDisk < 0) usedDisk = -1;
return usedDisk;
}
五玖雁、運(yùn)營商
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <CoreTelephony/CTCarrier.h>
CTTelephonyNetworkInfo *info = [[CTTelephonyNetworkInfo alloc] init];
CTCarrier *carrier = [info subscriberCellularProvider];
//當(dāng)前手機(jī)所屬運(yùn)營商名稱
NSString *mobileCarrier;
//先判斷有沒有SIM卡,如果沒有則不獲取本機(jī)運(yùn)營商
if (!carrier.isoCountryCode) {
mobileCarrier = @"無運(yùn)營商";
}else{
mobileCarrier = [carrier carrierName];
}
六盖腕、獲取設(shè)備型號
- (NSString *)iphoneType {
//需要導(dǎo)入頭文件:#import <sys/utsname.h>
struct utsname systemInfo;
uname(&systemInfo);
NSString *platform = [NSString stringWithCString:systemInfo.machine encoding:NSASCIIStringEncoding];
if ([platform isEqualToString:@"iPhone1,1"]) return @"iPhone 2G";
if ([platform isEqualToString:@"iPhone1,2"]) return @"iPhone 3G";
if ([platform isEqualToString:@"iPhone2,1"]) return @"iPhone 3GS";
if ([platform isEqualToString:@"iPhone3,1"]) return @"iPhone 4";
if ([platform isEqualToString:@"iPhone3,2"]) return @"iPhone 4";
if ([platform isEqualToString:@"iPhone3,3"]) return @"iPhone 4";
if ([platform isEqualToString:@"iPhone4,1"]) return @"iPhone 4S";
if ([platform isEqualToString:@"iPhone5,1"]) return @"iPhone 5";
if ([platform isEqualToString:@"iPhone5,2"]) return @"iPhone 5";
if ([platform isEqualToString:@"iPhone5,3"]) return @"iPhone 5c";
if ([platform isEqualToString:@"iPhone5,4"]) return @"iPhone 5c";
if ([platform isEqualToString:@"iPhone6,1"]) return @"iPhone 5s";
if ([platform isEqualToString:@"iPhone6,2"]) return @"iPhone 5s";
if ([platform isEqualToString:@"iPhone7,1"]) return @"iPhone 6 Plus";
if ([platform isEqualToString:@"iPhone7,2"]) return @"iPhone 6";
if ([platform isEqualToString:@"iPhone8,1"]) return @"iPhone 6s";
if ([platform isEqualToString:@"iPhone8,2"]) return @"iPhone 6s Plus";
if ([platform isEqualToString:@"iPhone8,4"]) return @"iPhone SE";
if ([platform isEqualToString:@"iPhone9,1"]) return @"iPhone 7";
if ([platform isEqualToString:@"iPhone9,2"]) return @"iPhone 7 Plus";
return platform;
}
七赫冬、地理位置
使用CLLocationManager和CLLocation兩個(gè)類
-(void)Collocaction{
self.locationManager = [[CLLocationManager alloc] init];
[self.locationManager requestAlwaysAuthorization];//請求授權(quán)
if ([CLLocationManager locationServicesEnabled]) {
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
self.locationManager.distanceFilter = 200.0f;
[self.locationManager startUpdatingLocation];
}
else {
NSLog(@"請開啟定位功能!");
}
}
//定位代理方法
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
// 獲取當(dāng)前所在的城市名
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
//根據(jù)經(jīng)緯度反向地理編譯出地址信息
[geocoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *array, NSError *error)
{
if (array.count > 0)
{
CLPlacemark *placemark = [array objectAtIndex:0];
//獲取城市
NSString *city = placemark.locality;
if (!city) {
//四大直轄市的城市信息無法通過locality獲得赊堪,只能通過獲取省份的方法來獲得(如果city為空衅鹿,則可知為直轄市)
city = placemark.administrativeArea;
}
//詳細(xì)地址
NSString *location = placemark.name;
//拼接成最終的位置
NSString *myLocation = [NSString stringWithFormat:@"%@%@",city,location];
}
else if (error == nil && [array count] == 0)
{
NSLog(@"No results were returned.");
}
else if (error != nil)
{
NSLog(@"An error occurred = %@", error);
}
}];
//停止定位
[manager stopUpdatingLocation];
}
// 定位失誤時(shí)調(diào)用
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(@"error:%@",error);
}
八截粗、獲取設(shè)備的IP地址
//獲取IP地址
#import <ifaddrs.h>
#import <arpa/inet.h>
#include <net/if.h>
#define IOS_CELLULAR @"pdp_ip0"
#define IOS_WIFI @"en0"
//#define IOS_VPN @"utun0"
#define IP_ADDR_IPv4 @"ipv4"
#define IP_ADDR_IPv6 @"ipv6"
//第一種適合在WiFi情況下使用,但是如果切換到蜂窩數(shù)據(jù)下,則返回?cái)?shù)據(jù)@“error”
//獲取設(shè)備當(dāng)前網(wǎng)絡(luò)IP地址
- (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";
}
//第二種可以獲取蜂窩數(shù)據(jù)下的IP地址
//獲取所有相關(guān)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;
}
// Get IP Address
- (NSString *)getIPAddress {
NSString *address = @"error";
struct ifaddrs *interfaces = NULL;
struct ifaddrs *temp_addr = NULL;
int success = 0;
// retrieve the current interfaces - returns 0 on success
success = getifaddrs(&interfaces);
if (success == 0) {
// Loop through linked list of interfaces
temp_addr = interfaces;
while(temp_addr != NULL) {
if(temp_addr->ifa_addr->sa_family == AF_INET) {
// Check if interface is en0 which is the wifi connection on the iPhone
if([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) {
// Get NSString from C String
address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
}
}
temp_addr = temp_addr->ifa_next;
}
}
// Free memory
freeifaddrs(interfaces);
return address;
}
九喻粹、獲取設(shè)備的位置
#import <CoreLocation/CoreLocation.h>
遵守CLLocationManagerDelegate代理
在info.plist中加入:
//允許在前臺使用時(shí)獲取GPS的描述
定位權(quán)限:Privacy - Location When In Use Usage Description
//允許永久使用GPS描述
定位權(quán)限: Privacy - Location Always Usage Description
在Build Phases 添加CoreLocation.framework庫
{
CLLocationManager *locationmanager;//定位服務(wù)
NSString *currentCity;//當(dāng)前城市
NSString *strlatitude;//經(jīng)度
NSString *strlongitude;//緯度
}
//獲取經(jīng)緯度
[self getLocation];
-(void)getLocation
{
//判斷定位功能是否打開
if ([CLLocationManager locationServicesEnabled]) {
locationmanager = [[CLLocationManager alloc]init];
locationmanager.delegate = self;
[locationmanager requestAlwaysAuthorization];
currentCity = [NSString new];
[locationmanager requestWhenInUseAuthorization];
//設(shè)置尋址精度
locationmanager.desiredAccuracy = kCLLocationAccuracyBest;
locationmanager.distanceFilter = 5.0;
[locationmanager startUpdatingLocation];
}
}
#pragma mark CoreLocation delegate (定位失敗)
//定位失敗后調(diào)用此代理方法
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
//設(shè)置提示提醒用戶打開定位服務(wù)
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"允許定位提示" message:@"請?jiān)谠O(shè)置中打開定位" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"打開定位" style:UIAlertActionStyleDefault handler:nil];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
[alert addAction:okAction];
[alert addAction:cancelAction];
[self presentViewController:alert animated:YES completion:nil];
}
#pragma mark 定位成功后則執(zhí)行此代理方法
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
[locationmanager stopUpdatingHeading];
//舊址
CLLocation *currentLocation = [locations lastObject];
CLGeocoder *geoCoder = [[CLGeocoder alloc]init];
//打印當(dāng)前的經(jīng)度與緯度
NSLog(@"%f,%f",currentLocation.coordinate.latitude,currentLocation.coordinate.longitude);
//反地理編碼
[geoCoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
if (placemarks.count > 0) {
CLPlacemark *placeMark = placemarks[0];
currentCity = placeMark.locality;
if (!currentCity) {
currentCity = @"無法定位當(dāng)前城市";
}
/*看需求定義一個(gè)全局變量來接收賦值*/
NSLog(@"----%@",placeMark.country);//當(dāng)前國家
NSLog(@"%@",currentCity);//當(dāng)前的城市
// NSLog(@"%@",placeMark.subLocality);//當(dāng)前的位置
// NSLog(@"%@",placeMark.thoroughfare);//當(dāng)前街道
// NSLog(@"%@",placeMark.name);//具體地址
}
}];
}