How to present guest Wi-Fi "terms & conditions" confirmation dialog programmatically? - ios

It is typical setup in bars / restaurants / airports where password-free Wi-Fi is available but requires accepting terms & conditions.
First time customer manually connects to Wi-Fi network which brings confirmation dialog and he accepts it. As result internet connection is alive, no problem here.
However next time customer visits the same place iOS device automatically connects to the known Wi-Fi and shows active Wi-Fi connection icon in status bar. But internet connection isn't available until customer accepts terms & conditions again. To do that customer has to either go to iOS settings or open Safari which brings confirmation dialog automatically.
Our app is designed for bars. Based on above iOS behavior regular customer sees that it has Wi-Fi connection in iPhone status bar, yet our app says "No internet connection". Combined this is very confusing UX.
Question: Is there programatic way to bring Wi-Fi confirmation dialog the same way as Safari does?

iOS should do this automatically if your captive portal is configured correctly.
When it connects to a WiFi network, iOS checks to see if http://captive.apple.com returns "success". If it does then it assumes that it has Internet access. If it returns any other content then it assumes that there is a captive portal and it will open the captive portal authentication screen.
This behaviour is independent of whether the user has connected to that hotspot previously.
Where there can be an issue is when the hotspot de-authenticates the user after some time, as iOS does not continually re-try http://captive.apple.com once it has connected successfully.
Your app can periodically check that http://captive.apple.com returns the correct response and open an SFSafariViewController if it doesn't

Related

How reconnect programatically Classic Bluetooh on IOS with MFi and external-accessory framework

I am creating an IOS App to connect into a Bluetooth Device using Classic Bluetooth with Mpi using ExternalAccessory Framework.
Using showBluetoothAccessoryPicker method, I can display an alert with a list of devices that allows the user to select one Device to pair.
I can perform Steps 1 -5 of my use case as below. However I not able to perform step 6
Use case:
The User picks one Device to pair. On that case, I am using showBluetoothAccessoryPicker
The App stores, into a variable, the accessory that the user picked
Turn off the Device
The App shows an alert "Connection dropped"
Turn On the Device
The App needs to reconnect with the Device automatically without needs to select it into a list.
Is there any way or method to pair a device without display a list?
As my company is a member of the Apple MFi licensing program, I asked for Apple support and I received the answer below.
"
In response to your request below, there is presently no support for implementing the bluetooth reconnection process from the device side after an existing connection has been broken. This would be an API enhancement request which you can submit using the Apple Developer feedback assistant web page - https://feedbackassistant.apple.com.
"
"
One option would be for the accessory to handle the reconnection process itself as this is a supported bluetooth option. However, I understand if for power conservation reasons, this is not supported accessory option."
It means, there is no way, yet, to implement it from the App side. if you need that, you need to do it on the Device side.
We can submit feedback for the Apple, using the Apple Developer feedback assistant web page - https://feedbackassistant.apple.com to ask them to create it
you need to make some changes in your firmware to reinitiate the connection when it identifies the connection drop. Or else you can write a method and call on connection drop in your application which keeps looking for device in proximity (with accessory info saved in your app variable) and as and when it finds, it connects using that accessory instance.

iOS Captive Network Assistant behavior on Hotspots

