swift - auto connect hotspot - ios

I know it has been asked before but I am asking again to make sure I didn't miss anything. I am currently using the next code in order to connect a specific hotspot. This prompt a message to the user -
let configuration = NEHotspotConfiguration(ssid: ssid,
passphrase: password,
isWEP: false)
NEHotspotConfigurationManager.shared.apply(configuration)
Is there anyway I can connect automatically without prompting this message? I need to switch between hotspots every few minutes. I don't mind showing the message once and after that connecting automatically but is there any way I can do it?

Related

When using NEHotspotConfiguration() to joing a network. Always recieve "unable to join"

I am implementing an APP through Xamarin that will force the iPhone to connect to a specific SSID.
Here is my code
var config = new NEHotspotConfiguration(SSID, Password, isWep: false)
config.JoinOnce = true;
var tcs = new TaskCompletionSource<NSError>();
NEHotspotConfigurationManager.SharedManager.ApplyConfiguration(config, err => tcs.SetResult(err));
There are two test result
Assume the target SSID I want to connect called "SSID-A"
I delete the record of "SSID-A" in the iOS system page. Then deploy this APP to the phone.
I give the correct SSID/Password into the code above.
The system popup a message "Unable to join". Failed to connect to this SSID.
I go to iOS system page. Manually connect to "SSID-A". Check the connection is done.
Then I connect to mobile phone to other SSID. And go back to the APP.
This time. It works.
Why there is a different at here?
What can I do to look more into this problem to solve this?
Thanks!
From applyConfiguration:completionHandler: of apple document, we could see the dicsussion that:
This method attempts to join the network only if it's found nearby. Also, because of the noticeable delay that the Hotspot 2.0 discovery mechanism may incur, the method doesn't attempt to join Hotspot 2.0 networks.
Therefore, Join once seems can not mark sure it works.We could have a try with remove this line, or set false as follows:
config.joinOnce = false;
In addition, it seems a bug in iOS 13 from Apple. You could have a look at this discussion.
In case it helps someone one day I had an issue suddenly start where my device was unable to join a network which has previously been working fine.
To test an error condition I tried connecting to a secure network without adding the passphase to the NEHotspotConfiguration. This attempt to join failed but then subsequently after putting the passphase back in the device wouldn't even display the join request dialog and would just fail with an 'Unable to join' error.
I eventually tried another test phone and this worked just fine so it seemed to be an issue on the device itself. I tried resetting my device's network settings but this made no difference.
The fix was to go into the device's wifi setting, join the network manually, return to my app, attempt to join, disconnect from the network in the device settings, and then forget the network. After that it worked fine on every subsequent attempt.

NEHotspotConfigurationManager unable to Join

