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

如何在iOS(Swift/Objective-C)中实现类似的Socket调用?

Replicating Java Socket Functionality in iOS (Swift & Objective-C)

Got it, let's break down how to replicate that Java socket request in iOS. Your Java code establishes a TCP socket connection, sends a JSON payload, and reads the response—here's how to do the same using both Swift and Objective-C.

Swift Implementation (Using Network Framework, iOS 12+)

The modern Network framework is Apple's recommended way for socket programming now, since it handles async operations gracefully and fits with iOS's concurrency model.

import Network

func makeSocketRequest() async throws -> String {
    // Define the socket endpoint
    let host = NWEndpoint.Host("socketurl.io")
    let port = NWEndpoint.Port(rawValue: 40008)!
    
    // Create the connection
    let connection = NWConnection(host: host, port: port, using: .tcp)
    
    // Set up state handling
    connection.stateUpdateHandler = { state in
        switch state {
        case .ready:
            print("Connection ready")
        case .failed(let error):
            print("Connection failed: \(error)")
        case .cancelled:
            print("Connection cancelled")
        default:
            break
        }
    }
    
    // Start the connection
    connection.start(queue: .global())
    
    // Prepare the JSON payload
    let jsonPayload = "{\"id\":1,\"method\":\"themethod\"}"
    guard let data = jsonPayload.data(using: .utf8) else {
        throw NSError(domain: "SocketError", code: 0, userInfo: [NSLocalizedDescriptionKey: "Failed to convert JSON to data"])
    }
    
    // Send the data
    connection.send(content: data, completion: .contentProcessed({ error in
        if let error = error {
            print("Send error: \(error)")
        } else {
            print("Payload sent successfully")
        }
    }))
    
    // Receive the response with async/await continuation (better than semaphores for production)
    let responseData = try await withCheckedThrowingContinuation { continuation in
        var accumulatedData = Data()
        
        connection.receive(minimumIncompleteLength: 1, maximumLength: 1024) { content, context, isComplete, error in
            if let error = error {
                continuation.resume(throwing: error)
                return
            }
            
            if let content = content {
                accumulatedData.append(content)
            }
            
            if isComplete {
                continuation.resume(returning: accumulatedData)
            } else {
                // Continue receiving more data if not complete
                connection.receive(minimumIncompleteLength: 1, maximumLength: 1024, completion: $0)
            }
        }
    }
    
    // Cancel the connection
    connection.cancel()
    
    // Convert response data to string
    guard let responseString = String(data: responseData, using: .utf8) else {
        throw NSError(domain: "SocketError", code: 1, userInfo: [NSLocalizedDescriptionKey: "Failed to convert response data to string"])
    }
    
    return responseString
}

Key Notes for Swift:

  • I used withCheckedThrowingContinuation here to make the receive logic fully async/await compliant—this is better practice than semaphores for production code.
  • Always handle connection states and errors to avoid unexpected crashes or hanging connections.
  • The Network framework simplifies TCP socket management and works seamlessly with iOS's async patterns.

Objective-C Implementation (Using NSStream)

If you need to support older iOS versions or prefer Objective-C, you can use NSInputStream and NSOutputStream:

#import <Foundation/Foundation.h>

@interface SocketManager : NSObject <NSStreamDelegate>
@property (nonatomic, strong) NSMutableData *responseData;
@property (nonatomic, strong) dispatch_semaphore_t responseSemaphore;
@end

@implementation SocketManager

- (NSString *)makeSocketRequestWithError:(NSError **)error {
    self.responseData = [NSMutableData data];
    self.responseSemaphore = dispatch_semaphore_create(0);
    
    NSString *host = @"socketurl.io";
    uint16_t port = 40008;
    
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)host, port, &readStream, &writeStream);
    
    NSInputStream *inputStream = (__bridge_transfer NSInputStream *)readStream;
    NSOutputStream *outputStream = (__bridge_transfer NSOutputStream *)writeStream;
    
    inputStream.delegate = self;
    outputStream.delegate = self;
    
    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    
    [inputStream open];
    [outputStream open];
    
    // Wait for connection and response (with 10s timeout)
    dispatch_semaphore_wait(self.responseSemaphore, dispatch_time(DISPATCH_TIME_NOW, 10 * NSEC_PER_SEC));
    
    // Clean up
    [inputStream close];
    [outputStream close];
    [inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    
    if (inputStream.streamError) {
        if (error) *error = inputStream.streamError;
        return nil;
    }
    
    NSString *responseString = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
    return responseString;
}

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode {
    switch (eventCode) {
        case NSStreamEventHasBytesAvailable: {
            uint8_t buffer[1024];
            NSInteger bytesRead = [(NSInputStream *)aStream read:buffer maxLength:sizeof(buffer)];
            if (bytesRead > 0) {
                [self.responseData appendBytes:buffer length:bytesRead];
            }
            break;
        }
        case NSStreamEventEndEncountered:
        case NSStreamEventErrorOccurred: {
            dispatch_semaphore_signal(self.responseSemaphore);
            break;
        }
        case NSStreamEventOpenCompleted: {
            // Send payload once stream is open
            if ([aStream isKindOfClass:[NSOutputStream class]]) {
                NSString *jsonStr = @"{\"id\":1,\"method\":\"themethod\"}";
                NSData *data = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
                [(NSOutputStream *)aStream write:data.bytes maxLength:data.length];
            }
            break;
        }
        default:
            break;
    }
}

@end

Key Notes for Objective-C:

  • This implementation uses NSStreamDelegate to handle stream events asynchronously, which is more reliable than simple loops.
  • A semaphore is used to wait for the response, but in a real app, you might want to use completion blocks instead of blocking the thread.
  • NSStream works on iOS 2.0+, making it a good choice for legacy projects.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:27:09