// // XSHelper.m // nochange // // Created by mac on 2024/10/15. // #import #import "XSHelper.h" NSError* XSErrorFromException(NSException* exception) { NSMutableDictionary* userInfo = [NSMutableDictionary dictionary]; [userInfo setObject:exception.name forKey:NSLocalizedFailureReasonErrorKey]; [userInfo setObject:exception.reason forKey:NSLocalizedDescriptionKey]; if (exception.userInfo) { [userInfo addEntriesFromDictionary:exception.userInfo]; } return [NSError errorWithDomain:@"ExceptionDomain" code:-1 userInfo:userInfo]; } // mach_absolute_time() double XSCalculateElapsedTime(uint64_t start, uint64_t end) { static mach_timebase_info_data_t timebaseInfo; if (timebaseInfo.denom == 0) { mach_timebase_info(&timebaseInfo); } uint64_t elapsed = end - start; uint64_t nanos = elapsed * timebaseInfo.numer / timebaseInfo.denom; return (double)nanos / NSEC_PER_MSEC; } // 小数位保留 float XSRoundToDecimal(float value, int decimalPlaces) { float multiplier = powf(10.0f, decimalPlaces); return roundf(value * multiplier) / multiplier; } void XSAfterNext(int sec, NextCallback next) { // 或使用GCD timer dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(0, 0)); dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, sec * NSEC_PER_SEC, 0); dispatch_source_set_event_handler(timer, ^{ // 延迟操作 next(); }); dispatch_resume(timer); } @interface XSHelper() { } @end @implementation XSHelper + (int)random:(int)min and:(int)max { return min + arc4random_uniform(max - min + 1); } + (NSData *)str2Data:(NSString *)str { return [str dataUsingEncoding:NSUTF8StringEncoding]; } + (NSString *)data2str: (NSData *) data { return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];; } + (BOOL) strIsEmpty: (NSString *)str { if (str == nil) { return YES; } if ([str isEqual:[NSNull null]]) { return YES; } if ([str length] <=0) { return YES; } return NO; } + (bool) isMatch: (NSString *)pattern test:(NSString *)test { NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:nil]; NSUInteger numberOfMatches = [regex numberOfMatchesInString:test options:0 range:NSMakeRange(0, [test length])]; return numberOfMatches > 0; } + (NSDictionary *) json2Dictionary: (NSString *)json { if(json == nil || [json isEqual:[NSNull null]] || [json isEqual:@""]) { return @{}; } return [XSHelper jsonData2Dictionary:[XSHelper str2Data:json]]; } + (NSDictionary *) jsonData2Dictionary: (NSData *)data { NSError *jsonError; NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&jsonError]; if (jsonError) { NSLog(@"json2dic error: %@", jsonError); } return dic; } + (NSData *)obj2JsonData:(id)obj { NSError *error; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:obj options:NSJSONWritingPrettyPrinted error:&error]; return jsonData; } + (NSString *)dic2Json: (NSDictionary *)dict { NSData *jsonData = [XSHelper obj2JsonData:dict]; return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; } + (NSString *)readFileText:(NSString *)path { NSError *error = nil; NSString *content = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; if (error) { NSLog(@"XS- Helper readFileText Error: %@", error.localizedDescription); return nil; } return content; } + (BOOL) saveFile: (NSString *) path data: (NSData *)data { return [data writeToFile:path atomically:YES]; } + (BOOL) saveFile: (NSString *) path text: (NSString *)text { NSData *data = [XSHelper str2Data:text]; return [XSHelper saveFile:path data:data]; } + (void) rmFiles: (NSString *) path { NSFileManager *man = [NSFileManager defaultManager]; if ([man fileExistsAtPath:path]) { NSArray *dirArray = [man contentsOfDirectoryAtPath:path error:nil]; for (NSString * str in dirArray) { NSString *subPath = [path stringByAppendingPathComponent:str]; NSLog(@"XS- del file:%@", subPath); NSError *error; [man removeItemAtPath:subPath error:&error]; if (error) { NSLog(@"XS- Error clearing: %@,,%@", path, error.localizedDescription); } } } else { NSLog(@"XS- %@ not found", path); } } + (NSNumber *)str2num:(NSString *)str { NSNumberFormatter *f = [[NSNumberFormatter alloc] init]; f.numberStyle = NSNumberFormatterDecimalStyle; NSNumber *myNumber = [f numberFromString:str]; return myNumber; } + (NSString *)replaceStr: (NSString *)text oldStr:(NSString *)oldStr newStr: (NSString *)newStr { return [text stringByReplacingOccurrencesOfString:oldStr withString:newStr]; } + (void)replaceMulStr: (NSMutableString *)text oldStr:(NSString *)oldStr newStr: (NSString *)newStr { [text replaceOccurrencesOfString:oldStr withString:newStr options:NSLiteralSearch range:NSMakeRange(0, [text length])]; } + (NSString *)replaceStr: (NSString *)text regex:(NSString *)regex newStr:(NSString *)newStr { NSError *error = nil; NSRegularExpression *nsregex = [NSRegularExpression regularExpressionWithPattern:regex options:0 error:&error]; if (!error) { NSString *newString = [nsregex stringByReplacingMatchesInString:text options:0 range:NSMakeRange(0, [text length]) withTemplate:@"YYYY-MM-DD"]; NSLog(@"%@", newString); // 输出: The date is YYYY-MM-DD return newString; } return text; } /// 编码:A => QQ== + (NSString *)base64Encode:(NSString *)string { // 1. 将字符串转换成二进制数据 NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding]; // 2. 利用 iOS 7.0 的方法,直接 base64 编码 return [data base64EncodedStringWithOptions:0]; } /// 解码:QQ== => A + (NSString *)base64Decode:(NSString *)string { // 1. 将base64编码后的字符串,解码成二进制数据 NSData *data = [[NSData alloc] initWithBase64EncodedString:string options:0]; // 2. 返回解码后的字符串 return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; } //-- img + (UIImage *) imageFromFile:(NSString *) path { return [UIImage imageWithContentsOfFile:path]; } + (NSString *)base64StringFromJpgImage:(UIImage *)image { NSData *imageData = UIImageJPEGRepresentation(image, 0.8); NSString *base64String = [imageData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn]; return base64String; } + (UIImage *)imageFromBase64String:(NSString *)base64String { NSData *imageData = [[NSData alloc] initWithBase64EncodedString:base64String options:NSDataBase64DecodingIgnoreUnknownCharacters]; return [UIImage imageWithData:imageData]; } + (UIImage *)png2jpg:(UIImage *)png { NSData *jpgdata = UIImageJPEGRepresentation(png, 0.8); return [UIImage imageWithData:jpgdata]; } + (double) getCurTime { // 获取当前日期和时间 NSDate *now = [NSDate date]; return [now timeIntervalSince1970]; } // Vision + (void)performOCROnImage:(UIImage *)image callback:(MyOCRCallback)callback { NSLog(@"XS- performOCROnImage"); if (!image) { NSLog(@"XS- No image provided"); callback(@""); return; } // 在后台队列中执行 OCR dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{ // 创建 VNImageRequestHandler VNImageRequestHandler *imageRequestHandler = [[VNImageRequestHandler alloc] initWithCIImage:[CIImage imageWithCGImage:image.CGImage] options:@{}]; // 创建文本识别请求 VNRecognizeTextRequest *textRecognitionRequest = [[VNRecognizeTextRequest alloc] initWithCompletionHandler:^(VNRequest * _Nonnull request, NSError * _Nullable error) { if (error) { NSLog(@"XS- Error: %@", error.localizedDescription); dispatch_async(dispatch_get_main_queue(), ^{ callback(@""); }); return; } NSMutableString *recognizedText = [NSMutableString string]; for (VNRecognizedTextObservation *observation in request.results) { VNRecognizedText *topCandidate = [observation topCandidates:1].firstObject; if (topCandidate) { [recognizedText appendFormat:@"%@\n", topCandidate.string]; } } NSLog(@"XS- Recognized Text:\n%@", recognizedText); // 在主线程上处理结果 dispatch_async(dispatch_get_main_queue(), ^{ callback(recognizedText); }); }]; // 设置识别语言(可选) textRecognitionRequest.recognitionLanguages = @[@"en-US", @"zh-Hans"]; // 执行请求 NSError *error; [imageRequestHandler performRequests:@[textRecognitionRequest] error:&error]; if (error) { NSLog(@"XS- Error performing OCR request: %@", error.localizedDescription); dispatch_async(dispatch_get_main_queue(), ^{ callback(@""); }); } }); } @end @implementation NSData (AES) - (NSData *)aesEncrypt: (NSString *)key iv:(NSString *)iv { return [self AES128operation:kCCEncrypt key:key iv:iv]; } - (NSData *)aesDecrypt: (NSString *)key iv:(NSString *)iv { return [self AES128operation:kCCDecrypt key:key iv:iv]; } - (NSData *)AES128operation:(CCOperation)operation key:(NSString *)key iv:(NSString *)iv { char keyPtr[kCCKeySizeAES128 + 1]; bzero(keyPtr, sizeof(keyPtr)); [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; // IV char ivPtr[kCCBlockSizeAES128 + 1]; bzero(ivPtr, sizeof(ivPtr)); [iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding]; size_t bufferSize = [self length] + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesEncrypted = 0; CCCryptorStatus cryptorStatus = CCCrypt(operation, kCCAlgorithmAES128, kCCOptionPKCS7Padding, keyPtr, kCCKeySizeAES128, ivPtr, self.bytes, self.length, buffer, bufferSize, &numBytesEncrypted); if(cryptorStatus == kCCSuccess) { NSLog(@"Success"); return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; } else { NSLog(@"Error"); } free(buffer); return nil; } @end @implementation NSString (AES) - (NSString *)aesEncrypt: (NSString *)key iv:(NSString *)iv { NSData *data = [[XSHelper str2Data:self] aesEncrypt:key iv:iv]; return [data base64EncodedStringWithOptions:0]; } - (NSString *)aesDecrypt: (NSString *)key iv:(NSString *)iv { NSData *data = [[NSData alloc] initWithBase64EncodedString:self options:0]; NSData *dec = [data aesDecrypt:key iv:iv]; return [XSHelper data2str:dec]; } @end