Tools.mm 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  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. {
  154. NSString *address = @"error";
  155. struct ifaddrs *interfaces = NULL;
  156. struct ifaddrs *temp_addr = NULL;
  157. int success = 0;
  158. // retrieve the current interfaces - returns 0 on success
  159. success = getifaddrs(&interfaces);
  160. if (success == 0)
  161. {
  162. // Loop through linked list of interfaces
  163. temp_addr = interfaces;
  164. while(temp_addr != NULL)
  165. {
  166. if(temp_addr->ifa_addr->sa_family == AF_INET)
  167. {
  168. // Check if interface is en0 which is the wifi connection on the iPhone
  169. if([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"])
  170. {
  171. // Get NSString from C String
  172. address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
  173. }
  174. }
  175. temp_addr = temp_addr->ifa_next;
  176. }
  177. }
  178. // Free memory
  179. freeifaddrs(interfaces);
  180. return address;
  181. }
  182. //获取IDFV
  183. + (NSString *)getIDFV
  184. {
  185. NSString * const KEY_USERNAME_PASSWORD = @"com.danson.jiaPeiCo.usernamepassword";
  186. NSString * const KEY_PASSWORD = @"com.danson.jiaPeiCo.password";
  187. //测试用 清除keychain中的内容
  188. // [Tools delete:KEY_USERNAME_PASSWORD];
  189. NSMutableDictionary *readUserPwd = (NSMutableDictionary *)[Tools load:KEY_USERNAME_PASSWORD];
  190. //NSLog(@"keychain------><>%@",readUserPwd);
  191. if (!readUserPwd) {
  192. //如果为空 说明是第一次安装 做存储操作
  193. //IDFV
  194. // NSString *identifierStr = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
  195. // NSMutableDictionary *usernamepasswordKVPairs = [NSMutableDictionary dictionaryWithObject:identifierStr forKey:KEY_PASSWORD];
  196. NSString *adId = [XYUUID uuidForDevice];
  197. // if (@available(iOS 14, *)) {
  198. // [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
  199. // if (status == ATTrackingManagerAuthorizationStatusAuthorized) {
  200. // adId = [[ASIdentifierManager sharedManager] advertisingIdentifier].UUIDString;
  201. // }
  202. // }];
  203. // } else {
  204. // // 使用原方式访问 IDFA
  205. // adId = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
  206. // }
  207. if (!adId) {
  208. // [MBProgressHUD showAutoMessage:@"IDFA还未授权"];
  209. [RQ_SHARE_FUNCTION showAlertWithTitle:@"温馨提示" message:@"获取广告标识失败,请在“设置-优易学车”中,打开“允许追踪”" alertControllerStyle:UIAlertControllerStyleAlert cancelButtonTitle:@"确定" otherButtonTitles:nil otherButtonStyles:nil completion:nil];
  210. return nil;
  211. } else {
  212. if ([adId isEqualToString:@"00000000-0000-0000-0000-000000000000"] || [adId isEqualToString:@"00000000000000000000000000000000"]) {
  213. [RQ_SHARE_FUNCTION showAlertWithTitle:nil message:@"获取广告标识失败,请在“设置-隐私-广告”中,关闭“限制广告跟踪”" alertControllerStyle:UIAlertControllerStyleAlert cancelButtonTitle:@"确定" otherButtonTitles:nil otherButtonStyles:nil completion:nil];
  214. return nil;
  215. } else {
  216. NSMutableDictionary *usernamepasswordKVPairs = [NSMutableDictionary dictionaryWithObject:adId forKey:KEY_PASSWORD];
  217. [Tools save:KEY_USERNAME_PASSWORD data:usernamepasswordKVPairs];
  218. return adId;
  219. }
  220. }
  221. }else{
  222. return [readUserPwd objectForKey:KEY_PASSWORD];
  223. }
  224. }
  225. //存
  226. + (void)save:(NSString *)service data:(id)data {
  227. //Get search dictionary
  228. NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
  229. //Delete old item before add new item
  230. SecItemDelete((__bridge CFDictionaryRef)keychainQuery);
  231. //Add new object to search dictionary(Attention:the data format)
  232. [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(__bridge id)kSecValueData];
  233. //Add item to keychain with the search dictionary
  234. SecItemAdd((__bridge CFDictionaryRef)keychainQuery, NULL);
  235. }
  236. + (NSMutableDictionary *)getKeychainQuery:(NSString *)service {
  237. return [NSMutableDictionary dictionaryWithObjectsAndKeys:
  238. (__bridge id)kSecClassGenericPassword,(__bridge id)kSecClass,
  239. service, (__bridge id)kSecAttrService,
  240. service, (__bridge id)kSecAttrAccount,
  241. (__bridge id)kSecAttrAccessibleAfterFirstUnlock,(__bridge id)kSecAttrAccessible,
  242. nil];
  243. }
  244. //取
  245. + (id)load:(NSString *)service {
  246. id ret = nil;
  247. NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
  248. //Configure the search setting
  249. //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
  250. [keychainQuery setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
  251. [keychainQuery setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
  252. CFDataRef keyData = NULL;
  253. if (SecItemCopyMatching((__bridge CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {
  254. @try {
  255. ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)keyData];
  256. } @catch (NSException *e) {
  257. NSLog(@"Unarchive of %@ failed: %@", service, e);
  258. } @finally {
  259. }
  260. }
  261. if (keyData)
  262. CFRelease(keyData);
  263. return ret;
  264. }
  265. //删除
  266. + (void)delete:(NSString *)service {
  267. NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
  268. SecItemDelete((__bridge CFDictionaryRef)keychainQuery);
  269. }
  270. //data转换为16进制
  271. + (NSString *)convertDataToHexStr:(NSData *)data {
  272. if (!data || [data length] == 0) {
  273. return @"";
  274. }
  275. NSMutableString *string = [[NSMutableString alloc] initWithCapacity:[data length]];
  276. [data enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) {
  277. unsigned char *dataBytes = (unsigned char*)bytes;
  278. for (NSInteger i = 0; i < byteRange.length; i++) {
  279. NSString *hexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) & 0xff];
  280. if ([hexStr length] == 2) {
  281. [string appendString:hexStr];
  282. } else {
  283. [string appendFormat:@"0%@", hexStr];
  284. }
  285. }
  286. }];
  287. return string;
  288. }
  289. //16进制转换为data
  290. + (NSData *)convertHexStrToData:(NSString *)str {
  291. if (!str || [str length] == 0) {
  292. return nil;
  293. }
  294. NSMutableData *hexData = [[NSMutableData alloc] initWithCapacity:8];
  295. NSRange range;
  296. if ([str length] % 2 == 0) {
  297. range = NSMakeRange(0, 2);
  298. } else {
  299. range = NSMakeRange(0, 1);
  300. }
  301. for (NSInteger i = range.location; i < [str length]; i += 2) {
  302. unsigned int anInt;
  303. NSString *hexCharStr = [str substringWithRange:range];
  304. NSScanner *scanner = [[NSScanner alloc] initWithString:hexCharStr];
  305. [scanner scanHexInt:&anInt];
  306. NSData *entity = [[NSData alloc] initWithBytes:&anInt length:1];
  307. [hexData appendData:entity];
  308. range.location += range.length;
  309. range.length = 2;
  310. }
  311. return hexData;
  312. }
  313. - (NSString *)getResultWithHexString:(NSString *)hexString {
  314. if (hexString.length < 8) {
  315. //NSLog(@"验证算法输入数据错误");
  316. return @"erroe";
  317. }
  318. int x = [Tools getHexNumWithString:[hexString substringToIndex:4]];
  319. int y = [Tools getHexNumWithString:[hexString substringFromIndex:4]];
  320. int z = 0x1323;
  321. hexString = [NSString stringWithFormat:@"%x",(x*z+y)^z];
  322. // //NSLog(@"%d,%d,%d,%x,%x,%x<---->%@",x,y,z,x,y,z,hexString);
  323. return hexString;
  324. }
  325. /**
  326. 将原本是16进制数字的字符串转换成计算机可以识别的int型10进制数据
  327. */
  328. + (int)getHexNumWithString:(NSString *)string {
  329. int number = 0;
  330. for (int i = 0; i < string.length; i ++) {
  331. NSString *letterOrNumber = [string substringWithRange:NSMakeRange(string.length - i - 1, 1)];
  332. int a = 0;
  333. if ([letterOrNumber isEqualToString:@"a"] || [letterOrNumber isEqualToString:@"A"]) {
  334. a = 10;
  335. }else if ([letterOrNumber isEqualToString:@"b"] || [letterOrNumber isEqualToString:@"B"]){
  336. a = 11;
  337. }else if ([letterOrNumber isEqualToString:@"c"] || [letterOrNumber isEqualToString:@"C"]){
  338. a = 12;
  339. }else if ([letterOrNumber isEqualToString:@"d"] || [letterOrNumber isEqualToString:@"D"]){
  340. a = 13;
  341. }else if ([letterOrNumber isEqualToString:@"e"] || [letterOrNumber isEqualToString:@"E"]){
  342. a = 14;
  343. }else if ([letterOrNumber isEqualToString:@"f"] || [letterOrNumber isEqualToString:@"F"]){
  344. a = 15;
  345. }else {
  346. a = [letterOrNumber intValue];
  347. }
  348. a = a * pow(16, i);
  349. number += a;
  350. }
  351. return number;
  352. }
  353. //将十六进制的字符串转换成NSString则可使用如下方式
  354. + (NSString *)convertHexStrToString:(NSString *)str {
  355. if (!str || [str length] == 0) {
  356. return nil;
  357. }
  358. NSMutableData *hexData = [[NSMutableData alloc] initWithCapacity:8];
  359. NSRange range;
  360. if ([str length] % 2 == 0) {
  361. range = NSMakeRange(0, 2);
  362. } else {
  363. range = NSMakeRange(0, 1);
  364. }
  365. for (NSInteger i = range.location; i < [str length]; i += 2) {
  366. unsigned int anInt;
  367. NSString *hexCharStr = [str substringWithRange:range];
  368. NSScanner *scanner = [[NSScanner alloc] initWithString:hexCharStr];
  369. [scanner scanHexInt:&anInt];
  370. NSData *entity = [[NSData alloc] initWithBytes:&anInt length:1];
  371. [hexData appendData:entity];
  372. range.location += range.length;
  373. range.length = 2;
  374. }
  375. NSString *string = [[NSString alloc]initWithData:hexData encoding:NSUTF8StringEncoding];
  376. return string;
  377. }
  378. //将NSString转换成十六进制的字符串则可使用如下方式
  379. + (NSString *)convertStringToHexStr:(NSString *)str {
  380. if (!str || [str length] == 0) {
  381. return @"";
  382. }
  383. NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
  384. NSMutableString *string = [[NSMutableString alloc] initWithCapacity:[data length]];
  385. [data enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) {
  386. unsigned char *dataBytes = (unsigned char*)bytes;
  387. for (NSInteger i = 0; i < byteRange.length; i++) {
  388. NSString *hexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) & 0xff];
  389. if ([hexStr length] == 2) {
  390. [string appendString:hexStr];
  391. } else {
  392. [string appendFormat:@"0%@", hexStr];
  393. }
  394. }
  395. }];
  396. return string;
  397. }
  398. @end