Discovering services via Bonjour on iOS 14 - ios

I'm having trouble understanding privacy constraints for local network service discovery using Bonjour on iOS 14. Here is what I found:
Using NetServiceBrowser, I'm able to discover services using:
browser.searchForServices(ofType: "_services._dns-sd._udp", inDomain: "local.")
I have to add a couple of keys to .plist file, but it works.
However, if I turn to NWBrowser, and try to run the same request, I get an error:
nw_browser_fail_on_dns_error_locked [B1] Invalid meta query type specified.
nw_browser_start_dns_browser_locked failed: BadParam(-65540)
I gather, this means I need the multicast entitlement.
Now, the question is, why would I go through all the trouble of requesting multicast entitlement from Apple, if I just can use NetServiceBrowser instead of NWBrowser? Doesn't NetServiceBrowser defeat the purpose of obtaining multicast entitlement?

According to the docs this error means that you passed an invalid value to NWBrowser - most probably it's the format of the service you're trying to discover.
You haven't posted your NWBrowser code, but for example, a wrong formatted service such as _example_.tcp would probably result in the error you're seeing. Make sure it is in the correct format, which should be something like _example._tcp..
Another thing you need to do is modify your Info.plist file and add two keys:
Bonjour Services - this is an array, the first item should be the service you're trying to discover, in my example, it is _example._tcp.
Privacy - Local Network Usage Description - that one takes an explanation text which will be shown to the user the moment you start discovery with NWBrowser.
Now regarding the entitlement you mentioned: it is only needed for apps that scan for all services on the network and not a specific one like in your case. I encourage you to watch this video, which explains everything I wrote here.
Lastly, why should you use NWBrowser over NetServiceBrowser? That's a very good question which I'm also trying to figure out the answer for 😆

The multicast entitlement is only required if you're scanning for all services. If you're scanning for a specific service - you don't need it
In iOS15 - if you do not have the entitlement you can not do
browser.searchForServices(ofType: "_services._dns-sd._udp", inDomain: "local.")
The reason to use NWBrowser is that it is the new api - NetServiceBrowser is deprecated. At some point - Apple will (probably) simply remove NetServiceBrowser. It's pretty deeply ingrained in a lot of software though - so I don't see them removing it any time soon.
NWBrowser is a somewhat easier API to use as far as straightforward browsing goes.
Note though - that if you want to resolve a service to get an IP address, you'll need to use NetService anyway...

Related

App Store - Help answering "Missing Compliance" (using Expo + Firebase)

I'm publishing my app to App Store and I have doubts regarding the "Missing Compliance" step.
Here's some info about the app:
I used Expo (Managed workflow). That means I don't have direct access to Xcode.
It's a simple 2D video game, free, with Expo ADMob. You can pay to remove Ads.
It requests a camera and library permission (to take a picture if the player wants). No Notifications, or any other extra thing.
It uses Firebase (Database, Storage, and Analytics) and Sentry. (for HTTPS connections)
I didn't manually include any "encryption" custom thing (that I'm aware of)
I'm publishing the App from Portugal, Europe. I plan to publish it worldwide, if possible.
Does your app use encryption? I didn't code anything related to it... but I assume I should say yes, right?
Does your app qualify for any of the exemptions provided in Category 5, Part 2 of the U.S. Export Administration Regulations?. My app is a simple JS video game, with MobAds. Should I say yes or no?
Does your app implement any encryption algorithms that are proprietary or not accepted as standards by international standard bodies (IEEE, IETF, ITU, etc.)? I did say no... is it right?
Does your app implement any standard encryption algorithms instead of, or in addition to, using or accessing the encryption within Apple’s operating system? If I say no, it shows an extra message about HTTPS. My app does use HTTPS for Firebase (Database, Storage, and Analytics) and Sentry.
Finally, if I say yes, it says: Version 0.1.0 (1) cannot be tested at this time because the build does not have associated export compliance documentation. Where do I find this documentation and how can I get it? I'm from Portugal, Europe.
Thank you!
Question 1:
Reply YES as you use HTTPS encryption for connections
Question 2:
For what you said about your app the reply is NO. In brief you don't use any function inside your app that use a custom cryptography or it's strictly medical app. The encryption that you use it's only for data passing from app to server, nothing inside your app is encrypted (app or a part/module of app is not encrypted).
Question 3:
No you don't use a custom crypt algorithm. That is usually used for bank app data inside the app.
Question 4:
Say NO. The US rules give an exception for apps with only HTTPS calls (that is what you do). Read here for a full explanation:
https://developer.apple.com/forums/thread/98071
https://www.cocoanetics.com/2017/02/itunes-connect-encryption-info/
Just add this key to info.plist file:
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
For expo users, automatically answer this question by adding this to your app.json/app.config.js:
{
"ios": {
"config": {
"usesNonExemptEncryption": false / true
}
}
}

