0

I've got the following code, which I know is being run:

ReadDelegate * del = [[ReadDelegate alloc] init];
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;

CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)(@"server.com"), port, &readStream, &writeStream);

NSInputStream * readSock = (__bridge_transfer NSInputStream*)readStream;

[readSock setDelegate:del];
[readSock scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

NSOutputStream * writeSock = (__bridge_transfer NSOutputStream*)writeStream;
[writeSock scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
NSLog(@"Open socket");
[readSock open];
[writeSock open];

[writeSock write:(uint8_t*)("request\0\0\0") maxLength:10];


while (YES) {
     //I'm skipping over inconsequential stuff
}
NSLog(@"finished reading");
[readSock close];
[writeSock close];

return [del getMessage];

My ReadDelegate class is declared like @interface ReadDelegate : NSObject <NSStreamDelegate> and includes a - (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode. That particular function just has a print statement in it to see if it's ever being called. It's not.

I know for a fact that the connection is being opened because my server is receiving the "request\0\0\0" message and the server is sending the file (I have tests in other environments which can receive the file just fine).

However, as mentioned, the ReadDelegate object declared in the beginning (del) never receives the stream message, even once (to say the stream is open or whatever).

Why is the delegate not being called?

River Tam
  • 3,096
  • 4
  • 31
  • 51

1 Answers1

1

It looks like your stream doesn't receive events because of your while loop.

Every new event from a stream can be handled in a new iteration of run loop. But the new iteration can not be started because the current one never finishes.

Pavel Osipov
  • 2,067
  • 1
  • 19
  • 27
  • I don't have my Mac with me, so I'll try this later, but is the run loop not run in a separate thread? Is there a way to make it run on a separate thread? – River Tam Aug 15 '14 at 14:28
  • [NSRunLoop currentRunLoop] runs in a thread from which the call was made and you should not block it if you want to continue handle its events. – Pavel Osipov Aug 15 '14 at 15:09
  • This worked, thank you! By the way, I ran into some sort of permissions problem which stemmed from the fact that the ReadDelegate was being destroyed at the end of this method. So when `stream` was being called, it was calling it on a dealloc'd object. I needed to preserve the ReadDelegate. – River Tam Aug 18 '14 at 21:19
  • This is an architecture problem. Just for testing purposes you can make your delegate as a static global variable. – Pavel Osipov Aug 19 '14 at 08:56
  • What is the best practice for this? I don't want to make the object itself a delegate. – River Tam Aug 20 '14 at 22:41
  • App architecture is a too huge topic for short answers at SO. You can see an example of using NSInputStream in console apps in tests for my POSInputStreamLibrary - https://github.com/pavelosipov/POSInputStreamLibrary. Test case can be considered as simple version of main function. If you want to look at some more rich sketches I can suggest book "Professional iOS Network Programming: Connecting the Enterprise to the iPhone and iPad" - http://bit.ly/1tswwYT – Pavel Osipov Aug 21 '14 at 06:07