Fix onboarding crashes, shortcut text, and data sources UX#6390
Conversation
UNUserNotificationCenter.current() asserts when called during SwiftUI view body evaluation. Wrap in DispatchQueue.main.async to defer the call until after the rendering pass. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Always show skip button so users aren't stuck waiting - Replace disabled "Finishing..." button with a spinner + status text - Show "Continue" button only when scanning is complete - Gmail/email connection no longer blocks the continue flow Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Greptile SummaryThis PR fixes a SIGABRT crash when tapping "English" during onboarding by deferring
Confidence Score: 4/5Mostly safe to merge; one P1 migration bug can cause existing mid-onboarding users to skip the Goal step. Score of 4 reflects a concrete P1 regression for a subset of users (those with hasInsertedDataSourcesStep=false who are at step 16) where Goal is silently skipped. All other findings are P2 style/animation issues that don't block correctness. OnboardingFlow.swift (not in diff but called from OnboardingView.swift) — the hasInsertedExportsStep migration threshold needs to be >= 17, not >= 16. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["onAppear — compute migratedStep()"] --> B{hasInsertedDataSourcesStep?}
B -- false, step≥16 --> C[step += 1]
B -- true --> D[no change]
C --> E{hasInsertedExportsStep?}
D --> E
E -- false, step≥16 --> F[step += 1]
E -- true --> G[no change]
F --> H{Both flags were false AND step was 16?}
G --> I[Correct: step lands on Goal=17]
H -- yes --> J["❌ step=18 = Tasks\n(Goal skipped)"]
H -- no --> I
|
| UNUserNotificationCenter.current().getNotificationSettings { settings in | ||
| DispatchQueue.main.async { |
There was a problem hiding this comment.
The getNotificationSettings completion closure body is indented at the same level as the outer DispatchQueue.main.async block rather than one level deeper, making the nesting structure hard to read. This is a style-only issue — the logic is correct.
| UNUserNotificationCenter.current().getNotificationSettings { settings in | |
| DispatchQueue.main.async { | |
| UNUserNotificationCenter.current().getNotificationSettings { settings in | |
| DispatchQueue.main.async { |
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
| if coordinator.isResearchComplete { | ||
| Button("Continue") { | ||
| onContinue() | ||
| } | ||
| .buttonStyle(OnboardingCardButtonStyle(isPrimary: true)) | ||
| .transition(.opacity.combined(with: .scale(scale: 0.95))) | ||
| } else { | ||
| HStack(spacing: 8) { | ||
| ProgressView() | ||
| .controlSize(.small) | ||
| .tint(OmiColors.textTertiary) | ||
| Text("Scanning your data sources...") | ||
| .font(.system(size: 13, weight: .medium)) | ||
| .foregroundColor(OmiColors.textTertiary) | ||
| } | ||
| } |
There was a problem hiding this comment.
.transition() has no effect without withAnimation
The .transition(.opacity.combined(with: .scale(scale: 0.95))) on the Continue button only fires when the view is inserted/removed inside an explicit animated transaction. Since coordinator.isResearchComplete is published state that changes on a background task, the branch flip likely happens outside any withAnimation {} context and the transition will be a hard cut. To make the animation actually play, trigger the relevant state change inside withAnimation, or add an .animation(.easeInOut, value: coordinator.isResearchComplete) modifier on the surrounding VStack.
|
Mac mini test: PASS - all onboarding fixes verified Build: Compiled and launched successfully (ad-hoc signed, Fix 1 - Crash on English click (UNUserNotificationCenter):
Fix 2 - Shortcut step text:
Fix 3 - Data sources step:
|
…ip button)
## Summary
- **Fix crash on "English" click**: `UNUserNotificationCenter.current()`
was being called during SwiftUI view body evaluation, causing an
assertion failure (SIGABRT). Deferred the call with
`DispatchQueue.main.async`.
- **Update shortcut step text**: Both shortcut screens now clearly state
which shortcut is being configured ("Ask a question" vs "Audio ask a
question") so users understand why buttons may not light up if shortcuts
are already assigned.
- **Data sources step UX**: Added skip button, replaced disabled
"Finishing..." button with a progress spinner, and show "Continue" only
when ready.
## Test plan
- [ ] Click "English" in onboarding language step — app should not crash
- [ ] Verify shortcut setup screens show updated text
- [ ] Verify data sources step has skip button and progress indicator
- [ ] Verify "Continue" appears after scanning completes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Summary
UNUserNotificationCenter.current()was being called during SwiftUI view body evaluation, causing an assertion failure (SIGABRT). Deferred the call withDispatchQueue.main.async.Test plan
🤖 Generated with Claude Code