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

Parameters
inputStream
Upon return, the input stream for the receiver.
outputStream
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");
    return;
}
_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.