Skip to content

fix: resolve Google Translate connection test and onboarding screen recording permission issues#65

Merged
hubo1989 merged 2 commits intomainfrom
fixgoogle-translate
Mar 18, 2026
Merged

fix: resolve Google Translate connection test and onboarding screen recording permission issues#65
hubo1989 merged 2 commits intomainfrom
fixgoogle-translate

Conversation

@hubo1989
Copy link
Owner

@hubo1989 hubo1989 commented Mar 5, 2026

Summary

  • Fix TranslationService.testConnection() to create provider lazily for third-party engines (Google, DeepL, Baidu, LLM) that require credentials before the provider can be instantiated
  • Fix OnboardingViewModel.requestScreenRecordingPermission() to trigger ScreenCaptureKit API before opening System Settings, ensuring the app appears in the Screen Recording permission list

Problem

  1. Google Translate (and other third-party translation engines) connection test always failed because the provider was never created before testing
  2. Onboarding screen recording permission button didn't register the app in the system permission list before opening System Settings

Solution

  1. Modified TranslationService.testConnection() to automatically create the provider using registry.createProvider() if it doesn't exist
  2. Modified OnboardingViewModel.requestScreenRecordingPermission() to call SCShareableContent.excludingDesktopWindows() first, matching the behavior in SettingsViewModel

Test plan

  • Configure Google Translate API key in settings and verify connection test succeeds
  • Test DeepL and Baidu connection tests similarly
  • Run app fresh (or reset onboarding) and verify screen recording permission button registers app in system permission list

🤖 Generated with Claude Code

Summary by CodeRabbit

  • 改进
    • 优化屏幕录制权限请求流程:先发起注册/排除桌面窗口的异步调用,再打开系统设置并开始轮询权限状态,改善用户体验与稳健性。
    • 提升连接测试逻辑:优先复用已有提供者,按需创建并加入错误处理与日志,增强连通性检测的可靠性与效率。

…ecording permission issues

- Fix TranslationService.testConnection() to create provider lazily for third-party engines
  (Google, DeepL, Baidu, LLM) that require credentials before the provider can be instantiated
- Fix OnboardingViewModel.requestScreenRecordingPermission() to trigger ScreenCaptureKit API
  before opening System Settings, ensuring the app appears in the Screen Recording permission list

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link

coderabbitai bot commented Mar 5, 2026

📝 Walkthrough

Walkthrough

本次变更调整了屏幕录制权限请求流程为异步注册后再打开系统设置并启动轮询;同时调整了 TranslationService.testConnection(for:),优先复用现有提供者并按需创建新提供者以检测连通性。

Changes

Cohort / File(s) Summary
屏幕录制权限流程
ScreenTranslate/Features/Onboarding/OnboardingViewModel.swift
当未获权限时改为先异步调用 SCShareableContent.excludingDesktopWindows(...)(忽略错误)以将应用注册到可共享内容列表,再在 MainActor 打开系统设置,最后启动权限轮询(替换了之前的立即打开设置逻辑)。
连接测试与提供者管理
ScreenTranslate/Services/TranslationService.swift
重构 testConnection(for:):先尝试从注册表复用现有提供者并返回其连通性;若无现有提供者,仅为需要 API Key 的引擎条件性创建提供者并检查连通性;创建失败或异常时记录日志并返回 false。

Sequence Diagram(s)

sequenceDiagram
    participant App as 应用
    participant SCContent as SCShareableContent
    participant Settings as 系统设置
    participant Poller as 权限轮询器

    App->>SCContent: call excludingDesktopWindows(...)
    SCContent-->>App: 返回(忽略错误)
    App->>Settings: 在 MainActor 上 打开 系统设置
    Settings->>Settings: 用户在系统设置中授予/拒绝权限
    App->>Poller: 启动权限轮询
    Poller->>Poller: 周期性检查权限状态
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 我在草丛里轻点脚步,
先登记,再敲设置之门,
提供者排队守望连接,
轮询悄声等待许可到来,
小胡萝卜跳舞庆祝新序曲 🥕✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR标题准确概括了主要变更:修复Google Translate连接测试和屏幕录制权限问题,与原始总结中的两个关键变更直接对应。
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fixgoogle-translate

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
ScreenTranslate/Features/Onboarding/OnboardingViewModel.swift (1)

194-196: MainActor.run 是多余的

由于 OnboardingViewModel 类已经标记为 @MainActor(第 9 行),类内所有方法默认在 MainActor 上执行。在 Task 闭包内部,继承了 actor 上下文,因此 await MainActor.run 是不必要的。

