Skip to content

chore!: raise the deployment target to iOS 18 - #15

Merged
romchornyi merged 9 commits into
masterfrom
chore/ios-18-deployment-target
Oct 23, 2026
Merged

romchornyi merged 9 commits into
masterfrom
chore/ios-18-deployment-target

Conversation

@romchornyi

@romchornyi romchornyi commented Aug 27, 2026 •

Copy link
Copy Markdown
Collaborator

Issue being fixed or feature implemented

dashwallet-ios is an iOS 18 app — platform :ios, '18.0' in its Podfile, and 18.0 on every
shipping build configuration of the dashwallet and dashpay targets, the two that link
this package. This library was still declaring iOS 14, so every component that wanted an API
newer than 2020 carried a second implementation for hosts that no longer exist: a whole
alternative SearchBar, single-line text fields without a styled prompt, a self-sizing sheet
that did not self-size, a SwitchView that told VoiceOver it was a button.

What was done?

The floor — Package.swift now declares .iOS(.v18) and, for the first time,
.macOS(.v15). The package never declared macOS at all, so a macOS build fell back to the
SwiftPM default and every type had to carry @available(macOS 11) by hand to compile there.

Fallback paths removed — SearchBar (the SearchBarLegacy bar and the pre-17 field),
AddressFieldView (pre-17 single-line field), DashSwitch (accentColor),
NavigationBarButtonStyle (the value-less animation(_:), which animates every change in
the view rather than just the press), SwitchView (.isButton instead of .isToggle),
BottomSheet (the isModalInPresentation shim, and selfSizingSheet returning self
below iOS 16). The #unavailable(iOS 26.0) check in selfSizingSheet stays, because that one
really is above the floor.

Deprecations cleared — five onChange(of:perform:) call sites move to the two-parameter
form. They were deprecated in iOS 17 but the replacement was unavailable at the old floor;
declaring the macOS platform surfaced three of them as warnings, and the iOS build the other
two. The package now builds warning-free for both platforms.

NumericKeyboardView — the panel was a fully rounded rectangle pushed below its own
frame so its bottom corners fell off screen, with a comment explaining why the shape that
says this in one line was out of reach. It is an UnevenRoundedRectangle now.

Annotations — 200 @available lines across 48 files, all at or below the declared floor,
are gone. The manifest states the minimum once.

Brought up to date with master — since this branch was cut, #16–#23 merged. Master is
merged in (no rebase, no force-push). The files those PRs added (Criteria, SimpleSelect,
List8View, NavigationBarCircle*, NavigationBarButton) are on the same floor now: no
annotations, and the two #available branches in NavigationBarCircleMenu and
NavigationBarButtonStyle are gone.

Smaller cleanups the floor allows — SearchBar is a single type again. Its public shell
existed only to switch between the focused bar and the legacy one. The one-line
BottomSheetDismissalModifier is inlined. TransactionView uses
overlay(alignment:content:), as do two previews. The as Color? casts that picked the iOS 15
tint overload are gone. The rewritten address field uses autocorrectionDisabled(). Stale
comments that named old releases are fixed.

Docs — CLAUDE.md's hard-constraint section is replaced by the new rule (don't annotate
at or below the floor; gate only what is newer). Component pages no longer restate an
@available line each, and the prose that recorded which feature lit up on which release is
either gone or now true.

How Has This Been Tested?

  • swift build and swift test clean on macOS (16 tests), and xcodebuild build-for-testing
    clean for the iOS Simulator — no errors, no warnings on either.
  • Every commit builds on its own.
  • iOS Release build (generic/platform=iOS) is clean too.
  • NumericKeyboardView rendered in the simulator before and after the shape change, light and
    dark: identical when the keyboard sits on the bottom edge.
  • Public surface checked against master: the sorted public/open declarations are identical.
    Every declaration that was removed was private (SearchBarLegacy,
    LegacyInteractiveDismissModifier, ModalInPresentationSetter, toggleTrait).
    dashwallet-ios develop uses no removed symbol.

Breaking Changes

Yes — this raises the minimum deployment target to iOS 18 / macOS 15. Any host below that
can no longer link the package. dashwallet-ios is the only consumer and is already there, with
one exception worth fixing before this merges:

