I am trying to read large Image file more than 300KB from NSInputStream. But i'm getting only upto 300KB. Other data are missing. Could you please help me if you know. i'm waiting for your valuable answer.
I mentioned my code below :
Call this readAllData method from NSStreamEventsHasBytesAvailable:
- (void)readAllData {
if (_readData == nil) {
_readData = [[NSMutableData data] retain];
}
while ([[_session inputStream] hasBytesAvailable])
{
unsigned int bytesRead = 0;
bytesRead = [[_session inputStream] read:buf maxLength:EAD_INPUT_BUFFER_SIZE];
if (bytesRead) {
NSMutableString *_string = [NSMutableString stringWithString:#""];
for (int i = 0; i < _readData.length; i++) {
unsigned char _byte;
[_readData getBytes:&_byte range:NSMakeRange(i, 1)];
if (_byte >= 32 && _byte < 127) {
[_string appendFormat:#"%c", _byte];
} else {
[_string appendFormat:#"[%d]", _byte];
}
}
[_readData appendBytes:(const void *)buf length:bytesRead];
}
}
NSString *string=[NSString stringWithFormat:#"%d",_readData.length];
UIAlertView *sesView = [[UIAlertView alloc] initWithTitle:#"readDatalength"
message:string
delegate:self
cancelButtonTitle:nil otherButtonTitles:#"OK" , nil];
[sesView show];
}
When method hasBytesAvailable returns NO it doesn't always mean, that NSInputStream is empty. NSInputStream is at end only when its status is NSStreamStatusAtEnd. For example a stream which was been built from NSURL is asynchronous and it has no all bytes immediately after opening. If that is your case you should subscribe to NSInputStream declaring some class as NSStreamDelegate.
Related
I need to read the received bytes and parse them with a custom method, which basically goes through bytes and skips every 0x7D (or a } ). But what happens now is that it does that for only one received packet, and I dont know why that is happening since im calling my method in didUpdateValueForCharacteristic :
- (void) peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
if (error)
{
NSLog(#"Error receiving notification for characteristic %#: %#", characteristic, error);
return;
}
NSLog(#"Received data on a characteristic.");
if (characteristic == self.rxCharacteristic)
{
self.bluetoothData = [[NSMutableData alloc] initWithData:[characteristic value]];
[self unstuff1:[characteristic value]];
NSLog(#"First NSDAta %#", self.bluetoothData);
[self unstuff1:self.bluetoothData];
NSLog(#"Parsed First NSDATA %#", self.bluetoothData);
NSString *stringForPrintingOutToConsole = [[NSString alloc] initWithData:self.bluetoothData encoding:NSASCIIStringEncoding];
[self.delegate didReceiveData:stringForPrintingOutToConsole];
}
else if ([characteristic.UUID isEqual:self.class.hardwareRevisionStringUUID])
{
NSString *hwRevision = #"";
const uint8_t *bytes = characteristic.value.bytes;
for (int i = 0; i < characteristic.value.length; i++)
{
NSLog(#"%x", bytes[i]);
hwRevision = [hwRevision stringByAppendingFormat:#"0x%02x, ", bytes[i]];
}
// this one reads the hardware revision
[self.delegate didReadHardwareRevisionString:[hwRevision substringToIndex:hwRevision.length-2]];
}
}
and a custom method for parsing :
- (NSMutableData *)unstuff1:(NSMutableData *)mutableData {
NSUInteger dataLength = [self.bluetoothData length];
unsigned char *bytes = [self.bluetoothData bytes];
uint16_t i, j = 0;
for (int i = 0; i < dataLength; i++)
{
if (bytes[i] == 0x7D)
{
bytes[j] = bytes[i+1] ^ 0x20;
i++;
} else
{
bytes[j] = bytes[i];
j++;
}
}
return mutableData;
}
if anyone has a clue, i'd highly appreciate help.
I am trying to store text data as compressed blobs.
[db executeUpdate:#"create table blobTable (a text, b blob)"];
[db executeUpdate:#"insert into blobTable (a, b) values (?, compressMe('random text string'))", #"lord of the rings"];
And then I try to query them using:
FMResultSet *rs = [db executeQuery:#"select uncompressMe(b) as k from blobTable where a = ?", #"lord of the rings"];
Where compressMe and uncompressMe are defined as:
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:dbPath];
[queue inDatabase:^(FMDatabase *adb) {
[adb makeFunctionNamed:#"compressMe" maximumArguments:1 withBlock:^(sqlite3_context *context, int aargc, sqlite3_value **aargv) {
if (sqlite3_value_type(aargv[0]) == SQLITE_TEXT) {
#autoreleasepool {
const char *c = (const char *)sqlite3_value_text(aargv[0]);
NSString *s = [NSString stringWithUTF8String:c];
NSLog(#"string to compress: %#", s);
NSData *compressedBody = [self gzipDeflate:[s dataUsingEncoding:NSUTF8StringEncoding]];
sqlite3_result_blob(context, (__bridge const void *)(compressedBody), [compressedBody length], nil);
}
}
else {
NSLog(#"Unknown formart for StringStartsWithH (%d) %s:%d", sqlite3_value_type(aargv[0]), __FUNCTION__, __LINE__);
sqlite3_result_null(context);
}
}];
}];
[queue inDatabase:^(FMDatabase *adb) {
[adb makeFunctionNamed:#"uncompressMe" maximumArguments:1 withBlock:^(sqlite3_context *context, int aargc, sqlite3_value **aargv) {
if (sqlite3_value_type(aargv[0]) == SQLITE_BLOB) {
#autoreleasepool {
NSLog(#"inside uncompressMe");
NSUInteger len = sqlite3_value_bytes(aargv[0]);
Byte *byteData = (Byte*)malloc(len);
memcpy(byteData, sqlite3_value_blob(aargv[0]), len);
NSData *data = [[NSData alloc] initWithBytes:byteData length:len];
NSData *deflatedBody = [self gzipInflate:data];
NSString *deflatedString = [[NSString alloc] initWithData:deflatedBody encoding:NSUTF8StringEncoding];
sqlite3_result_text(context, (__bridge const void *)(deflatedString), -1, SQLITE_UTF8);
}
}
else {
NSLog(#"Unknown formart for StringStartsWithH (%d) %s:%d", sqlite3_value_type(aargv[0]), __FUNCTION__, __LINE__);
sqlite3_result_null(context);
}
}];
}];
For the sake of completeness, the zip functions are defined as such:
- (NSData *)gzipInflate:(NSData*)data
{
if ([data length] == 0) return data;
unsigned full_length = [data length];
unsigned half_length = [data length] / 2;
NSMutableData *decompressed = [NSMutableData dataWithLength: full_length + half_length];
BOOL done = NO;
int status;
z_stream strm;
strm.next_in = (Bytef *)[data bytes];
strm.avail_in = [data length];
strm.total_out = 0;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
if (inflateInit2(&strm, (15+32)) != Z_OK) return nil;
while (!done)
{
// Make sure we have enough room and reset the lengths.
if (strm.total_out >= [decompressed length])
[decompressed increaseLengthBy: half_length];
strm.next_out = [decompressed mutableBytes] + strm.total_out;
strm.avail_out = [decompressed length] - strm.total_out;
// Inflate another chunk.
status = inflate (&strm, Z_SYNC_FLUSH);
if (status == Z_STREAM_END) done = YES;
else if (status != Z_OK) break;
}
if (inflateEnd (&strm) != Z_OK) return nil;
// Set real length.
if (done)
{
[decompressed setLength: strm.total_out];
return [NSData dataWithData: decompressed];
}
else return nil;
}
- (NSData *)gzipDeflate:(NSData*)data
{
if ([data length] == 0) return data;
z_stream strm;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.total_out = 0;
strm.next_in=(Bytef *)[data bytes];
strm.avail_in = [data length];
// Compresssion Levels:
// Z_NO_COMPRESSION
// Z_BEST_SPEED
// Z_BEST_COMPRESSION
// Z_DEFAULT_COMPRESSION
if (deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY) != Z_OK) return nil;
NSMutableData *compressed = [NSMutableData dataWithLength:16384]; // 16K chunks for expansion
do {
if (strm.total_out >= [compressed length])
[compressed increaseLengthBy: 16384];
strm.next_out = [compressed mutableBytes] + strm.total_out;
strm.avail_out = [compressed length] - strm.total_out;
deflate(&strm, Z_FINISH);
} while (strm.avail_out == 0);
deflateEnd(&strm);
[compressed setLength: strm.total_out];
return [NSData dataWithData:compressed];
}
However, the uncompressMe function doesnt seem to succeed. It fails in the Inflate method, which always returns a nil. Any thoughts what I might be doing wrong? I have checked to make sure that the blob column does get populated.
I feel like issue is from below code:
NSUInteger len = sqlite3_value_bytes(aargv[0]);
Byte *byteData = (Byte*)malloc(len);
memcpy(byteData, sqlite3_value_blob(aargv[0]), len);
NSData *data = [[NSData alloc] initWithBytes:byteData length:len];
Try this to load NSData from database instead of creating byte variable and copying it.
const void *bytes = sqlite3_column_blob(statement, 3);
NSData *data = [[NSData alloc] initWithBytes:bytes length:size];
Im writing an IOS application for my first time. It is supposed to connect to a static IP device, and send certain "known" commands to it. But for some reason Im unable to establish a connection.
Bellow are the functions I use to establish my connection, and write data to the port.
-(void)connection//:(NSString *)serviceName forIpAddress:(NSString *)ipAddress forPort:(NSString *)portNo
{
if(input && output)
[self close];
NSString *urlString = [NSString stringWithFormat:#"%.%.%.%", "192.168.3.120"];
NSURL *website = [NSURL URLWithString:urlString];
if (!website) {
NSLog(#"%# is not a valid URL", website);
}
CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)[website host], 43, &readStream, &writeStream);
CFReadStreamSetProperty(readStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
CFWriteStreamSetProperty(writeStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
NSInputStream *input = (__bridge NSInputStream *)readStream;
NSOutputStream *output= (__bridge NSOutputStream *)writeStream;
}
- (void)open {
[input setDelegate:self];
[output setDelegate:self];
[input scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
[output scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode]; [input open];
[output open];
}
-(void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent
{
NSString *event;
switch (streamEvent)
{
case NSStreamEventNone:
event = #"NSStreamEventNone";
break;
case NSStreamEventOpenCompleted:
event = #"NSStreamEventOpenCompleted";
break;
case NSStreamEventHasBytesAvailable:
event = #"NSStreamEventHasBytesAvailable";
if (theStream == input)
{
uint8_t buffer[1024];
NSInteger len;
while ([input hasBytesAvailable])
{
len = [input read:buffer maxLength:1024];
if (len > 0)
{
NSMutableString *output = [[NSMutableString alloc]initWithBytes:buffer length:len encoding:NSUTF8StringEncoding]; NSLog(#"Received data--------------------%#", output);
}
}
}
break;
case NSStreamEventHasSpaceAvailable:
event = #"NSStreamEventHasSpaceAvailable";
break;
case NSStreamEventErrorOccurred:
event = #"NSStreamEventErrorOccurred";
//[self close];
break;
case NSStreamEventEndEncountered:
break; default:
event = #"NSStreamEventEndEncountered";
//[self close];
event = #"Unknown"; break;
}
NSLog(#"event------%#",event);
}
- (void)close
{
[input close];
[output close];
[input removeFromRunLoop:[NSRunLoop currentRunLoop]forMode:NSDefaultRunLoopMode];
[output removeFromRunLoop:[NSRunLoop currentRunLoop]forMode:NSDefaultRunLoopMode];
[input setDelegate:nil];
[output setDelegate:nil];
input = nil;
output = nil;
}
- (void)dataSending:(NSString*)data
{
if(output)
{
if(![output hasSpaceAvailable])
return;
NSData *_data=[data dataUsingEncoding:NSUTF8StringEncoding];
NSInteger data_len = [_data length];
uint8_t *readBytes = (uint8_t *)[_data bytes];
int byteIndex=0;
unsigned int len=0;
while (TRUE)
{
len = ((data_len - byteIndex >= 40960) ? 40960 : (data_len-byteIndex));
if(len==0)
break;
uint8_t buf[len];
(void)memcpy(buf, readBytes, len);
len = [output write:(const uint8_t *)buf maxLength:len];
byteIndex += len;
readBytes += len;
}
NSLog(#"Sent data----------------------%#",data);
}
}
I do call the mentioned functions through that code as a test, and nothing happens
- (IBAction)pumpchange:(id)sender {
[self connection];
[self open];
if ([self.pump backgroundImageForState:(UIControlStateNormal)]==[UIImage imageNamed:#"PumpOff.png"])
{
[self.pump setBackgroundImage:[UIImage imageNamed:#"PumpOn.png"] forState:(UIControlStateNormal)];
[self dataSending:#"pump_on"];
}
else //if ([self.pump backgroundImageForState:(UIControlStateNormal)]==[UIImage imageNamed:#"PumpOn.png"])
{
[self.pump setBackgroundImage:[UIImage imageNamed:#"PumpOff.png"] forState:(UIControlStateNormal)];
[self dataSending:#"pump_off"];
}
[self close];
}
Thanks in Advance
There seem to be some misunderstandings how format strings work, because
NSString *urlString = [NSString stringWithFormat:#"%.%.%.%", "192.168.3.120"];
just gives you the string #"...". Perhaps you meant
NSString *urlString = [NSString stringWithFormat:#"%d.%d.%d.%d", 192, 168, 3, 120];
or
NSString *urlString = [NSString stringWithFormat:#"%s", "192.168.3.120"];
But you don't need a format string at all:
NSString *urlString = #"192.168.3.120";
I have the following AcceptCallBack method and was hoping to add an UIActivityIndicator while the method is running, hence the [mvc performSelectorOnMainThread:#selector(invoke) withObject:nil waitUntilDone:YES];. invoke is the method which makes the UI changes. And then I have this line [mvc performSelectorOnMainThread:#selector(hide) withObject:nil waitUntilDone:YES]; to remove the UIActivityIndicator. However what seem to happen is that invoke only gets called when AcceptCallBack has finished executing. Are AcceptCallBack and invoke not running on two different threads, therefore allowing them to run simultaneously??
void AcceptCallBack(
CFSocketRef socket,
CFSocketCallBackType type,
CFDataRef address,
const void *data,
void *info)
{
NSLog(#"Start Receiving...");
MasterViewController* mvc = (__bridge MasterViewController*)info;
[mvc performSelectorOnMainThread:#selector(invoke) withObject:nil waitUntilDone:YES];
CFReadStreamRef readStream = NULL;
CFWriteStreamRef writeStream = NULL;
CFIndex bytes;
UInt8 buffer[8192];
UInt8 * fileData;
UInt8 recv_len = 0;
/* The native socket, used for various operations */
CFSocketNativeHandle sock = *(CFSocketNativeHandle *) data;
/* Create the read and write streams for the socket */
CFStreamCreatePairWithSocket(kCFAllocatorDefault, sock,
&readStream, &writeStream);
if (!readStream || !writeStream) {
close(sock);
fprintf(stderr, "CFStreamCreatePairWithSocket() failed\n");
return;
}
CFReadStreamOpen(readStream);
CFWriteStreamOpen(writeStream);
bool headerRead = false;
int dataWritten = 0;
NSMutableString* filename = NULL;
NSMutableString * header = [[NSMutableString alloc] init];
while (true) {
memset(buffer, 0, sizeof(buffer));
bytes = CFReadStreamRead(readStream, buffer, sizeof(buffer));
recv_len += bytes;
if (bytes < 0) {
fprintf(stderr, "CFReadStreamRead() failed: %d\n", (int)bytes);
close(sock);
return;
}
if (bytes == 0) {
break;
}
if (!headerRead) {
for (int b=0; b<bytes; b++) {
if (buffer[b] == '\n') {
headerRead = true;
NSLog(#"Header is: %#", header);
NSArray *listItems = [header componentsSeparatedByString:#":"];
filename = [[NSMutableString alloc] init];
[filename appendString:[listItems objectAtIndex:2]];
[filename replaceOccurrencesOfString:#"/" withString:#"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [filename length])];
fileData = (UInt8*)malloc(sizeof(UInt8) * [[listItems objectAtIndex:3] intValue]);
b++;
memcpy(fileData, buffer + b, bytes - b);
dataWritten = bytes - b;
break;
} else {
[header appendFormat:#"%c", buffer[b]];
}
}
} else {
memcpy(fileData + dataWritten, buffer, bytes);
dataWritten += bytes;
}
}
NSString* docFile = [NSTemporaryDirectory() stringByAppendingPathComponent:filename];
NSData * outputData = [[NSData alloc] initWithBytes:fileData length:dataWritten];
if ([outputData writeToFile:docFile atomically:false] == YES) {
NSLog(#"File received and successfully written out to file------------------------------");
MasterViewController * thing = (__bridge MasterViewController*)info;
[thing restClient:NULL loadedFile:docFile];
NSString *destDir = #"/Slide2Me/";
[[thing restClient] uploadFile:filename toPath:destDir
withParentRev:nil fromPath:docFile];
[mvc performSelectorOnMainThread:#selector(hide) withObject:nil waitUntilDone:YES];
} else {
NSLog(#"Failed to write received data to file");
}
}
EDIT
So what I ended up doing to get my desired result is put all the above code in dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0) and sandwich it with the changes I want to make on the main thread like so....
void AcceptCallBack(
CFSocketRef socket,
CFSocketCallBackType type,
CFDataRef address,
const void *data,
void *info)
{
NSLog(#"Start Receiving...");
MasterViewController* mvc = (__bridge MasterViewController*)info;
[mvc performSelectorOnMainThread:#selector(invoke) withObject:nil waitUntilDone:YES];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
[the code above];
});
[mvc performSelectorOnMainThread:#selector(hide) withObject:nil waitUntilDone:YES];
}
You can use GCD to make it multithreaded, and give signal when indicator start and stop.
performSelector... will be executed when function is finished..
and It doesn't say how you call the AcceptCallBack method, I guess it's already on main thread. If it is then you need to call the AcceptCallback in another thread and use below code to perform "invoke" method on main thread.
dispatch_async(dispatch_get_main_queue(), ^{
<do work here>
});
http://developer.apple.com/library/ios/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html#//apple_ref/doc/uid/TP40008091-CH102-SW1
EDIT:
I would do it like this
static dispatch_queue_t processing_queue;
static dispatch_queue_t request_processing_queue() {
if (processing_queue == NULL) {
processing_queue = dispatch_queue_create("com.xxx.processing", 0);
}
return processing_queue;
}
void AcceptCallBack(
CFSocketRef socket,
CFSocketCallBackType type,
CFDataRef address,
const void *data,
void *info)
{
__block MasterViewController* mvc = (__bridge MasterViewController*)info;
dispatch_async(processing_queue(), ^{
dispatch_async(dispatch_get_main_queue(), ^{
[mvc invoke];
});
..... < Do AcceptCallback Code Here >
dispatch_async(dispatch_get_main_queue(), ^{
[mvc hide];
});
});
}
WARNING: This is just pseudo code..
I am desperately trying to figure out how to detect errors when opening TCP streams using NSStream +getStreamsToHost/CFStreamCreatePairWithSocket(). If I do this:
NSInputStream* input = nil;
NSOutputStream* output = nil;
[NSStream getStreamstoHost:[NSHost hostWithName:#"localhost"] port:80 inputStream:&input outputStream:&output];
NSError* error1 = [input streamError];
assert(error1 == nil);
NSStreamStatus status1 = [input streamStatus];
[input open];
NSError* error2 = [input streamError];
assert(error2 == nil);
NSStreamStatus status2 = [input streamStatus];
status1 is NSStreamStatusNotOpen, which is expected. error1 is nil. error2 is also nil, and status2 is NSStreamStatusOpening. If I telnet to the same address, I get connection refused - there is nothing listening on port 80. If I try to connect to some nonsensical address, such as yaddayadda, I get nil streams.
How do I handle errors properly? No example anywhere seems to handle error conditions, and the docs don't say anything about it, other than the streams may be nil. I'm stumped. Don't tell me I have to run the connection through a run loop, just to get proper error handling...?
I know there's always the possibility of using good ol' BSD sockets, but the docs warns against that, as some high level networking features may fail (auto connections over VPN, and similar stuff).
I faced the same problem and this is how i fixed it.
In my case i used the SSL but you can skip that part of code.
NSString *host = #"10.38.129.234";
CFReadStreamRef readStream = NULL;
CFWriteStreamRef writeStream = NULL;
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (CFStringRef)host, 403, &readStream, &writeStream);
[readStream setProperty:NSStreamSocketSecurityLevelSSLv3 forKey:NSStreamSocketSecurityLevelKey];
[readStream setProperty:(id)kCFBooleanFalse forKey:(NSString *)kCFStreamPropertyShouldCloseNativeSocket];
[writeStream setProperty:NSStreamSocketSecurityLevelSSLv3 forKey:NSStreamSocketSecurityLevelKey];
[writeStream setProperty:(id)kCFBooleanFalse forKey:(NSString *)kCFStreamPropertyShouldCloseNativeSocket];
//Setup SSL properties
NSDictionary *settings = [[NSDictionary alloc] initWithObjectsAndKeys:
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredCertificates,
[NSNumber numberWithBool:YES], kCFStreamSSLAllowsAnyRoot,
[NSNumber numberWithBool:NO], kCFStreamSSLValidatesCertificateChain,
#"10.38.129.234",kCFStreamSSLPeerName,
nil];
settings = [settings autorelease];
CFReadStreamSetProperty(readStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings);
CFWriteStreamSetProperty(writeStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings);
//Open the OutputStream
CFWriteStreamOpen(writeStream);
UInt8 buf[] = "your message ";
[self writeToStream:writeStream :buf];
//Read the Stream
CFReadStreamOpen(readStream);
NSString *response = [self readFromStream:readStream];
if(response != nil)
{
NSLog(#"%#",response);
}
UInt8 pull[] = "another message\n";
[self writeToStream:writeStream :pull];
response = [self readFromStream:readStream];
if(response != nil)
{
NSLog(#"%#",response);
}
//Close the readstream
CFReadStreamClose(readStream);
CFRelease(readStream);
readStream = NULL;
//Close the writestream
CFWriteStreamClose(writeStream);
CFRelease(writeStream);
writeStream = NULL;
read over the stream guide at apple LINK
you will see you are suppose to have a method that switches stream events like so
- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {
switch (streamEvent)
{
case NSStreamEventOpenCompleted:
{
DDLogVerbose(#"Stream opened");
break;
}
case NSStreamEventHasBytesAvailable:
{
if(!rawData) {
rawData = [[NSMutableData data] retain];
}
uint8_t buf[1024];
unsigned int len = 0;
len = [(NSInputStream *)theStream read:buf maxLength:1024];
if(len) {
[rawData initWithBytes:buf length:len];
} else {
DDLogVerbose(#"no buffer!");
}
const uint8_t *bytes = [rawData bytes];
NSMutableArray *mutableBuffer = [[NSMutableArray alloc] initWithCapacity:len];
for (int i =0; i < [rawData length]; i++) {
[mutableBuffer addObject:[NSString stringWithFormat:#"%02X", bytes[i]]];
}
[self gateKeeper:mutableBuffer];
[mutableBuffer release];
break;
}
case NSStreamEventErrorOccurred:
{
if ([theStream isKindOfClass:[NSInputStream class]]) {
NSString* address = [self getAddress];
NSString* myIPAdress = [NSString stringWithFormat:#"IP Address: %#", address];
//[cClient updateRequest];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Cant Connect" message:[NSString stringWithFormat:#"Cant connect to server: %#, Make sure you are connected to the proper wireless network. Your Ip Address is %#",CCV.ipAddress,myIPAdress] delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:#"Reconnect", nil];
[alert show];
[alert release];
}
break;
}
case NSStreamEventEndEncountered:
{
[theStream close];
[theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[theStream release];
break;
}
case NSStreamEventHasSpaceAvailable:
{
//DDLogVerbose(#"has space available");
break;
}
case NSStreamEventNone:
{
DDLogVerbose(#"none");
break;
}
default:
{
DDLogVerbose(#"Unknown event");
}
}
}
What you need to do is either poll for the status using the streamStatus method on the input stream, or schedule the streams for events in a run loop. To better provide error information about erroneous host names, it's better to resolve the name before hand using either NSHost or CFHost.