Skip to content

Instantly share code, notes, and snippets.

@douglasjunior
Forked from rbresjer/IOSWifiManager.h
Last active August 13, 2024 07:12
Show Gist options
  • Save douglasjunior/c2b43cee378b5d8ce6935d928ba6caaa to your computer and use it in GitHub Desktop.
Save douglasjunior/c2b43cee378b5d8ce6935d928ba6caaa to your computer and use it in GitHub Desktop.
Programatically join Wi-Fi network on iOS with React Native wrapper for NEHotspotConfiguration
import { Platform, NativeModules } from 'react-native'
const IOSWifiManager = NativeModules.IOSWifiManager
const wifiConnect = (ssid) => (
IOSWifiManager.connectToSSID(ssid)
)
const wifiConnectProtected = (ssid, password, isWep) => (
IOSWifiManager.connectToProtectedSSID(ssid, password, isWep)
)
const wifiDisconnect = (ssid) => (
IOSWifiManager.disconnectFromSSID(ssid)
)
const wifiCurrentSSID = () => (
IOSWifiManager.currentSSID()
)
// Created by Rutger Bresjer on 10/10/2017
// Notes:
// - Be sure to enable "Hotspot Configuration" capability for the iOS target
// - Make sure the NetworkExtension framework is linked to the target
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
@interface IOSWifiManager : NSObject <RCTBridgeModule>
@end
#import "IOSWifiManager.h"
#import <NetworkExtension/NetworkExtension.h>
#import <SystemConfiguration/CaptiveNetwork.h>
// If using official settings URL
//#import <UIKit/UIKit.h>
@implementation IOSWifiManager
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(connectToSSID:(NSString*)ssid
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
if (TARGET_IPHONE_SIMULATOR == 0) {
if (@available(iOS 11.0, *)) {
NEHotspotConfiguration* configuration = [[NEHotspotConfiguration alloc] initWithSSID:ssid];
configuration.joinOnce = true;
[[NEHotspotConfigurationManager sharedManager] applyConfiguration:configuration completionHandler:^(NSError * _Nullable error) {
if (error != nil) {
reject(@"nehotspot_error", @"Error while configuring WiFi", error);
} else {
resolve(nil);
}
}];
} else {
reject(@"ios_error", @"Not supported in iOS<11.0", nil);
}
} else {
reject(@"ios_error", @"Not supported on Simulator", nil);
}
}
RCT_EXPORT_METHOD(connectToProtectedSSID:(NSString*)ssid
withPassphrase:(NSString*)passphrase
isWEP:(BOOL)isWEP
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
if (TARGET_IPHONE_SIMULATOR == 0) {
if (@available(iOS 11.0, *)) {
NEHotspotConfiguration* configuration = [[NEHotspotConfiguration alloc] initWithSSID:ssid passphrase:passphrase isWEP:isWEP];
configuration.joinOnce = true;
[[NEHotspotConfigurationManager sharedManager] applyConfiguration:configuration completionHandler:^(NSError * _Nullable error) {
if (error != nil) {
reject(@"nehotspot_error", @"Error while configuring WiFi", error);
} else {
resolve(nil);
}
}];
} else {
reject(@"ios_error", @"Not supported in iOS<11.0", nil);
}
} else {
reject(@"ios_error", @"Not supported on Simulator", nil);
}
}
RCT_EXPORT_METHOD(disconnectFromSSID:(NSString*)ssid
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
if (@available(iOS 11.0, *)) {
[[NEHotspotConfigurationManager sharedManager] getConfiguredSSIDsWithCompletionHandler:^(NSArray<NSString *> *ssids) {
if (ssids != nil && [ssids indexOfObject:ssid] != NSNotFound) {
[[NEHotspotConfigurationManager sharedManager] removeConfigurationForSSID:ssid];
}
resolve(nil);
}];
} else {
reject(@"ios_error", @"Not supported in iOS<11.0", nil);
}
}
RCT_REMAP_METHOD(currentSSID,
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
NSString *kSSID = (NSString*) kCNNetworkInfoKeySSID;
NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces();
for (NSString *ifnam in ifs) {
NSDictionary *info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
if (info[kSSID]) {
resolve(info[kSSID]);
return;
}
}
reject(@"cannot_detect_ssid", @"Cannot detect SSID", nil);
}
@end
@lefoy
Copy link

lefoy commented Aug 8, 2018

Be careful when using App-Prefs:root=WIFI
We got this response from Apple when trying to publish a version of our app.

Guideline 2.5.1 - Performance - Software Requirements

Your app uses the "prefs:root=" non-public URL scheme, which is a private entity. The use of non-public APIs is not permitted on the App Store because it can lead to a poor user experience should these APIs change.

Continuing to use or conceal non-public APIs in future submissions of this app may result in the termination of your Apple Developer account, as well as removal of all associated apps from the App Store.

Next Steps

To resolve this issue, please revise your app to provide the associated functionality using public APIs or remove the functionality using the "prefs:root" or "App-Prefs:root" URL scheme.

@douglasjunior
Copy link
Author

@lefoy why you need to use this? I didn't have to use this in my project.

@saxenanickk
Copy link

@douglasjunior I got my app rejected from Apple because of App-Prefs:root=WIFI. Please help.

@douglasjunior
Copy link
Author

Hi @saxenanickk, I will ask you the same question I asked to the @lefoy:

why you need to use this? I didn't have to use this in my project.

@lefoy
Copy link

lefoy commented Nov 27, 2019

@douglasjunior
Copy link
Author

douglasjunior commented Nov 27, 2019

Yes, but it is just a String in the code, you dont need to add this on the CFBundleURLSchemes.

If you look closer, the function constantsToExport is unused.

@lefoy
Copy link

lefoy commented Nov 27, 2019

I didn't, I just used this code and they detected the string in the code.

@saxenanickk
Copy link

I changed it to the Official Way of opening Settings.

@corles
Copy link

corles commented Jul 21, 2022

Is there a way to list available wifi networks? We are doing an iot device that needs an external installer and want to let the customer select the network and enter a password on the installer's phone.

@TraFost
Copy link

TraFost commented Aug 13, 2024

Is there a way to list available wifi networks? We are doing an iot device that needs an external installer and want to let the customer select the network and enter a password on the installer's phone.

did u already get the solution?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment