Fixed ios api

This commit is contained in:
Martin Obrátil 2014-11-12 16:40:46 +01:00
parent d13b37b960
commit 5083cfe79b
4 changed files with 392 additions and 389 deletions

View File

@ -1,19 +1,19 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@interface SocketAdapter : NSObject <NSStreamDelegate> { @interface SocketAdapter : NSObject <NSStreamDelegate> {
@public @public
} }
- (void)connect:(NSString *)host port:(NSNumber*)port; - (void)open:(NSString *)host port:(NSNumber*)port;
- (void)write:(NSArray *)dataArray; - (void)write:(NSArray *)dataArray;
- (void)shutdownWrite; - (void)shutdownWrite;
- (void)close; - (void)close;
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)event; - (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)event;
@property (copy) void (^openEventHandler)(); @property (copy) void (^openEventHandler)();
@property (copy) void (^openErrorEventHandler)(NSString*); @property (copy) void (^openErrorEventHandler)(NSString*);
@property (copy) void (^dataConsumer)(NSArray*); @property (copy) void (^dataConsumer)(NSArray*);
@property (copy) void (^closeEventHandler)(BOOL); @property (copy) void (^closeEventHandler)(BOOL);
@property (copy) void (^errorEventHandler)(NSString*); @property (copy) void (^errorEventHandler)(NSString*);
@end @end

View File

