From 13d06d50eb50080be921d4c120e2b626c403353d Mon Sep 17 00:00:00 2001 From: aria Date: Wed, 22 Apr 2026 19:29:46 +0900 Subject: [PATCH] fixed ios wifi part support. retry 2. --- README.md | 1 + package.json | 2 +- plugin.xml | 2 +- src/ios/CDVBluememeUtils.m | 30 +++++++++++++++++++++++++++--- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a91f35b..6a167f3 100644 --- a/README.md +++ b/README.md @@ -213,6 +213,7 @@ iOS WiFi: - 使用 `NEHotspotConfiguration`。 - 插件会向 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 的 `NEHotspotConfiguration` password initializer 公开支持 WEP/WPA/WPA2 Personal。WPA2/WPA3 mixed 通常应先按 `security: "wpa2"` 测试;如果 WPA2-only 可用但 mixed 不可用,需要调整热点兼容性配置或改用配置描述文件/MDM 流程。 - iOS 不提供第三方 App 断开当前 WiFi 的公开 API,因此 `disconnectWifi` 在 iOS 返回错误。 Firebase: diff --git a/package.json b/package.json index a141f4a..5d6d619 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bluememe-utils", - "version": "0.1.1", + "version": "0.1.2", "description": "Cordova utilities for WiFi, Firebase Cloud Messaging, and biometric unlock for OutSystems 11 apps.", "license": "MIT", "files": [ diff --git a/plugin.xml b/plugin.xml index a47871b..0aecb06 100644 --- a/plugin.xml +++ b/plugin.xml @@ -2,7 +2,7 @@ + version="0.1.2"> bluememe-utils Cordova utilities for WiFi, Firebase Cloud Messaging, and biometric unlock. MIT diff --git a/src/ios/CDVBluememeUtils.m b/src/ios/CDVBluememeUtils.m index 70dc806..c6395d4 100644 --- a/src/ios/CDVBluememeUtils.m +++ b/src/ios/CDVBluememeUtils.m @@ -286,6 +286,10 @@ static NSString * const BluememeDeviceKeyDefaultsKey = @"bluememe_utils_device_k NSString *ssid = [self stringFromDictionary:options key:@"ssid"]; NSString *password = [self stringFromDictionary:options key:@"password"]; NSString *security = [[self stringFromDictionary:options key:@"security"] lowercaseString]; + if (security.length == 0) { + security = password.length == 0 ? @"open" : @"wpa2"; + } + BOOL isOpen = [security isEqualToString:@"open"] || [security isEqualToString:@"none"]; BOOL isWep = [security isEqualToString:@"wep"] || [self boolFromDictionary:options key:@"isWep" defaultValue:NO]; BOOL joinOnce = [self boolFromDictionary:options key:@"joinOnce" defaultValue:defaultJoinOnce]; BOOL hiddenSsid = [self boolFromDictionary:options key:@"hiddenSsid" defaultValue:NO]; @@ -295,6 +299,16 @@ static NSString * const BluememeDeviceKeyDefaultsKey = @"bluememe_utils_device_k return; } + if (!isOpen && password.length == 0) { + [self sendErrorForCommand:command code:@"INVALID_WIFI_OPTIONS" message:@"password is required for secured WiFi networks."]; + return; + } + + if (!isOpen && !isWep && (password.length < 8 || password.length > 63)) { + [self sendErrorForCommand:command code:@"INVALID_WIFI_OPTIONS" message:@"WPA/WPA2 passphrase must be 8 to 63 characters."]; + return; + } + #if TARGET_OS_SIMULATOR [self sendErrorForCommand:command code:@"UNSUPPORTED_IOS_SIMULATOR" @@ -304,7 +318,7 @@ static NSString * const BluememeDeviceKeyDefaultsKey = @"bluememe_utils_device_k if (@available(iOS 11.0, *)) { NEHotspotConfiguration *configuration = nil; - if (password.length == 0 || [security isEqualToString:@"open"]) { + if (isOpen) { configuration = [[NEHotspotConfiguration alloc] initWithSSID:ssid]; } else { configuration = [[NEHotspotConfiguration alloc] initWithSSID:ssid passphrase:password isWEP:isWep]; @@ -317,7 +331,14 @@ 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 sendWifiApplyErrorForCommand:command error:error]; + NSDictionary *context = @{ + @"ssid": ssid, + @"security": security, + @"passwordLength": @(password.length), + @"joinOnce": @(joinOnce), + @"hiddenSsid": @(hiddenSsid) + }; + [self sendWifiApplyErrorForCommand:command error:error context:context]; return; } NSDictionary *result = @{ @@ -335,9 +356,12 @@ static NSString * const BluememeDeviceKeyDefaultsKey = @"bluememe_utils_device_k } } -- (void)sendWifiApplyErrorForCommand:(CDVInvokedUrlCommand *)command error:(NSError *)error +- (void)sendWifiApplyErrorForCommand:(CDVInvokedUrlCommand *)command error:(NSError *)error context:(NSDictionary *)context { NSMutableDictionary *details = [NSMutableDictionary dictionary]; + if (context != nil) { + [details addEntriesFromDictionary:context]; + } if (error.domain.length > 0) { details[@"nativeDomain"] = error.domain; }