The Testnet configuration of the dashpay target was the one exception at 17.0. It was moved
to 18.0 in dashpay/dashwallet-ios#1081, so every configuration on develop is 18.0 now.

Release tag: this must ship as 2.0.0, not 1.x. The frozen master of dashwallet-ios is
still iOS 15 and pins DashUIKit with upToNextMajor from 1.0.0. A 1.x tag cut after this merge
would break it on the next resolve. develop tracks the master branch of this repo, so it
picks the change up directly.

No API was removed or renamed: every public type, initialiser and parameter is unchanged, and
the components behave as they already did on iOS 18 hosts.

One visible change: the NumericKeyboardView panel used to be a fully rounded rectangle pushed
32pt below its own frame. A host that placed the keyboard away from the bottom edge saw that
32pt strip under the keys. The panel now ends at its frame and still runs into the bottom safe
area. dashwallet-ios has eight call sites, all going through HardwareNumericKeyboardView:
send, specify amount, internal transfer, Coinbase transfer, DashSpend (two), Evonode withdrawal
and the contact profile sheet. Each one should get a quick visual check against this branch.

Follow-ups, deliberately left out of this PR:

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have made corresponding changes to the documentation

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Platform Support

    • Updated the minimum supported versions to iOS 18 and macOS 15.
  • Improvements

    • Updated buttons, inputs, menus, sheets, and other components to use current platform behavior.
    • Refined address-field and search interactions, sheet presentation, and keyboard styling.
  • Documentation

    • Updated platform requirements and component guidance to reflect the supported versions and current behavior.

Roman and others added 6 commits August 27, 2026 17:24
dashwallet-ios, the only consumer, has been iOS 18 for a while: its Podfile
says `platform :ios, '18.0'` and every shipping build configuration of the
`dashwallet` and `dashpay` targets — the two that link this package — is
18.0. Nothing has needed the iOS 14 floor for some time, and holding it costs
a fallback path in every component that wants an API newer than 2020.

macOS is declared alongside it at 15. The package never declared a macOS
platform at all, so a macOS build fell back to the SwiftPM default and every
type had to carry `@available(macOS 11)` by hand to compile there. Saying it
once in the manifest replaces all of that.

The `Hard constraint` section in CLAUDE.md is replaced by the new rule: do not
annotate for anything at or below the floor, and gate only what is genuinely
newer — as `selfSizingSheet` still does for iOS 26 corner styling.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Every branch here existed to keep a component running below the old floor, and
each one was a second implementation that nobody could see fail:

- `SearchBar` dispatched between a focus-driven bar and `SearchBarLegacy`, a
  whole second bar without the cancel animation. The legacy one is gone and the
  shell renders the focused bar directly.
- `SearchBar` and `AddressFieldView` each carried a pre-iOS 17 `TextField`
  without a styled prompt — and, in the address field, without the vertical
  axis that gives it its two-line read-out.
- `DashSwitch` fell back to `accentColor`, `NavigationBarButtonStyle` to the
  value-less `animation(_:)` — the one that animates every change in the view,
  not just the press.
- `SwitchView` reported `.isButton` instead of `.isToggle` to VoiceOver.
- `BottomSheet` had the `isModalInPresentation` shim added for iOS 14 last
  week, and `selfSizingSheet` returned `self` unmodified below iOS 16 — a
  self-sizing sheet that did not self-size. The `#unavailable(iOS 26.0)` check
  stays: that one is genuinely above the floor.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`onChange(of:perform:)` was deprecated in iOS 17 / macOS 14. It stayed because
the old floor made the replacement unavailable; declaring the macOS platform
surfaced it as three build warnings. The package builds warning-free again.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The panel was a fully rounded rectangle pushed below its own frame by the
corner radius so its bottom corners fell off screen, with a comment explaining
that the shape saying this in one line was iOS 16 and the library shipped to
14. It no longer does, so the workaround goes and the shape says what it draws.

Rendered before and after in the simulator, light and dark: identical.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
200 `@available` lines across 48 files, every one of them at or below the
declared floor: `iOS 14 / macOS 11` on nearly every public type, `macOS 10.15`
on the Foundation-level token types, `iOS 17 / macOS 14` on each `#Preview`.
The manifest states the minimum once, so repeating a lower one per declaration
only invited the question of which is true.