♻️ 简化代码
         Task {
             do {
                 // This will trigger the system to register the app in Screen Recording permissions
                 _ = try await SCShareableContent.excludingDesktopWindows(false, onScreenWindowsOnly: true)
             } catch {
                 // Expected when permission not granted - app is now registered
             }
 
             // Open System Settings after triggering the API
-            await MainActor.run {
-                openScreenRecordingSettings()
-            }
+            openScreenRecordingSettings()
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ScreenTranslate/Features/Onboarding/OnboardingViewModel.swift` around lines
194 - 196, Remove the redundant await MainActor.run wrapper inside
OnboardingViewModel (class is already annotated `@MainActor`) and directly call
openScreenRecordingSettings() from the Task closure; update the Task block that
currently calls await MainActor.run { openScreenRecordingSettings() } to simply
invoke openScreenRecordingSettings() so the call uses the existing actor
context.
ScreenTranslate/Services/TranslationService.swift (1)

395-398: 内置引擎返回 false 可能导致 UI 误导

根据 EngineConfigSheet.swift (Context snippet 2),当 testConnection 返回 false 时,UI 会显示红色 "xmark.circle.fill" 图标和 "engine.config.test.failed" 消息。

对于内置引擎 (apple, mtranServer, ollama),如果 provider 由于某种原因未注册,返回 false 会让用户误以为连接失败,而实际上可能只是 provider 初始化问题。

建议区分"引擎不可用"和"连接测试失败"两种情况,或者在日志中记录这种边界情况以便调试。

♻️ 建议:添加日志以便调试
         guard engine.requiresAPIKey else {
             // Built-in engines should already be registered
+            logger.warning("Built-in engine \(engine.rawValue) has no registered provider")
             return false
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ScreenTranslate/Services/TranslationService.swift` around lines 395 - 398,
The guard in testConnection that returns false when engine.requiresAPIKey is
false causes built-in engines to appear as failing in the UI; update the
testConnection implementation so that for built-in engines (when
engine.requiresAPIKey == false) it does NOT return false—instead detect if the
provider is missing/unregistered, emit a clear debug/warning log (use the
existing logging facility) with details about the missing provider, and return a
positive/neutral result (e.g., true or a distinct successful/unknown result
consistent with EngineConfigSheet.swift expectations) so the UI doesn't show an
erroneous connection failure; reference the testConnection method and
engine.requiresAPIKey check and add logging around the provider
lookup/registration path.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@ScreenTranslate/Features/Onboarding/OnboardingViewModel.swift`:
- Around line 194-196: Remove the redundant await MainActor.run wrapper inside
OnboardingViewModel (class is already annotated `@MainActor`) and directly call
openScreenRecordingSettings() from the Task closure; update the Task block that
currently calls await MainActor.run { openScreenRecordingSettings() } to simply
invoke openScreenRecordingSettings() so the call uses the existing actor
context.

In `@ScreenTranslate/Services/TranslationService.swift`:
- Around line 395-398: The guard in testConnection that returns false when
engine.requiresAPIKey is false causes built-in engines to appear as failing in
the UI; update the testConnection implementation so that for built-in engines
(when engine.requiresAPIKey == false) it does NOT return false—instead detect if
the provider is missing/unregistered, emit a clear debug/warning log (use the
existing logging facility) with details about the missing provider, and return a
positive/neutral result (e.g., true or a distinct successful/unknown result
consistent with EngineConfigSheet.swift expectations) so the UI doesn't show an
erroneous connection failure; reference the testConnection method and
engine.requiresAPIKey check and add logging around the provider
lookup/registration path.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b4790527-a7a1-4bea-b1d6-0f36a2631b04

📥 Commits

Reviewing files that changed from the base of the PR and between 5369666 and 437cf19.

📒 Files selected for processing (2)
  • ScreenTranslate/Features/Onboarding/OnboardingViewModel.swift
  • ScreenTranslate/Services/TranslationService.swift

- Remove redundant MainActor.run wrapper in OnboardingViewModel (class is already @mainactor)
- Add logging for missing built-in engine providers and return true instead of false
  to avoid false connection failure in UI

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@ScreenTranslate/Services/TranslationService.swift`:
- Around line 395-400: The current guard handling for engine.requiresAPIKey
returns true when a provider is missing which causes false-positive connectivity
(e.g., .ollama is requiresAPIKey == false but can be unreachable); change the
logic in the guard block so that when a provider is not found you log the
warning via logger.warning("Built-in engine \(engine.rawValue) provider not
found in registry") and return false (or perform an actual connectivity probe)
instead of returning true, ensuring engine.requiresAPIKey == false does not
bypass real connectivity checks.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 258bf1b4-fbc8-43f2-9f35-5e8a0ad8f8d7

📥 Commits

Reviewing files that changed from the base of the PR and between 437cf19 and 998f4dd.

📒 Files selected for processing (2)
  • ScreenTranslate/Features/Onboarding/OnboardingViewModel.swift
  • ScreenTranslate/Services/TranslationService.swift

Comment on lines +395 to +400
guard engine.requiresAPIKey else {
// Built-in engines (apple, mtranServer) should already be registered in init
// If missing, log warning but return true to avoid false failure in UI
logger.warning("Built-in engine \(engine.rawValue) provider not found in registry")
return true
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

requiresAPIKey == false 分支会导致 .ollama 连通性误报成功。

当 provider 不存在时直接 return true 会跳过真实连接检查;而 .ollama 也属于 requiresAPIKey == false,因此会被误判为“连接成功”。

建议修复
-        guard engine.requiresAPIKey else {
-            // Built-in engines (apple, mtranServer) should already be registered in init
-            // If missing, log warning but return true to avoid false failure in UI
-            logger.warning("Built-in engine \(engine.rawValue) provider not found in registry")
-            return true
-        }
+        if !engine.requiresAPIKey {
+            switch engine {
+            case .apple, .mtranServer:
+                // 仅对预注册内建引擎保留当前兜底行为
+                logger.warning("Built-in engine \(engine.rawValue) provider not found in registry")
+                return true
+            default:
+                // 例如 .ollama:仍需创建 provider 并执行真实连通性检测
+                break
+            }
+        }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ScreenTranslate/Services/TranslationService.swift` around lines 395 - 400,
The current guard handling for engine.requiresAPIKey returns true when a
provider is missing which causes false-positive connectivity (e.g., .ollama is
requiresAPIKey == false but can be unreachable); change the logic in the guard
block so that when a provider is not found you log the warning via
logger.warning("Built-in engine \(engine.rawValue) provider not found in
registry") and return false (or perform an actual connectivity probe) instead of
returning true, ensuring engine.requiresAPIKey == false does not bypass real
connectivity checks.

@hubo1989 hubo1989 merged commit c86aebf into main Mar 18, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant