For a couple of days I try to implement a App that browses for Bonjour-Services in my Network and display them in the Console (for the first step). I implemented a class with a NSNetServiceBrowser and initialized it as indicated in many posts here. But after finding the Service i cannot resolve it to make the hostname accessible for me.
Service-resolving always leads in an error
-72004 (NSNetServicesBadArgumentError).
I tried to use @"local." as domain or my specific service to finde instead of @"_services._dns-sd._udp." but this all leads to the same result.
//
// Bonjour.m
// BonjourTest
//
// Created by PellePe on 21.07.18.
// Copyright © 2018 PellePe. All rights reserved.
//
#import "Bonjour.h"
#import <Foundation/Foundation.h>
#include <netinet/in.h>
#define SERVICE_DOMAIN @"local"
#define SERVICE_TYPE @"_bonjourTest._tcp"
#define SERVICE_NAME @"Bonjour Test"
@interface Bonjour () <NSNetServiceDelegate, NSNetServiceBrowserDelegate>
@property (nonatomic, strong) NSMutableArray<NSNetService *> *detectedServices;
@property (nonatomic, strong) NSNetServiceBrowser *netServiceBrowser;
@end
@implementation Bonjour
#pragma mark -
#pragma mark Service Browsing
- (BOOL)isBrowsing {
return self.netServiceBrowser != NULL;
}
- (void)startServiceBrowsing:(NSString *)type {
if (self.detectedServices == NULL) {
self.detectedServices = [[NSMutableArray<NSNetService*> alloc] init];
} else {
[self.detectedServices removeAllObjects];
}
self.netServiceBrowser = [[NSNetServiceBrowser alloc] init];
self.netServiceBrowser.includesPeerToPeer = YES;
self.netServiceBrowser.delegate = self;
[self.netServiceBrowser searchForServicesOfType: type // SERVICE_TYPE
inDomain: @""];
}
- (void)stopServiceBrowsing {
assert(self.netServiceBrowser != NULL);
[self.netServiceBrowser stop];
self.netServiceBrowser = NULL;
}
#pragma mark -
#pragma NSNetServiceDelegate
-(void)netServiceWillResolve:(NSNetService *)sender {
NSLog(@"netService will resolve - %@", sender.hostName);
}
- (void)netService:(NSNetService *)sender
didNotResolve:(NSDictionary<NSString *,NSNumber *> *)errorDict {
NSLog(@"netService did not resolve");
for (NSString *key in [errorDict allKeys]) {
NSLog(@"%@: %@", key, [errorDict objectForKey: key]);
}
}
- (void)netServiceDidResolveAddress:(NSNetService *)sender {
NSLog(@"netService did resolve address - %@", sender.hostName);
}
#pragma mark -
#pragma mark NSNetServiceBrowserDelegate
- (void)netServiceBrowserWillSearch:(NSNetServiceBrowser *)browser {
NSLog(@"Browser will search");
}
- (void)netServiceBrowserDidStopSearch:(NSNetServiceBrowser *)browser {
NSLog(@"Browser did stop search");
}
- (void)netServiceBrowser:(NSNetServiceBrowser *)browser didFindService:(NSNetService *)service moreComing:(BOOL)moreComing {
[self.detectedServices addObject: service];
service.delegate = self;
[service resolveWithTimeout: 100];
NSLog(@"Find service: %@ - %@ - %@ (%@)", service.name, service.hostName, service.type, moreComing ? @"YES" : @"No");
}
- (void)netServiceBrowser:(NSNetServiceBrowser *)browser didRemoveService:(NSNetService *)service moreComing:(BOOL)moreComing {
NSLog(@"Remove service: %@ - %@ - %@", service.name, service.hostName, service.type);
}
@end
I searched the net for many hours but couldn't find any hint on the error -72004. Using the NSNetServiceBrowser i have no influence on how the services are initialized.
Does anyone have an idea what goes wrong with it?
So the problem here is that when you search for
_services._dns-sd._udp.you won't get the actual services, but you will get all the service types, so for example.This query will return services that will look like this
and this is valid and you can resolve without problems, but when you browse like this:
the returned service will look like the following:
So to fix that you need to search again with the new type to get the actual services.