You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NSURLConnection迁移至NSURLSession后代理未触发问题求助

解决NSURLSession代理方法未被调用的问题

看起来你在把NSURLConnection迁移到NSURLSession时遇到了代理方法不触发的问题,我帮你梳理下代码里的几个关键错误,改完这些应该就能解决了:

1. 确保NSURLSession被强持有且正确初始化代理

NSURLSession如果是局部变量会被立即释放,而且必须显式指定delegate才能触发代理回调。首先给你的类添加一个强引用的session属性:

@property (strong, nonatomic) NSURLSession *session;

然后修改createSession方法,必须配置delegate和delegateQueue:

- (void)createSession {
    if (!self.session) {
        NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
        // 指定当前类为代理,同时设置回调队列(这里用主队列和你原来的NSURLConnection行为一致)
        self.session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    }
}

注意:不要用[NSURLSession sharedSession],这个默认session不会触发代理方法。

2. 修复didReceiveResponse代理方法,必须调用completionHandler

你当前的实现没有调用传入的completionHandler,这会让NSURLSession不知道如何处理后续响应,直接导致didReceiveData等后续代理方法不触发。修改后:

-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {
    // 建议把receivedData改成类的属性,避免全局变量的问题
    self.receivedData = [[NSMutableData alloc] init];
    // 必须调用这个block,告诉session允许继续接收数据
    completionHandler(NSURLSessionResponseAllow);
}

3. 修复认证挑战代理方法,改用NSURLSession的completionHandler处理

你还在沿用NSURLConnection的challenge.sender方式处理认证,这在NSURLSession里是无效的,必须用传入的completionHandler来完成挑战处理:

-(void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler {
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
        NSURLCredential *cred = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
        // 通过completionHandler告诉session使用这个凭证
        completionHandler(NSURLSessionAuthChallengeUseCredential, cred);
    } else if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodClientCertificate]) {
        // 无客户端证书时继续请求
        completionHandler(NSURLSessionAuthChallengeContinueWithoutCredential, nil);
    } else {
        // 其他认证类型默认处理,避免请求卡住
        completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
    }
}

4. 修复willCacheResponse代理方法,正确调用completionHandler

当前实现没有调用completionHandler,这会导致缓存逻辑异常,需要通过block返回nil来禁用缓存:

-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask willCacheResponse:(NSCachedURLResponse *)proposedResponse completionHandler:(void (^)(NSCachedURLResponse * _Nullable))completionHandler {
    // 传入nil禁用缓存,和你原来的NSURLConnection行为一致
    completionHandler(nil);
}

5. 优化receivedData的使用(可选但推荐)

把全局的receivedData改成类的属性,避免多线程下的问题,同时更符合OC的编码规范:

@property (strong, nonatomic) NSMutableData *receivedData;

后续所有操作都用self.receivedData来替代全局变量。

把这些修改都完成后,你的NSURLSession代理方法应该就能正常触发了,功能也会和原来的NSURLConnection保持一致。

内容的提问来源于stack exchange,提问作者Francis F

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:49:17