Friday, June 21, 2013

NSNetService getInputStream example in Objective C (iOS).

NSNetService getInputStream

Retrieves by reference the input and output streams for the receiver and returns a Boolean value that indicates whether they were retrieved successfully.

- (BOOL)getInputStream:(NSInputStream **)inputStream outputStream:(NSOutputStream **)outputStream

Upon return, the input stream for the receiver.
Upon return, the output stream for the receiver.

Return Value
YES if the streams are created successfully, otherwise NO.

Discussion of [NSNetService getInputStream]
After this method is called, no delegate callbacks are called by the receiver.

NSNetService getInputStream example.
Don't believe everything apple claims,

There are a lot of problems with setting up streams with the NSNetworkService.

It will work if you do the following:

First obtain a port to publish the network on. DO NOT PICK A PORT YOURSELF.

Then you can use that port for publishing the network.

Get the client streams with:

[nService qNetworkAdditions_getInputStream:&istream outputStream:&ostream];
The error a lot of programmers make is publishing a network by picking a port themselves and then opening the streams with

[nService qNetworkAdditions_getInputStream:&istream outputStream:&ostream];
The streams will not open....

conclusion: publish by first obtaining a port and then use something like:

self.netService = [[NSNetService alloc] initWithDomain:@"local" type:@"_xxx._tcp." name:serviceName port:(int) self.port];
open streams with
CFStreamCreatePairWithSocket(kCFAllocatorDefault, nativeSocketHandle, &readStream, &writeStream);
open streams with (you open a connection here)
EchoConnection * connection = [[EchoConnection alloc] initWithInputStream:( NSInputStream *)readStream outputStream:( NSOutputStream *)writeStream];
        [self.connections addObject:connection];
then browse for services and add them

then open streams on the desired services from the one you browsed with

[nService qNetworkAdditions_getInputStream:&istream outputStream:&ostream];
(and open them with [istream open] and [ostream open])

Example of [NSNetService getInputStream].
I have just changed my method as below

NSInputStream  *tempInput  = nil;
NSOutputStream *tempOutput = nil;

// note the following method returns _inStream and _outStream with a retain count that the caller must eventually release
if (![netService getInputStream:&tempInput outputStream:&tempOutput]) {

    NSLog(@"error in get input and output streams");
_inStream  = tempInput;
_outStream = tempOutput;

NSNetService getInputStream example.
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
 if (inputStream && outputStream) [self closeStreams];
 if (indexPath.row) {
NSNetService * selectedService = [serviceList objectAtIndex:indexPath.row];
if ([selectedService getInputStream:&inputStream outputStream:&outputStream]) [self openStreams];
serverLabel.text = [[serviceList objectAtIndex:indexPath.row] name];

End of NSNetService getInputStream example article.