I am using NEHotspotConfigurationManager to connect wifi programmatically.
Its an open Network without any password
I am using below code:
if (#available(iOS 11.0, *)) {
NEHotspotConfiguration *config = [[NEHotspotConfiguration
alloc]initWithSSID:SSIDName];
[NEHotspotConfigurationManager.sharedManager applyConfiguration:config completionHandler:^(NSError* error) {
if (error) {
printf([error description]);
}
else
{
printf(#"success");
}
}];
I am connecting to the hostpot/access point of one device, but every time I am getting an error of unable to join but in response it goes to success as the error is nil. Is there any thing I need to add in configuration or add in setting or am I missing anything ?
PS: The wifi is of IOT device
-Thanks in advance
This is an Apple bug in iOS.
Once the request has made it past the Network Extension framework, down to the Wi-Fi subsystem, errors are displayed to the user rather than delivered to your completion handler.
see https://forums.developer.apple.com/thread/96834
What you can do as a workaround:
try to connect
if the error is nil, you may be connected (due to the above mentioned bug this is unclear)
then check which network you are connected to
For more information, including sample code, see my answer here: https://stackoverflow.com/a/56589229/2331445
Additional Hints
Entitlement
Like #zero3nna already mentioned in the comments, the Hotspot Configuration entitlement must be added.
Check SSID name
Make sure you spelled the SSID correctly. I made a test with a NanoESP IoT device and for my device the definition would look like this:
NSString *SSIDName = #"NanoESP";
If you are using a non-existent SSID name (e.g. NanoESP2), there is a dialog that says that it is not possible to join the network.
Due to the above mentioned error you will get a success message in the console of Xcode, which is of course wrong:
Delayed Wi-Fi indicator
I have noticed that using the correct SSID works, but it takes quite some time for this connection to my specific IoT device to appear with the typical icon in the iOS status bar. For some time it's just not shown, see screenshot. To check the status anyway, go to iOS Settings / Wi-Fi:

NEHotspotConfigurationManager error problem when the wifi not exist

I found a problem when i try to connect a non-existent wifi, this is my code:
let configuration = NEHotspotConfiguration.init(ssid: "wifi-name")
NEHotspotConfigurationManager.shared.apply(configuration) { [unowned self] (error) in
print("NEHotspotConfigurationManager.error: \(error)")
}
if the wifi dosen't exist, i see and dialog with
"impossible to connect network "wifi-nam""
But the error in the NEHotspotConfigurationManager is nil, so how can control if a specific ssid wifi exists?
The unfortunate answer is: You can not control if a specific WiFi exists.
This is the intended behaviour. If you could check if a certain wifi is nearby, you could track a user with that information. This is why android asks for location permissions if you want to do this. On iOS this is currently simply not possible.

How to programmatically connect to a WiFi network given the SSID and password

I am trying to replicate an existing Android Application that I made to iOS. In my application, I should be able to connect to a WiFi network given the SSID and the Password. The SSID and the Password can be hardcoded or can be inputted by the user. I was going through the internet to research how this can be done on iOS, however, it seems that this behavior is highly discouraged and that there's no way on doing this using public/documented libraries that won't get your application rejected by the App Store.
The thing is I'll be using this application personally and I don't plan on submitting it to the App Store so it's okay if I use external libraries. If my friends would want to use it, I could export an enterprise ipa and give them instructions on how to install it.
Upon searching, it seemed that MobileWifi.framework was a good candidate. However, it does not seem that there's a straightforward way of using this library to connect to a WiFi network given the SSID and the Password.
Is there anyone who has successfully tried to connect to a Wifi Network given the SSID and Password?
With iOS 11, Apple provided public API you can use to programmatically join a WiFi network without leaving your app.
The class you’ll need to use is called NEHotspotConfiguration.
To use it, you need to enable the Hotspot capability in your App Capabilities (Adding Capabilities). Quick working example :
NEHotspotConfiguration *configuration = [[NEHotspotConfiguration
alloc] initWithSSID:#“SSID-Name”];
configuration.joinOnce = YES;
[[NEHotspotConfigurationManager sharedManager] applyConfiguration:configuration completionHandler:nil];
This will prompt the user to join the “SSID-Name” WiFi network. It will stay connected to the WiFi until the user leaves the app.
This doesn't work with the simulator you need to run this code with an actual device to make it work.
More informations here :
https://developer.apple.com/documentation/networkextension/nehotspotconfiguration
connect wifi networks in iOS 11. You can connect wifi using ssid and password like following.
Enable Hotspot on App Id configure services
After Enable Hotspot Configuration
Swift 4.0 Code for iOS 11 Only:
import NetworkExtension
...
let configuration = NEHotspotConfiguration.init(ssid: "SSIDname", passphrase: "Password", isWEP: false)
configuration.joinOnce = true
NEHotspotConfigurationManager.shared.apply(configuration) { (error) in
if error != nil {
if error?.localizedDescription == "already associated."
{
print("Connected")
}
else{
print("No Connected")
}
}
else {
print("Connected")
}
}
Contrary to what you see here and other places, you can do it. It's hard to make pretty enough for normal users, but if doesn't have to be then it's really easy to code. It's an enterprise admin thing, but anyone can do it. Look up "Connection Profiles." Comcast does this in their iOS app to setup their hotspots for you, for example.
Basically, it's an XML document that you get the device to ingest via Safari or Mail. There's a lot of tricks to it and the user experience isn't great, but I can confirm that it works in iOS 10 and it doesn't require jailbreaking. You use Configurator to generate the XML, and I suggest this thread for serving it (but people don't find it because it's not specifically about WiFi), and this blog for querying if it's installed which is surprisingly nontrivial but does indeed work.
I've answered this question many times, but either don't have enough rep or am too dumb to figure out how to close questions as duplicate so better answers can be found more easily.
UPDATE: iOS 11 provides APIs for this functionality directly (finally!). See NEHotspotConfiguration. Our Xamarin C# code now looks like:
var config = new NEHotspotConfiguration(Ssid, Pw, false);
config.JoinOnce = false;
Short answer, no.
Long answer :)
This question was asked many times:
Connect to WiFi programmatically in ios
connect to a specific wifi programmatically in ios with a given SSID and Password
Where do I find iOS Obj-C code to scan and connect to wifi (private API)
Programmatically auto-connect to WiFi iOS
The most interesting answer seems to be in the first link which points to a GitHub project: wifiAssociate. However someones in the third link explains that this doesn't work anymore with iOS8 so you might have hard time getting it running.
Furthermore the iDevice must be jailbroken.
Make sure both Network Extensions & Hotspot Configuration are turned on in Capabilities.
let wiFiConfig = NEHotspotConfiguration(ssid: YourSSID,
passphrase: YourPassword, isWEP: false)
wiFiConfig.joinOnce = false /*set to 'true' if you only want to join
the network while the user is within the
app, then have it disconnect when user
leaves your app*/
NEHotspotConfigurationManager.shared.apply(wiFiConfig) { error in
if error != nil {
//an error occurred
print(error?.localizedDescription)
}
else {
//success
}
}
my two cents:
if you got:
Undefined symbols for architecture i386:
"_OBJC_CLASS_$_NEHotspotConfigurationManager", referenced from:
objc-class-ref in WiFiViewController.o "_OBJC_CLASS_$_NEHotspotConfiguration", referenced from:
objc-class-ref in WiFiViewController.o ld: symbol(s) not found for architecture i386
simply it does NOT work under simulator.
on real device it does compile.
so use:
class func startHotspotHelperStuff(){
if TARGET_IPHONE_SIMULATOR == 0 {
if #available(iOS 11.0, *) {
let configuration = NEHotspotConfiguration(ssid: "ss")
configuration.joinOnce = true
NEHotspotConfigurationManager.shared.apply(configuration, completionHandler: { (err: Error?) in
print(err)
})
} else {
// Fallback on earlier versions
}
}// if TARGET_IPHONE_SIMULATOR == 0
}
We can programmatically connect wifi networks after IOS 11. You can connect wifi using ssid and password like following.
Swift
var configuration = NEHotspotConfiguration.init(ssid: "wifi name", passphrase: "wifi password", isWEP: false)
configuration.joinOnce = true
NEHotspotConfigurationManager.shared.apply(configuration) { (error) in
if error != nil {
//an error accured
print(error?.localizedDescription)
}
else {
//success
}
}
You can connect to wifi using Xcode 9 and swift 4
let WiFiConfig = NEHotspotConfiguration(ssid: "Mayur1",
passphrase: "123456789",
isWEP: false)
WiFiConfig.joinOnce = false
NEHotspotConfigurationManager.shared.apply(WiFiConfig) { error in
// Handle error or success
print(error?.localizedDescription)
}
I'm not sure if this will help anyone but there IS a Wifi QR code that Apple put into iOS since version 9 if I'm not mistaken. It's been there a while.
You can go here: https://qifi.org
Put your SSID and password in. Print out the QR code or just keep it on a screen. Point the iPhone at the QR code using the camera app. You will get a notification bar that if you press will setup your WIFI connection on the fly.
This 'should' work with Android but I haven't test it yet. It DOES work with iOS.
The nice thing with this solution is you can make your WIFI base 'hidden' on the network and folks can still connect to it which is very desirable in a high traffic area for security reasons.

Air for iOS webview - Close webview on SSL error

In the StageWebView in Air for iOS, if there is a SSL certificate error, by default it will prompt the user with:
"A secure connection with this site cannot be verified. Would you
still like to proceed?
The certificate you are viewing does not match the name of the site
you are trying to view."
When this occurs, is there any way to stop the message from occurring and just hide the webview?
I've added error handling code:
function webview_error(event:ErrorEvent) {
trace(event);
webView.stage = null;
isConnected = false;
}
But it only fires if the user hits "No" I don't want them to have that option to avoid Man in the Middle attacks.
Thanks.

Resources