如何修改NSURLSessionConfiguration的defaultSessionConfiguration全局配置?
问题根源
每次调用[NSURLSessionConfiguration defaultSessionConfiguration]都会返回全新的配置实例,你修改第一次获取的实例仅改变了该内存对象的状态,不会影响系统后续生成的新实例,因此第二次拿到的configuration2仍为默认的空代理配置。
解决方案:Method Swizzling 拦截默认配置方法
要实现全局修改默认配置,需通过Method Swizzling替换系统的defaultSessionConfiguration方法,让每次调用都自动带上你的代理设置。
具体实现步骤
- 创建
NSURLSessionConfiguration的分类:
// NSURLSessionConfiguration+ProxyOverride.h #import <Foundation/Foundation.h> @interface NSURLSessionConfiguration (ProxyOverride) @end
// NSURLSessionConfiguration+ProxyOverride.m #import "NSURLSessionConfiguration+ProxyOverride.h" #import <objc/runtime.h> #import <CFNetwork/CFNetwork.h> @implementation NSURLSessionConfiguration (ProxyOverride) + (void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ Class class = [self class]; SEL originalSelector = @selector(defaultSessionConfiguration); SEL swizzledSelector = @selector(swizzled_defaultSessionConfiguration); Method originalMethod = class_getClassMethod(class, originalSelector); Method swizzledMethod = class_getClassMethod(class, swizzledSelector); // 安全交换方法实现 BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod)); if (didAddMethod) { class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); } else { method_exchangeImplementations(originalMethod, swizzledMethod); } }); } + (NSURLSessionConfiguration *)swizzled_defaultSessionConfiguration { // 调用原方法获取基础配置 NSURLSessionConfiguration *config = [self swizzled_defaultSessionConfiguration]; // 配置代理参数(使用CFNetwork常量避免拼写错误) NSDictionary *proxyDict = @{ (__bridge NSString *)kCFNetworkProxiesHTTPSEnable: @1, (__bridge NSString *)kCFNetworkProxiesHTTPSProxy: @"localhost", (__bridge NSString *)kCFNetworkProxiesHTTPSPort: @1234, // 如需HTTP代理可补充以下配置 (__bridge NSString *)kCFNetworkProxiesHTTPEnable: @1, (__bridge NSString *)kCFNetworkProxiesHTTPProxy: @"localhost", (__bridge NSString *)kCFNetworkProxiesHTTPPort: @1234 }; config.connectionProxyDictionary = proxyDict; return config; } @end
- 将该分类文件加入项目编译即可,无需额外调用,
+load方法会在App启动阶段自动执行方法交换。
注意事项
- Method Swizzling必须在
+load方法中通过dispatch_once执行,确保仅交换一次,避免重复操作引发异常。 - 如果第三方库使用
[NSURLSession sharedSession],该会话基于首次调用defaultSessionConfiguration的实例创建,只要你的分类在sharedSession初始化前加载(默认App启动阶段即可),就能让第三方库的请求走代理。
内容的提问来源于stack exchange,提问作者Shmulinson
相关产品推荐
相关产品推荐