@ -1,189 +1,192 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <netdb.h> #include <netdb.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#import "SocketAdapter.h" #import "SocketAdapter.h"
CFReadStreamRef readStream; CFReadStreamRef readStream;
CFWriteStreamRef writeStream; CFWriteStreamRef writeStream;
NSInputStream *inputStream; NSInputStream *inputStream;
NSOutputStream *outputStream; NSOutputStream *outputStream;
BOOL wasOpenned = FALSE; BOOL wasOpenned = FALSE;
@implementation SocketAdapter @implementation SocketAdapter
- (void)connect:(NSString *)host port:(NSNumber*)port { - (void)open:(NSString *)host port:(NSNumber*)port {
NSLog(@"Setting up connection to %@ : %@", host, [port stringValue]); NSLog(@"Setting up connection to %@ : %@", host, [port stringValue]);
if (![self isIp:host]) { if (![self isIp:host]) {
host = [self resolveIp:host]; host = [self resolveIp:host];
} }
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (__bridge CFStringRef)host, [port intValue], &readStream, &writeStream); CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (__bridge CFStringRef)host, [port intValue], &readStream, &writeStream);
CFReadStreamSetProperty(readStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue); CFReadStreamSetProperty(readStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
CFWriteStreamSetProperty(writeStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue); CFWriteStreamSetProperty(writeStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
if(!CFWriteStreamOpen(writeStream) || !CFReadStreamOpen(readStream)) { if(!CFWriteStreamOpen(writeStream) || !CFReadStreamOpen(readStream)) {
NSLog(@"Error, streams not open"); NSLog(@"Error, streams not open");
@throw [NSException exceptionWithName:@"SocketException" reason:@"Cannot open streams." userInfo:nil]; @throw [NSException exceptionWithName:@"SocketException" reason:@"Cannot open streams." userInfo:nil];
} }
inputStream = (__bridge NSInputStream *)readStream; inputStream = (__bridge NSInputStream *)readStream;
[inputStream setDelegate:self]; [inputStream setDelegate:self];
[inputStream open]; [inputStream open];
outputStream = (__bridge NSOutputStream *)writeStream; outputStream = (__bridge NSOutputStream *)writeStream;
[outputStream open]; [outputStream open];
[self performSelectorOnMainThread:@selector(runReadLoop) withObject:nil waitUntilDone:NO]; [self performSelectorOnMainThread:@selector(runReadLoop) withObject:nil waitUntilDone:NO];
} }
-(BOOL)isIp:(NSString*) host { -(BOOL)isIp:(NSString*) host {
const char *utf8 = [host UTF8String]; const char *utf8 = [host UTF8String];
// Check valid IPv4. // Check valid IPv4.
struct in_addr dst; struct in_addr dst;
int success = inet_pton(AF_INET, utf8, &(dst.s_addr)); int success = inet_pton(AF_INET, utf8, &(dst.s_addr));
if (success != 1) { if (success != 1) {
// Check valid IPv6. // Check valid IPv6.
struct in6_addr dst6; struct in6_addr dst6;
success = inet_pton(AF_INET6, utf8, &dst6); success = inet_pton(AF_INET6, utf8, &dst6);
} }
return (success == 1); return (success == 1);
} }
-(NSString*)resolveIp:(NSString*) host { -(NSString*)resolveIp:(NSString*) host {
NSLog(@"Resolving host: %@", host); NSLog(@"Resolving host: %@", host);
const char *buff = [host cStringUsingEncoding:NSUTF8StringEncoding]; const char *buff = [host cStringUsingEncoding:NSUTF8StringEncoding];
struct hostent *host_entry = gethostbyname(buff); struct hostent *host_entry = gethostbyname(buff);
if(host_entry == NULL) { if(host_entry == NULL) {
@throw [NSException exceptionWithName:@"NSException" reason:@"Cannot resolve hostname." userInfo:nil]; @throw [NSException exceptionWithName:@"NSException" reason:@"Cannot resolve hostname." userInfo:nil];
} }
char *hostCstring = inet_ntoa(*((struct in_addr *)host_entry->h_addr_list[0])); char *hostCstring = inet_ntoa(*((struct in_addr *)host_entry->h_addr_list[0]));
host = [NSString stringWithUTF8String:hostCstring]; host = [NSString stringWithUTF8String:hostCstring];
NSLog(@"Resolved ip: %@", host); NSLog(@"Resolved ip: %@", host);
return host; return host;
} }
- (void)runReadLoop { - (void)runReadLoop {
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
} }
- (void)shutdownWrite { - (void)shutdownWrite {
NSLog(@"Shuting down write on socket."); NSLog(@"Shuting down write on socket.");
[self closeOutputStream]; [self closeOutputStream];
int socket = [self socknumForStream: inputStream]; int socket = [self socknumForStream: inputStream];
shutdown(socket, 1); shutdown(socket, 1);
} }
- (void)closeInputStream { - (void)closeInputStream {
[inputStream close]; [inputStream close];
[inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream setDelegate:nil]; [inputStream setDelegate:nil];
inputStream = nil; inputStream = nil;
} }
- (void)closeOutputStream { - (void)closeOutputStream {
[outputStream close]; [outputStream close];
outputStream = nil; outputStream = nil;
} }
-(int) socknumForStream: (NSStream *)stream -(int) socknumForStream: (NSStream *)stream
{ {
int sock = -1; int sock = -1;
NSData *sockObj = [stream propertyForKey: NSData *sockObj = [stream propertyForKey:
(__bridge NSString *)kCFStreamPropertySocketNativeHandle]; (__bridge NSString *)kCFStreamPropertySocketNativeHandle];
if ([sockObj isKindOfClass:[NSData class]] && if ([sockObj isKindOfClass:[NSData class]] &&
([sockObj length] == sizeof(int)) ) { ([sockObj length] == sizeof(int)) ) {
const int *sockptr = (const int *)[sockObj bytes]; const int *sockptr = (const int *)[sockObj bytes];
sock = *sockptr; sock = *sockptr;
} }
return sock; return sock;
} }
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)event { - (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)event {
switch(event) { switch(event) {
case NSStreamEventOpenCompleted: { case NSStreamEventOpenCompleted: {
self.openEventHandler(); self.openEventHandler();
wasOpenned = TRUE; wasOpenned = TRUE;
break; break;
} }
case NSStreamEventHasBytesAvailable: { case NSStreamEventHasBytesAvailable: {
if(stream == inputStream) { if(stream == inputStream) {
uint8_t buf[65535]; uint8_t buf[65535];
long len = [inputStream read:buf maxLength:65535]; long len = [inputStream read:buf maxLength:65535];
if(len > 0) { if(len > 0) {
NSMutableArray *dataArray = [[NSMutableArray alloc] init]; NSMutableArray *dataArray = [[NSMutableArray alloc] init];
for (long i = 0; i < len; i++) { for (long i = 0; i < len; i++) {
[dataArray addObject:[NSNumber numberWithUnsignedChar:buf[i]]]; [dataArray addObject:[NSNumber numberWithUnsignedChar:buf[i]]];
} }
self.dataConsumer(dataArray); self.dataConsumer(dataArray);
} }
} }
break; break;
} }
case NSStreamEventEndEncountered: { case NSStreamEventEndEncountered: {
if(stream == inputStream) { if(stream == inputStream) {
[self closeInputStream]; [self closeInputStream];
self.closeEventHandler(FALSE); self.closeEventHandler(FALSE);
break; break;
} }
} }
case NSStreamEventErrorOccurred: case NSStreamEventErrorOccurred:
{ {
NSLog(@"Stream event error: %@", [[stream streamError] localizedDescription]); NSLog(@"Stream event error: %@", [[stream streamError] localizedDescription]);
[self close]; if (wasOpenned) {
self.errorEventHandler([[stream streamError] localizedDescription]);
if (wasOpenned) { self.closeEventHandler(TRUE);
self.errorEventHandler([[stream streamError] localizedDescription]); }
self.closeEventHandler(TRUE); else {
} self.errorEventHandler([[stream streamError] localizedDescription]);
else { self.openErrorEventHandler([[stream streamError] localizedDescription]);
self.errorEventHandler([[stream streamError] localizedDescription]); }
self.openErrorEventHandler([[stream streamError] localizedDescription]); //[self closeStreams];
} break;
break; }
} default: {
default: {
break;
break; }
} }
} }
}
- (void)write:(NSArray *)dataArray {
- (void)write:(NSArray *)dataArray { uint8_t buf[dataArray.count];
uint8_t buf[dataArray.count]; for (int i = 0; i < dataArray.count; i++) {
for (int i = 0; i < dataArray.count; i++) { buf[i] = (unsigned char)[[dataArray objectAtIndex:i] integerValue];
buf[i] = (unsigned char)[[dataArray objectAtIndex:i] integerValue]; }
} NSInteger bytesWritten = [outputStream write:buf maxLength:dataArray.count];
NSInteger bytesWritten = [outputStream write:buf maxLength:dataArray.count]; if (bytesWritten == -1) {
if (bytesWritten == -1) { @throw [NSException exceptionWithName:@"SocketException" reason:[outputStream.streamError localizedDescription] userInfo:nil];
@throw [NSException exceptionWithName:@"SocketException" reason:[outputStream.streamError localizedDescription] userInfo:nil]; }
} }
}
- (void)close {
- (void)close { self.closeEventHandler(FALSE);
self.closeEventHandler(FALSE); [self closeStreams];
[self closeOutputStream]; }
[self closeInputStream];
} - (void)closeStreams {
[self closeOutputStream];
[self closeInputStream];
}
@end @end

