iOS / Mac Bonjour service not found on network - iphone

I have an iOS app that publishes a Bonjour service. On my network, the Mac app recognizes the service and everything runs smoothly. On some networks however, the Bonjour service is not "seen" by the Mac. I can't reproduce this on my own network. I have had users check for the service using Bonjour Browser and it's not found. Is there a way to diagnose this problem further? I thought it might be a firewall / router issue but some users have very simple Apple-based networks (Airport). Any ideas on what could be causing this?

Have you tried implementing the
- (void)netService:(NSNetService *)sender didNotPublish:(NSDictionary *)errorDict
method? it can occasionally provide useful information although I have found the NSNetService to have strange behaviour sometimes also. Stopping the NSNetService and re-publishing is an ugly option which seemed to work for me to some extent.

Make sure you implement ...didNotPublish... as above. Some routers filter out multicast packets, and unfortunately if you don't control the network there's not an awful lot you can do about it.

Another followup: modifying the device name seems to resolve the issue. One user noted that his iPad was discovered but not his iPhone. Bonjour Browser confirmed the presence of the iPad service with no iPhone service. Renaming the iPhone resolved the issue. This is truly an odd behavior.

Related

iPhone simulator writes to socket fine - but not iPhone

Despite working earlier, my socket chat app now refuses to write to socket on the iPhone!
It works fine on the simulator and again, used to run fine on my phone. I don't really know where to start troubleshooting this issue --- just seems weird. My server doesn't detect anything trying to connect.
Any ideas on how to start troubleshooting this?
Thanks tons.
I did run into a problem where using sockets on the iPhone would not open up the cell phone network unless something else opened it first. I had to run an http call to a generic web site first, and then the sockets would communicate normally. Try putting a call, like sendSynchronousRequest, to a generic web site, like www.apple.com, before opening your socket, and see if it works in that case.
I need to stop wasting all you nice peoples' time.
Long story, my friend updated to iOS 5.1. Now the 3G network reads 4G on iOS 5.1. So I turned off my (5.0) wifi to see if mine cell network was "4G" (which, of course, it wasn't).
But yeah, having turned off wifi my app could no longer join my locally hosted server...
I grabbed Charles though, and it looks handy, so thanks for that anyways. Also Owen's comment about the cell network originally made me think about checking my wifi, as my app shouldn't even be using the cell network yet. But I'll keep in mind what you said for the future.
Thanks everybody!

How can I simplify addressing an iOS device using Bonjour?

I would like to make an application for iOS devices that would communicate with a special type of remote device using HTTP POST requests. The problem is that this device would actually act in the role of a client, while iOS device has to be the server accepting the requests. The next problem, host name and port has to be configured statically at the device sending the requests.
While I'm aware it's possible to give it a try using Dynamic DNS services and UPnP/IGD or NAT-PMP to overcome the problem with iOS device being behind the NAT router, I was wondering whether using Bonjour could simplify the problem in some way. I'm quite a newbie in networking so I'm looking for the direction and want to avoid research of Bonjour if it's not going to bring me anything.
Any other idea of how to solve the problem is appreciated as well.
I had a think about this. IMHO you can't guarantee you'll always be able to expose an iOS based service over a WAN (although it's possible) so this isn't practical.
The best solution I suggest is using uPNP to open the device behind a router to the outside world, then have it send an iOS push notification to the iPhone with the details (hostname, ip, port, etc).
The iPhone would then would then have to set up some kind of persistent connection with the firewalled device to receive data.
Bonjour is a good system to discover and connect to services/clients, but only on your local network. I don't think it is a good idea to try it over the internet.

IphoneOS sockets example

I am trying to get a simple sockets program working on the Ipad.
To do this I am using the CFStreamCreatePairWithSocketToHost command.
It works fine on the simulator.
The problem is that it does not work on the iPad (I checked connectivity issues using the iPad's safari, and everything seems fine).
What I want to do is have the iPad open a connection to a PC. The reason I used CFStreamCreatePairWithSocketToHost was that I found a simple 10 line sample program which does this.
My questions:
1 - Does CFStreamCreatePairWithSocketToHost work on the iPad
2 - Can anyone direct me to a simple sample for ipad socket communications (I tried apple dev, and google. No sample that I found could be considered simple (less than 50 lines of code...))
Update:
Also tried sockets and NSHost, both withAddress and withName.
The results were the same: works perfectly inside the simulator, but does not work on the iPad.
I would suggest to use the socket-wrapper AsyncSocket. The download comes with a sample project.
edit
the most recent version can be found here
The low level APIs don't turn on the cellular radios. Use a very high level API to connect, then after the radios are turned on, disconnect if necessary, and (re)connect via BSD sockets.
An HTTP request to a server near the same destination IP would probably be sufficient.
Found the problem...
There was a "rouge" proxy problem in my organization, which was forwarding the saffari, but not my program (even thoughthe safati was not on an http port).
Solved, and thanks for your help.

Question about using Bonjour or other methods to secure a connection with a non computer device

So I have a project I am working on, and I would basically like to send a basic yes/no command from the iPhone to a wifi enabled device that is also connectedto the network on the same router. This other device is not a computer, so I am wondering if I can still use Bonjour? In order to use Bonjour, do both of the communicating devices need to have some sort of a script installed and running that is allowing them to communicate? What would be the best way to connect to this device that is connected to the router, and then to send information/commands to it? I could really use some help finding a direction, because once I identify which tools I need to use, I can research them out and get it done (maybe). If anyone could offer any insight/suggestions whatsoever, it would be greatly appreciated!! Thanks in advance
Bonjour is a local service discovery protocol based on multicast DNS. Even if your device supports it you still need some piece of software on the device to listen to your commands.

Why does NSNetServiceBrowser find unpublished services in iPhone OS?

Building a desktop version of my mobile app and providing the user syncing over wifi. Everything works great in the simulator - no problems resolving net services (which are published by the desktop app) or noticing when services become unavailable.
The problem is when I run the app on the phone services are discovered and resolved (sometiems) but the NSNetServiceBrowser never notices when a service becomes unavailable. When this happens the net service browser constantly finds a net service (that is no longer published) resolves it but then can't connect to it. After several failed attempts the service browser delegate's "didRemoveService" is finally called and the app begins to behave correctly again.
I'd post my code but I've discovered the same issue is happening in Apple's WiTap example. Services are published and discovered but once they are made unavailable the client running the service browser doesn't update - and repeatedly tries to resolve a service that "shouldn't" exist.
I've discovered that running WiTap with wifi turned off (so Bonjour uses bluetooth) everything works fine. I can't find anyone complaining about WiTap not working and can't find this issue anywhere else online. Any reason - possibly with iPhone OS or my wireless network - why a net service browser can find and correctly resolve (but can't connect to) services that are unavailable?
Bonjour/NSNetServiceBrowser on the iPhone/iPod Touch will utilize both Wifi and Bluetooth for service discovery--at least on supported devices. Each time you begin browsing for services, it will search both WiFi and Bluetooth (which you can verify in the iPhone's Console, in Organizer). Since your Simulator "device" cannot use Bluetooth, your iPhone discovers it over WiFi. However, if you are using NSNetService to publish on your iPhone, then you are publishing over both WiFi and Bluetooth as well (if supported and enabled). NSNetServiceBrowser, when running on BT-capable hardware, will dutifully find that both instances, and report both via delegate callbacks.
Bluetooth PAN setup takes longer than publishing via Wifi, so the BT-discovered services often show up well after all the Wifi-based services have been discovered and resolved. When testing two real devices, I've even seen both services show up in my UI (usually only after the other phone crashes).
It does make for some frustrating coding, though. Your best bet is to utilize netService:didNotResolve: to either (i) retry resolution, or (ii) invalidate the netService instance and wait for the other phone to relaunch their app.
Also, there are a couple of other areas things can go wrong. Since the NSNetService instance provided to you is autoreleased, you need to retain it. Most people add it to an NSMutableArray or NSMutableDictionary. If that's the case, make sure that you have properly initialized it before adding the object. Since messages to nil are perfectly ok, if you send addObject: to nil it will appear as though everything is working fine. Except that it isn't. This crops up very often in Bonjour troubleshooting, and happens to the best of us. Make sure that your NSNetService gets scheduled into an actively running runloop, and one that is running in default or common modes.
There is an open bug filed with Apple (as of 10/4/09) whereby every so often, a Bonjour update will not result in a delegate method getting fired. I have only observed this occurring on a 3GS. The result is a client app that is out of sync with the network.
NSNetServiceBrowser should consistently notify when a service leaves the network (under nominal conditions). The bug above is only an intermittent one, and apparently, hardware specific. If you see it occurring consistently, then it's likely that your app is throwing an exception. If you are using background threads, this can occur without causing your whole app to crash. You may want to check your iPhones Console and logs for error messages. Make sure you have set a breakpoint on the symbol objc_exception_throw.
Here's another troubleshooting tip that I've found invaluable. Monitor Bonjour broadcasts on your dev machine via Terminal using the following command: dns-sd -B _serviceName. This will let you see all comings and goings on your local network for your service. If your app quits, but dns-sd does not show a Remove event, then your code needs revisiting. If dns-sd shows a remove event, but your other apps don't process it correctly, you may be seeing the above mentioned bug. It may also be the case that your code isn't doing what you think it's doing. And remember, this will only help you troubleshoot Wifi-to-Wifi service Bonjour. Bluetooth to Bluetooth is not supported from the iPhone Simulator.
Read the full article, Troubleshooting Bonjour Networking for the iPhone, at my dev blog.