Update iOS debugging info

This commit is contained in:
aria committed 2026-04-03 12:40:43 +09:00
1 parent 41739ef881
commit 92735af955
2 files changed
+177 -24

No files matched your search

+2
View File
@@ -47,6 +47,8 @@ document.addEventListener("deviceready", function () {
});
```
iOS 成功时会额外返回 `connectionSucceeded`、`connectionStatus` 和 `details`。其中 `details` 会包含 `configuredSSIDs`、`requestedSSIDConfiguredByApp`、`passphraseLength` 等诊断字段;失败时同样会把输入摘要和 native 错误信息放进 `error.details`,便于定位是参数问题还是系统拒绝。
## 推荐模式
### 1. 设备级保存网络
+175 -24
View File
@@ -23,7 +23,14 @@
}
NSString *message = [NSString stringWithFormat:@"Mode '%@' is not supported on iOS. Use 'save' or 'localOnly'.", resolvedMode];
[self sendErrorCode:@"MODE_NOT_SUPPORTED" message:message details:nil command:command];
[self sendErrorCode:@"MODE_NOT_SUPPORTED"
message:message
details:@{
@"platform": @"ios",
@"requestedMode": requestedMode ?: @"",
@"resolvedMode": resolvedMode ?: @""
}
command:command];
}
- (void)connectLocalOnly:(CDVInvokedUrlCommand *)command
@@ -101,15 +108,22 @@
{
if (@available(iOS 11.0, *)) {
NSString *ssid = [self stringForKey:@"ssid" inOptions:options];
NSString *security = [self normalizeSecurity:[self stringForKey:@"security" inOptions:options]];
NSMutableDictionary *requestDetails = [self requestDetailsForOptions:options
ssid:ssid
security:security
mode:mode
joinOnce:joinOnce];
if (ssid.length == 0) {
requestDetails[@"invalidOption"] = @"ssid";
[self sendErrorCode:@"INVALID_OPTIONS"
message:@"Missing required option: ssid"
details:nil
details:requestDetails
command:command];
return;
}
NSString *security = [self normalizeSecurity:[self stringForKey:@"security" inOptions:options]];
NEHotspotConfiguration *configuration = nil;
if ([security isEqualToString:@"OPEN"]) {
@@ -117,23 +131,36 @@
} else if ([security isEqualToString:@"WPA2"]) {
NSString *passphrase = [self stringForKey:@"passphrase" inOptions:options];
if (passphrase.length == 0) {
requestDetails[@"invalidOption"] = @"passphrase";
[self sendErrorCode:@"INVALID_OPTIONS"
message:@"Missing required option: passphrase"
details:nil
details:requestDetails
command:command];
return;
}
if (passphrase.length < 8 || passphrase.length > 63) {
requestDetails[@"invalidOption"] = @"passphrase";
requestDetails[@"validation"] = @"WPA2 passphrase must be between 8 and 63 characters.";
[self sendErrorCode:@"INVALID_OPTIONS"
message:@"Invalid passphrase length for WPA2 Wi-Fi."
details:requestDetails
command:command];
return;
}
configuration = [[NEHotspotConfiguration alloc] initWithSSID:ssid passphrase:passphrase isWEP:NO];
} else if ([security isEqualToString:@"WPA3"]) {
requestDetails[@"invalidOption"] = @"security";
[self sendErrorCode:@"MODE_NOT_SUPPORTED"
message:@"iOS hotspot configuration supports OPEN, WEP, WPA, and WPA2. WPA3 is not exposed by this plugin on iOS."
details:nil
details:requestDetails
command:command];
return;
} else {
NSString *message = [NSString stringWithFormat:@"Unsupported security type on iOS: %@", security];
[self sendErrorCode:@"INVALID_SECURITY" message:message details:nil command:command];
requestDetails[@"invalidOption"] = @"security";
[self sendErrorCode:@"INVALID_SECURITY" message:message details:requestDetails command:command];
return;
}
@@ -142,26 +169,24 @@
dispatch_async(dispatch_get_main_queue(), ^{
[[NEHotspotConfigurationManager sharedManager] applyConfiguration:configuration completionHandler:^(NSError * _Nullable error) {
if (error != nil) {
[self sendNativeError:error code:@"IOS_WIFI_CONFIGURATION_FAILED" command:command];
if (error != nil && ![self isAlreadyAssociatedError:error]) {
[self sendNativeError:error
code:@"IOS_WIFI_CONFIGURATION_FAILED"
requestDetails:requestDetails
command:command];
return;
}
NSMutableDictionary *result = [@{
@"mode": mode,
@"ssid": ssid,
@"apiName": @"NEHotspotConfigurationManager",
@"platform": @"ios",
@"joinOnce": @(joinOnce),
@"hidden": @(configuration.hidden),
@"saved": @(!joinOnce)
} mutableCopy];
if ([mode isEqualToString:@"localOnly"]) {
result[@"boundToProcess"] = @NO;
}
[self sendSuccess:result command:command];
NSString *connectionStatus = error == nil ? @"APPLIED" : @"ALREADY_ASSOCIATED";
[self sendApplyConfigurationSuccessForSSID:ssid
security:security
mode:mode
joinOnce:joinOnce
configuration:configuration
requestDetails:requestDetails
connectionStatus:connectionStatus
nativeError:error
command:command];
}];
});
return;
@@ -173,6 +198,99 @@
command:command];
}
- (NSMutableDictionary *)requestDetailsForOptions:(NSDictionary *)options
ssid:(NSString *)ssid
security:(NSString *)security
mode:(NSString *)mode
joinOnce:(BOOL)joinOnce
{
NSString *passphrase = [self stringForKey:@"passphrase" inOptions:options];
BOOL hidden = [self boolForKey:@"hidden" inOptions:options defaultValue:NO];
NSMutableDictionary *details = [@{
@"platform": @"ios",
@"apiName": @"NEHotspotConfigurationManager",
@"resolvedMode": mode ?: @"",
@"security": security ?: @"",
@"joinOnce": @(joinOnce),
@"hidden": @(hidden),
@"ssidLength": @(ssid.length),
@"passphraseProvided": @(passphrase.length > 0),
@"systemVersion": [[NSProcessInfo processInfo] operatingSystemVersionString] ?: @""
} mutableCopy];
if (passphrase.length > 0) {
details[@"passphraseLength"] = @(passphrase.length);
}
if (options[@"localOnly"] != nil) {
details[@"localOnly"] = @([self boolForKey:@"localOnly" inOptions:options defaultValue:NO]);
}
return details;
}
- (NSMutableDictionary *)baseConnectionResultForSSID:(NSString *)ssid
security:(NSString *)security
mode:(NSString *)mode
joinOnce:(BOOL)joinOnce
configuration:(NEHotspotConfiguration *)configuration
requestDetails:(NSDictionary *)requestDetails
connectionStatus:(NSString *)connectionStatus
{
NSMutableDictionary *result = [@{
@"mode": mode ?: @"",
@"ssid": ssid ?: @"",
@"security": security ?: @"",
@"apiName": @"NEHotspotConfigurationManager",
@"platform": @"ios",
@"joinOnce": @(joinOnce),
@"hidden": @(configuration.hidden),
@"saved": @(!joinOnce),
@"connectionSucceeded": @YES,
@"connectionStatus": connectionStatus ?: @"UNKNOWN",
@"details": [requestDetails mutableCopy]
} mutableCopy];
if ([mode isEqualToString:@"localOnly"]) {
result[@"boundToProcess"] = @NO;
}
return result;
}
- (void)sendApplyConfigurationSuccessForSSID:(NSString *)ssid
security:(NSString *)security
mode:(NSString *)mode
joinOnce:(BOOL)joinOnce
configuration:(NEHotspotConfiguration *)configuration
requestDetails:(NSDictionary *)requestDetails
connectionStatus:(NSString *)connectionStatus
nativeError:(NSError * _Nullable)nativeError
command:(CDVInvokedUrlCommand *)command API_AVAILABLE(ios(11.0))
{
NSMutableDictionary *result = [self baseConnectionResultForSSID:ssid
security:security
mode:mode
joinOnce:joinOnce
configuration:configuration
requestDetails:requestDetails
connectionStatus:connectionStatus];
NSMutableDictionary *details = [result[@"details"] mutableCopy];
details[@"configurationApplied"] = @YES;
if (nativeError != nil) {
[details addEntriesFromDictionary:[self nativeErrorDetails:nativeError]];
}
[[NEHotspotConfigurationManager sharedManager] getConfiguredSSIDsWithCompletionHandler:^(NSArray<NSString *> * _Nonnull ssids) {
NSArray<NSString *> *configuredSsids = ssids ?: @[];
details[@"configuredSSIDs"] = configuredSsids;
details[@"requestedSSIDConfiguredByApp"] = @([configuredSsids containsObject:ssid]);
result[@"details"] = details;
[self sendSuccess:result command:command];
}];
}
- (NSDictionary *)optionsFromCommand:(CDVInvokedUrlCommand *)command
{
if ([command.arguments count] == 0) {
@@ -279,19 +397,52 @@
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
- (void)sendNativeError:(NSError *)error code:(NSString *)code command:(CDVInvokedUrlCommand *)command
- (NSDictionary *)nativeErrorDetails:(NSError *)error
{
NSMutableDictionary *details = [NSMutableDictionary dictionary];
if (error.domain.length > 0) {
details[@"domain"] = error.domain;
}
details[@"nativeCode"] = @(error.code);
if (error.localizedDescription.length > 0) {
details[@"nativeMessage"] = error.localizedDescription;
}
id failureReason = error.userInfo[NSLocalizedFailureReasonErrorKey];
if ([failureReason isKindOfClass:[NSString class]] && [failureReason length] > 0) {
details[@"failureReason"] = failureReason;
}
id recoverySuggestion = error.userInfo[NSLocalizedRecoverySuggestionErrorKey];
if ([recoverySuggestion isKindOfClass:[NSString class]] && [recoverySuggestion length] > 0) {
details[@"recoverySuggestion"] = recoverySuggestion;
}
id debugDescription = error.userInfo[NSDebugDescriptionErrorKey];
if ([debugDescription isKindOfClass:[NSString class]] && [debugDescription length] > 0) {
details[@"debugDescription"] = debugDescription;
}
return details;
}
- (BOOL)isAlreadyAssociatedError:(NSError *)error
{
return error != nil &&
[error.domain isEqualToString:NEHotspotConfigurationErrorDomain] &&
error.code == NEHotspotConfigurationErrorAlreadyAssociated;
}
- (void)sendNativeError:(NSError *)error
code:(NSString *)code
requestDetails:(NSDictionary *)requestDetails
command:(CDVInvokedUrlCommand *)command
{
NSMutableDictionary *details = [requestDetails mutableCopy] ?: [NSMutableDictionary dictionary];
[details addEntriesFromDictionary:[self nativeErrorDetails:error]];
details[@"connectionSucceeded"] = @NO;
details[@"connectionStatus"] = @"FAILED";
[self sendErrorCode:code
message:error.localizedDescription
details:details