We have a hotspot product using SMS authentication method. The user chooses our WiFi Hotspot network and is redirected to our login page.
On iOS and Adroid, a Captive Portal pop-up is activated showing our login page. We ask users to fill in a form and submit their phone number. When they click "Submit" we send them an SMS with a verification code.
The login window (hosted on our server) changes to a new page which is displaying a field to enter the verification code. So far so good... If the user sees the "notification popup" for the SMS on his screen on top of the captive window, he can see the code and enter it in the provided field and authenticate.
But if he doesn't have SMS notification set like this, he has to go to his SMS app and look up the code. Now, the only way to do that is to close the Captive popup but then he gets disconnected from our hotspot. If he reconnects he needs to fill in the form again and gets a new SMS but he faces the same problem.
Now, all this time user is not authenticated, so in iOS the captive window displays "Cancel" in the top right corner. I have seen this same method on other hotspots, but from the first Captive window, the control displayed in top right corner is "Done". As far as I know, the difference there is that the "Done" control is shown when the user is authenticated and "Cancel" while he hasn't been authenticated yet.
Is there a way to "fool" the CNA to "think" the user has internet access and display "Done" so when Captive window is closed, the device stays connected to our Hotspot?
We are thinking either some "two-step" authentication, like temporary (to get "Done") and then the "real" one after entering verification code.
Another way might be to use some kind of script (like "Success" trick on iOS) to fool the CNA into thinking there's internet access. But where and how to apply the "Success trick"? In some of the HTML pages in the router? Or somewhere in our login page code?
Different OS versions and different platforms check for internet access in different ways. iOS for example looks for one of these:
http://captive.apple.com/hotspot-detect.html
http://captive.apple.com
etc.
Android uses (among others):
http://clients3.google.com/generate_204
The best solution is for your captive portal to allow access to these through the firewall. If you're using MAC filtering via ipfw or iptables this is easy. If you're doing DNS spoofing it's harder -- for those cases I'd just include the "success" pages in your captive portal package.

Swift: How to check if my app has WLAN permission and the device is connected to a WIFI source?

I'm developing an app in which I need to know:
Does my app has the permission to access WLAN network.
Is the device currently connected to a WIFI.
I know you can use Reachability to check if the device is connected to the internet, but it return true even if the app doesn't has the permission to access network. How can I know the 2 information I listed above ?
Additional information: This is not a regular app. This app is used to control a toy via WIFI. So I don't really care if the app is connected to the internet. All I want to know is if the app has the permission to access WLAN network.
If you are worried that there may be a captive portal giving a false "connected" status to Reachability then you need to attempt to retrieve a known piece of data from a known website; then if you get the expected result you can be fairly confident that your app has network access.
For example, http://captive.apple.com returns:
<HTML>
<HEAD>
<TITLE>Success</TITLE>
</HEAD>
<BODY>
Success
</BODY>
</HTML>
This is the web site that iOS and macOS attempt to access in order to determine whether the hotspot login helper window should be shown.
If iOS doesn't get the expected "success" (as is the case if all access is redirected to a "login" screen) or the connection times out then the helper window is shown.

Run my app from when connected to a particular wifi : ios

Many Wi-Fi hotspots these days have a "web login", especially free ones. You know, the ones that redirect any HTTP request to their login form.ios first connect to a wifi network then opens up the login page of the network where we fill our credentials and then it let us access the internet. Now I am creating a ios app that runs when connected to a particular network and instead of opening my browser the app takes user credentials once and automatically login for user and user can access the internet. Now how do I open my app whenever the user connects to the network and instead of opening up the app I would like it to show my app notification with the option of Login or Logout in the notification bar.
In android it appears like this:
You need to register a URL scheme within your app, and then configure your login page to call a certain URL containing the information you need. For example, if your app was called "Foobar", a valid URL might look like foobar://auth?user=jacobking&pass=password123. As I said, you will need to tell iOS that your app is listening for the foobar scheme. When iOS receives this URL, it will ask your app delegate if it can open it which you will answer through canOpenURL.
A detailed explaination and code examples can be found here.

Facebook.com and the iOS7 Captive Portal Detection

