fix: support iOS 26#764
Conversation
📝 WalkthroughWalkthroughThis PR introduces a new SwiftUI-based local currency/fiat selector interface system with supporting geometry tracking components. It refactors the payment tab from a custom button to native tab bar integration, updates spacing/styling across views, adds color assets, and enhances build configuration for Xcode 26 compatibility and preview support. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~65 minutes Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
DashWallet/Sources/UI/Main/MainTabbarController.swift (1)
243-254: Fix unused closure parameter and consider consistent error handling.The static analyzer flags that
contextis unused. Also, if"tabbar_pay_button"asset is missing, this silently renders just a blue circle (unlike lines 48/67 which force-unwrap).♻️ Proposed fix
- let image = renderer.image { context in + let image = renderer.image { _ in // Draw blue circle background UIColor.dw_dashBlue().setFill() UIBezierPath(ovalIn: rect).fill() // Draw icon centered - if let icon = UIImage(named: "tabbar_pay_button") { + guard let icon = UIImage(named: "tabbar_pay_button") else { + assertionFailure("Missing tabbar_pay_button asset") + return + } - let iconSize = CGSize(width: 22, height: 22) - let iconOrigin = CGPoint(x: (size - iconSize.width) / 2, y: (size - iconSize.height) / 2) - icon.draw(in: CGRect(origin: iconOrigin, size: iconSize)) - } + let iconSize = CGSize(width: 22, height: 22) + let iconOrigin = CGPoint(x: (size - iconSize.width) / 2, y: (size - iconSize.height) / 2) + icon.draw(in: CGRect(origin: iconOrigin, size: iconSize)) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Main/MainTabbarController.swift` around lines 243 - 254, In MainTabbarController inside the renderer.image closure, replace the unused closure parameter `context` with `_` (e.g., `renderer.image { _ in ... }`) to silence the analyzer, and make handling of the "tabbar_pay_button" asset consistent with other sites (lines 48/67) by forcing the asset presence instead of silently skipping: replace the `if let icon = UIImage(named: "tabbar_pay_button") { ... }` with a non-optional access (or a guard that aborts/asserts) so the code either draws the icon or fails loudly when the asset is missing.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@DashWallet/Sources/UI/Home/HomeViewController`+Shortcuts.swift:
- Line 325: The file HomeViewController+Shortcuts.swift is missing a single
trailing newline at EOF which triggers SwiftLint; open the file
(HomeViewController+Shortcuts.swift) and ensure the file ends with exactly one
newline character (add a single trailing newline after the last line) so it
conforms to the single trailing newline rule used by SwiftLint/SwiftFormat.
In `@DashWallet/Sources/UI/Main/MainTabbarController.swift`:
- Line 93: Remove the dead stored property paymentIsOpened from
MainTabbarController: delete the declaration `private var paymentIsOpened =
false` and remove any assignments to it in closePayments(),
paymentsViewControllerWantsToImportPrivateKey(), and showPaymentsController();
keep the existing flow implemented by the EmptyController
interceptor/PaymentButton refactor and ensure no other code references
paymentIsOpened (search for the symbol and remove or adapt any leftover uses).
---
Nitpick comments:
In `@DashWallet/Sources/UI/Main/MainTabbarController.swift`:
- Around line 243-254: In MainTabbarController inside the renderer.image
closure, replace the unused closure parameter `context` with `_` (e.g.,
`renderer.image { _ in ... }`) to silence the analyzer, and make handling of the
"tabbar_pay_button" asset consistent with other sites (lines 48/67) by forcing
the asset presence instead of silently skipping: replace the `if let icon =
UIImage(named: "tabbar_pay_button") { ... }` with a non-optional access (or a
guard that aborts/asserts) so the code either draws the icon or fails loudly
when the asset is missing.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 726a1ba0-1c64-45d6-9516-323bce902d09
⛔ Files ignored due to path filters (1)
DashWallet/Resources/AppAssets.xcassets/Shortcuts/shortcut_scanToPay.imageset/scan.svgis excluded by!**/*.svg
📒 Files selected for processing (6)
DashWallet/Sources/UI/Buy Sell/BuySellPortal.storyboardDashWallet/Sources/UI/Home/HomeViewController+Shortcuts.swiftDashWallet/Sources/UI/Home/Views/Shortcuts/ShortcutsView.swiftDashWallet/Sources/UI/Main/MainTabbarController.swiftDashWallet/Sources/UI/Menu/Security/Advanced Security/Model/DWBaseAdvancedSecurityModel.mDashWallet/Sources/UI/Views/Navigation/BaseNavigationController.swift
💤 Files with no reviewable changes (2)
- DashWallet/Sources/UI/Views/Navigation/BaseNavigationController.swift
- DashWallet/Sources/UI/Buy Sell/BuySellPortal.storyboard
There was a problem hiding this comment.
Actionable comments posted: 8
🧹 Nitpick comments (7)
DashWallet/Sources/UI/Menu/Settings/LocalCurrency/Cells/LocalCurrencyCellView.swift (2)
45-59: Use explicit shapes if older iOS targets are still supported.Lines 45 and 59 use SwiftUI shape shorthand. If the deployment target is below iOS 17, replace it with explicit shapes to avoid availability issues. Apple Shape docs list these as standard-shape shorthand APIs: https://developer.apple.com/documentation/SwiftUI/Shape
♻️ Proposed compatibility-safe change
- .clipShape(.rect) + .clipped()- .clipShape(.circle) + .clipShape(Circle())🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Menu/Settings/LocalCurrency/Cells/LocalCurrencyCellView.swift` around lines 45 - 59, The shorthand shape usage in flagSection (the .clipShape(.rect) and .clipShape(.circle) calls) can break on pre-iOS17 targets; replace those shorthand calls with explicit shape types (e.g., clipShape(Rectangle()) and clipShape(Circle())) in the LocalCurrencyCellView's flagSection, keeping the frame size (Layout.flagSize) and the UIImage(named:) existence check logic unchanged.
101-113: PreferTextconcatenation for highlighted ranges.This avoids relying on localized-string interpolation for dynamic currency names/codes and keeps the styled segment explicit.
♻️ Proposed simplification
- return Text("\(before)\(Text(match).foregroundColor(.dashBlue))\(after)") + return Text(before) + Text(match).foregroundColor(.dashBlue) + Text(after)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Menu/Settings/LocalCurrency/Cells/LocalCurrencyCellView.swift` around lines 101 - 113, The highlightedText(_ text: String, query: String) function currently builds a single interpolated Text using "\(before)\(Text(match).foregroundColor(.dashBlue))\(after)" which can trigger localized-string interpolation and is less explicit; change it to concatenate explicit Text pieces instead: create Text(before) + Text(match).foregroundColor(.dashBlue) + Text(after) so the styled segment is an explicit Text view and avoids interpolation/localization issues while preserving the existing trimming/range logic.DashWallet/Sources/UI/SwiftUI Components/SearchBar.swift (2)
48-48: Avoid iOS 17 shape shorthand in a pre-iOS 17-compatible view.Line 48 uses
.rect(cornerRadius:)while this same component has an earlier-iOS fallback at Lines 118-125. If the app still supports iOS 16 or below, prefer the explicit shape initializer. Apple Shape docs list.rectas SwiftUI standard-shape shorthand: https://developer.apple.com/documentation/SwiftUI/Shape♻️ Proposed compatibility-safe change
- .clipShape(.rect(cornerRadius: Layout.fieldCornerRadius)) + .clipShape(RoundedRectangle(cornerRadius: Layout.fieldCornerRadius, style: .continuous))🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/SwiftUI` Components/SearchBar.swift at line 48, The view uses the iOS 17 shape shorthand `.rect(cornerRadius:)` in the clipShape call; replace that shorthand with the explicit shape initializer used in the earlier fallback (e.g., use RoundedRectangle(cornerRadius: Layout.fieldCornerRadius) as the argument to clipShape) so the SearchBar.swift component remains compatible with iOS 16 and earlier; update the clipShape call where `.rect(cornerRadius: Layout.fieldCornerRadius)` appears (and ensure visual parity with the existing fallback logic around the earlier lines).
35-35: Remove or wire up the unused cancel-button measurement state.
cancelButtonWidthandcancelButtonMeasurementare never read bybody, so this adds dead state updates without affecting layout.🧹 Proposed cleanup
- `@State` private var cancelButtonWidth: CGFloat = 0- private var cancelButtonMeasurement: some View { - cancelButton - .fixedSize() - .padding(.leading, Layout.fieldSpacing) - .hidden() - .captureSize { size in - if abs(cancelButtonWidth - size.width) > 0.5 { - cancelButtonWidth = size.width - } - } - } -Also applies to: 91-101
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/SwiftUI` Components/SearchBar.swift at line 35, The cancelButtonWidth and cancelButtonMeasurement `@State` properties in SearchBar are unused by body and should be removed to eliminate dead state; find the declarations cancelButtonWidth and cancelButtonMeasurement (and any related measurement helper code that only updates them) and either wire them into layout logic used by body (e.g., use cancelButtonWidth to conditionally animate or offset the cancel button) or simply delete both state properties and their update calls so no unused state updates remain.DashWallet/Sources/UI/SwiftUI Components/Geometry Readers/FrameReader.swift (1)
20-24: Clean up the SwiftLint warnings in this new utility.Move the doc comment before the availability attribute, use
Void, and discard the unused preview loop parameter.🧹 Proposed SwiftLint cleanup
-@available(iOS 14, *) /// Adds a transparent View and read it's frame. /// /// Adds a GeometryReader with infinity frame. +@available(iOS 14, *) public struct FrameReader: View { @@ - func readingFrame(coordinateSpace: CoordinateSpace = .global, onChange: `@escaping` (_ frame: CGRect) -> ()) -> some View { + func readingFrame(coordinateSpace: CoordinateSpace = .global, onChange: `@escaping` (_ frame: CGRect) -> Void) -> some View { @@ - ForEach(0..<30) { x in + ForEach(0..<30) { _ inAs per coding guidelines,
**/*.swift: Use SwiftFormat and SwiftLint for Swift code formatting and linting as configured in.swiftformatand.swiftlint.ymlfiles.Also applies to: 53-53, 78-78
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/SwiftUI` Components/Geometry Readers/FrameReader.swift around lines 20 - 24, Move the doc comment for FrameReader to sit before the `@available`(iOS 14, *) attribute, update any functions or type aliases returning an empty tuple to use Void, and remove or replace the unused preview loop parameter in the PreviewProvider (discard it with _ or remove the loop variable) so SwiftLint warnings are resolved; check the FrameReader struct and its associated preview code (including the occurrences referenced around the other instances) to apply these three changes consistently.DashWallet/Sources/UI/SwiftUI Components/ScrollViews/ScrollViewWithOnScrollChanged.swift (1)
21-33: Apply the SwiftLint spelling for the generic constraint and closure return type.This keeps the new component compliant with the configured lint rules.
🧹 Proposed SwiftLint cleanup
-public struct ScrollViewWithOnScrollChanged<Content:View>: View { +public struct ScrollViewWithOnScrollChanged<Content: View>: View { @@ - let onScrollChanged: (_ origin: CGPoint) -> () + let onScrollChanged: (_ origin: CGPoint) -> Void @@ - onScrollChanged: `@escaping` (_ origin: CGPoint) -> ()) { + onScrollChanged: `@escaping` (_ origin: CGPoint) -> Void) {As per coding guidelines,
**/*.swift: Use SwiftFormat and SwiftLint for Swift code formatting and linting as configured in.swiftformatand.swiftlint.ymlfiles.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/SwiftUI` Components/ScrollViews/ScrollViewWithOnScrollChanged.swift around lines 21 - 33, The generic constraint and closure return type in ScrollViewWithOnScrollChanged should follow SwiftLint rules: change the generic constraint in the struct declaration (ScrollViewWithOnScrollChanged<Content:View>) to include a space after the colon (ScrollViewWithOnScrollChanged<Content: View>) and update the onScrollChanged closure signature (onScrollChanged: (_ origin: CGPoint) -> ()) to use Swift's Void type (onScrollChanged: `@escaping` (_ origin: CGPoint) -> Void); apply the same Void return type in the public init parameter list so both the stored property and initializer use the corrected closure signature.DashWallet/Sources/UI/SwiftUI Components/Geometry Readers/LocationReader.swift (1)
20-24: Clean up the SwiftLint warnings in the location reader.Move the doc comment before the availability attribute, use
Void, and replace the unused preview parameter with_.🧹 Proposed SwiftLint cleanup
-@available(iOS 14, *) /// Adds a transparent View and read it's center point. /// /// Adds a GeometryReader with 0px by 0px frame. +@available(iOS 14, *) public struct LocationReader: View { @@ - func readingLocation(coordinateSpace: CoordinateSpace = .global, onChange: `@escaping` (_ location: CGPoint) -> ()) -> some View { + func readingLocation(coordinateSpace: CoordinateSpace = .global, onChange: `@escaping` (_ location: CGPoint) -> Void) -> some View { @@ - ForEach(0..<30) { x in + ForEach(0..<30) { _ inAs per coding guidelines,
**/*.swift: Use SwiftFormat and SwiftLint for Swift code formatting and linting as configured in.swiftformatand.swiftlint.ymlfiles.Also applies to: 48-48, 74-74
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/SwiftUI` Components/Geometry Readers/LocationReader.swift around lines 20 - 24, Move the doc comment so it appears before the `@available`(iOS 14, *) attribute for the LocationReader struct, change any function or property type using the empty tuple () to Void, and replace the named unused preview parameter in the preview provider (or any initializer/closure) with an underscore (_) to silence unused-parameter SwiftLint warnings; update occurrences inside the LocationReader type and its PreviewProvider to reflect these changes (look for symbols LocationReader and the preview provider or preview/init parameter name).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@DashWallet.xcodeproj/project.pbxproj`:
- Line 6: The project contains objectVersion = 70 and Xcode 16-specific
PBXFileSystemSynchronizedRootGroup entries which require a newer xcodeproj gem;
update the Gemfile to require xcodeproj >= 1.27.0 (and run bundle update
xcodeproj to refresh Gemfile.lock) so CocoaPods/Xcode project parsing succeeds,
and update CI configuration (the workflow or image settings) to use Xcode 16+ so
the environment matches the project format.
- Around line 497-501: The PBX project contains duplicate PBXBuildFile entries
for several Info.plist resources in the same PBXResourcesBuildPhase; locate the
duplicated PBXBuildFile entries (e.g., the two Topper-Info.plist entries
5151C8C92F913BF100F0A604 and 5151C8CD2F913BF100F0A604, the duplicated
Coinbase-Info.plist, GoogleService-Info.plist, and ZenLedger-Info.plist entries)
and remove the redundant PBXBuildFile lines from each PBXResourcesBuildPhase
(for phases 75D5F3BC191EC270004AB296 and C9D2C90A2A320AA000D15901), keeping only
the canonical PBXBuildFile reference (the correct fileRef) for each plist so
each resource appears exactly once in its Resources build phase.
In `@DashWallet/Sources/UI/Menu/Settings/LocalCurrency/LocalCurrencyView.swift`:
- Line 107: The SwiftLint complaints in LocalCurrencyView relate to spacing and
ternary usage in the .padding call and an operator-spacing violation elsewhere;
update the .padding(filteredItems.count > 0 ? 6 : 0) usage in LocalCurrencyView
to a lint-friendly form (for example use filteredItems.isEmpty ? 0 : 6 or ensure
proper spaces around operators) so the ternary and comparison follow SwiftLint
rules, and fix the operator spacing at the other offending expression (line with
the operator violation) by adding/removing spaces so it conforms to
operator_usage_whitespace; then run SwiftFormat/SwiftLint to reformat and verify
no warnings remain.
- Line 136: The .animation(.smooth, value: scrollOffset) call in
LocalCurrencyView uses Animation.smooth which is iOS 17-only and will crash on
iOS 15–16; replace it with a cross-version animation (e.g., .animation(.default,
value: scrollOffset) or .animation(.interactiveSpring(...), value: scrollOffset)
) or wrap the iOS-17-only animation in an availability check so that for iOS 17+
you use .smooth and for earlier OSes you fall back to a supported animation,
keeping the reference to scrollOffset and LocalCurrencyView unchanged.
In
`@DashWallet/Sources/UI/Menu/Settings/LocalCurrency/LocalCurrencyViewModel.swift`:
- Line 125: The entry in the flagByCode dictionary uses "Algeria" with capital A
which breaks the lowercase asset naming convention; update the value for key
"DZD" in flagByCode to "algeria" so it matches the other lowercase flag asset
names and the expected asset lookup behavior.
In `@DashWallet/Sources/UI/Menu/Settings/SettingsScreen.swift`:
- Around line 189-201: The showCurrencySelector function currently pushes a raw
UIHostingController(rootView: LocalCurrencyView) which bypasses
BaseNavigationController's navigation/back handling; create a thin hosting
controller subclass (e.g., LocalCurrencyHostingController:
UIHostingController<LocalCurrencyView>) that conforms to the same
navigation-display protocol or interfaces used by other SwiftUI wrappers in the
project, instantiate that wrapper with the LocalCurrencyView, and push the
wrapper (controller) instead of a bare UIHostingController in
showCurrencySelector to restore proper nav-bar/back-button behavior.
In `@DashWallet/Sources/UI/SwiftUI` Components/SearchBar.swift:
- Around line 66-83: Remove the unnecessary `@ViewBuilder` annotation from the
clearButton computed property and convert explicit Button(action: { ... }) { ...
} forms to the preferred trailing-label style using the closure-first syntax,
e.g. change Button(action: { text = "" }) { Image(...) } to Button { text = "" }
label: { Image(systemName: "xmark.circle.fill").foregroundColor(...) }, and do
the same refactor for cancelButton (change Button(action: { text = "";
withAnimation { isEditing = false }; isFocused = false }) { ... } to Button {
text = ""; withAnimation(.easeInOut(duration: Layout.animationDuration)) {
isEditing = false }; isFocused = false } label: { ... }), ensuring you update
the label closures accordingly.
- Line 29: Change the static constant animationDuration from CGFloat to
TimeInterval (or Double) in the SearchBar component so it matches SwiftUI's
Animation.easeInOut(duration:), and update any places referencing
SearchBar.animationDuration (used in the animation modifiers around the view
state changes) to pass the value directly without casting; ensure the constant's
declaration (animationDuration) and all usages in animation(...) calls use the
TimeInterval/Double type.
---
Nitpick comments:
In
`@DashWallet/Sources/UI/Menu/Settings/LocalCurrency/Cells/LocalCurrencyCellView.swift`:
- Around line 45-59: The shorthand shape usage in flagSection (the
.clipShape(.rect) and .clipShape(.circle) calls) can break on pre-iOS17 targets;
replace those shorthand calls with explicit shape types (e.g.,
clipShape(Rectangle()) and clipShape(Circle())) in the LocalCurrencyCellView's
flagSection, keeping the frame size (Layout.flagSize) and the UIImage(named:)
existence check logic unchanged.
- Around line 101-113: The highlightedText(_ text: String, query: String)
function currently builds a single interpolated Text using
"\(before)\(Text(match).foregroundColor(.dashBlue))\(after)" which can trigger
localized-string interpolation and is less explicit; change it to concatenate
explicit Text pieces instead: create Text(before) +
Text(match).foregroundColor(.dashBlue) + Text(after) so the styled segment is an
explicit Text view and avoids interpolation/localization issues while preserving
the existing trimming/range logic.
In `@DashWallet/Sources/UI/SwiftUI` Components/Geometry Readers/FrameReader.swift:
- Around line 20-24: Move the doc comment for FrameReader to sit before the
`@available`(iOS 14, *) attribute, update any functions or type aliases returning
an empty tuple to use Void, and remove or replace the unused preview loop
parameter in the PreviewProvider (discard it with _ or remove the loop variable)
so SwiftLint warnings are resolved; check the FrameReader struct and its
associated preview code (including the occurrences referenced around the other
instances) to apply these three changes consistently.
In `@DashWallet/Sources/UI/SwiftUI` Components/Geometry
Readers/LocationReader.swift:
- Around line 20-24: Move the doc comment so it appears before the
`@available`(iOS 14, *) attribute for the LocationReader struct, change any
function or property type using the empty tuple () to Void, and replace the
named unused preview parameter in the preview provider (or any
initializer/closure) with an underscore (_) to silence unused-parameter
SwiftLint warnings; update occurrences inside the LocationReader type and its
PreviewProvider to reflect these changes (look for symbols LocationReader and
the preview provider or preview/init parameter name).
In `@DashWallet/Sources/UI/SwiftUI`
Components/ScrollViews/ScrollViewWithOnScrollChanged.swift:
- Around line 21-33: The generic constraint and closure return type in
ScrollViewWithOnScrollChanged should follow SwiftLint rules: change the generic
constraint in the struct declaration
(ScrollViewWithOnScrollChanged<Content:View>) to include a space after the colon
(ScrollViewWithOnScrollChanged<Content: View>) and update the onScrollChanged
closure signature (onScrollChanged: (_ origin: CGPoint) -> ()) to use Swift's
Void type (onScrollChanged: `@escaping` (_ origin: CGPoint) -> Void); apply the
same Void return type in the public init parameter list so both the stored
property and initializer use the corrected closure signature.
In `@DashWallet/Sources/UI/SwiftUI` Components/SearchBar.swift:
- Line 48: The view uses the iOS 17 shape shorthand `.rect(cornerRadius:)` in
the clipShape call; replace that shorthand with the explicit shape initializer
used in the earlier fallback (e.g., use RoundedRectangle(cornerRadius:
Layout.fieldCornerRadius) as the argument to clipShape) so the SearchBar.swift
component remains compatible with iOS 16 and earlier; update the clipShape call
where `.rect(cornerRadius: Layout.fieldCornerRadius)` appears (and ensure visual
parity with the existing fallback logic around the earlier lines).
- Line 35: The cancelButtonWidth and cancelButtonMeasurement `@State` properties
in SearchBar are unused by body and should be removed to eliminate dead state;
find the declarations cancelButtonWidth and cancelButtonMeasurement (and any
related measurement helper code that only updates them) and either wire them
into layout logic used by body (e.g., use cancelButtonWidth to conditionally
animate or offset the cancel button) or simply delete both state properties and
their update calls so no unused state updates remain.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 0dfcfd9f-8697-4aab-987f-1552d360eb2b
📒 Files selected for processing (19)
DashWallet.xcodeproj/project.pbxprojDashWallet.xcodeproj/xcshareddata/xcschemes/dashwallet.xcschemeDashWallet/AppDelegate.mDashWallet/Sources/UI/Menu/Settings/LocalCurrency/Cells/LocalCurrencyCellView.swiftDashWallet/Sources/UI/Menu/Settings/LocalCurrency/CurrencyItem.swiftDashWallet/Sources/UI/Menu/Settings/LocalCurrency/LocalCurrencyView.swiftDashWallet/Sources/UI/Menu/Settings/LocalCurrency/LocalCurrencyViewModel.swiftDashWallet/Sources/UI/Menu/Settings/SettingsScreen.swiftDashWallet/Sources/UI/SwiftUI Components/Color+DWStyle.swiftDashWallet/Sources/UI/SwiftUI Components/Geometry Readers/FrameReader.swiftDashWallet/Sources/UI/SwiftUI Components/Geometry Readers/LocationReader.swiftDashWallet/Sources/UI/SwiftUI Components/ScrollViews/ScrollViewWithOnScrollChanged.swiftDashWallet/Sources/UI/SwiftUI Components/SearchBar.swiftShared/Resources/SharedAssets.xcassets/Colors/Black/Black1000Alpha30.colorset/Contents.jsonShared/Resources/SharedAssets.xcassets/Colors/Black/Black1000Alpha50.colorset/Contents.jsonShared/Resources/SharedAssets.xcassets/Colors/NumberKeyboardHighlightedTextColor.colorset/Contents.jsonShared/Resources/SharedAssets.xcassets/Colors/SearchBackground.colorset/Contents.jsonShared/Resources/SharedAssets.xcassets/Colors/ShadowColor.colorset/Contents.jsonShared/Resources/SharedAssets.xcassets/Colors/TertiaryBackgroundColor.colorset/Contents.json
✅ Files skipped from review due to trivial changes (9)
- DashWallet.xcodeproj/xcshareddata/xcschemes/dashwallet.xcscheme
- DashWallet/AppDelegate.m
- Shared/Resources/SharedAssets.xcassets/Colors/TertiaryBackgroundColor.colorset/Contents.json
- Shared/Resources/SharedAssets.xcassets/Colors/Black/Black1000Alpha50.colorset/Contents.json
- Shared/Resources/SharedAssets.xcassets/Colors/NumberKeyboardHighlightedTextColor.colorset/Contents.json
- Shared/Resources/SharedAssets.xcassets/Colors/ShadowColor.colorset/Contents.json
- Shared/Resources/SharedAssets.xcassets/Colors/Black/Black1000Alpha30.colorset/Contents.json
- Shared/Resources/SharedAssets.xcassets/Colors/SearchBackground.colorset/Contents.json
- DashWallet/Sources/UI/SwiftUI Components/Color+DWStyle.swift
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (2)
.github/workflows/release-xcode26.yml (1)
5-8: Redundant branch patterns.
release/**already matches everythingrelease/*matches (and more), so listing both is redundant. Keep onlyrelease/**(or onlyrelease/*if you intentionally want to exclude nested paths likerelease/2026/04).♻️ Proposed fix
push: branches: - - release/* - release/**Also consider adding a
concurrencyblock so rapid pushes to the same release branch don't queue multiple 90-minute archive jobs:concurrency: group: release-xcode26-${{ github.ref }} cancel-in-progress: true🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/release-xcode26.yml around lines 5 - 8, The push branch patterns are redundant: remove the duplicate "release/*" entry and keep only "release/**" in the push.branches list so nested release paths are still matched; additionally add a concurrency block with group: release-xcode26-${{ github.ref }} and cancel-in-progress: true to prevent long-running duplicate jobs from queuing (place the concurrency stanza at the top level of the workflow alongside the push trigger).fastlane/Fastfile (1)
85-92: Use fastlane'sensure_xcode_versionaction instead of rolling custom regex.Replace the regex check with
ensure_xcode_version(version: "26", strict: false)to match Xcode 26.x. The built-in action provides clearer error messages and avoids custom parsing logic. Note: this action depends on the deprecated xcode-install gem; for new projects, consider thexcodesaction as an alternative.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@fastlane/Fastfile` around lines 85 - 92, The custom Xcode detection in the private_lane :ensure_xcode_26 currently parses xcodebuild output with a regex; replace that logic by calling Fastlane's ensure_xcode_version action to validate Xcode 26.x (e.g., ensure_xcode_version(version: "26", strict: false)) inside the ensure_xcode_26 lane, removing the sh("xcodebuild -version") parsing and the UI.user_error! path; if you need a non-deprecated alternative, consider using the xcodes action instead and document that choice in the lane.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/release-xcode26.yml:
- Around line 20-23: The workflow uses the maxim-lobanov/setup-xcode action with
an unsupported semver shorthand value for the input key xcode-version; change
the xcode-version value from "26.x" to a valid SemVer string or range (e.g.,
"26" to allow any 26.x or a specific patch like "26.3"), so update the
xcode-version field in the Select Xcode 26.x step to a supported format.
- Around line 35-38: The GitHub Actions step named "Setup CocoaPods" currently
uses maxim-lobanov/setup-cocoapods@v1 which is unmaintained; replace the action
reference with the actively maintained fork step-security/setup-cocoapods@v1
(preserve the existing `version: "1.15.2"` input and any other with/inputs) so
the step reads the same but points to the maintained action; update any workflow
documentation/comments that mention the old action name to reflect the new
action.
In `@fastlane/Fastfile`:
- Around line 23-24: The beta lane currently calls ensure_xcode_26 which raises
UI.user_error! and blocks developers on Xcode 15/16 from running fastlane beta
before cocoapods_install; remove or relax that hard guard in the beta lane by
either moving the ensure_xcode_26 call back to the CI-only lane
(release_archive_ci) or replacing the hard error in the ensure_xcode_26
invocation within the beta lane with a soft warning/log (e.g., warn and
continue) so local TestFlight pushes still work until the team migrates to Xcode
26; update the Fastfile references to ensure_xcode_26, beta, release_archive_ci,
cocoapods_install, and any UI.user_error! calls accordingly.
- Around line 49-65: The lane release_archive_ci currently duplicates CocoaPods
installation and is missing a CI-friendly build flag; remove the external pod
install --repo-update step from the workflow (release-xcode26.yml) so
cocoapods_install in the lane is the sole install, and update the build_app call
in release_archive_ci to include skip_profile_detection: true alongside
skip_codesigning: true to prevent provisioning/profile lookups on CI.
---
Nitpick comments:
In @.github/workflows/release-xcode26.yml:
- Around line 5-8: The push branch patterns are redundant: remove the duplicate
"release/*" entry and keep only "release/**" in the push.branches list so nested
release paths are still matched; additionally add a concurrency block with
group: release-xcode26-${{ github.ref }} and cancel-in-progress: true to prevent
long-running duplicate jobs from queuing (place the concurrency stanza at the
top level of the workflow alongside the push trigger).
In `@fastlane/Fastfile`:
- Around line 85-92: The custom Xcode detection in the private_lane
:ensure_xcode_26 currently parses xcodebuild output with a regex; replace that
logic by calling Fastlane's ensure_xcode_version action to validate Xcode 26.x
(e.g., ensure_xcode_version(version: "26", strict: false)) inside the
ensure_xcode_26 lane, removing the sh("xcodebuild -version") parsing and the
UI.user_error! path; if you need a non-deprecated alternative, consider using
the xcodes action instead and document that choice in the lane.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 5853d409-78cf-492d-a8bc-5e02a8a1f398
📒 Files selected for processing (2)
.github/workflows/release-xcode26.ymlfastlane/Fastfile
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
DashWallet/Sources/UI/Main/MainTabbarController.swift (1)
40-46:.paymentenum cases are now dead code.Since the Payment tab item is built via
makePaymentTabImage()inconfigureControllers(), the.paymentbranches in bothiconandselectedIconare no longer referenced. You can drop the case (or route it throughmakePaymentTabImage()) to avoid stale code.♻️ Proposed cleanup
var icon: UIImage { let name: String switch self { case .home: name = "tabbar_home_icon" case .contacts: name = "tabbar_contacts_icon" - case .payment: - name = "tabbar_pay_button" case .explore: name = "tabbar_discover_icon" case .more: name = "tabbar_other_icon" + case .payment: + // Rendered via MainTabbarController.makePaymentTabImage() + return UIImage() } return UIImage(named: name)!.withRenderingMode(.alwaysOriginal) }(Apply the analogous change to
selectedIcon.)Also applies to: 59-65
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@DashWallet/Sources/UI/Main/MainTabbarController.swift` around lines 40 - 46, The .payment enum branches in the MainTabbarItem's icon and selectedIcon are dead now that the Payment tab image is provided by makePaymentTabImage() in configureControllers(); remove the .payment case entries (or have them call through to makePaymentTabImage()) in both icon and selectedIcon so the enum switch isn't stale, updating MainTabbarItem.icon and MainTabbarItem.selectedIcon to either omit .payment or return the same image produced by makePaymentTabImage().
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@DashWallet/Sources/UI/Main/MainTabbarController.swift`:
- Around line 192-198: The Payment tab's UITabBarItem (created as item and
assigned to paymentVC of type EmptyController) lacks an accessibilityLabel so
VoiceOver users get no meaningful announcement; set item.accessibilityLabel to a
clear, localized string (e.g., "Payments" via NSLocalizedString) before
assigning it to paymentVC.tabBarItem so the tab is announced properly (do not
rely on accessibilityIdentifier).
- Around line 245-264: The closure passed to UIGraphicsImageRenderer.image in
makePaymentTabImage() declares an unused parameter named context which triggers
SwiftLint; update the closure signature to use an unnamed parameter (_) instead
of context (i.e., change { context in ... } to { _ in ... }) so the unused
parameter warning is resolved while keeping the drawing logic in
makePaymentTabImage intact.
---
Nitpick comments:
In `@DashWallet/Sources/UI/Main/MainTabbarController.swift`:
- Around line 40-46: The .payment enum branches in the MainTabbarItem's icon and
selectedIcon are dead now that the Payment tab image is provided by
makePaymentTabImage() in configureControllers(); remove the .payment case
entries (or have them call through to makePaymentTabImage()) in both icon and
selectedIcon so the enum switch isn't stale, updating MainTabbarItem.icon and
MainTabbarItem.selectedIcon to either omit .payment or return the same image
produced by makePaymentTabImage().
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 3da3a1fd-b199-4147-9ccc-6e85dbec18cf
📒 Files selected for processing (6)
DashWallet.xcodeproj/project.pbxprojDashWallet/Sources/UI/Home/HomeViewController+Shortcuts.swiftDashWallet/Sources/UI/Main/MainTabbarController.swiftDashWallet/Sources/UI/Menu/Settings/SettingsScreen.swiftDashWallet/Sources/UI/SwiftUI Components/Color+DWStyle.swiftDashWallet/Sources/UI/Views/Navigation/BaseNavigationController.swift
💤 Files with no reviewable changes (1)
- DashWallet/Sources/UI/Views/Navigation/BaseNavigationController.swift
🚧 Files skipped from review as they are similar to previous changes (3)
- DashWallet/Sources/UI/SwiftUI Components/Color+DWStyle.swift
- DashWallet/Sources/UI/Menu/Settings/SettingsScreen.swift
- DashWallet.xcodeproj/project.pbxproj
Issue being fixed or feature implemented
What was done?
How Has This Been Tested?
Breaking Changes
Checklist:
For repository code-owners and collaborators only
Summary by CodeRabbit
Release Notes
New Features
Bug Fixes
UI Improvements