Also folds in the last two deprecated `onChange(of:perform:)` call sites, in
`BottomSheet` and `SearchBar`. They sit in UIKit-only paths, so the macOS build
of the previous commit could not see them; the iOS simulator build did.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Every component page opened with the `@available` line the type used to carry,
and the prose recorded which feature lit up on which release — a SearchBar
paragraph for the iOS 14 bar that no longer exists, a self-sizing sheet
described as a no-op below iOS 16, swipe blocking split across two APIs. None
of it is true at an iOS 18 floor, and none of it was worth restating per page
now that the manifest says it once.

`ScrollViewWithOnScrollChanged` keeps its page but says plainly that it
predates `onScrollGeometryChange` and that new code can use the system API.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 27, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
📥 Commits

Reviewing files that changed from the base of the PR and between 5034779 and 97db78d.

📒 Files selected for processing: 65
  • CLAUDE.md
  • Package.swift
  • README.md
  • Sources/DashUIKit/Button/DashButton.swift
  • Sources/DashUIKit/Components/AddressFieldView.swift
  • Sources/DashUIKit/Components/BottomSheet/BottomSheet.swift
  • Sources/DashUIKit/Components/BottomSheet/SheetFeature.swift
  • Sources/DashUIKit/Components/CoinSelector.swift
  • Sources/DashUIKit/Components/ConverterCard/ConverterArrowBadge.swift
  • Sources/DashUIKit/Components/ConverterCard/ConverterCard.swift
  • Sources/DashUIKit/Components/ConverterCard/ConverterCardItem.swift
  • Sources/DashUIKit/Components/ConverterCard/ConverterCardRow.swift
  • Sources/DashUIKit/Components/Criteria.swift
  • Sources/DashUIKit/Components/DashAmount.swift
  • Sources/DashUIKit/Components/DashSwitch.swift
  • Sources/DashUIKit/Components/EnterAmount/CurrencyOption.swift
  • Sources/DashUIKit/Components/EnterAmount/DashBalanceView.swift
  • Sources/DashUIKit/Components/EnterAmount/DashPickerView.swift
  • Sources/DashUIKit/Components/EnterAmount/DualSwapAmountView.swift
  • Sources/DashUIKit/Components/EnterAmount/EnterAmountView.swift
  • Sources/DashUIKit/Components/EnterAmount/SwapAmountView.swift
  • Sources/DashUIKit/Components/Geometry/FrameReader.swift
  • Sources/DashUIKit/Components/Geometry/LocationReader.swift
  • Sources/DashUIKit/Components/Geometry/ScaleToFitWidth.swift
  • Sources/DashUIKit/Components/Geometry/ScrollViewWithOnScrollChanged.swift
  • Sources/DashUIKit/Components/Icons/CheckmarkIcon.swift
  • Sources/DashUIKit/Components/Icons/ChevronIcon.swift
  • Sources/DashUIKit/Components/Icons/InfoRoundIcon.swift
  • Sources/DashUIKit/Components/Icons/XmarkIcon.swift
  • Sources/DashUIKit/Components/Illustrations/ErrorIllustration.swift
  • Sources/DashUIKit/Components/Illustrations/LoadingIllustration.swift
  • Sources/DashUIKit/Components/Illustrations/SuccessIllustration.swift
  • Sources/DashUIKit/Components/MenuItem.swift
  • Sources/DashUIKit/Components/NavigationBar.swift
  • Sources/DashUIKit/Components/NavigationBarButton.swift
  • Sources/DashUIKit/Components/NavigationBarCircleButton.swift
  • Sources/DashUIKit/Components/NavigationBarCircleIcon.swift
  • Sources/DashUIKit/Components/NavigationBarCircleMenu.swift
  • Sources/DashUIKit/Components/NumericKeyboardView.swift
  • Sources/DashUIKit/Components/RadioButtonRow.swift
  • Sources/DashUIKit/Components/ReceiveEstimateView.swift
  • Sources/DashUIKit/Components/SearchBar.swift
  • Sources/DashUIKit/Components/SimpleSelect.swift
  • Sources/DashUIKit/Components/Switch/Components/ThumbView.swift
  • Sources/DashUIKit/Components/Switch/SwitchView.swift
  • Sources/DashUIKit/Components/SystemMessageView.swift
  • Sources/DashUIKit/Components/Toast.swift
  • Sources/DashUIKit/Components/TopIntro/TopIntroView.swift
  • Sources/DashUIKit/Components/Transaction/TransactionView.swift
  • Sources/DashUIKit/Foundation/Color+DashUI.swift
  • Sources/DashUIKit/Foundation/DashTextStyle.swift
  • Sources/DashUIKit/Foundation/Font+DashUI.swift
  • Sources/DashUIKit/Foundation/Icon_DashUI.swift
  • Sources/DashUIKit/Foundation/Image+DashUI.swift
  • Sources/DashUIKit/Foundation/LineHeight+DashUI.swift
  • Sources/DashUIKit/Table List/List1View.swift
  • Sources/DashUIKit/Table List/List8View.swift
  • Sources/DashUIKit/ViewModifiers/MenuViewModifier.swift
  • docs/README.md
  • docs/amount-and-currency.md
  • docs/buttons-and-inputs.md
  • docs/feedback.md
  • docs/lists-and-rows.md
  • docs/navigation-and-containers.md
  • docs/utilities.md
