// // XSHttpHelper.m // nochange // // Created by mac on 2024/10/23. // #import #import "XSHttpHelper.h" #import "XSHelper.h" #import "XSPhoneConfig.h" #import @interface SSLBypassDelegate : NSObject @end @implementation NSURLSession (SSLBypass) + (NSURLSession *)sessionWithoutSSLValidation { NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; return [NSURLSession sessionWithConfiguration:configuration delegate:[[SSLBypassDelegate alloc] init] delegateQueue:nil]; } @end @implementation SSLBypassDelegate - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler { if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; completionHandler(NSURLSessionAuthChallengeUseCredential, credential); } } @end @interface XSHttpHelper () { @private NSString *apikey; @private NSURLSession *_session; // 新增session实例变量 } @end @implementation XSHttpHelper -(instancetype)init { if (self = [super init]) { apikey = [[XSPhoneConfig sharedInstance] ApiKey]; self.timeoutInterval = 15.0; // 默认超时时间15秒 // 创建并重用一个NSURLSession实例 NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; configuration.timeoutIntervalForRequest = self.timeoutInterval; configuration.timeoutIntervalForResource = self.timeoutInterval; self->_session = [NSURLSession sessionWithConfiguration:configuration delegate:[[SSLBypassDelegate alloc] init] delegateQueue:nil]; return self; } return nil; } // http begin --------- - (void) doGET: (NSString*) urlStr withCallback:(request_callback) callback withError: (error_callback) errorCallback { @try { NSLog(@"XS- doGET URL:%@", urlStr); NSURL *url = [NSURL URLWithString:urlStr]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:self.timeoutInterval]; [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; [request setValue:self->apikey forHTTPHeaderField:@"apikey"]; // 使用重用的session self.dataTask = [self->_session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSLog(@"XS- http get res"); if (error) { NSLog(@"XS- http get error: %@", error); errorCallback(error); } else { NSLog(@"XS- %@;Response:\n%@", urlStr, [XSHelper data2str: data]); callback(data);// do something with the data } }]; [self.dataTask resume]; } @catch (NSException *exception) { NSLog(@"XS- http get exception error,%@", exception); errorCallback(XSErrorFromException(exception)); } } - (NSData *) doGET: (NSString*) urlStr { dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); __block NSData* _data = nil; [self doGET:urlStr withCallback:^(NSData *data) { _data = data; dispatch_semaphore_signal(semaphore); } withError:^(NSError *err) { dispatch_semaphore_signal(semaphore); }]; // 设置超时时间为self.timeoutInterval dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.timeoutInterval * NSEC_PER_SEC)); // 等待信号量 long result = dispatch_semaphore_wait(semaphore, timeout); if (result == 0) { // 在超时之前收到了信号 NSLog(@"doGET end"); } else { // 超时 NSLog(@"doGET 等待超时"); // 取消请求,避免资源浪费 [self.dataTask cancel]; } return _data; } - (void) doPOST: (NSString*) urlStr json: (NSString *)json withCallback:(request_callback) callback withError: (error_callback) errorCallback { @try { NSLog(@"XS- doPOST:%@", urlStr); NSURL *url = [NSURL URLWithString:urlStr]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:self.timeoutInterval]; // 统一超时设置 [request setHTTPMethod:@"POST"]; // 设置请求头 [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; [request setValue:self->apikey forHTTPHeaderField:@"apikey"]; NSLog(@"XS- POST body:\n%@", json); // 将字典转换为JSON数据 NSData *bodyData = [XSHelper str2Data:json]; [request setHTTPBody:bodyData]; // 使用重用的session self.postDataTask = [self->_session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { if (error) { NSLog(@"XS- post error : %@", error); errorCallback(error); } else { NSLog(@"XS- %@;Response:\n%@", urlStr, [XSHelper data2str: data]); callback(data); } }]; [self.postDataTask resume]; } @catch (NSException *exception) { NSLog(@"XS- post exception;%@", exception); errorCallback(XSErrorFromException(exception)); } } - (NSData*) doPOST:(NSString *)urlStr json:(NSString *)json { dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); __block NSData* _data = nil; [self doPOST:urlStr json:json withCallback:^(NSData *data) { _data = data; dispatch_semaphore_signal(semaphore); } withError:^(NSError *err) { dispatch_semaphore_signal(semaphore); }]; // 设置超时时间为self.timeoutInterval dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.timeoutInterval * NSEC_PER_SEC)); // 等待信号量 long result = dispatch_semaphore_wait(semaphore, timeout); if (result == 0) { // 在超时之前收到了信号 NSLog(@"do POST end"); } else { // 超时 NSLog(@"do POST 等待超时"); // 取消请求,避免资源浪费 [self.postDataTask cancel]; } return _data; } - (void)requestNetworkPermissions { NEHotspotConfigurationManager *manager = [NEHotspotConfigurationManager sharedManager]; // 请求本地网络权限 [manager getConfiguredSSIDsWithCompletionHandler:^(NSArray *ssids) { if (ssids) { NSLog(@"已获取网络权限"); } }]; } // 设置网络配置 - (void)setupNetworkConfiguration { NEHotspotConfiguration *config = [[NEHotspotConfiguration alloc] initWithSSID:@"YourSSID"]; [[NEHotspotConfigurationManager sharedManager] applyConfiguration:config completionHandler:^(NSError * _Nullable error) { if (error) { NSLog(@"网络配置错误: %@", error); } else { NSLog(@"网络配置成功"); } }]; } - (void)cancelAllRequests { [self.dataTask cancel]; [self.postDataTask cancel]; self.dataTask = nil; self.postDataTask = nil; } - (void)cancelCurrentGETRequest { [self.dataTask cancel]; self.dataTask = nil; } - (void)cancelCurrentPOSTRequest { [self.postDataTask cancel]; self.postDataTask = nil; } @end