Friday, June 21, 2013

NSNetService initWithDomain example in Objective C (iOS).


NSNetService initWithDomain

Returns the receiver, initialized as a network service of a given type and sets the initial host information.

- (id)initWithDomain:(NSString *)domain type:(NSString *)type name:(NSString *)name

Parameters of [NSNetService initWithDomain]
domain
The domain for the service. For the local domain, use @"local." not @"".
type
The network service type.
type must contain both the service type and transport layer information. To ensure that the mDNS responder searches for services, as opposed to hosts, prefix both the service name and transport layer name with an underscore character (“_”). For example, to search for an HTTP service on TCP, you would use the type string "_http._tcp.". Note that the period character at the end of the string, which indicates that the domain name is an absolute name, is required.
name
The name of the service to resolve.

Return Value of [NSNetService initWithDomain]
The receiver, initialized as a network service named name of type type in the domain domain.

Discussion of [NSNetService initWithDomain]
This method is the appropriate initializer to use to resolve a service—to publish a service, use initWithDomain:type:name:port:.

If you know the values for domain, type, and name of the service you wish to connect to, you can create an NSNetService object using this initializer and call resolveWithTimeout: on the result.

You cannot use this initializer to publish a service. This initializer passes an invalid port number to the designated initializer, which prevents the service from being registered. Calling publish on an NSNetService object initialized with this method generates a call to your delegate’s netService:didNotPublish: method with an NSNetServicesBadArgumentError error.

NSNetService initWithDomain example.
I'm not sure, but it looks like the request is not actually scheduled in a run loop for some reason. Maybe try something like this to schedule it?

NSNetService *service = [[[NSNetService alloc] initWithDomain:@"local." type:@"_daap._tcp." name:@"My_Mac"] autorelease];
[service setDelegate:self];
[service scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:@"PrivateMyMacServiceMode"];
[service resolveWithTimeout:8.0];
Stupid question, but are you explicitly implementing NSServiceDelegate protocol or just have the methods?

Example of [NSNetService initWithDomain].
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])

NSNetService initWithDomain example.
#import "ServerController.h"

@interface ServerController ()

-(void)startService;
-(void)stopService;

@end

@implementation ServerController

-(void)awakeFromNib {   
    [self startService];
}

-(void)startService {
    netService = [[NSNetService alloc] initWithDomain:@"" type:@"_cocoaforsci._tcp."
        name:@"" port:7865];
    netService.delegate = self;
    [netService publish];
}

-(void)stopService {
    [netService stop];
    [netService release];
    netService = nil;
}

-(void)dealloc {
    [self stopService];
    [super dealloc];
}

#pragma mark Net Service Delegate Methods
-(void)netService:(NSNetService *)aNetService didNotPublish:(NSDictionary *)dict {
    NSLog(@"Failed to publish: %@", dict);
}

@end

End of NSNetService initWithDomain example article.