What sections of Apple Health app are available via the x-apple-health:// URL scheme?

I want let users view the Weight section of Apple's Health app to allow them to see detailed data, etc. I manage to open the Health app via the URL scheme x-apple-health://, but I would like to send them directly to the right place, e.g. x-apple-health://HealthData/measurements/Weight. I have had no success after trying different paths that made some sense.
Anyone has a reference on this?
Apple has not documented the x-apple-health:// scheme for use by apps. Attempting to use it is like using SPI - even if you find something that works now, it is likely to break in a future version of iOS. You should file a Radar with Apple to request an API for this purpose.

Getting a valid CBUUID from a Bluetooth device for scanning

I am writing a simple device browser for a specific kind of Bluetooth device (a card reader). I understand you're supposed to pass in an array of services specified by CBUUIDs to the scanForPeripherals(withServices:options:) method.
To find these IDs, I've scanned without a service filter, found my device, and looked in advertisementData["kCBAdvDataServiceUUIDs"] where I found a single 64-bit CBUUID looking something like this: 0x00000001c413e940.
How do I convert this string into a valid CBUUID that I can pass in as a service filter? I have tried the CBUUID(string:) initialiser, but it just throws a runtime exception saying it's not a valid UUID.
I've also looked in the device's reference manual and found the following table:
However, none of these appear to work - no devices appear in the scan when filtering by these service UUIDs.
Finally, when I examine the device in LightBlue it reports 1 service broadcasting (FFF0), but when I attempt to filter by this service, no devices show.
I'm starting to think the service filter is just plain broken. Does anyone ever actually use it?
Update: It works! I rebuilt and reinstalled the app and the device appeared when scanning with a service filter for FFF0. Thanks Paulw11 for your help.

Get local network hostnames in iOS

I would like to get All device name in entire local network. I just been searching over 2 days and haven't find a solution yet.
I can able to get Bonjour services with using NSNetServiceBrowser. What i am trying to do is same as Fing app ( in app store) does.
As screenshot below, I would like to get "My iPhone" iPhone name with iOS.
Regards
Onder
Seems like NEHotspotHelper is what you're looking for. Specifically a class func supportedNetworkInterfaces() -> [Any] method.
In order to make it work, you'll need to accomplish some additional steps. Please, check this question to get more information.
Also don't forget to add NetworkExtension.framework to your target.

Add IP Range to Transport Security Layer in Info.plist iOS

I'm currently working on an app that will accept a user's login, password, and ip address to run rest get requests. I have done some research once I realized that TSL is going to be enforced by Apple and we cannot submit apps to the App Store using NSAllowsArbitraryLoads = YES.
Because of the nature of my application I will not be aware of the ip address so I cannot exactly specify the domain unless I use some kind of ip range or add the domain to info.plist once the user enters the ip address into the field. I have not seen anything online where people use ip ranges when adding exceptions for TLS and from what I understand I can only read info.plist in swift and not write to it. Currently kind of stuck at the moment. If anyone could point me in the right direction that would be great thanks!
The new App Transport Security rules were first introduced at this WWDC16 session. Also stated here was that these rules only applied to apps that had the ability to comply. If you believe you have an app that can't, I believe they said you should contact them. Use the link above to check out the WWDC session (searchable transcript included).
Edit: After checking out the transcript again, they said you'll need to "provide justification" for it. This might be justification at the time you submit your app, but you could contact Apple Developer Relations to find out.

Resources