Tools.mm 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. //
  2. // Tools.m
  3. // jiaPei
  4. //
  5. // Created by apple on 16/3/12.
  6. // Copyright © 2016年 JCZ. All rights reserved.
  7. //
  8. #import "Tools.h"
  9. #import "SDSoundPlayer.h"
  10. #import "sys/utsname.h"
  11. //广告标识
  12. #import <AdSupport/ASIdentifierManager.h>
  13. #import "XYUUID.h"
  14. //获取IP地址
  15. #import <ifaddrs.h>
  16. #import <arpa/inet.h>
  17. @implementation Tools
  18. #pragma mark - iphoneX验证
  19. + (BOOL)isIPhoneX {
  20. struct utsname systemInfo;
  21. uname(&systemInfo);
  22. NSString *platform = [NSString stringWithCString:systemInfo.machine encoding:NSASCIIStringEncoding];
  23. if ([platform isEqualToString:@"i386"] || [platform isEqualToString:@"x86_64"]) {
  24. // 模拟器下采用屏幕的高度来判断
  25. return [UIScreen mainScreen].bounds.size.height == 812;
  26. }
  27. // iPhone10,6是美版iPhoneX 感谢hegelsu指出:https://github.com/banchichen/TZImagePickerController/issues/635
  28. BOOL isIPhoneX = [platform isEqualToString:@"iPhone10,3"] || [platform isEqualToString:@"iPhone10,6"];
  29. return isIPhoneX;
  30. }
  31. + (NSString *)getPathWithFileName:(NSString *)fileName
  32. {
  33. NSString *document = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
  34. NSString *filePath = [document stringByAppendingPathComponent:fileName];
  35. return filePath;
  36. }
  37. + (NSString *)isWan:(NSString *)string
  38. {
  39. NSString *newString = string;
  40. if (string.length > 4) {
  41. newString = [NSString stringWithFormat:@"%@.%@万",[string substringToIndex:string.length - 4],[string substringWithRange:NSMakeRange(string.length - 4, 1)]];
  42. }
  43. return newString;
  44. }
  45. //播报声音
  46. +(void)playAudioWithString:(NSString *)string
  47. {
  48. dispatch_async(dispatch_get_main_queue(), ^{
  49. SDSoundPlayer *player = [SDSoundPlayer SDSoundPlayerInit];
  50. [player setDefaultWithVolume:-1.0 rate:0.5 pitchMultiplier:1.2];
  51. [player play:string];
  52. });
  53. }
  54. //验证是否是电话号码
  55. + (BOOL)isMobileNumber:(NSString *)mobileNum
  56. {
  57. // 电信号段:133/153/180/181/189/177
  58. // 联通号段:130/131/132/155/156/185/186/145/176
  59. // 移动号段:134/135/136/137/138/139/150/151/152/157/158/159/182/183/184/187/188/147/178
  60. // 虚拟运营商:170
  61. NSString *MOBILE = @"^1(3[0-9]|4[57]|5[0-35-9]|8[0-9]|7[06-8])\\d{8}$";
  62. NSPredicate *regextestmobile = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", MOBILE];
  63. return [regextestmobile evaluateWithObject:mobileNum];
  64. }
  65. //汉字转拼音
  66. + (NSString *)pinYinFromChinese:(NSString *)chinese
  67. {
  68. if (chinese.length < 1) {
  69. return @"";
  70. }
  71. return [ChineseToPinyin pinyinFromChiniseString:chinese];
  72. }
  73. //根据图片二进制流获取图片格式
  74. + (NSString *)typeForImageData:(NSData *)data {
  75. uint8_t c;
  76. [data getBytes:&c length:1];
  77. switch (c) {
  78. case 0xFF:
  79. return @"jpeg";
  80. case 0x89:
  81. return @"png";
  82. case 0x47:
  83. return @"gif";
  84. case 0x49:
  85. case 0x4D:
  86. return @"tiff";
  87. }
  88. return @"jpg";
  89. }
  90. //烦烦烦 每次返回的都不一样 这里给个方法 解决图片的问题 优先显示photo
  91. + (NSString *)imageStringWithPhotoString:(NSString *)firstString HeadImgString:(NSString *)secondString Type:(NSInteger)type
  92. {
  93. NSString *imgString = @"";
  94. if (type == 1) {
  95. imgString = firstString;
  96. if (imgString && imgString.length > 0) {
  97. NSString *photoString = @"http://fj.jppt.com.cn";
  98. if (imgString && ![imgString hasPrefix:@"http"]){
  99. imgString = [photoString stringByAppendingString:imgString];
  100. }
  101. }else{
  102. imgString = secondString;
  103. if (imgString && ![imgString hasPrefix:@"http"]){
  104. imgString = [imgPreFix stringByAppendingString:imgString];
  105. }
  106. }
  107. }else{
  108. imgString = secondString;
  109. if (imgString && imgString.length > 0) {
  110. if (imgString && ![imgString hasPrefix:@"http"]){
  111. imgString = [imgPreFix stringByAppendingString:imgString];
  112. }
  113. }else{
  114. imgString = firstString;
  115. NSString *photoString = @"http://fj.jppt.com.cn";
  116. if (imgString && ![imgString hasPrefix:@"http"]){
  117. imgString = [photoString stringByAppendingString:imgString];
  118. }
  119. }
  120. }
  121. if (!imgString) {
  122. imgString = @"";
  123. }
  124. return imgString;
  125. }
  126. + (UIImage *)watermarkImage:(UIImage *)img withDic:(NSDictionary *)dic
  127. {
  128. NSString *mark = @"";
  129. int w = img.size.width;
  130. int h = img.size.height;
  131. UIGraphicsBeginImageContext(img.size);
  132. [img drawInRect:CGRectMake(0, 0, w, h)];
  133. NSDictionary *attr = @{
  134. NSFontAttributeName: [UIFont boldSystemFontOfSize:16], //设置字体
  135. NSForegroundColorAttributeName : [UIColor redColor] //设置字体颜色
  136. };
  137. mark = dic[@"up1"];
  138. [mark drawInRect:CGRectMake(10, 10, 200, 20) withAttributes:attr]; //上一
  139. mark = dic[@"up2"];
  140. [mark drawInRect:CGRectMake(10, 35, 200, 20) withAttributes:attr]; //上二
  141. mark = dic[@"down1"];
  142. [mark drawInRect:CGRectMake(w - 170, h - 80 , 170, 20) withAttributes:attr]; //下一
  143. mark = dic[@"down2"];
  144. [mark drawInRect:CGRectMake(w - 170, h - 55 , 170, 20) withAttributes:attr]; //下二
  145. mark = dic[@"down3"];
  146. [mark drawInRect:CGRectMake(w - 170, h - 30 , 170, 20) withAttributes:attr]; //下三
  147. UIImage *aimg = UIGraphicsGetImageFromCurrentImageContext();
  148. UIGraphicsEndImageContext();
  149. return aimg;
  150. }
  151. //获取ip地址
  152. + (NSString *)getIpAddresses {
  153. NSString *address = @"error";
  154. struct ifaddrs *interfaces = NULL;
  155. struct ifaddrs *temp_addr = NULL;
  156. // 获取当前设备的网络接口列表
  157. if (getifaddrs(&interfaces) == 0) {
  158. // 遍历链表中的接口
  159. temp_addr = interfaces;
  160. while (temp_addr != NULL) {
  161. sa_family_t sa_type = temp_addr->ifa_addr->sa_family;
  162. if (sa_type == AF_INET || sa_type == AF_INET6) {
  163. // 检查接口是否为WiFi连接
  164. NSString *iface = [NSString stringWithUTF8String:temp_addr->ifa_name];
  165. if ([iface isEqualToString:@"en0"]) {
  166. // 获取IPv4地址
  167. if (sa_type == AF_INET) {
  168. address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
  169. }
  170. // 获取IPv6地址
  171. else {
  172. char str[INET6_ADDRSTRLEN];
  173. inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)temp_addr->ifa_addr)->sin6_addr), str, INET6_ADDRSTRLEN);
  174. address = [NSString stringWithUTF8String:str];
  175. }
  176. }
  177. }
  178. temp_addr = temp_addr->ifa_next;
  179. }
  180. }
  181. // 释放链表内存
  182. freeifaddrs(interfaces);
  183. return address;
  184. }
  185. //获取IDFV
  186. + (NSString *)getIDFV
  187. {
  188. NSString * const KEY_USERNAME_PASSWORD = @"com.danson.jiaPeiCo.usernamepassword";
  189. NSString * const KEY_PASSWORD = @"com.danson.jiaPeiCo.password";
  190. //测试用 清除keychain中的内容
  191. // [Tools delete:KEY_USERNAME_PASSWORD];
  192. NSMutableDictionary *readUserPwd = (NSMutableDictionary *)[Tools load:KEY_USERNAME_PASSWORD];
  193. //NSLog(@"keychain------><>%@",readUserPwd);
  194. if (!readUserPwd) {
  195. //如果为空 说明是第一次安装 做存储操作
  196. //IDFV
  197. // NSString *identifierStr = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
  198. // NSMutableDictionary *usernamepasswordKVPairs = [NSMutableDictionary dictionaryWithObject:identifierStr forKey:KEY_PASSWORD];
  199. NSString *adId = [XYUUID uuidForDevice];
  200. // if (@available(iOS 14, *)) {
  201. // [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
  202. // if (status == ATTrackingManagerAuthorizationStatusAuthorized) {
  203. // adId = [[ASIdentifierManager sharedManager] advertisingIdentifier].UUIDString;
  204. // }
  205. // }];
  206. // } else {
  207. // // 使用原方式访问 IDFA
  208. // adId = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
  209. // }
  210. if (!adId) {
  211. // [MBProgressHUD showAutoMessage:@"IDFA还未授权"];
  212. [RQ_SHARE_FUNCTION showAlertWithTitle:@"温馨提示" message:@"获取广告标识失败,请在“设置-优易学车”中,打开“允许追踪”" alertControllerStyle:UIAlertControllerStyleAlert cancelButtonTitle:@"确定" otherButtonTitles:nil otherButtonStyles:nil showInWindow:NO completion:nil];
  213. return nil;
  214. } else {
  215. if ([adId isEqualToString:@"00000000-0000-0000-0000-000000000000"] || [adId isEqualToString:@"00000000000000000000000000000000"]) {
  216. [RQ_SHARE_FUNCTION showAlertWithTitle:nil message:@"获取广告标识失败,请在“设置-隐私-广告”中,关闭“限制广告跟踪”" alertControllerStyle:UIAlertControllerStyleAlert cancelButtonTitle:@"确定" otherButtonTitles:nil otherButtonStyles:nil showInWindow:NO completion:nil];
  217. return nil;
  218. } else {
  219. NSMutableDictionary *usernamepasswordKVPairs = [NSMutableDictionary dictionaryWithObject:adId forKey:KEY_PASSWORD];
  220. [Tools save:KEY_USERNAME_PASSWORD data:usernamepasswordKVPairs];
  221. return adId;
  222. }
  223. }
  224. }else{
  225. return [readUserPwd objectForKey:KEY_PASSWORD];
  226. }
  227. }
  228. //存
  229. + (void)save:(NSString *)service data:(id)data {
  230. //Get search dictionary
  231. NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
  232. //Delete old item before add new item
  233. SecItemDelete((__bridge CFDictionaryRef)keychainQuery);
  234. //Add new object to search dictionary(Attention:the data format)
  235. [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(__bridge id)kSecValueData];
  236. //Add item to keychain with the search dictionary
  237. SecItemAdd((__bridge CFDictionaryRef)keychainQuery, NULL);
  238. }
  239. + (NSMutableDictionary *)getKeychainQuery:(NSString *)service {
  240. return [NSMutableDictionary dictionaryWithObjectsAndKeys:
  241. (__bridge id)kSecClassGenericPassword,(__bridge id)kSecClass,
  242. service, (__bridge id)kSecAttrService,
  243. service, (__bridge id)kSecAttrAccount,
  244. (__bridge id)kSecAttrAccessibleAfterFirstUnlock,(__bridge id)kSecAttrAccessible,
  245. nil];
  246. }
  247. //取
  248. + (id)load:(NSString *)service {
  249. id ret = nil;
  250. NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
  251. //Configure the search setting
  252. //Since in our simple case we are expecting only a single attribute to be returned (the password) we can set the attribute kSecReturnData to kCFBooleanTrue
  253. [keychainQuery setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
  254. [keychainQuery setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
  255. CFDataRef keyData = NULL;
  256. if (SecItemCopyMatching((__bridge CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {
  257. @try {
  258. ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)keyData];
  259. } @catch (NSException *e) {
  260. NSLog(@"Unarchive of %@ failed: %@", service, e);
  261. } @finally {
  262. }
  263. }
  264. if (keyData)
  265. CFRelease(keyData);
  266. return ret;
  267. }
  268. //删除
  269. + (void)delete:(NSString *)service {
  270. NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
  271. SecItemDelete((__bridge CFDictionaryRef)keychainQuery);
  272. }
  273. //data转换为16进制
  274. + (NSString *)convertDataToHexStr:(NSData *)data {
  275. if (!data || [data length] == 0) {
  276. return @"";
  277. }
  278. NSMutableString *string = [[NSMutableString alloc] initWithCapacity:[data length]];
  279. [data enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) {
  280. unsigned char *dataBytes = (unsigned char*)bytes;
  281. for (NSInteger i = 0; i < byteRange.length; i++) {
  282. NSString *hexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) & 0xff];
  283. if ([hexStr length] == 2) {
  284. [string appendString:hexStr];
  285. } else {
  286. [string appendFormat:@"0%@", hexStr];
  287. }
  288. }
  289. }];
  290. return string;
  291. }
  292. //16进制转换为data
  293. + (NSData *)convertHexStrToData:(NSString *)str {
  294. if (!str || [str length] == 0) {
  295. return nil;
  296. }
  297. NSMutableData *hexData = [[NSMutableData alloc] initWithCapacity:8];
  298. NSRange range;
  299. if ([str length] % 2 == 0) {
  300. range = NSMakeRange(0, 2);
  301. } else {
  302. range = NSMakeRange(0, 1);
  303. }
  304. for (NSInteger i = range.location; i < [str length]; i += 2) {
  305. unsigned int anInt;
  306. NSString *hexCharStr = [str substringWithRange:range];
  307. NSScanner *scanner = [[NSScanner alloc] initWithString:hexCharStr];
  308. [scanner scanHexInt:&anInt];
  309. NSData *entity = [[NSData alloc] initWithBytes:&anInt length:1];
  310. [hexData appendData:entity];
  311. range.location += range.length;
  312. range.length = 2;
  313. }
  314. return hexData;
  315. }
  316. - (NSString *)getResultWithHexString:(NSString *)hexString {
  317. if (hexString.length < 8) {
  318. //NSLog(@"验证算法输入数据错误");
  319. return @"erroe";
  320. }
  321. int x = [Tools getHexNumWithString:[hexString substringToIndex:4]];
  322. int y = [Tools getHexNumWithString:[hexString substringFromIndex:4]];
  323. int z = 0x1323;
  324. hexString = [NSString stringWithFormat:@"%x",(x*z+y)^z];
  325. // //NSLog(@"%d,%d,%d,%x,%x,%x<---->%@",x,y,z,x,y,z,hexString);
  326. return hexString;
  327. }
  328. /**
  329. 将原本是16进制数字的字符串转换成计算机可以识别的int型10进制数据
  330. */
  331. + (int)getHexNumWithString:(NSString *)string {
  332. int number = 0;
  333. for (int i = 0; i < string.length; i ++) {
  334. NSString *letterOrNumber = [string substringWithRange:NSMakeRange(string.length - i - 1, 1)];
  335. int a = 0;
  336. if ([letterOrNumber isEqualToString:@"a"] || [letterOrNumber isEqualToString:@"A"]) {
  337. a = 10;
  338. }else if ([letterOrNumber isEqualToString:@"b"] || [letterOrNumber isEqualToString:@"B"]){
  339. a = 11;
  340. }else if ([letterOrNumber isEqualToString:@"c"] || [letterOrNumber isEqualToString:@"C"]){
  341. a = 12;
  342. }else if ([letterOrNumber isEqualToString:@"d"] || [letterOrNumber isEqualToString:@"D"]){
  343. a = 13;
  344. }else if ([letterOrNumber isEqualToString:@"e"] || [letterOrNumber isEqualToString:@"E"]){
  345. a = 14;
  346. }else if ([letterOrNumber isEqualToString:@"f"] || [letterOrNumber isEqualToString:@"F"]){
  347. a = 15;
  348. }else {
  349. a = [letterOrNumber intValue];
  350. }
  351. a = a * pow(16, i);
  352. number += a;
  353. }
  354. return number;
  355. }
  356. //将十六进制的字符串转换成NSString则可使用如下方式
  357. + (NSString *)convertHexStrToString:(NSString *)str {
  358. if (!str || [str length] == 0) {
  359. return nil;
  360. }
  361. NSMutableData *hexData = [[NSMutableData alloc] initWithCapacity:8];
  362. NSRange range;
  363. if ([str length] % 2 == 0) {
  364. range = NSMakeRange(0, 2);
  365. } else {
  366. range = NSMakeRange(0, 1);
  367. }
  368. for (NSInteger i = range.location; i < [str length]; i += 2) {
  369. unsigned int anInt;
  370. NSString *hexCharStr = [str substringWithRange:range];
  371. NSScanner *scanner = [[NSScanner alloc] initWithString:hexCharStr];
  372. [scanner scanHexInt:&anInt];
  373. NSData *entity = [[NSData alloc] initWithBytes:&anInt length:1];
  374. [hexData appendData:entity];
  375. range.location += range.length;
  376. range.length = 2;
  377. }
  378. NSString *string = [[NSString alloc]initWithData:hexData encoding:NSUTF8StringEncoding];
  379. return string;
  380. }
  381. //将NSString转换成十六进制的字符串则可使用如下方式
  382. + (NSString *)convertStringToHexStr:(NSString *)str {
  383. if (!str || [str length] == 0) {
  384. return @"";
  385. }
  386. NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
  387. NSMutableString *string = [[NSMutableString alloc] initWithCapacity:[data length]];
  388. [data enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) {
  389. unsigned char *dataBytes = (unsigned char*)bytes;
  390. for (NSInteger i = 0; i < byteRange.length; i++) {
  391. NSString *hexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) & 0xff];
  392. if ([hexStr length] == 2) {
  393. [string appendString:hexStr];
  394. } else {
  395. [string appendFormat:@"0%@", hexStr];
  396. }
  397. }
  398. }];
  399. return string;
  400. }
  401. @end