Don't show cellular data warning on iOS - ios

If a user decides to not allow an app to access cellular data every time they try to open the app they are shown a warning telling them that cellular data is turned off.
Is there a way in the SDK to stop showing this message or control when / where it is displayed?

The system will show this message if you try to access the Internet when permission has been revoked. To prevent it from appearing, you could use Apple's Reachability code to detect network availability, and only make web calls if the network is available.
See also, this StackOverflow post.

Related

iOS 13.2 message: nehelper sent invalid result code [1] for Wi-Fi information request

My app uses locationservices for tracking and geofencing in the background.
Now with iOS 13.2 I see every second the following message in the console:
Anchorwatch nehelper sent invalid result code [1] for Wi-Fi information request
My app does nothing with the WiFi system and when I disable WiFi on the device the message disappears.
While there seem to be no adverse effects by the message I learned the hard way that ignoring message might be a bad idea.
Can anyone hint me to why this message is coming and what I can do to supress it ?
I've managed to make it on iOS 13.3. Here goes how I make it.
(EDIT Aug/2020: I've tested this on iOS 13.6 and worked same)
The official documentation of CNCopyCurrentNetworkInfo says that the function is providing real SSID/BSSID of current connection if the app
has an "Access WiFi Information Entitlement" (see here) and
is one of 1) Core Location , 2) using NEHotspotConfiguration to connect current Wi-Fi Network, and 3) VPN app.
I've already configured "Access WiFi Information Entitlement", therefore only meet the first requirement. It does work on iOS 13.1 but doesn't work on iOS 13.3. To meet the latter requirement, I decided to include the Core Location in my APP. I've checked the code in here but I gotta to add some constants below on my app's Info.plist to avoid error.
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Application requires user’s location for better user experience.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Application requires user’s location for better user experience.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Application requires user’s location for better user experience.</string>
I also needed to call
manager.requestWhenInUseAuthorization()
before
manager.requestAlwaysAuthorization()
to popup the dialog when user launch the app for the first time.
User needed to allow the permission at the first launch. If it is allowed as "Always", the app can use CNCopyCurrentNetworkInfo without error.
It eventually turned out, that a third party framework that my app uses, launches those calls to CNCopyCurrentNetworkInfo.
After I added WiFi access capabilities as described here to the app itself the error message disappeared
Check out WWDC 19 session 713, It happenes because in iOS13 in order to get WiFi details you should allow location permission, each time you try to pull CNCopyCurrentNetworkInfo data from CNCopySupportedInterfaces array you will get this log.
silly solution may be to try to enable location permission and you will not get this error anymore

When does iOS display "need to bond" dialog?

I am writing an iOS app that communicates with a BLE device that we are developing. Most communication does not require bonding, but there are some secure features where bonding will be required. I've put those secure features in a separate service which has been flagged as requiring bonding, and when I try to access that service iOS correctly starts the bonding process.
The problem I'm having, is that I want to be able to control exactly when this bonding takes place so I can design my UI appropriately. Most of the time, iOS waits until I try to access the secure service before it starts the bonding process, but I have also seen the bonding dialog appear shortly after I call CBPeripheral.DiscoverCharacteristics() and long before I actually use the secure service for anything. The bonding dialog seems to appear later if I'm re-running the app when I've already bonded once and then deleted the bonding both in iOS and the remote BLE device.
I'm guessing that iOS is caching the service/characteristic information, so after the first connection when I call CBPeripheral.DiscoverCharacteristics() it's not actually communicating with the remote BLE device, and thus isn't triggering the need to bond.
There's a discussion about how to clear the bluetooth cache on OSX, but nothing similar for iOS. I've tried this:
Unbond device in iOS
Turn off Bluetooth
Turn off iPad
Turn iPad back on
Turn Bluetooth back on
But the bonding request dialog still comes later, which I'm guessing means the cache didn't actually get cleared.
If the devices are unbonded and the peripheral sends an SMP "Security Request", it will show the popup.
It also shows it when you try to interact with a protected characteristic.

Connect Browser & Advertiser without showing alert message in Multipeer connectivity