💤 Files with no reviewable changes: 41
  • Sources/DashUIKit/Foundation/Icon_DashUI.swift
  • Sources/DashUIKit/Components/ConverterCard/ConverterArrowBadge.swift
  • Sources/DashUIKit/Components/ConverterCard/ConverterCardItem.swift
  • Sources/DashUIKit/Components/ReceiveEstimateView.swift
  • Sources/DashUIKit/Components/EnterAmount/DualSwapAmountView.swift
  • Sources/DashUIKit/Components/Switch/Components/ThumbView.swift
  • Sources/DashUIKit/Components/ConverterCard/ConverterCardRow.swift
  • Sources/DashUIKit/Components/NavigationBarCircleButton.swift
  • Sources/DashUIKit/ViewModifiers/MenuViewModifier.swift
  • Sources/DashUIKit/Components/NavigationBarCircleIcon.swift
  • Sources/DashUIKit/Components/SimpleSelect.swift
  • Sources/DashUIKit/Components/RadioButtonRow.swift
  • Sources/DashUIKit/Components/TopIntro/TopIntroView.swift
  • Sources/DashUIKit/Components/Icons/XmarkIcon.swift
  • Sources/DashUIKit/Foundation/Font+DashUI.swift
  • Sources/DashUIKit/Components/Illustrations/SuccessIllustration.swift
  • Sources/DashUIKit/Components/EnterAmount/CurrencyOption.swift
  • Sources/DashUIKit/Components/EnterAmount/DashBalanceView.swift
  • Sources/DashUIKit/Foundation/LineHeight+DashUI.swift
  • Sources/DashUIKit/Components/Illustrations/ErrorIllustration.swift
  • Sources/DashUIKit/Table List/List1View.swift
  • Sources/DashUIKit/Table List/List8View.swift
  • Sources/DashUIKit/Components/Illustrations/LoadingIllustration.swift
  • Sources/DashUIKit/Components/CoinSelector.swift
  • Sources/DashUIKit/Foundation/Color+DashUI.swift
  • Sources/DashUIKit/Components/Icons/CheckmarkIcon.swift
  • Sources/DashUIKit/Components/Geometry/ScaleToFitWidth.swift
  • Sources/DashUIKit/Components/Toast.swift
  • Sources/DashUIKit/Components/Icons/InfoRoundIcon.swift
  • Sources/DashUIKit/Components/SystemMessageView.swift
  • Sources/DashUIKit/Foundation/Image+DashUI.swift
  • Sources/DashUIKit/Components/NavigationBar.swift
  • Sources/DashUIKit/Components/EnterAmount/DashPickerView.swift
  • Sources/DashUIKit/Components/Icons/ChevronIcon.swift
  • Sources/DashUIKit/Components/ConverterCard/ConverterCard.swift
  • Sources/DashUIKit/Foundation/DashTextStyle.swift
  • Sources/DashUIKit/Components/Criteria.swift
  • Sources/DashUIKit/Components/DashAmount.swift
  • Sources/DashUIKit/Button/DashButton.swift
  • Sources/DashUIKit/Components/EnterAmount/EnterAmountView.swift
  • Sources/DashUIKit/Components/MenuItem.swift

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

📝 Walkthrough

The package deployment floor changes to iOS 18 and macOS 15. Availability annotations and older-platform fallback branches are removed across SwiftUI components. Related README, contributor guidance, and component documentation are updated.

