mirror of
https://github.com/xweiba/location-spoofer.git
synced 2026-09-26 16:41:54 +08:00
fix(i18n): 修复首选语言回退并准备 v1.0.8
This commit is contained in:
+14
-14
@@ -95,10 +95,10 @@ struct BugReportView: View {
|
||||
do {
|
||||
let response = try await thirdPartyProxy.query()
|
||||
let active = response.success && response.latitude != nil && response.longitude != nil
|
||||
let savedCoordinate = active ? String(localized: "是") : String(localized: "否")
|
||||
testLog = String(localized: "第三方代理测试模式:模块连接成功;已保存坐标=\(savedCoordinate)")
|
||||
let savedCoordinate = active ? AppLocalization.string("是") : AppLocalization.string("否")
|
||||
testLog = AppLocalization.string("第三方代理测试模式:模块连接成功;已保存坐标=\(savedCoordinate)")
|
||||
} catch {
|
||||
testLog = String(localized: "第三方代理测试模式:模块连接失败;\(error.localizedDescription)")
|
||||
testLog = AppLocalization.string("第三方代理测试模式:模块连接失败;\(error.localizedDescription)")
|
||||
}
|
||||
} else {
|
||||
_ = await setup.runVerificationTest()
|
||||
@@ -132,21 +132,21 @@ struct BugReportView: View {
|
||||
private func bugReport(appVersion: String, systemVersion: String, testLog: String) -> String {
|
||||
let client = runtimeMode.mode == .thirdParty
|
||||
? thirdPartyClient.selectedClient.name
|
||||
: String(localized: "不适用")
|
||||
let reproducible = isReproducible ? String(localized: "是") : String(localized: "否")
|
||||
let diagnostics = testLog.isEmpty ? String(localized: "(无诊断数据)") : testLog
|
||||
: AppLocalization.string("不适用")
|
||||
let reproducible = isReproducible ? AppLocalization.string("是") : AppLocalization.string("否")
|
||||
let diagnostics = testLog.isEmpty ? AppLocalization.string("(无诊断数据)") : testLog
|
||||
return """
|
||||
### \(String(localized: "环境信息"))
|
||||
\(String(localized: "App 版本")): \(appVersion)
|
||||
\(String(localized: "系统版本")): iOS \(systemVersion)
|
||||
\(String(localized: "运行模式")): \(runtimeMode.mode.displayName)
|
||||
\(String(localized: "第三方客户端")): \(client)
|
||||
\(String(localized: "可复现环境")): \(reproducible)
|
||||
### \(AppLocalization.string("环境信息"))
|
||||
\(AppLocalization.string("App 版本")): \(appVersion)
|
||||
\(AppLocalization.string("系统版本")): iOS \(systemVersion)
|
||||
\(AppLocalization.string("运行模式")): \(runtimeMode.mode.displayName)
|
||||
\(AppLocalization.string("第三方客户端")): \(client)
|
||||
\(AppLocalization.string("可复现环境")): \(reproducible)
|
||||
|
||||
### \(String(localized: "问题描述"))
|
||||
### \(AppLocalization.string("问题描述"))
|
||||
\(description.trimmingCharacters(in: .whitespacesAndNewlines))
|
||||
|
||||
### \(String(localized: "诊断日志"))
|
||||
### \(AppLocalization.string("诊断日志"))
|
||||
```
|
||||
\(diagnostics)
|
||||
```
|
||||
|
||||
@@ -177,7 +177,7 @@ struct ContentView: View {
|
||||
switch prompt.requirement {
|
||||
case .required:
|
||||
let details = prompt.releaseNotes
|
||||
?? String(localized: "更新说明暂时无法加载,请前往最新 Release 页面查看。")
|
||||
?? AppLocalization.string("更新说明暂时无法加载,请前往最新 Release 页面查看。")
|
||||
return Alert(
|
||||
title: Text("需要更新"),
|
||||
message: Text(
|
||||
@@ -189,7 +189,7 @@ struct ContentView: View {
|
||||
)
|
||||
case .recommended:
|
||||
let details = prompt.releaseNotes
|
||||
?? String(localized: "更新说明暂时无法加载,请前往最新 Release 页面查看。")
|
||||
?? AppLocalization.string("更新说明暂时无法加载,请前往最新 Release 页面查看。")
|
||||
return Alert(
|
||||
title: Text("发现新版本"),
|
||||
message: Text(
|
||||
|
||||
+11
-11
@@ -109,9 +109,9 @@ struct RuntimeLogsView: View {
|
||||
let result = await setup.runVerificationTest()
|
||||
testSucceeded = result.isSuccess
|
||||
testResult = result.isSuccess
|
||||
? String(localized: "环境检测通过")
|
||||
: String(localized: "环境检测失败: \(result.localizedTitle)")
|
||||
if !result.isSuccess { testResult += String(localized: ",查看下方日志") }
|
||||
? AppLocalization.string("环境检测通过")
|
||||
: AppLocalization.string("环境检测失败: \(result.localizedTitle)")
|
||||
if !result.isSuccess { testResult += AppLocalization.string(",查看下方日志") }
|
||||
testMessage = setup.testLog
|
||||
}
|
||||
isTesting = false; refresh()
|
||||
@@ -248,26 +248,26 @@ struct RuntimeLogsView: View {
|
||||
let response = try await thirdPartyProxy.query()
|
||||
let active = response.success && response.latitude != nil && response.longitude != nil
|
||||
testSucceeded = true
|
||||
testResult = active ? String(localized: "第三方模块连接通过,已有坐标") : String(localized: "第三方模块连接通过,暂无坐标")
|
||||
testResult = active ? AppLocalization.string("第三方模块连接通过,已有坐标") : AppLocalization.string("第三方模块连接通过,暂无坐标")
|
||||
testMessage = thirdPartyTestLog(active: active)
|
||||
} catch {
|
||||
testSucceeded = false
|
||||
testResult = String(localized: "第三方模块连接失败")
|
||||
testResult = AppLocalization.string("第三方模块连接失败")
|
||||
testMessage = thirdPartyTestLog(error: error)
|
||||
}
|
||||
}
|
||||
|
||||
private func thirdPartyTestLog(active: Bool? = nil, error: Error? = nil) -> String {
|
||||
var lines = [
|
||||
String(localized: "======== 第三方代理连接检测 ========"),
|
||||
String(localized: "模式: 测试模式"),
|
||||
String(localized: "请求: wloc-settings/save?action=query")
|
||||
AppLocalization.string("======== 第三方代理连接检测 ========"),
|
||||
AppLocalization.string("模式: 测试模式"),
|
||||
AppLocalization.string("请求: wloc-settings/save?action=query")
|
||||
]
|
||||
if let active {
|
||||
lines.append(String(localized: "拦截响应: 有效 JSON"))
|
||||
lines.append(String(localized: "已保存坐标: \(active ? String(localized: "是") : String(localized: "否"))"))
|
||||
lines.append(AppLocalization.string("拦截响应: 有效 JSON"))
|
||||
lines.append(AppLocalization.string("已保存坐标: \(active ? AppLocalization.string("是") : AppLocalization.string("否"))"))
|
||||
} else if let error {
|
||||
lines.append(String(localized: "结果: \(error.localizedDescription)"))
|
||||
lines.append(AppLocalization.string("结果: \(error.localizedDescription)"))
|
||||
}
|
||||
return lines.joined(separator: "\n")
|
||||
}
|
||||
|
||||
+34
-34
@@ -221,13 +221,13 @@ struct FirstSetupView: View {
|
||||
}
|
||||
guard !setup.message.isEmpty else { return nil }
|
||||
return [
|
||||
String(localized: "======== 第三方代理运行检测 ========"),
|
||||
String(localized: "当前客户端:\(thirdPartyClient.selectedClient.name)"),
|
||||
String(localized: "触发来源:地图或设置中的第三方代理操作"),
|
||||
String(localized: "请求动作:WLOC 配置接口"),
|
||||
String(localized: "检测结果:失败"),
|
||||
String(localized: "错误详情:\(setup.message)"),
|
||||
String(localized: "处理建议:确认模块已启用,并检查 MITM、证书和代理/VPN 连接。")
|
||||
AppLocalization.string("======== 第三方代理运行检测 ========"),
|
||||
AppLocalization.string("当前客户端:\(thirdPartyClient.selectedClient.name)"),
|
||||
AppLocalization.string("触发来源:地图或设置中的第三方代理操作"),
|
||||
AppLocalization.string("请求动作:WLOC 配置接口"),
|
||||
AppLocalization.string("检测结果:失败"),
|
||||
AppLocalization.string("错误详情:\(setup.message)"),
|
||||
AppLocalization.string("处理建议:确认模块已启用,并检查 MITM、证书和代理/VPN 连接。")
|
||||
].joined(separator: "\n")
|
||||
}
|
||||
|
||||
@@ -354,7 +354,7 @@ struct FirstSetupView: View {
|
||||
if let url = await setup.proxy.prepareCertificateDownloadURL() {
|
||||
certificateDownloadDestination = CertificateDownloadDestination(url: url)
|
||||
} else {
|
||||
setupActionError = setup.proxy.error ?? String(localized: "无法准备证书下载页面,请查看诊断日志")
|
||||
setupActionError = setup.proxy.error ?? AppLocalization.string("无法准备证书下载页面,请查看诊断日志")
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -468,7 +468,7 @@ struct FirstSetupView: View {
|
||||
|
||||
Text("返回格式")
|
||||
.font(.subheadline.bold())
|
||||
Text(String(localized: """
|
||||
Text(AppLocalization.string("""
|
||||
成功:{"success":true,"longitude":113.0,"latitude":22.0,"accuracy":25}
|
||||
失败:{"success":false,"error":"错误说明"}
|
||||
"""))
|
||||
@@ -565,7 +565,7 @@ struct FirstSetupView: View {
|
||||
if let thirdPartyFailureLog {
|
||||
testResultView(
|
||||
success: false,
|
||||
title: String(localized: "接口连接失败"),
|
||||
title: AppLocalization.string("接口连接失败"),
|
||||
log: thirdPartyFailureLog
|
||||
)
|
||||
.id("thirdPartyFailureLog")
|
||||
@@ -698,7 +698,7 @@ struct FirstSetupView: View {
|
||||
UIApplication.shared.open(url, options: [:]) { opened in
|
||||
guard !opened else { return }
|
||||
Task { @MainActor in
|
||||
manualHint = String(localized: "无法打开 \(client.name),请确认客户端已安装后手动打开。")
|
||||
manualHint = AppLocalization.string("无法打开 \(client.name),请确认客户端已安装后手动打开。")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -760,7 +760,7 @@ struct FirstSetupView: View {
|
||||
let success = result.isSuccess
|
||||
testResultView(
|
||||
success: success,
|
||||
title: success ? String(localized: "环境检测通过") : failureSummary(result),
|
||||
title: success ? AppLocalization.string("环境检测通过") : failureSummary(result),
|
||||
log: setup.testLog
|
||||
)
|
||||
}
|
||||
@@ -889,17 +889,17 @@ struct FirstSetupView: View {
|
||||
]
|
||||
)
|
||||
thirdPartyTestFailure = ThirdPartyConnectionTestFailure(message: [
|
||||
String(localized: "======== 第三方代理连接检测 ========"),
|
||||
String(localized: "当前客户端:\(client.name)"),
|
||||
String(localized: "配置接口:/wloc-settings/save"),
|
||||
String(localized: "请求动作:WLOC query"),
|
||||
String(localized: "检查范围:模块拦截、MITM、证书、代理/VPN 连接"),
|
||||
String(localized: "连接状态:\(connectionState)"),
|
||||
String(localized: "检测结果:失败"),
|
||||
String(localized: "耗时:\(elapsedMilliseconds) ms"),
|
||||
String(localized: "错误类型:\(errorType)"),
|
||||
String(localized: "错误详情:\(error.localizedDescription)"),
|
||||
String(localized: "处理建议:\(ThirdPartyProxyError.recoverySuggestion(for: error))。")
|
||||
AppLocalization.string("======== 第三方代理连接检测 ========"),
|
||||
AppLocalization.string("当前客户端:\(client.name)"),
|
||||
AppLocalization.string("配置接口:/wloc-settings/save"),
|
||||
AppLocalization.string("请求动作:WLOC query"),
|
||||
AppLocalization.string("检查范围:模块拦截、MITM、证书、代理/VPN 连接"),
|
||||
AppLocalization.string("连接状态:\(connectionState)"),
|
||||
AppLocalization.string("检测结果:失败"),
|
||||
AppLocalization.string("耗时:\(elapsedMilliseconds) ms"),
|
||||
AppLocalization.string("错误类型:\(errorType)"),
|
||||
AppLocalization.string("错误详情:\(error.localizedDescription)"),
|
||||
AppLocalization.string("处理建议:\(ThirdPartyProxyError.recoverySuggestion(for: error))。")
|
||||
].joined(separator: "\n"))
|
||||
showsThirdPartyFailureLog = true
|
||||
}
|
||||
@@ -909,11 +909,11 @@ struct FirstSetupView: View {
|
||||
private var thirdPartyConnectionStateDescription: String {
|
||||
switch thirdPartyProxy.connectionState {
|
||||
case .unknown:
|
||||
return String(localized: "未检测")
|
||||
return AppLocalization.string("未检测")
|
||||
case .connected(let active):
|
||||
return active ? String(localized: "已连接,有保存坐标") : String(localized: "已连接,无保存坐标")
|
||||
return active ? AppLocalization.string("已连接,有保存坐标") : AppLocalization.string("已连接,无保存坐标")
|
||||
case .failed(let message):
|
||||
return String(localized: "连接失败(\(message))")
|
||||
return AppLocalization.string("连接失败(\(message))")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -966,14 +966,14 @@ struct FirstSetupView: View {
|
||||
|
||||
private func failureSummary(_ result: VerificationResult) -> String {
|
||||
switch result {
|
||||
case .certNotTrusted: return String(localized: "证书尚未安装或信任")
|
||||
case .wifiProxyNotConfigured: return String(localized: "Wi-Fi 代理未正确设置")
|
||||
case .proxyNotRunning: return String(localized: "本地代理未能启动")
|
||||
case .verificationInProgress: return String(localized: "检测仍在进行")
|
||||
case .verificationSuperseded: return String(localized: "检测结果已过期")
|
||||
case .coordinateWriteFailed: return String(localized: "坐标写入失败")
|
||||
case .patchFailed: return String(localized: "定位改写检测失败")
|
||||
case .success: return String(localized: "环境检测通过")
|
||||
case .certNotTrusted: return AppLocalization.string("证书尚未安装或信任")
|
||||
case .wifiProxyNotConfigured: return AppLocalization.string("Wi-Fi 代理未正确设置")
|
||||
case .proxyNotRunning: return AppLocalization.string("本地代理未能启动")
|
||||
case .verificationInProgress: return AppLocalization.string("检测仍在进行")
|
||||
case .verificationSuperseded: return AppLocalization.string("检测结果已过期")
|
||||
case .coordinateWriteFailed: return AppLocalization.string("坐标写入失败")
|
||||
case .patchFailed: return AppLocalization.string("定位改写检测失败")
|
||||
case .success: return AppLocalization.string("环境检测通过")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+12
-12
@@ -301,7 +301,7 @@ struct MapHomeView: View {
|
||||
}
|
||||
} message: {
|
||||
Text(
|
||||
"你正在使用 \(communityContributionClient?.name ?? String(localized: "第三方客户端"))。点击“去提交”会先复制投稿模板,并在 App 内打开社区页面。采纳后将收录到 README,可选择是否匿名署名。"
|
||||
"你正在使用 \(communityContributionClient?.name ?? AppLocalization.string("第三方客户端"))。点击“去提交”会先复制投稿模板,并在 App 内打开社区页面。采纳后将收录到 README,可选择是否匿名署名。"
|
||||
)
|
||||
}
|
||||
.alert("已复制投稿模板", isPresented: $showCommunityTemplateCopied) {
|
||||
@@ -483,7 +483,7 @@ struct MapHomeView: View {
|
||||
// 当前选点
|
||||
HStack {
|
||||
VStack(alignment: .leading, spacing: 3) {
|
||||
Text(mapState.displayName ?? String(localized: "当前选点")).font(.subheadline.weight(.semibold)).lineLimit(1)
|
||||
Text(mapState.displayName ?? AppLocalization.string("当前选点")).font(.subheadline.weight(.semibold)).lineLimit(1)
|
||||
coordinateRow(label: "GCJ-02(国内)", system: .gcj02)
|
||||
coordinateRow(label: "WGS-84(国际)", system: .wgs84)
|
||||
}
|
||||
@@ -585,15 +585,15 @@ struct MapHomeView: View {
|
||||
private var buttonTitle: String {
|
||||
if runtimeMode.mode == .thirdParty {
|
||||
switch spoofState {
|
||||
case .idle: return String(localized: "同步到第三方代理")
|
||||
case .verifying: return String(localized: "检测并同步中…")
|
||||
case .active: return String(localized: "停止第三方虚拟定位")
|
||||
case .idle: return AppLocalization.string("同步到第三方代理")
|
||||
case .verifying: return AppLocalization.string("检测并同步中…")
|
||||
case .active: return AppLocalization.string("停止第三方虚拟定位")
|
||||
}
|
||||
}
|
||||
switch spoofState {
|
||||
case .idle: return String(localized: "开始虚拟定位")
|
||||
case .verifying: return String(localized: "验证环境中…")
|
||||
case .active: return String(localized: "停止虚拟定位")
|
||||
case .idle: return AppLocalization.string("开始虚拟定位")
|
||||
case .verifying: return AppLocalization.string("验证环境中…")
|
||||
case .active: return AppLocalization.string("停止虚拟定位")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1092,7 +1092,7 @@ struct MapHomeView: View {
|
||||
"请求动作": "WLOC query",
|
||||
"错误": response.error ?? "未知错误"
|
||||
])
|
||||
setup.requestThirdPartySetup(message: response.error ?? String(localized: "第三方代理查询失败"))
|
||||
setup.requestThirdPartySetup(message: response.error ?? AppLocalization.string("第三方代理查询失败"))
|
||||
}
|
||||
} catch {
|
||||
spoofState = .idle
|
||||
@@ -1145,7 +1145,7 @@ struct MapHomeView: View {
|
||||
"Wi-Fi接口": String(net.isWiFiEnabled)
|
||||
])
|
||||
activeTip = nil
|
||||
setup.requestSetup(message: String(localized: "当前未连接可用的 Wi-Fi,请连接 Wi-Fi 后配置 127.0.0.1:8888 手动代理。"))
|
||||
setup.requestSetup(message: AppLocalization.string("当前未连接可用的 Wi-Fi,请连接 Wi-Fi 后配置 127.0.0.1:8888 手动代理。"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1520,7 +1520,7 @@ struct MapHomeView: View {
|
||||
}
|
||||
searchResults = (response?.mapItems ?? []).prefix(6).map { item in
|
||||
let r = SearchLocationResult(
|
||||
name: item.name ?? String(localized: "未命名"),
|
||||
name: item.name ?? AppLocalization.string("未命名"),
|
||||
subtitle: [item.placemark.locality, item.placemark.subLocality, item.placemark.thoroughfare]
|
||||
.compactMap { $0 }
|
||||
.filter { !$0.isEmpty }
|
||||
@@ -1532,7 +1532,7 @@ struct MapHomeView: View {
|
||||
])
|
||||
return r
|
||||
}
|
||||
if searchResults.isEmpty { searchError = String(localized: "没有找到相关地点") }
|
||||
if searchResults.isEmpty { searchError = AppLocalization.string("没有找到相关地点") }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ struct PaopaoLocationSpooferApp: App {
|
||||
var body: some Scene {
|
||||
WindowGroup {
|
||||
ContentView()
|
||||
.environment(\.locale, AppLocalization.locale)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,13 +154,13 @@ final class ProxyManager: ObservableObject {
|
||||
do {
|
||||
if !isRunning { try await start() }
|
||||
guard let url = URL(string: "http://127.0.0.1:8888/cert") else {
|
||||
error = String(localized: "证书下载地址无效")
|
||||
error = AppLocalization.string("证书下载地址无效")
|
||||
return nil
|
||||
}
|
||||
error = nil
|
||||
return url
|
||||
} catch {
|
||||
self.error = String(localized: "启动代理失败: \(error.localizedDescription)")
|
||||
self.error = AppLocalization.string("启动代理失败: \(error.localizedDescription)")
|
||||
RuntimeLogger.error("APP", "Certificate", "准备证书下载失败", error: error)
|
||||
return nil
|
||||
}
|
||||
@@ -182,5 +182,5 @@ struct ProxyCoordinateSnapshot: Equatable {
|
||||
|
||||
enum ProxyError: LocalizedError {
|
||||
case startFailed
|
||||
var errorDescription: String? { String(localized: "Go proxy 启动失败") }
|
||||
var errorDescription: String? { AppLocalization.string("Go proxy 启动失败") }
|
||||
}
|
||||
|
||||
+21
-21
@@ -30,7 +30,7 @@ struct SettingsView: View {
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
@State private var activeTip: TipKind?
|
||||
@State private var proxyOperationError = ""
|
||||
@State private var proxyOperationAlertTitle = String(localized: "代理操作失败")
|
||||
@State private var proxyOperationAlertTitle = AppLocalization.string("代理操作失败")
|
||||
@State private var modeOperationRunning = false
|
||||
@State private var copiedClient: ThirdPartyProxyClient?
|
||||
@State private var copiedMITMHostname: String?
|
||||
@@ -319,12 +319,12 @@ struct SettingsView: View {
|
||||
)
|
||||
case .available(let prompt):
|
||||
let details = prompt.releaseNotes
|
||||
?? String(localized: "更新说明暂时无法加载,请前往最新 Release 页面查看。")
|
||||
?? AppLocalization.string("更新说明暂时无法加载,请前往最新 Release 页面查看。")
|
||||
let message: String
|
||||
if prompt.requirement == .required {
|
||||
message = String(localized: "当前版本 \(prompt.currentVersion) 已停止支持,请更新到 \(prompt.latestVersion) 后继续使用。\n\n\(details)")
|
||||
message = AppLocalization.string("当前版本 \(prompt.currentVersion) 已停止支持,请更新到 \(prompt.latestVersion) 后继续使用。\n\n\(details)")
|
||||
} else {
|
||||
message = String(localized: "当前版本 \(prompt.currentVersion),最新版本 \(prompt.latestVersion)。\n\n\(details)")
|
||||
message = AppLocalization.string("当前版本 \(prompt.currentVersion),最新版本 \(prompt.latestVersion)。\n\n\(details)")
|
||||
}
|
||||
return Alert(
|
||||
title: prompt.requirement == .required ? Text("需要更新") : Text("发现新版本"),
|
||||
@@ -351,7 +351,7 @@ struct SettingsView: View {
|
||||
try await proxy.start()
|
||||
} catch {
|
||||
proxy.error = error.localizedDescription
|
||||
proxyOperationAlertTitle = String(localized: "代理操作失败")
|
||||
proxyOperationAlertTitle = AppLocalization.string("代理操作失败")
|
||||
proxyOperationError = error.localizedDescription
|
||||
}
|
||||
} else {
|
||||
@@ -482,27 +482,27 @@ struct SettingsView: View {
|
||||
|
||||
private var thirdPartyStatusText: String {
|
||||
switch thirdPartyProxy.connectionState {
|
||||
case .unknown: return String(localized: "未检测")
|
||||
case .connected(let active): return active ? String(localized: "已连接,有坐标") : String(localized: "已连接,无坐标")
|
||||
case .failed: return String(localized: "连接失败")
|
||||
case .unknown: return AppLocalization.string("未检测")
|
||||
case .connected(let active): return active ? AppLocalization.string("已连接,有坐标") : AppLocalization.string("已连接,无坐标")
|
||||
case .failed: return AppLocalization.string("连接失败")
|
||||
}
|
||||
}
|
||||
|
||||
private var virtualLocationStatusText: String {
|
||||
if runtimeMode.mode == .localWiFi {
|
||||
return actions.virtualLocationEnabled ? String(localized: "已开启") : String(localized: "已关闭")
|
||||
return actions.virtualLocationEnabled ? AppLocalization.string("已开启") : AppLocalization.string("已关闭")
|
||||
}
|
||||
if case .connected(let active) = thirdPartyProxy.connectionState {
|
||||
return active ? String(localized: "第三方已保存") : String(localized: "未保存")
|
||||
return active ? AppLocalization.string("第三方已保存") : AppLocalization.string("未保存")
|
||||
}
|
||||
return String(localized: "未知")
|
||||
return AppLocalization.string("未知")
|
||||
}
|
||||
|
||||
private var workflowDescription: String {
|
||||
if runtimeMode.mode == .thirdParty {
|
||||
return String(localized: "App 只负责地图选点、收藏和发送 WGS-84 坐标。第三方代理客户端通过模块拦截 Apple WLOC 请求并持久化当前坐标;本模式不启动本机代理,不使用 App 的 CA,也不需要配置 127.0.0.1:8888。")
|
||||
return AppLocalization.string("App 只负责地图选点、收藏和发送 WGS-84 坐标。第三方代理客户端通过模块拦截 Apple WLOC 请求并持久化当前坐标;本模式不启动本机代理,不使用 App 的 CA,也不需要配置 127.0.0.1:8888。")
|
||||
}
|
||||
return String(localized: """
|
||||
return AppLocalization.string("""
|
||||
App 在设备本地运行一个代理服务器(127.0.0.1:8888)。
|
||||
|
||||
通过 WiFi 手动代理配置,让系统发往 Apple 定位域名(gs-loc.apple.com、gsp-ssl.ls.apple.com、bluedot.is.autonavi.com 等)的定位请求经过这个本地代理。代理使用已安装的 CA 证书对 HTTPS 流量做中间人解密,把 Apple 返回的定位坐标改写为你设置的虚拟坐标,再加密返回给系统,从而实现虚拟定位。
|
||||
@@ -523,8 +523,8 @@ struct SettingsView: View {
|
||||
if runtimeMode.isInitialized(.thirdParty) {
|
||||
do {
|
||||
_ = try await thirdPartyProxy.query()
|
||||
proxyOperationAlertTitle = String(localized: "模式已切换")
|
||||
proxyOperationError = String(localized: "第三方代理模式检测通过。请关闭 Wi-Fi 中的 127.0.0.1:8888 手动代理,避免双重拦截。")
|
||||
proxyOperationAlertTitle = AppLocalization.string("模式已切换")
|
||||
proxyOperationError = AppLocalization.string("第三方代理模式检测通过。请关闭 Wi-Fi 中的 127.0.0.1:8888 手动代理,避免双重拦截。")
|
||||
} catch {
|
||||
openThirdPartySetup(for: error)
|
||||
}
|
||||
@@ -546,8 +546,8 @@ struct SettingsView: View {
|
||||
let result = await setup.runVerificationTest()
|
||||
setup.applyVerificationResult(result)
|
||||
if result.isSuccess {
|
||||
proxyOperationAlertTitle = String(localized: "模式已切换")
|
||||
proxyOperationError = String(localized: "APP 模式环境检测通过。请停用第三方 WLOC 模块或代理连接,避免双重拦截。")
|
||||
proxyOperationAlertTitle = AppLocalization.string("模式已切换")
|
||||
proxyOperationError = AppLocalization.string("APP 模式环境检测通过。请停用第三方 WLOC 模块或代理连接,避免双重拦截。")
|
||||
} else {
|
||||
dismiss()
|
||||
}
|
||||
@@ -608,14 +608,14 @@ struct SettingsView: View {
|
||||
try setup.certificateStore.reset()
|
||||
runtimeMode.resetInitialization(.localWiFi)
|
||||
guard await setup.prepareLocalServices() else {
|
||||
proxyOperationAlertTitle = String(localized: "证书重置失败")
|
||||
proxyOperationAlertTitle = AppLocalization.string("证书重置失败")
|
||||
proxyOperationError = setup.message
|
||||
return
|
||||
}
|
||||
setup.requestCertificateSetup()
|
||||
dismiss()
|
||||
} catch {
|
||||
proxyOperationAlertTitle = String(localized: "证书重置失败")
|
||||
proxyOperationAlertTitle = AppLocalization.string("证书重置失败")
|
||||
proxyOperationError = error.localizedDescription
|
||||
}
|
||||
}
|
||||
@@ -626,8 +626,8 @@ struct SettingsView: View {
|
||||
UIApplication.shared.open(url, options: [:]) { opened in
|
||||
guard !opened else { return }
|
||||
Task { @MainActor in
|
||||
proxyOperationAlertTitle = String(localized: "无法打开客户端")
|
||||
proxyOperationError = String(localized: "无法打开 \(client.name),请确认客户端已安装后手动打开。")
|
||||
proxyOperationAlertTitle = AppLocalization.string("无法打开客户端")
|
||||
proxyOperationError = AppLocalization.string("无法打开 \(client.name),请确认客户端已安装后手动打开。")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+23
-23
@@ -36,7 +36,7 @@ final class SetupCoordinator: ObservableObject {
|
||||
message = ""
|
||||
return true
|
||||
} catch {
|
||||
message = String(localized: "本地代理初始化失败:\(error.localizedDescription)")
|
||||
message = AppLocalization.string("本地代理初始化失败:\(error.localizedDescription)")
|
||||
RuntimeLogger.error("APP", "Startup", "本地服务初始化失败", error: error)
|
||||
return false
|
||||
}
|
||||
@@ -48,19 +48,19 @@ final class SetupCoordinator: ObservableObject {
|
||||
case .success:
|
||||
trustState = .trusted
|
||||
needsSetup = false
|
||||
message = String(localized: "✓ 定位环境正常")
|
||||
message = AppLocalization.string("✓ 定位环境正常")
|
||||
case .certNotTrusted:
|
||||
trustState = .unavailable
|
||||
setupStep = .cert
|
||||
needsSetup = true
|
||||
message = String(localized: "CA 证书未安装或未信任")
|
||||
message = AppLocalization.string("CA 证书未安装或未信任")
|
||||
case .verificationInProgress, .verificationSuperseded:
|
||||
break
|
||||
default:
|
||||
trustState = .unavailable
|
||||
setupStep = .proxy
|
||||
needsSetup = true
|
||||
message = String(localized: "Wi-Fi 代理未正确设置,请检查 127.0.0.1:8888")
|
||||
message = AppLocalization.string("Wi-Fi 代理未正确设置,请检查 127.0.0.1:8888")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,36 +108,36 @@ final class SetupCoordinator: ObservableObject {
|
||||
testLog = ""
|
||||
let log = { (msg: String) in self.testLog += msg + "\n" }
|
||||
|
||||
log(String(localized: "======== 代理验证测试 ========"))
|
||||
log(String(localized: "App 版本: \(appVersion)"))
|
||||
log(String(localized: "系统版本: iOS \(UIDevice.current.systemVersion)"))
|
||||
log(AppLocalization.string("======== 代理验证测试 ========"))
|
||||
log(AppLocalization.string("App 版本: \(appVersion)"))
|
||||
log(AppLocalization.string("系统版本: iOS \(UIDevice.current.systemVersion)"))
|
||||
log("")
|
||||
|
||||
// Step A: Proxy running
|
||||
log(String(localized: "[步骤 A] 检查代理是否运行…"))
|
||||
log(String(localized: " 端口: 127.0.0.1:8888"))
|
||||
log(AppLocalization.string("[步骤 A] 检查代理是否运行…"))
|
||||
log(AppLocalization.string(" 端口: 127.0.0.1:8888"))
|
||||
let stepAStart = Date()
|
||||
if !proxy.isRunning {
|
||||
log(String(localized: " ⚠ 代理未运行,尝试启动…"))
|
||||
log(AppLocalization.string(" ⚠ 代理未运行,尝试启动…"))
|
||||
do { try await proxy.start() } catch {
|
||||
log(String(localized: " ✗ 启动失败: \(error.localizedDescription)"))
|
||||
log(AppLocalization.string(" ✗ 启动失败: \(error.localizedDescription)"))
|
||||
return .proxyNotRunning
|
||||
}
|
||||
log(String(localized: " ✓ 代理启动成功"))
|
||||
log(AppLocalization.string(" ✓ 代理启动成功"))
|
||||
} else {
|
||||
log(String(localized: " ✓ 代理已在运行中"))
|
||||
log(AppLocalization.string(" ✓ 代理已在运行中"))
|
||||
}
|
||||
collectProxyLogs(since: stepAStart, to: log)
|
||||
|
||||
// Step B: Combined CA + WiFi proxy check (single request)
|
||||
log("")
|
||||
log(String(localized: "[步骤 B] 检测证书与 WiFi 代理…"))
|
||||
log(String(localized: " 方式: 请求 baidu.com/paopao-verify-<token>"))
|
||||
log(String(localized: " 结果判定: TLS 错误=证书问题 / 响应不匹配=代理未配置 / 匹配=通过"))
|
||||
log(AppLocalization.string("[步骤 B] 检测证书与 WiFi 代理…"))
|
||||
log(AppLocalization.string(" 方式: 请求 baidu.com/paopao-verify-<token>"))
|
||||
log(AppLocalization.string(" 结果判定: TLS 错误=证书问题 / 响应不匹配=代理未配置 / 匹配=通过"))
|
||||
let stepBStart = Date()
|
||||
let verifyToken = CoreBridge.refreshVerifyToken()
|
||||
guard !verifyToken.isEmpty else {
|
||||
log(String(localized: " ✗ 无法生成验证 token"))
|
||||
log(AppLocalization.string(" ✗ 无法生成验证 token"))
|
||||
return .certNotTrusted
|
||||
}
|
||||
do {
|
||||
@@ -150,17 +150,17 @@ final class SetupCoordinator: ObservableObject {
|
||||
let statusCode = (resp as? HTTPURLResponse)?.statusCode ?? 0
|
||||
let body = String(data: data, encoding: .utf8) ?? ""
|
||||
if body == verifyToken {
|
||||
log(String(localized: " ✓ 证书已信任,WiFi 代理已配置"))
|
||||
log(AppLocalization.string(" ✓ 证书已信任,WiFi 代理已配置"))
|
||||
} else {
|
||||
log(String(localized: " ✗ 响应不匹配: HTTP \(statusCode), \(data.count) bytes,WiFi 代理未配置"))
|
||||
log(AppLocalization.string(" ✗ 响应不匹配: HTTP \(statusCode), \(data.count) bytes,WiFi 代理未配置"))
|
||||
return .wifiProxyNotConfigured
|
||||
}
|
||||
} catch {
|
||||
let ns = error as NSError
|
||||
let msg = error.localizedDescription
|
||||
log(String(localized: " ✗ 请求失败 [\(ns.domain) code=\(ns.code)]: \(msg)"))
|
||||
log(AppLocalization.string(" ✗ 请求失败 [\(ns.domain) code=\(ns.code)]: \(msg)"))
|
||||
if isCertificateTrustError(nsError: ns, message: msg) {
|
||||
log(String(localized: " TLS/证书校验失败,CA 证书未信任"))
|
||||
log(AppLocalization.string(" TLS/证书校验失败,CA 证书未信任"))
|
||||
return .certNotTrusted
|
||||
}
|
||||
return .wifiProxyNotConfigured
|
||||
@@ -168,7 +168,7 @@ final class SetupCoordinator: ObservableObject {
|
||||
collectProxyLogs(since: stepBStart, to: log)
|
||||
|
||||
log("")
|
||||
log(String(localized: "======== 环境检测通过 ✓ ========"))
|
||||
log(AppLocalization.string("======== 环境检测通过 ✓ ========"))
|
||||
return .success
|
||||
}
|
||||
|
||||
@@ -202,7 +202,7 @@ final class SetupCoordinator: ObservableObject {
|
||||
$0.source == "CORE" && $0.category == "Proxy" && $0.timestamp >= date
|
||||
}
|
||||
guard !proxyEntries.isEmpty else { return }
|
||||
log(String(localized: " --- 代理日志 ---"))
|
||||
log(AppLocalization.string(" --- 代理日志 ---"))
|
||||
for e in proxyEntries {
|
||||
log(" " + e.localizedMessage)
|
||||
}
|
||||
|
||||
@@ -25,13 +25,13 @@ enum SystemSettingsDestination {
|
||||
var manualPath: String {
|
||||
switch self {
|
||||
case .appPermissions:
|
||||
return String(localized: "请手动打开「设置」,找到本 App 后检查定位权限。")
|
||||
return AppLocalization.string("请手动打开「设置」,找到本 App 后检查定位权限。")
|
||||
case .general:
|
||||
return String(localized: "请手动打开「设置 → 通用」。")
|
||||
return AppLocalization.string("请手动打开「设置 → 通用」。")
|
||||
case .wifi:
|
||||
return String(localized: "请手动打开「设置 → 无线局域网」,进入当前 Wi-Fi 的详情页。")
|
||||
return AppLocalization.string("请手动打开「设置 → 无线局域网」,进入当前 Wi-Fi 的详情页。")
|
||||
case .locationServices:
|
||||
return String(localized: "请手动打开「设置 → 隐私与安全性 → 定位服务」。")
|
||||
return AppLocalization.string("请手动打开「设置 → 隐私与安全性 → 定位服务」。")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user