Currently i am exploring the multipeer connectivity framework.I have 2 option in my application Advertiser & Browser.
So when user fire up the browser on one device, and the advertiser on another then they should be able to find each other. When the device appears in the browser, and the user taps on it, then the user with the advertising device will be presented with an alert allowing them to choose whether or not to make the connection.
But i want when browser taps any particular advertiser it will automatically make connection without alert message.
Note:- Currently i am using MCBrowserViewController and MCAdvertiserAssistant
So is it possible to do ? Can any one have done it ?
The Multipeer Connectivity framework provides additional APIs that support programmatic discovery and customize the experience beyond what’s provided by MCBrowserViewController and MCAdvertiserAssitant.
This way you can immediately send out an invite without waiting for user interaction.
MCNearbyServiceBrowser and MCNearbyServiceAdvertiser provide methods to handle programmatic discovery for the browser and advertiser respectively. The MCNearbyServiceBrowserDelegate protocol supports your custom browser by enabling you to respond to finding nearby devices, while MCNearbyServiceAdvertiserDelegate helps you handle browser invitations programmatically.
You’ll have to do the heavy lifting in your code to construct your browser’s UI, present nearby devices and initiate invitations to peers. On the advertiser end, the UI work involves presenting the invitation to the user, getting the user’s response, and calling a handler to pass the user response to the browser.
However, once the peers are connected, sending data works exactly the same as
before.
To see how to set up these check out NSHipster for some additional code examples of this at this link. He uses an UIActionSheet but you could simply just accept the invitation in advertiser:didReceiveInvitationFromPeer:withContext:invitationHandler:.
invitationHandler(YES, self.session);

Is there a cellular data usage API in iOS 7?

iOS 7 introduced a new user configuration to disable cellular data for specific apps. It can be configured in "Settings"->"Cellular" and then scrolling down.
You'll find a switch for each installed app and can see how much cellular data it has consumed.
How can I programmatically test if the switch is turned on for my app? Is there an API for that? Can I determine how much data my app has used over cellular?
I'm not asking to get the values for all apps. I'm only interested in my apps usage.
There is no API to detect your download consumption or whether cellular is active for your app.
If your app tries to connect to a website, but cellular is turned off, then iOS may ask the user to turn cellular back on. I'm not exactly sure how that works, but it is probably similar to the iOS 6 "no network connection" alert that would pop up if there is no connection but an app tries to access the internet.
You can check if the current internet connection is over WiFi or Cellular, but if Cellular is disabled you will just be told that there is no network connection.
More details here: iOS Detect 3G or WiFi
You can't check if the cellular data switch is turned on.
The closest thing is that you can check if a specific host is reachable over cellular connection using the SCNetworkReachability kSCNetworkReachabilityFlagsIsWWAN flag.
Additionally, you can enable/disable cellular data for specific connections using the NSURLRequest allowsCellularAccess property.
Reference: https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/Platform-SpecificNetworkingTechnologies/Platform-SpecificNetworkingTechnologies.html
This answer suggests how data usage can be measured system-wide: iPhone Data Usage Tracking/Monitoring

iOS app upload data to server as soon as network is available

I have an app that tracks wildlife where the user enters data based on their observations (eg. user enters they see 3 moose). The data is then uploaded to a server. However, because this app will be used out in the field where there is often no internet connection, I want to save data if there is no connection, and upload the data as soon as the network is available
I know about Reachability, but it looks like I can only check if the internet connection is available at that moment, and doesn't check in the background for internet connectivity
So to summarize:
If there is an internet connection when users submits data, then that's fine.
If there is no internet connection, when user submits data, I want to save this data. As soon as there is an internet connection, I want the data to be uploaded, without needing the user to open up the app again. I can't rely on the user to open the app again causing the data to be submitted, because they will likely only use this app out of the range of cell towers, and will likely NEVER run the app in a location with a network connection, so it would have to automatically submit this data for them.
Looking around, I can't find an answer so I'm beginning to wonder...is this even possible?
No, Apple don't allow applications to run indefinitely in the background for this purpose, and they don't allow applications to be triggered remotely or anything of that nature. At best you could have your application run in the background to get notifications about major location changes, but you'd have to have it as a proper feature rather than a hack to get around this limitation, otherwise your application won't get approved by Apple.
I know it's possible to utilize the network in the background but only for a limited time after the user closes the app. You could create a timer which checks for a network connection (using Reachability or by pinging Google) and set the timer to fire every minute after the app closes. It's not a very efficient solution but it may work. You should look into how long you can maintain a connection after the app close though, I think it is 5-10 minutes.

Resources