Changes: Platform migration

Layer / File(s) Summary
Deployment contract
Package.swift, CLAUDE.md, README.md
The package targets iOS 18 and macOS 15. Availability guidance now requires body-level gating only for APIs newer than the package floor.
Source migration
Sources/DashUIKit/...
Public declarations and previews lose older availability annotations. Search, address fields, bottom sheets, navigation controls, switches, geometry readers, and related components remove legacy branches or adopt newer SwiftUI API forms.
Documentation sync
docs/*.md
Documentation removes obsolete platform annotations and fallback descriptions. It records the updated API and deployment guidance.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Other

Sequence Diagram(s)

sequenceDiagram
  participant PackageConfiguration
  participant SwiftUIComponents
  participant Documentation
  PackageConfiguration->>SwiftUIComponents: Set iOS 18 and macOS 15 deployment floor
  SwiftUIComponents->>SwiftUIComponents: Remove older availability branches and annotations
  SwiftUIComponents->>Documentation: Update component and API descriptions
Loading

Possibly related issues

Suggested reviewers: jeanpierreroma

Merge Risk: ⚪ Minimal · up to 97db7

No actionable issue remains from the supplied changes; the documented iOS 18 and macOS 15 requirement is ready for normal merge checks.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 15 files. (9 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Title check Passed The title clearly and concisely describes the primary change: raising the deployment target to iOS 18. It omits the related macOS 15 target but remains accurate and specific.
Full details: Docstring Coverage

Explanation

Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 15 files. (9 skipped: 9 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

Eight PRs landed on master since this branch was cut (#16–#23). Their new
files came with the old floor's annotations and two fallback branches, which
this merge brings onto the iOS 18 floor the same way the earlier commits did
for everything else:

- `@available(iOS 14, macOS 11)` / `(iOS 17, macOS 14)` dropped from
  `Criteria`, `SimpleSelect`, `List8View` and the `NavigationBarCircle*` /
  `NavigationBarButton` files, previews included.
- `NavigationBarButtonStyle` moved to `NavigationBarButton.swift` on master;
  the branch's copy in `NavigationBar.swift` is gone and the moved one uses
  `animation(_:value:)` unconditionally.
- `NavigationBarCircleMenu` always takes the bar's button style — the pre-16
  branch that dimmed the menu by hand is gone, and with it the unused
  `isEnabled`.
- `AddressFieldView`'s two new focus mirrors use the two-parameter
  `onChange`.
- The three new doc pages lose their `@available` line, and the circle-menu
  paragraph its "On iOS 16+".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Found by the local review passes over the whole PR:

- `SearchBar` is one type again. The public shell only existed to choose
  between the focused bar and the legacy one.
- `BottomSheetDismissalModifier` had become a one-line wrapper around
  `interactiveDismissDisabled`. The call site now uses the modifier directly
  and keeps a comment on why the flag is passed rather than branched on.
- `TransactionView`, plus the `LocationReader` and
  `ScrollViewWithOnScrollChanged` previews, use `overlay(alignment:content:)`.
  The comment pinning `TransactionView` to the iOS 14 target is gone.
- The `as Color?` casts that selected the iOS 15 `tint` overload are gone,
  and the rewritten address field uses `autocorrectionDisabled()`.
- `NumericKeyboardView` drops a `.top` background alignment. It only mattered
  for the old shape that overhung its frame.
- Stale comments are fixed in `ScrollViewWithOnScrollChanged` (wrong release
  for `onScrollGeometryChange`) and `SheetFeature` (a macOS 13 reason).
- `docs/buttons-and-inputs.md` said the address field takes 1–3 lines; the
  code limits it to 1–2.
- CLAUDE.md says "up to iOS 18". Its rule no longer suggests annotating a
  declaration and also gating it in the body.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@romchornyi

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@romchornyi romchornyi mentioned this pull request Oct 23, 2026
2 of 4 tasks
@romchornyi romchornyi changed the title chore: raise the deployment target to iOS 18 chore!: raise the deployment target to iOS 18 Oct 23, 2026
@romchornyi
romchornyi merged commit f61235e into master Oct 23, 2026
7 checks passed
@romchornyi
romchornyi deleted the chore/ios-18-deployment-target branch October 23, 2026 18:22
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