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

iOS Objective-C中NSURLSessionWebSocketDelegate代理方法未触发求助

潜在原因及解决建议

1. 协议与代理方法签名错误

你的代码里声明的协议是<NSURLWebSocketDelegate>,但正确的协议应为NSURLSessionWebSocketDelegate;同时代理方法的第一个参数类型错误,系统要求的是NSURLSessionWebSocketTask而非NSURLWebSocket。这两个错误会直接导致系统无法识别你的代理实现,进而不会触发代理方法。

解决:

  • 修改协议声明为<NSURLSessionWebSocketDelegate>
  • 修正代理方法的参数与签名:
    - (void)URLSession:(NSURLSession *)session webSocketTask:(NSURLSessionWebSocketTask *)webSocketTask didReceiveMessage:(NSURLSessionWebSocketMessage *)message;
    - (void)URLSession:(NSURLSession *)session webSocketTask:(NSURLSessionWebSocketTask *)webSocketTask didCloseWithCode:(NSURLSessionWebSocketCloseCode)code reason:(NSData *)reason wasClean:(BOOL)wasClean;
    

2. 使用sharedSession导致代理失效

[NSURLSession sharedSession]是系统共享的会话实例,它不支持自定义代理(内部默认无代理执行队列)。用这个会话创建WebSocket任务,代理方法不会被触发。

解决:
创建自定义NSURLSession,明确指定代理和代理队列:

NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
webSocketTask = [session webSocketTaskWithRequest:immutableRequest];

3. WebSocket任务或代理对象被提前释放

如果webSocketTask是局部变量,或者作为代理对象的ViewController被提前释放,系统无法持有代理对象来调用方法。

解决:

  • 将webSocketTask声明为ViewController的强引用属性,确保其生命周期与VC一致:
    @property (strong, nonatomic) NSURLSessionWebSocketTask *webSocketTask;
    
  • 确保代理对象(ViewController)在WebSocket连接存续期间不会被释放,比如避免循环引用的同时维持必要的强引用。

4. 可选补充:连接成功的代理方法

若需要确认连接成功状态,可以补充实现以下代理方法:

- (void)URLSession:(NSURLSession *)session webSocketTask:(NSURLSessionWebSocketTask *)webSocketTask didOpenWithProtocol:(NSString *)protocol {
    // 连接成功后的操作,比如发送初始消息
}

修正后的完整代码示例

@interface YourViewController () <NSURLSessionWebSocketDelegate>
@property (strong, nonatomic) NSURLSessionWebSocketTask *webSocketTask;
@property (strong, nonatomic) NSURLSession *webSocketSession;
@end

@implementation YourViewController

- (void)setupWebSocket {
    NSURL *url = [NSURL URLWithString:@"wss://your-websocket-endpoint.com"];
    NSMutableURLRequest *mutableRequest = [NSMutableURLRequest requestWithURL:url];
    NSURLRequest *immutableRequest = [mutableRequest copy];
    
    // 创建自定义会话
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    self.webSocketSession = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    
    self.webSocketTask = [self.webSocketSession webSocketTaskWithRequest:immutableRequest];
    [self.webSocketTask resume];
}

#pragma mark - NSURLSessionWebSocketDelegate

- (void)URLSession:(NSURLSession *)session webSocketTask:(NSURLSessionWebSocketTask *)webSocketTask didOpenWithProtocol:(NSString *)protocol {
    NSLog(@"WebSocket连接成功");
}

- (void)URLSession:(NSURLSession *)session webSocketTask:(NSURLSessionWebSocketTask *)webSocketTask didReceiveMessage:(NSURLSessionWebSocketMessage *)message {
    if (message.string) {
        NSLog(@"收到文本消息:%@", message.string);
    } else if (message.data) {
        NSLog(@"收到二进制消息:%@", message.data);
    }
}

- (void)URLSession:(NSURLSession *)session webSocketTask:(NSURLSessionWebSocketTask *)webSocketTask didCloseWithCode:(NSURLSessionWebSocketCloseCode)code reason:(NSData *)reason wasClean:(BOOL)wasClean {
    NSString *reasonStr = [[NSString alloc] initWithData:reason encoding:NSUTF8StringEncoding];
    NSLog(@"WebSocket关闭,code:%ld,reason:%@,是否干净关闭:%d", (long)code, reasonStr, wasClean);
}

@end

内容的提问来源于stack exchange,提问作者mohamed mansoor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 13:16:11