Search code examples
objective-cgcdasyncsocket

IOS GCDAsyncSocket didReadData not called when implement in NSObject class


Im implementing GCDAsyncSocket delegate in NSObject class, then call it in viewController. When running it, i found 'didConnectToHost' and 'didWriteDataWithTag' is called, but i didn't see 'didReadData' called. Here is my code:

SocketUtils.h

@interface SocketUtils : NSObject <GCDAsyncSocketDelegate>
@property (nonatomic) void (^SocketCallback)(id data);
@property (nonatomic) NSString *message;
@property (nonatomic) UIViewController *vc;
+ (SocketUtils *) createSocket:(NSString *)message inViewController:(UIViewController *)vc;
- (void) connectToSocket;
@end

SocketUtils.m

@implementation SocketUtils{
    GCDAsyncSocket *socket;
}

+ (SocketUtils *) createSocket:(NSString *)message inViewController:(UIViewController *)vc{
    SocketUtils *this = [[self alloc] init];
    this.message = message;
    [this connectToSocket];
    return this;
}

- (void)connectToSocket{
    socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
    NSError *err = nil;
    if (![socket connectToHost:SOCKET_IP onPort:[SOCKET_PORT intValue] error:&err])
    {
        NSLog(@"err: %@", [err localizedDescription]);
        if(err){
            [Utils showErrorDialog:[err localizedDescription] atViewController:_vc];
        }
        return;
    }
}

#pragma mark - Socket delegate
- (void)socket:(GCDAsyncSocket *)sender didConnectToHost:(NSString *)host port:(UInt16)port
{
    NSLog(@"Cool,didConnectToHost: %@", host);
    [socket writeData:[_message dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];
}

- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag
{
    [socket readDataWithTimeout:-1 tag:0];
    NSLog(@"didWriteDataWithTag: %ld", tag);
}

- (void)socket:(GCDAsyncSocket *)sender didReadData:(NSData *)data withTag:(long)tag
{
    NSLog(@"didReadData : %@", data);
    NSData *strData = [data subdataWithRange:NSMakeRange(0, [data length])];
    NSString *msg = [[NSString alloc] initWithData:strData encoding:NSUTF8StringEncoding];
    _SocketCallback(msg);
}

- (void)socketDidCloseReadStream:(GCDAsyncSocket *)sock{
    NSLog(@"socketDidCloseReadStream");
}

-(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err{
    NSLog(@"disconnected to socket: %@", err);
    [Utils showErrorDialog:[err localizedDescription] atViewController:_vc];
}

- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket
{
    NSLog(@"Accepted new socket from %@:%hu", [newSocket connectedHost], [newSocket connectedPort]);
}

Then in viewController i called:

socketUtils = [SocketUtils createSocket:@"GET_BOARD_CODE" inViewController:self];
    socketUtils.SocketCallback = ^(id data) {
        doSth();
    };

The first thing that I predict is the destroying of this class, but i try to keep all @property = strong, but not work.

Can anyone help?


Solution

  • after many times to search, i realized that i forgot to append "\r\n" to message. Okey just change 1 line of code to:

    this.message = [message stringByAppendingString:@"\r\n"];
    

    And it work as expect.