2016-12-08 2 views
6

J'essaie de créer un service Bonjour dans mon application iOS, mais je n'arrive pas à le publier. Seule la méthode déléguée netServiceWillPublish est jamais appelée et le service n'apparaît pas en utilisant DNS-SD.Problèmes Bonjour sur iOS

Voici mon code:

var service: NetService? = nil 

func start() { 
    createSockets() 

    service = NetService(domain: "test", type: "_test._tcp.", name: "Test", port: Int32(port)) 
    service?.delegate = self 
    service?.startMonitoring() 
    service?.publish() 
    service?.setTXTRecord(NetService.data(fromTXTRecord: [ 
     "model": "AppleTV3,2,1".data(using: .utf8)!, 
     "srcvers": "160.10".data(using: .utf8)!, 
     "features": "0x100009FF".data(using: .utf8)!, 
     "deviceId": "b8:53:ac:43:f3:15".data(using: .utf8)!, 
     "pw": "0".data(using: .utf8)!, 
     "rmodel": "MacBookPro10,2".data(using: .utf8)! 
     ])) 

} 

private func createSockets() { 
    ipv4Socket = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_STREAM, IPPROTO_TCP, kCFSocketAutomaticallyReenableAcceptCallBack, socketCallback, nil) 

    var sin = sockaddr_in() 

    memset(&sin, 0, MemoryLayout<sockaddr_in>.size) 
    sin.sin_len = __uint8_t(MemoryLayout<sockaddr_in>.size) 
    sin.sin_family = sa_family_t(AF_INET); /* Address family */ 
    sin.sin_port = in_port_t(port) /* Or a specific port */ 
    sin.sin_addr.s_addr = INADDR_ANY 

    let sincfd = withUnsafePointer(to: &sin) { 
     $0.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout<sockaddr_in>.size) { 
      return CFDataCreate(kCFAllocatorDefault, $0, MemoryLayout<sockaddr_in>.size) 
     } 
    } 

    CFSocketSetAddress(ipv4Socket, sincfd) 

    let socketsource = CFSocketCreateRunLoopSource(
     kCFAllocatorDefault, 
     ipv4Socket, 
     0); 

    CFRunLoopAddSource(
     CFRunLoopGetCurrent(), 
     socketsource, 
     CFRunLoopMode.defaultMode); 
} 

Je suis nouveau à ce type de réseau dans iOS, ce que je fais mal ici?

+2

Peut-être que vous pouvez essayez de garder une référence de votre NetService? Peut-être que ça a été désaffecté. – koropok

+1

Le NetService a une référence au niveau de la classe dans le code qui ne fonctionne pas. Je l'ai juste changé dans le post pour étaler ce que nous faisons, car il est propriétaire. Je mettrai à jour l'extrait de code afin de refléter cela. Merci. – Jake

+0

J'utilise une tierce partie obj-c pour les connexions bonjour et ça marche bien. Je ne sais pas si cela pourrait aider. https://github.com/jdiehl/async-network – koropok

Répondre

5

L'utilisation de service?.publish(options: NetService.Options.listenForConnections) et de ne pas créer le socket a résolu le problème.

Il finit par laisser cette publication crée automatiquement un écouteur TCP pour IPv4 et IPv6 pour le NetService.

d'Apple Documentation:

/* When passed to -publishWithOptions:, in addition to publishing the service, a 
* TCP listener is started for both IPv4 and IPv6 on the port specified by the 
* NSNetService. If the listening port can't be opened, an error is reported using 
* -netService:didNotPublish:. Specify a port number of zero to use a random port. 
* When -netServiceDidPublish: is called, -port will return the actual listening 
* port number. Since the listener only supports TCP, the publish will fail with 
* NSNetServicesBadArgumentError if the NSNetService type does not end with "_tcp". 
* New incoming connections will be delivered in the form of NSStreams via the 
* -netService:didAcceptConnectionWithInputStream:outputStream: delegate method. 
*/ 
@available(iOS 7.0, *) 
public static var listenForConnections: NetService.Options { get }