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
相关产品推荐
相关产品推荐