I created a router that connects to facebook to get some info before a user may access the internet.
First they connect, get the Captive Portal Page and then continue to a facebook login. Since the upgrade to iOS7 it fails to load the facebook login page. On my mac with the Captive Portal Assistant it has no problems and even on the phone itself while using the iOS version of safari there are no problems.
What is going wrong here? Is facebook filtering request from the iOS7 Captive Portal Assistant or is Apple doing some sneaky stuff here?
It seems the problem is widespread and only related to facebook.
Update: I worked with the beta's and they worked fine a few weeks ago. Now with the same beta version it doesn't anymore. So another point for the facebook explaination.
Regards, Cas
This problem was fixed by Apple since IOS 8. But as all iPhone 4 users can't upgrade to IOS 8 this problem is still one.
The IOS 7 devices check for the following domains:
www.appleiphonecell.com
captive.apple.com
captive.apple.com
www.apple.com
www.itools.info
www.ibook.info
www.airport.us
www.thinkdifferent.us
Whitelisting this domains stops the login mask to be appearing as the IOS device thinks, that the internet is working as expected. This way you have control on the things which happens, as the IOS device does not interrupts anything, if you use a normal browser for login.
If you don't whitelist the domains, the following thing happens. I debugged it on routers with several IOS devices and they all did mostly the same:
If you connect to a wifi, the IOS device tries to connect to one of the domains, which are listed above. If it can contact one of the domains, it tries another one. If it can't, it starts the redirect, which is controlled by the router. Sometimes it query one or more domains, before it thinks, that the internet is working.
After the check, the login screen redirects to your router and then to the login screen of your captive portal. This behavior stayed the same as it was on IOS 6 or before.
Now you start an oauth login to a 3rd party provider like Facebook, Google or Twitter. And now the difference appears. You can check it on a router, if you run it in debug mode. As the IOS device goes to an other domain for oauth login (like www.facebook.com) the iPhone thinks, that something changed and starts to query one of the apple domains, which are listed above. The user sees only a white screen and in the background the IOS device tries to contact one of the domains repeatedly. For the user this seems to be an error, as the screen stays white or takes very long to show the login on the 3rd party provider. Sometimes it stops loading and nothing happens forever.
To avoid this behavior, you must whitelist the above listed domains. This is a not a common behavior for IOS users, but this way, your browser have the control of the login session and the IOS device don't interrupt it as it does with the login screen.
Some shallow parts of information is reported on the following sites:
https://supportforums.cisco.com/docs/DOC-36523
http://www.cadincweb.com/why-your-apple-ios-7-device-wont-connect-to-the-wifi-network
https://discussions.apple.com/thread/5355766
I couldn't find a detailed description of the problem and found the one above myself by debugging all parts with some routers and IOS devices like iPhones and iPads.
I've just tested various router settings and noticed that iOS 7 is NOT trying to contact above mentioned sites/URLs when router's DOMAIN field is blank.
My guess is that blank domain points to a consumer-type network set up and Apple is not expecting a Captive Portal at such network. If you have access to administer your router see if you can clear out the DOMAIN field (and restart/retest).
I found my solution to my problem. (a while ago, but I found this post again)
First I found out, iOS makes 3 calls, first to check, second to get the page that needs to be displayed, third to check again after the pageload. Then I discovered, for every POST or GET action made by the page, regarding of the source page was refreshed, iOS checks for an active internet connection. Since the facebook api makes a lot of calls, the browser starts stalling(possible in combination with QoS on my router) and freezes the page.
My Solution:
Since I am in control of the DNS records of the Router I use, I redirected all domains towards my own server.
First I saved the check request, this to later identify the user when he comes back for the 3th request.
When the second request comes I just display an info window that every thing is right, and the user has to click the "Done" button.
The page is loaded, so iOS checks again, but i recognize the user so I display the OK-code Apple also displays. The "Done" button us show, and the user has "internet", according to iOS..
On the page that I display, I instruct the user to open the webbrowser. When he does, he opens a page and my portal with the right page is shown(I can detect this based on the Browser Agent). Then my facebook api start doing its job, and of we go :-)
Let me know if someone needs some more info on how to detect or maybe even a code sample if necessary.
Extra Information
To capture a user on your own server, redirect every request to your processing page using for example .htaccess. The request is made to a domain with a subfile e.g:
http://captive.apple.com/getrT09Nx7G/YNrnUOulnDj/3cfrq3M40iR.html
To keep multiple users apart, use the unique url the device tries to contact when checking for internet, in this case: /getYT09Nx7G/YN1nUOulnDj/3cfMq3M40iR.html

Resources