Bonjour, also known as zero-configuration networking, enables automatic discovery of devices and services on a local network using industry standard.

Pinned Posts

Posts under Bonjour tag

50 Posts
Sort by:
Post not yet marked as solved
4 Replies
1.2k Views
Hello there, We have an iPad application which uses mDNS to find specific devices on the network then it resolves an IP address so then the application can connect to it through websocket. It has been working for years now. Recently our clients started to update their iPads to iOS 17 and suddenly this functionality stopped working. When I wanted to test out what's going on I found out that when I run the application on an iPad simulator on my macbook it can resolve the IP address immediately but when I run it on an iPad it cannot. That seemed weird so I decided to look into the code and I saw that the NetServiceBrowser api had been deprecated and I thought that maybe that's the problem so I refactored the code to use NWBrowser which was rather easy it found the service, but then when I wanted to meg an NWConnection to it the same error happened. From macOS it works fine but on the iPad the connection's state never gets ready, it hangs on the preparing state. I created a new test application just with this functionality to test it on an iPhone too. Well it seems that the issue is appearing on the iOS too. One other thing to mention, I created a simple node.js application which uses mDNS broadcast to simulate this device which we're trying to connect. The weird part that both the iPad and the iPhone can resolve it's address. I'm curious if something has changed since iOS 16, I couldn't find anything and I don't know where to go next, or how can somebody reproduce this error without the device. Any help is appreciated. Here is my discovery code: import UIKit import Network class ViewController: UIViewController { var browser: NWBrowser! override func viewDidLoad() { super.viewDidLoad() browser = NWBrowser(for: .bonjour(type: "_http._tcp", domain: ""), using: .tcp) browser.stateUpdateHandler = { newState in switch newState { case .failed(let error): print("NW Browser: now in Error state: \(error)") self.browser.cancel() case .ready: print("NW Browser: new bonjour discovery - ready") case .setup: print("NW Browser: ooh, apparently in SETUP state") default: break } } browser.browseResultsChangedHandler = { ( results, changes ) in print("NW Browser: Scan results found:") for result in results { switch result.endpoint { case let .service(name: name, type: _, domain: _, interface: _): // All of our device has 'justfit' in their name if name.uppercased().contains("JUSTFIT"){ print(name) let proto: NWParameters = .tcp if let opt = proto.defaultProtocolStack.internetProtocol as? NWProtocolIP.Options { opt.version = .v4 } let connection = NWConnection(to: result.endpoint, using: proto) connection.stateUpdateHandler = { state in if state == .ready { if let path = connection.currentPath, let endpoint = path.remoteEndpoint { switch(endpoint) { case let .hostPort(host: host, port: port): print("IP: \(host), port: \(port)") break default: break } connection.cancel() } } else { print(state) } } connection.start(queue: .main) } default: break } } } browser.start(queue: .main) } }
Posted
by lcsoka.
Last updated
.
Post not yet marked as solved
1 Replies
442 Views
I'm running a webserver for a specific service on port 8900 I'm using telegraph to run the webserver, so that opens and claims the port. I also want to advertise the service on bonjour - ideally with the correct port. This is trivial with NetService - but that's deprecated, so I should probably move to the Network framework. I can advertise without specifying a port listener = try NWListener(service: service, using: .tcp) but, then my service broadcasts addresses with port:61443 I can advertise using listener = try NWListener(using: .tcp, on: <myport>) however, that fails in my use case because (unsurprisingly) the Listener isn't able to get the port (my server already has it) Is this just a gap in the new API, or am I missing something?
Posted Last updated
.
Post not yet marked as solved
1 Replies
665 Views
I'm currently trying to use an ESP8266, connecting to my home WiFi and starting a mDNS service. Then im trying to discover this service using the bonsoir package in flutter. So far so good. On Android everything works fine, but i want to use the app on the iPhone too. As far as i understood the information in this video 'developer.apple.com' i need to add this to my info.plist: <key>NSLocalNetworkUsageDescription</key> <string>Some understandable text for the user.</string> <key>NSBonjourServices</key> <array> <string>_http._tcp.</string> </array> I wrote a short python script which resolves the service in my network and im getting the following output: Service ESP8266Control._http._tcp.local. added, service info: ServiceInfo(type='_http._tcp.local.', name='ESP8266Control._http._tcp.local.', addresses=[b'\xc0\xa8\x02\xa0'], port=80, weight=0, priority=0, server='ESP8266Control.local.', properties={b'SN': b'10 - 00001'}, interface_index=None) Address: ['192.168.2.160'] Port: 80 Service Name: ESP8266Control._http._tcp.local. Server: ESP8266Control.local. Properties: {b'SN': b'10 - 00001'} My flutter app should be correct because on android everything works as expected. I tried to discover the service in my network by building my app on a mac book for ios. The popup for using the network appears with the defined message "Some understandable text for the user." and i have to confirm the usage of network discovery usage. But when i hit the button in my app to search for my wordclock, the following error is output: [discovery] [28317] Bonsoir has encountered an error during discovery : ["NSNetServicesErrorCode": -72008, "NSNetServicesErrorDomain": 10] [VERBOSE-2:dart_vm_initializer.cc(41)] Unhandled Exception: PlatformException(discoveryError, Bonsoir has encountered an error during discovery., {NSNetServicesErrorCode: -72008, NSNetServicesErrorDomain: 10}, null) Is my syntax wrong in my info.plist? I also tried to use this ESP8266Control._http._tcp. and several combinations with .local at the end, with and without the service name and with _http and _tcp seperated as 2 individual entries. I tried A LOT of combinations, but nothing changes anything. This is one of the combinations i've tried: <array> <string>_ESP8266Control._http._tcp</string> </array> <key>NSLocalNetworkUsageDescription</key> <string>Need access to connect with the clock itself.</string> <key>NSLocationAlwaysUsageDescription</key> <string>This app needs access to location when in the background.</string> <key>NSLocationWhenInUseUsageDescription</key> <string>This app needs access to your location to show nearby networks to connect the Wordclock to.</string> I would apprecciate help so much, we wasted so much time on this and the apple support told they can't help us... Best regards MeisterTubi
Posted Last updated
.
Post not yet marked as solved
1 Replies
400 Views
I have some EPS8266 and ESP32 devices. I used to obtain the IPs of these devices through MDNS and then control them. However, after I upgraded to IOS17, the devices cannot be searched. I can see the name of the device in the Discovery APP, but the IP of the device cannot be loaded. IOS16 and below versions can search for devices normally. Is this intended functionality cut or just a bug?
Posted
by oscailiao.
Last updated
.
Post marked as solved
5 Replies
600 Views
As noted here, https://developer.apple.com/forums/thread/116799 the Network framework probably won't have a connection available when running in the background. We've been using the BGTask for a couple years now to start a URLSession and pull data from a web server. It works very nicely and reliably. Do we have any options if we want to connect to another iPad, though? I ran a test and even if I have a "server" iPad running a Network framework listener (NWListener), and the app is in the foreground and the screen on, a "client" iPad (NWBrowser) cannot connect to the NWListener when trying to connect from the BGTask; it gives a DefunctConnection error. Why does the Network framework not have the network available to it, but a URLSession does? Is this a limitation of the iPad, or the Network framework? If I had an iPad running as a web server like this project, https://github.com/swisspol/GCDWebServer and an iPad client tries to connect a URLSession to it, would that work? If this is an iPad limitation, could I use a MacBook on the network as a web server and connect to that instead?
Posted Last updated
.
Post not yet marked as solved
1 Replies
626 Views
I'm trying to create and advertise a Bonjour service via Network.framework. In Xcode, target, Info tab, I've added the entry to plist: And then written the following code: guard let listener = try? NWListener(service: .init(name: "My Printer Service", type: "_printer._tcp"),using: .tcp) else { return nil } self.listener = listener listener.stateUpdateHandler = { newState in switch newState { case.ready: print("starting") case .failed(let error): print("error: \(error)") default: print(newState) } } listener.start(queue: .main) However, the status is failed with error message: POSIXErrorCode(rawValue: 22): Invalid argument
Posted
by dan101.
Last updated
.
Post marked as solved
2 Replies
485 Views
How can I use the Network framework to establish a "client-server" type relationship between a server iPad and, say, 3 client iPads? I've downloaded the TicTacToe sample app, https://developer.apple.com/documentation/network/building_a_custom_peer-to-peer_protocol which demonstrates nicely a connection between a PeerListener and a PeerBrowser. However, I then tried to make an array of PeerConnection objects rather than a single one, and send data to each one separately from the PeerListener. However, what appears to happen is that the 1st PeerBrowser connects successfully, but when the 2nd PeerBrowser connects, it replaces the 1st PeerBrowser, and both PeerConnection objects in the array point to the 2nd PeerBrowser, so when I send data via either PeerConnection, the data arrives at the 2nd PeerBrowser. Is it possible to do this? If so, how can I establish multiple PeerConnections between 1 "server" iPad and multiple "client" iPads?
Posted Last updated
.
Post not yet marked as solved
0 Replies
14k Views
I regularly get asked questions about local network privacy. This is my attempt to collect together the answers for the benefit of all. Before you delve into the details, familiarise yourself with the basics by watching WWDC 2020 Session 10110 Support local network privacy in your app. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" Local Network Privacy FAQ With local network privacy, any app that wants to interact with devices on your network must ask for permission the first time that it attempts that access. Local network privacy is implemented on iOS, iPadOS, and the current visionOS beta. It’s not implemented on other platforms, including macOS and tvOS. Some common questions about local network privacy are: FAQ-1 What is a local network? FAQ-2 What operations require local network access? FAQ-3 What operations require the multicast entitlement? FAQ-4 Do I need the multicast entitlement? FAQ-5 I’ve been granted the multicast entitlement; how do I enable it? FAQ-6 Can App Clips access the local network? FAQ-7 How does local network privacy work with app extensions? FAQ-8 How do I explicitly trigger the local network privacy alert? FAQ-9 How do I tell whether I’ve been granted local network access? FAQ-10 How do I use the unsatisfied reason property? FAQ-11 Do I need a local network usage description property? FAQ-12 Can I test on the simulator? FAQ-13 Once my app has displayed the local network privacy alert, how can I reset its state so that it shows again? FAQ-14 How do I map my Multipeer Connectivity service type to an entry in the Bonjour services property? FAQ-15 My app presents the local network privacy alert unexpectedly. Is there a way to track down the cause? FAQ-16 On a small fraction of devices my app fails to present the local network privacy alert. What’s going on? FAQ-17 Why does local network privacy get confused when I install two variants of my app? FAQ-18 Can my app trigger the local network privacy alert when the device is on WWAN? Revision History 2023-10-31 Fixed a bug in the top-level FAQ that mistakenly removed some recent changes. Added FAQ-18. 2023-10-19 Added a preamble to clarify that local network privacy is only relevant on specific platforms. 2023-09-14 Added FAQ-17. 2023-08-29 Added FAQ-16. 2023-03-13 Added connecting a UDP socket to FAQ-2. 2022-10-04 Added screen shots to FAQ-11. 2022-09-22 Fixed the pointer from FAQ-9 to FAQ-10. 2022-09-19 Updated FAQ-3 to cover iOS 16 changes. Made other minor editorial changes. 2020-11-12 Made a minor tweak to FAQ-9. 2020-10-17 Added FAQ-15. Added a second suggestion to FAQ-13. 2020-10-16 First posted.
Posted
by eskimo.
Last updated
.
Post not yet marked as solved
0 Replies
340 Views
This post is part of the Local Network Privacy FAQ. Can my app trigger the local network privacy alert when the device is on WWAN? Yes. While the local network privacy alert is most commonly seen when the device is on a Wi-Fi network, that’s not required. It’s possible for your app to trigger the local network privacy alert on a device that is on WWAN. Indeed, the alert can show up even if you: Leave the current Wi-Fi network in Control Center Turn Wi-Fi off in Settings Enable Airplane Mode in Settings Back to the FAQ
Posted
by eskimo.
Last updated
.
Post not yet marked as solved
5 Replies
945 Views
NWTXTRecord dictionary keys are lowercased in iOS 17, on iOS Simulator and the device. Records returned by NWBrowser in the listener block: browser.browseResultsChangedHandler = { result, changes in metadata : ["dvty": “AppName”, "txtvers": "1", "dbid": "50BFB79F"] But the actual keys are: "DvTy", "DbId". So, in iOS 17 all keys were lowercased, but not in any previous versions. And if in the app we were looking for “DvTy” key, nil is returned. The existing app simply stopped working properly in the first iOS 17 betas. Is it a bug or the app should be updated now to check for lowercased keys always? FB12309561
Posted
by Serge.
Last updated
.
Post marked as solved
9 Replies
1.9k Views
I have iPhone named myphone. To get its IP address on local network, I used to do do host myphone.local in Terminal, or just checking if it is alive by ping myphone.local. This basic mDNS function worked every time, but with iOS 17 betas it is not working anymore. Is this intended functionality cut or just a bug?
Posted
by filsav.
Last updated
.
Post not yet marked as solved
4 Replies
635 Views
Hi, We have an app that make HTTP requests to a device on the local network using connect-by-name semantics and for which the name is resolved using mDNS aka mydevice.local. The HTTP request is made using a URLSession (internally using the React-native v0.68.1 fetch implementation) We have a latency problem in the case where the local network router IPv6 is not enabled, under certain conditions. Even though IPv6 is not enabled, our device mDNS resolver advertises the IPv6 AAAA address record of its link-local address (aka fe80::...). From our understanding this seems to be normal, it is the client responsibility to figure out how to contact the host. On iOS 16.0.2 and 16.1.1, we observe in Instruments that the app will first make an attempt on the IPv6 address record alone, timeout after 2 seconds and 3 retries, and then only try the IPv4 address record immediatly after the 3rd IPv6 attempt. For some reason the same name resolution attempts are made for every dataTaskWithRequest calls (even though the same session is reused and not invalidated). This is running on a real iPhone, but the same behavior is observed using the simulator 16.2 instead. The more or less same observation is made if we use Safari rather than our app. We have this latency of 2 seconds, but we can't confirm the same behavior with Instruments. We don't observe this problem on iOS 16.6 and 16.6.1, as well as the simulator running 15.2 (on the same computer running the simulator 16.2). Reading this excellent post and TN3151, we understand that our non-enabled IPv6 is mitigated using the "Happy Eyeballs" algorithm, for which 2 engineers at Apple refined the original algorithm in RFC8305 which is dated end of 2017. From this, we assume that the behavior we see on iOS 16.0.2 and 16.1.1 is incorrect. So for now we assume that this algorithm has been implemented since quite some time in iOS, and we are wondering if something is broken in iOS 16.0 and 16.1? As far as we understand, iOS 16 seems to conform to RFC6724 with an IPv6 preference in its default policy. We understand that all this is a lot of assumptions, but tracking this problem between platforms and accross implementations has been quite intense, so we want to know if we are looking in the right direction. From our observation, it seems that there is something really wrong with iOS 16.0.2 but we also can't believe that would have slip through during Apple beta-test phase either. So if there is something wrong on our side, what could it be? Thanks!
Posted Last updated
.
Post not yet marked as solved
3 Replies
587 Views
I need to get all devices names which are connected to same wifi. I tried NetServiceBrowser, in netServiceBrowser(_ browser: NetServiceBrowser, didFind service: NetService, moreComing: Bool) function I get some devices name like Macbook or iPad with search service type of browser.searchForServices(ofType: "_services._dns-sd._udp.", inDomain: "local.") But in this service type I cant get iPhones. I'm not sure if this is the right way, which framework should I use to accomplish this? Am I on the right track? What permits do I need to get? I need your help. Best regards.
Posted Last updated
.
Post marked as solved
5 Replies
1.3k Views
I'm using the following: mDNSResponder 1790.80.10 Bonjour Conformance Test (BCT) 1.5.2 Linux 6.1.y kernel I'm testing an Airplay 2 speaker as part of our self certification. When BCT gets into the mDNS tests mDNSResponder fails the subsequent conflict test with this message: ERROR 2023-06-12 10:37:29.398711-0500 _sub_conflict 03570: Device did not complete its probing sequence for a new name after a subsequent conflict arose for its previously acquired name. BCT then retries three times with each retry failing with the same message. Am I missing something from my software that interacts with the mdns daemon? Is this a known issue with the posix build for mDNSResponder? What can I do to get this test to pass? Any help would be appreciated. Ethan
Posted Last updated
.
Post not yet marked as solved
1 Replies
589 Views
I installed Gentoo in virtual machine using Apple Virtualization framework. In linux then I installed avahi, configured the network in Bridge mode. Now I want to connect from this virtual machine to other computer in local network. I can see other computers on the local network, and connect with them using local IP address. But for some reason these are not detected using .local domain. I run avahi-browse -at|grep PS3 and it detected 4 entries for this computer: IPV4 _ssh._tcp local IPV6 _ssh._tcp local IPV4 _sftp-ssh._tcp local IPV6 _sftp-ssh._tcp local Also avahi-resolve -n PS3.local correctly detects IPv6 address of this machine. So why cannot I connect with the computer using PS3.local name?
Posted
by DDudycz.
Last updated
.
Post marked as solved
8 Replies
1.1k Views
Is it possible to disable Local network option from xcode, so that do not popup notification to user about turn off /on and user could not disable or enable it
Posted
by Ben77.
Last updated
.
Post marked as solved
25 Replies
10k Views
Hi, I'm new to swift programming and right now writing an app for esp8266-controlled lamp device. My lamp is broadcasting it's own IP through bonjour. So all I want is to discover any lamps in my network (http.tcp) and to read name and value. Is there any example of such implementation? All I found so far is old or a lit bit complicated for such simple question. Thanks in advance!
Posted
by tarantino.
Last updated
.
Post not yet marked as solved
3 Replies
671 Views
I have an system that is designed around a collection of devices (iPhones or iPads) discovered via bonjour and connected with a NWConnection over TCP. Commands issued from one of the devices are sent to each of the peers and should be executed as soon as they are received. The problem I am encountering is a high variability in transit time device to device that I am having a hard time accounting for. By 'high' I am noting anywhere from 20-80ms of latency device to device. CPU utilization on each iPhone is essentially 0. Keepalives are enabled and firing off every 2 seconds. Additionally, the physical devices all have bluetooth off (as recommended in other posts) The interesting part is when I add into the connection mix an iPhone simulator (running on either a M1 MacBook Air, or my M1U Studio). When a command is issued from the simulator instance, all connected devices report back anywhere within ~0-3ms of deviation from the initiator, which is more what I expect from the network. Thinking that it's perhaps the M1 series of chips being far and away more competent than the A15's in the iPhone 13's and 14 that are in my testbed, I added my M1 iPad to the mix. Invoking a command from the iPad has similar variability as invoking it from one of the iPhones. The code is stupid simple and I'm posting here prior to opening up a DTS case in the hope that there's a magic "shouldUseSpeedholes=true" flag I can set. I have gone through several variations: using UDP instead of TCP (worse variations), changing from a listener/browser on each device to a single browser, multiple listener (no difference), changing from keeping things on the main queue (as in the docs) to a separate concurrent high priority dispatch queue (no difference). There is no TLS in the mix. I have tried both allowing peer-to-peer as well as not (no difference). I'm even using a single purpose project instead of my main codebase to isolate everything else that could be messing with scheduling with communications. I've tried each band of my WIFI (2.4 and 2x5ghz SSIDs) - no change. Sending func send(option: AppFramingOptions, withData data: Data?) { let message = NWProtocolFramer.Message(appFramingOption: option) let context = NWConnection.ContentContext(identifier: "\(option.rawValue)", metadata: [message]) for (uniqueKey, connection) in connections { if uniqueKey.contains(serviceName) { connection.send(content: data, contentContext: context, isComplete: true, completion: .idempotent) } } } In the above function, I am looking for the serviceName because I want to use connections connected via the browser as opposed to the listener (which isn't tagged with service name info in the endpoint). The check avoids a device receiving the command twice. Receiving connection.receiveMessage { content, contentContext, isComplete, error in guard error == nil else { connection.cancel() return } if let msg = contentContext?.protocolMetadata(definition: AppFraming.definition) as? NWProtocolFramer.Message { switch msg.appFramingOption { default: self.messageReceivedHandler?(content, msg.appFramingOption, Date().timeIntervalSince1970, withUniqueKey) } } receiveMessage() } } It's very much patterned off the TicTacToe example code (with a mechanism for multiple connections). My next step is embedding a web server in each device and making REST calls rather than commands over a TCP stream (which is CRAZY INSANE I KNOW). I also do not want to have to have a Macintosh dependency for this system because I cannot get predictable(ish) transit times. Any help is appreciated!
Posted
by bxlewi1.
Last updated
.
Post not yet marked as solved
1 Replies
694 Views
Unable to launch this sample project. Xcode says it cannot open the file. Building a custom peer-to-peer protocol I'm trying to build iPhone as a mouse. I am not planning on releasing it but more like a practice for myself. I have one other question, how to use a mac app to receive mouse data while it's in background as it's required by my app. Is Background Tasks the right way ? I am planning to use Network framework for networking but there is not much documentation available. Pardon me if it's a basic question.
Posted
by Kruthay.
Last updated
.