View File

@ -1,12 +1,12 @@
#import <Cordova/CDV.h> #import <Cordova/CDV.h>
@interface SocketPlugin : CDVPlugin { @interface SocketPlugin : CDVPlugin {
NSMutableDictionary *socketAdapters; NSMutableDictionary *socketAdapters;
} }
-(void) connect: (CDVInvokedUrlCommand *) command; -(void) open: (CDVInvokedUrlCommand *) command;
-(void) write: (CDVInvokedUrlCommand *) command; -(void) write: (CDVInvokedUrlCommand *) command;
-(void) close: (CDVInvokedUrlCommand *) command; -(void) close: (CDVInvokedUrlCommand *) command;
-(void) setOptions: (CDVInvokedUrlCommand *) command; -(void) setOptions: (CDVInvokedUrlCommand *) command;
@end @end

View File

@ -1,173 +1,173 @@
#import "SocketPlugin.h" #import "SocketPlugin.h"
#import "SocketAdapter.h" #import "SocketAdapter.h"
#import <cordova/CDV.h> #import <cordova/CDV.h>
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@implementation SocketPlugin : CDVPlugin @implementation SocketPlugin : CDVPlugin
- (void) connect : (CDVInvokedUrlCommand*) command { - (void) open : (CDVInvokedUrlCommand*) command {
NSString *socketKey = [command.arguments objectAtIndex:0]; NSString *socketKey = [command.arguments objectAtIndex:0];
NSString *host = [command.arguments objectAtIndex:1]; NSString *host = [command.arguments objectAtIndex:1];
NSNumber *port = [command.arguments objectAtIndex:2]; NSNumber *port = [command.arguments objectAtIndex:2];
if (socketAdapters == nil) { if (socketAdapters == nil) {
self->socketAdapters = [[NSMutableDictionary alloc] init]; self->socketAdapters = [[NSMutableDictionary alloc] init];
} }
__block SocketAdapter* socketAdapter = [[SocketAdapter alloc] init]; __block SocketAdapter* socketAdapter = [[SocketAdapter alloc] init];
socketAdapter.openEventHandler = ^ void () { socketAdapter.openEventHandler = ^ void () {
[self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK] callbackId:command.callbackId]; [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK] callbackId:command.callbackId];
[self->socketAdapters setObject:socketAdapter forKey:socketKey]; [self->socketAdapters setObject:socketAdapter forKey:socketKey];
socketAdapter = nil; socketAdapter = nil;
}; };
socketAdapter.openErrorEventHandler = ^ void (NSString *error){ socketAdapter.openErrorEventHandler = ^ void (NSString *error){
[self.commandDelegate [self.commandDelegate
sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:error] sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:error]
callbackId:command.callbackId]; callbackId:command.callbackId];
socketAdapter = nil; socketAdapter = nil;
}; };
socketAdapter.errorEventHandler = ^ void (NSString *error){ socketAdapter.errorEventHandler = ^ void (NSString *error){
NSMutableDictionary *errorDictionaryData = [[NSMutableDictionary alloc] init]; NSMutableDictionary *errorDictionaryData = [[NSMutableDictionary alloc] init];
[errorDictionaryData setObject:@"Error" forKey:@"type"]; [errorDictionaryData setObject:@"Error" forKey:@"type"];
[errorDictionaryData setObject:error forKey:@"errorMessage"]; [errorDictionaryData setObject:error forKey:@"errorMessage"];
[errorDictionaryData setObject:socketKey forKey:@"socketKey"]; [errorDictionaryData setObject:socketKey forKey:@"socketKey"];
[self dispatchEventWithDictionary:errorDictionaryData]; [self dispatchEventWithDictionary:errorDictionaryData];
}; };
socketAdapter.dataConsumer = ^ void (NSArray* dataArray) { socketAdapter.dataConsumer = ^ void (NSArray* dataArray) {
NSMutableDictionary *dataDictionary = [[NSMutableDictionary alloc] init]; NSMutableDictionary *dataDictionary = [[NSMutableDictionary alloc] init];
[dataDictionary setObject:@"DataReceived" forKey:@"type"]; [dataDictionary setObject:@"DataReceived" forKey:@"type"];
[dataDictionary setObject:dataArray forKey:@"data"]; [dataDictionary setObject:dataArray forKey:@"data"];
[dataDictionary setObject:socketKey forKey:@"socketKey"]; [dataDictionary setObject:socketKey forKey:@"socketKey"];
[self dispatchEventWithDictionary:dataDictionary]; [self dispatchEventWithDictionary:dataDictionary];
}; };
socketAdapter.closeEventHandler = ^ void (BOOL hasErrors) { socketAdapter.closeEventHandler = ^ void (BOOL hasErrors) {
NSMutableDictionary *closeDictionaryData = [[NSMutableDictionary alloc] init]; NSMutableDictionary *closeDictionaryData = [[NSMutableDictionary alloc] init];
[closeDictionaryData setObject:@"Close" forKey:@"type"]; [closeDictionaryData setObject:@"Close" forKey:@"type"];
[closeDictionaryData setObject:(hasErrors == TRUE ? @"true": @"false") forKey:@"hasError"]; [closeDictionaryData setObject:(hasErrors == TRUE ? @"true": @"false") forKey:@"hasError"];
[closeDictionaryData setObject:socketKey forKey:@"socketKey"]; [closeDictionaryData setObject:socketKey forKey:@"socketKey"];
[self dispatchEventWithDictionary:closeDictionaryData]; [self dispatchEventWithDictionary:closeDictionaryData];
[self removeSocketAdapter:socketKey]; [self removeSocketAdapter:socketKey];
}; };
[self.commandDelegate runInBackground:^{ [self.commandDelegate runInBackground:^{
@try { @try {
[socketAdapter connect:host port:port]; [socketAdapter open:host port:port];
} }
@catch (NSException *e) { @catch (NSException *e) {
[self.commandDelegate [self.commandDelegate
sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:e.reason] sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:e.reason]
callbackId:command.callbackId]; callbackId:command.callbackId];
socketAdapter = nil; socketAdapter = nil;
} }
}]; }];
} }
- (void) write:(CDVInvokedUrlCommand *) command { - (void) write:(CDVInvokedUrlCommand *) command {
NSString* socketKey = [command.arguments objectAtIndex:0]; NSString* socketKey = [command.arguments objectAtIndex:0];
NSArray *data = [command.arguments objectAtIndex:1]; NSArray *data = [command.arguments objectAtIndex:1];
SocketAdapter *socket = [self getSocketAdapter:socketKey]; SocketAdapter *socket = [self getSocketAdapter:socketKey];
[self.commandDelegate runInBackground:^{ [self.commandDelegate runInBackground:^{
@try { @try {
[socket write:data]; [socket write:data];
[self.commandDelegate [self.commandDelegate
sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK] sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK]
callbackId:command.callbackId]; callbackId:command.callbackId];
} }
@catch (NSException *e) { @catch (NSException *e) {
[self.commandDelegate [self.commandDelegate
sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:e.reason] sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:e.reason]
callbackId:command.callbackId]; callbackId:command.callbackId];
} }
}]; }];
} }
- (void) shutdownWrite:(CDVInvokedUrlCommand *) command { - (void) shutdownWrite:(CDVInvokedUrlCommand *) command {
NSString* socketKey = [command.arguments objectAtIndex:0]; NSString* socketKey = [command.arguments objectAtIndex:0];
SocketAdapter *socket = [self getSocketAdapter:socketKey]; SocketAdapter *socket = [self getSocketAdapter:socketKey];
[self.commandDelegate runInBackground:^{ [self.commandDelegate runInBackground:^{
@try { @try {
[socket shutdownWrite]; [socket shutdownWrite];
[self.commandDelegate [self.commandDelegate
sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK] sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK]
callbackId:command.callbackId]; callbackId:command.callbackId];
} }
@catch (NSException *e) { @catch (NSException *e) {
[self.commandDelegate [self.commandDelegate
sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:e.reason] sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:e.reason]
callbackId:command.callbackId]; callbackId:command.callbackId];
} }
}]; }];
} }
- (void) close:(CDVInvokedUrlCommand *) command { - (void) close:(CDVInvokedUrlCommand *) command {
NSString* socketKey = [command.arguments objectAtIndex:0]; NSString* socketKey = [command.arguments objectAtIndex:0];
SocketAdapter *socket = [self getSocketAdapter:socketKey]; SocketAdapter *socket = [self getSocketAdapter:socketKey];
[self.commandDelegate runInBackground:^{ [self.commandDelegate runInBackground:^{
@try { @try {
[socket close]; [socket close];
[self.commandDelegate [self.commandDelegate
sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK] sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK]
callbackId:command.callbackId]; callbackId:command.callbackId];
} }
@catch (NSException *e) { @catch (NSException *e) {
[self.commandDelegate [self.commandDelegate
sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:e.reason] sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:e.reason]
callbackId:command.callbackId]; callbackId:command.callbackId];
} }
}]; }];
} }
- (void) setOptions: (CDVInvokedUrlCommand *) command { - (void) setOptions: (CDVInvokedUrlCommand *) command {
} }
- (SocketAdapter*) getSocketAdapter: (NSString*) socketKey { - (SocketAdapter*) getSocketAdapter: (NSString*) socketKey {
SocketAdapter* socketAdapter = [self->socketAdapters objectForKey:socketKey]; SocketAdapter* socketAdapter = [self->socketAdapters objectForKey:socketKey];
if (socketAdapter == nil) { if (socketAdapter == nil) {
NSString *exceptionReason = [NSString stringWithFormat:@"Cannot find socketKey: %@. Connection is probably closed.", socketKey]; NSString *exceptionReason = [NSString stringWithFormat:@"Cannot find socketKey: %@. Connection is probably closed.", socketKey];
@throw [NSException exceptionWithName:@"IllegalArgumentException" reason:exceptionReason userInfo:nil]; @throw [NSException exceptionWithName:@"IllegalArgumentException" reason:exceptionReason userInfo:nil];
} }
return socketAdapter; return socketAdapter;
} }
- (void) removeSocketAdapter: (NSString*) socketKey { - (void) removeSocketAdapter: (NSString*) socketKey {
NSLog(@"Removing socket adapter from storage."); NSLog(@"Removing socket adapter from storage.");
[self->socketAdapters removeObjectForKey:socketKey]; [self->socketAdapters removeObjectForKey:socketKey];
} }
- (BOOL) socketAdapterExists: (NSString*) socketKey { - (BOOL) socketAdapterExists: (NSString*) socketKey {
SocketAdapter* socketAdapter = [self->socketAdapters objectForKey:socketKey]; SocketAdapter* socketAdapter = [self->socketAdapters objectForKey:socketKey];
return socketAdapter != nil; return socketAdapter != nil;
} }
- (void) dispatchEventWithDictionary: (NSDictionary*) dictionary { - (void) dispatchEventWithDictionary: (NSDictionary*) dictionary {
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:nil]; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:nil];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
[self dispatchEvent:jsonString]; [self dispatchEvent:jsonString];
} }
- (void) dispatchEvent: (NSString *) jsonEventString { - (void) dispatchEvent: (NSString *) jsonEventString {
NSString *jsToEval = [NSString stringWithFormat : @"window.Socket.dispatchEvent(%@);", jsonEventString]; NSString *jsToEval = [NSString stringWithFormat : @"window.Socket.dispatchEvent(%@);", jsonEventString];
[self.commandDelegate evalJs:jsToEval]; [self.commandDelegate evalJs:jsToEval];
} }
@end @end