fixed ios wifi part support.

This commit is contained in:
aria committed 2026-04-22 18:23:18 +09:00
1 parent e8169780b8
commit faa51215f3
3 files changed
+130 -3

No files matched your search

+2 -1
View File
@@ -211,7 +211,8 @@ Android WiFi:
iOS WiFi:
- 使用 `NEHotspotConfiguration`。
- 必须在 Apple Developer 账号和 App entitlements 中开启 `Hotspot Configuration` capability。
- 插件会向 Cordova iOS entitlements 写入 `com.apple.developer.networking.HotspotConfiguration`,但仍必须在 Apple Developer App ID 中开启 `Hotspot Configuration` capability,并使用包含该 capability 的 provisioning profile 重新构建。
- 如果 iOS 返回 `NEHotspotConfigurationErrorDomain` code `8` / `internal error`,优先检查 App ID、entitlements、provisioning profile 是否都包含 `Hotspot Configuration`,并确认是在真机前台运行,不是在模拟器中测试。
- iOS 不提供第三方 App 断开当前 WiFi 的公开 API,因此 `disconnectWifi` 在 iOS 返回错误。
Firebase:
+6
View File
@@ -96,6 +96,12 @@
<config-file target="*-Info.plist" parent="BLUEMEME_FIREBASE_STORAGE_BUCKET">
<string>$IOS_FIREBASE_STORAGE_BUCKET</string>
</config-file>
<config-file target="*-Debug.plist" parent="com.apple.developer.networking.HotspotConfiguration">
<true />
</config-file>
<config-file target="*-Release.plist" parent="com.apple.developer.networking.HotspotConfiguration">
<true />
</config-file>
<header-file src="src/ios/CDVBluememeUtils.h" />
<source-file src="src/ios/CDVBluememeUtils.m" />
+122 -2
View File
@@ -3,6 +3,7 @@
#import <FirebaseCore/FirebaseCore.h>
#import <LocalAuthentication/LocalAuthentication.h>
#import <NetworkExtension/NetworkExtension.h>
#import <TargetConditionals.h>
#import <UIKit/UIKit.h>
static NSString * const BluememeDeviceKeyDefaultsKey = @"bluememe_utils_device_key";
@@ -293,6 +294,13 @@ static NSString * const BluememeDeviceKeyDefaultsKey = @"bluememe_utils_device_k
return;
}
#if TARGET_OS_SIMULATOR
[self sendErrorForCommand:command
code:@"UNSUPPORTED_IOS_SIMULATOR"
message:@"iOS WiFi configuration requires a physical device."];
return;
#endif
if (@available(iOS 11.0, *)) {
NEHotspotConfiguration *configuration = nil;
if (password.length == 0 || [security isEqualToString:@"open"]) {
@@ -305,7 +313,7 @@ static NSString * const BluememeDeviceKeyDefaultsKey = @"bluememe_utils_device_k
[[NEHotspotConfigurationManager sharedManager] applyConfiguration:configuration completionHandler:^(NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error != nil && error.code != NEHotspotConfigurationErrorAlreadyAssociated) {
[self sendErrorForCommand:command code:@"WIFI_CONNECT_FAILED" message:(error.localizedDescription ? error.localizedDescription : @"Unable to apply WiFi configuration.")];
[self sendWifiApplyErrorForCommand:command error:error];
return;
}
NSDictionary *result = @{
@@ -323,6 +331,111 @@ static NSString * const BluememeDeviceKeyDefaultsKey = @"bluememe_utils_device_k
}
}
- (void)sendWifiApplyErrorForCommand:(CDVInvokedUrlCommand *)command error:(NSError *)error
{
NSMutableDictionary *details = [NSMutableDictionary dictionary];
if (error.domain.length > 0) {
details[@"nativeDomain"] = error.domain;
}
details[@"nativeCode"] = @(error.code);
NSString *nativeError = [self hotspotConfigurationErrorNameForCode:error.code];
if (nativeError.length > 0) {
details[@"nativeError"] = nativeError;
}
if (error.localizedFailureReason.length > 0) {
details[@"nativeFailureReason"] = error.localizedFailureReason;
}
if (error.localizedRecoverySuggestion.length > 0) {
details[@"nativeRecoverySuggestion"] = error.localizedRecoverySuggestion;
}
[self sendErrorForCommand:command
code:@"WIFI_CONNECT_FAILED"
message:[self wifiApplyErrorMessageForError:error]
details:details];
}
- (NSString *)wifiApplyErrorMessageForError:(NSError *)error
{
if (![error.domain isEqualToString:NEHotspotConfigurationErrorDomain]) {
return error.localizedDescription.length > 0 ? error.localizedDescription : @"Unable to apply WiFi configuration.";
}
switch (error.code) {
case 1:
return @"Invalid WiFi SSID.";
case 2:
return @"Invalid WPA/WPA2/WPA3 passphrase.";
case 3:
return @"Invalid WEP passphrase.";
case 4:
return @"Invalid EAP settings.";
case 5:
return @"Invalid Hotspot 2.0 settings.";
case 6:
return @"Invalid Hotspot 2.0 domain name.";
case 7:
return @"The user denied the iOS WiFi connection prompt.";
case 8:
return @"iOS returned NEHotspotConfigurationErrorInternal. Check that the App ID, entitlements, and provisioning profile include Hotspot Configuration, then test on a physical device.";
case 9:
return @"Another iOS WiFi configuration request is already pending.";
case 10:
return @"iOS system WiFi configuration failed.";
case 11:
return @"iOS returned an unknown WiFi configuration error.";
case 12:
return @"joinOnce is not supported for this WiFi configuration.";
case 14:
return @"The app must be in the foreground to configure WiFi.";
case 15:
return @"Invalid SSID prefix.";
default:
return error.localizedDescription.length > 0 ? error.localizedDescription : @"Unable to apply WiFi configuration.";
}
}
- (NSString *)hotspotConfigurationErrorNameForCode:(NSInteger)code
{
switch (code) {
case 0:
return @"invalid";
case 1:
return @"invalidSSID";
case 2:
return @"invalidWPAPassphrase";
case 3:
return @"invalidWEPPassphrase";
case 4:
return @"invalidEAPSettings";
case 5:
return @"invalidHS20Settings";
case 6:
return @"invalidHS20DomainName";
case 7:
return @"userDenied";
case 8:
return @"internal";
case 9:
return @"pending";
case 10:
return @"systemConfiguration";
case 11:
return @"unknown";
case 12:
return @"joinOnceNotSupported";
case 13:
return @"alreadyAssociated";
case 14:
return @"applicationIsNotInForeground";
case 15:
return @"invalidSSIDPrefix";
default:
return @"";
}
}
- (NSDictionary *)biometricAvailability
{
LAContext *context = [[LAContext alloc] init];
@@ -620,7 +733,14 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
- (void)sendErrorForCommand:(CDVInvokedUrlCommand *)command code:(NSString *)code message:(NSString *)message
{
NSDictionary *error = @{@"code": code ? code : @"ERROR", @"message": message ? message : @""};
[self sendErrorForCommand:command code:code message:message details:nil];
}
- (void)sendErrorForCommand:(CDVInvokedUrlCommand *)command code:(NSString *)code message:(NSString *)message details:(NSDictionary *)details
{
NSMutableDictionary *error = details == nil ? [NSMutableDictionary dictionary] : [details mutableCopy];
error[@"code"] = code ? code : @"ERROR";
error[@"message"] = message ? message : @"";
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:error];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
}