Collect findings from other people's writing, with sources

The skill so far only held what we broke ourselves. Most of what is worth
knowing about a new SDK is found rather than suffered — release notes,
other people's articles — and that deserves a place too, on terms that
stay fair to whoever wrote it.

So: entries in our own words, source named and linked, and the one thing
no external article can supply — what it would replace in our code and
whether it is genuinely a step forward. Attribution answers plagiarism,
not copyright, so nothing is pasted; an API signature is a fact, the
paragraph explaining it is not ours to take.

First four entries come from Natalia Panferova's writing at nilcoalescing
.com: the close button role and concentric corners, both of which replace
things we hand-built; ScrollPosition, which replaces one wrapper view;
and the iOS 27 toolbar APIs, which we cannot use at our deployment target
but which would delete a workaround the day we can.

A LICENSE was overdue and now says plainly what is ours, what is Apple's
and stays out of the repository, and what belongs to the authors we cite.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
TomUviandClaude Opus 5 committed 2026-08-16 23:14:51 +02:00
1 parent 905ad2ce3e
commit f84852d49c
8 files changed
+257 -9

No files matched your search

+12 -3
View File
@@ -11,14 +11,23 @@
{
"name": "pdat-swift-practice",
"source": "./pdat-swift-practice",
"description": "Practices for SwiftUI, Core Data, XcodeGen and Swift Testing that come from production incidents rather than documentation.",
"version": "0.1.0",
"description": "Curated Apple platform findings with sources, plus practices learned from production incidents.",
"version": "0.2.0",
"author": {
"name": "PDAT s.r.o."
},
"license": "MIT",
"category": "development",
"keywords": ["swift", "swiftui", "ios", "macos", "watchos", "core-data", "xcodegen", "swift-testing"]
"keywords": [
"swift",
"swiftui",
"ios",
"macos",
"watchos",
"core-data",
"xcodegen",
"swift-testing"
]
}
]
}
+37
View File
@@ -0,0 +1,37 @@
MIT License
Copyright (c) 2026 PDAT s.r.o.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
---
This licence covers what we wrote: the text of the skills, the export
script, and the plugin metadata.
It does not cover, and this repository does not redistribute:
- Apple's skills that ship inside Xcode. `bin/export-apple-skills.sh`
exports them from a local installation; they remain Apple's, under
whatever terms accompany the Xcode they came from. Material exported
from a pre-release Xcode is confidential under the Apple Developer
Agreement and must not be published anywhere.
- The articles, talks and documentation cited in `apple-findings`. Those
entries are our own summaries with the source named; the originals
belong to their authors.
+27 -2
View File
@@ -4,7 +4,14 @@ A Claude Code plugin marketplace for Apple platform work.
## What is here
**`pdat-swift-practice`** — one skill, `xcode-practice`. Practices for
**`pdat-swift-practice`** — two skills.
`apple-findings` is a curated file of APIs worth adopting that we found
elsewhere: what each one is, what it would replace in our code, whether it
is genuinely a step forward, and where we read about it. Written in our own
words with sources named — see [Sourcing](#sourcing).
`xcode-practice` is the opposite direction: practices for
SwiftUI, Core Data, XcodeGen and Swift Testing that came out of shipping
apps: work that must not happen in a view `body`, blobs that must stay off
the main thread, derived collections computed once, Keychain access
@@ -57,7 +64,25 @@ Push a change, bump `version` in both `.claude-plugin/marketplace.json` and
`pdat-swift-practice/.claude-plugin/plugin.json`, then `/plugin marketplace
update` locally. Without the version bump, installs will not notice.
## Adding to the skill
## Sourcing
`apple-findings` collects other people's discoveries, so it follows rules
that keep it honest and lawful:
- **Write the entry yourself.** An API signature is a fact and facts are
free to restate. The paragraph explaining it is the author's work, and
crediting them does not make copying it acceptable — attribution answers
plagiarism, not copyright.
- **Name the source** — author, title, publication, date — and link it.
Partly courtesy, partly so a stale entry can be checked against the
original later.
- **Say what it replaces in our code.** This is the half no external
article can write, and the reason the file is worth keeping at all.
- **Prefer the vendor's own material where it exists.** When Apple's
shipped skills cover the same API, defer to them and keep only the
"what of ours does this replace" note.
## Adding to `xcode-practice`
The bar is deliberately high: something that actually went wrong, more than
once, and whose fix is not obvious from the framework documentation. A rule
+14 -4
View File
@@ -1,14 +1,24 @@
{
"name": "pdat-swift-practice",
"version": "0.1.0",
"description": "Practices for SwiftUI, Core Data, XcodeGen and Swift Testing that come from production incidents rather than documentation.",
"version": "0.2.0",
"description": "Curated Apple platform findings with sources, plus practices learned from production incidents.",
"author": {
"name": "PDAT s.r.o.",
"email": "tomas.uvira@pdat.cz"
},
"license": "MIT",
"keywords": ["swift", "swiftui", "ios", "macos", "watchos", "core-data", "xcodegen", "swift-testing"],
"keywords": [
"swift",
"swiftui",
"ios",
"macos",
"watchos",
"core-data",
"xcodegen",
"swift-testing"
],
"skills": [
"./skills/xcode-practice"
"./skills/xcode-practice",
"./skills/apple-findings"
]
}
@@ -0,0 +1,39 @@
---
name: apple-findings
description: A curated file of Apple platform APIs worth adopting, each with where we found it and what it would replace in our code — iOS 26 UI affordances (close button role, concentric corners), modern scrolling APIs, and things noted for a later deployment target. Use when reviewing SwiftUI code for outdated patterns, when a hand-built control might have a system equivalent, or when deciding whether a newly published API is worth adopting.
---
# Findings
Things worth adopting that we found elsewhere — release notes, other
people's writing, conference talks — written up in our own words with the
source named, and with the part nobody else can write for us: what it
would replace in our code and whether it is actually a step forward.
Read `references/` for the individual entries.
| File | Covers |
|---|---|
| `references/ios26-ui.md` | `Button(role: .close)`, concentric corners |
| `references/scrolling.md` | `ScrollPosition` and friends |
| `references/waiting-on-target.md` | Known, not yet usable at our deployment target |
## How to add an entry
**Write it yourself.** Do not paste someone else's prose or their longer
code examples. An API signature is a fact and facts are free; a paragraph
explaining it is their work. Name the source and link it — that is
courtesy and it lets the next person check whether the entry has aged.
Every entry answers four things:
1. **What it is** — the API, in one or two sentences.
2. **What it replaces** — the hand-built thing in our code, with the file
if we know it. An entry without this is a bookmark, not a finding.
3. **Whether it is a step forward** — sometimes the honest answer is "no,
ours is fine", and that is worth recording so nobody re-litigates it.
4. **Source** — author, title, link, date read.
If an entry turns out to be wrong or the API changes, fix it in place and
say so. A stale finding is worse than no finding, because it is quoted
with confidence.
@@ -0,0 +1,61 @@
# iOS 26 UI affordances
## `Button(role: .close)`
**What it is.** A button role that renders the platform's standard close
control — an `xmark`, positioned and labelled by the system — without
supplying a label or icon. Distinct from `.cancel`, which implies
discarding work; `.close` is for dismissing something informational.
```swift
.toolbar {
Button(role: .close) { dismiss() }
}
```
**What it replaces.** Every hand-assembled close button: an
`Image(systemName: "xmark.circle.fill")` with a hierarchical rendering
mode, a colour chosen to sit on the background, `.buttonStyle(.plain)`,
and a manual `accessibilityLabel("Close")`. We had two of those in one
file alone.
**Step forward?** Yes, unambiguously. Correct placement per platform,
VoiceOver label and its localisation come from the system, and two
hand-written strings leave the catalogue. Roughly six lines become one.
**Source.** Natalia Panferova, "Add a Close button to SwiftUI modals on
iOS 26", nilcoalescing.com, 20 Oct 2025. Read 16 Aug 2026.
## Concentric corners
**What it is.** Nested rounded rectangles whose inner and outer corner
arcs share a centre, so the gap between them stays even the whole way
round. `ConcentricRectangle` is the shape; `containerShape(.rect(cornerRadius:))`
tells nested views what they are sitting inside so they can derive their
own radius. `isUniform: true` forces all four corners equal, and a
`minimum:` guarantees a floor when the inner shape sits far from the edge.
```swift
ZStack {
ConcentricRectangle().fill(.thickMaterial)
ConcentricRectangle(corners: .concentric, isUniform: true)
.fill(Color.blue.gradient)
}
.containerShape(.rect(cornerRadius: 24))
```
**What it replaces.** Hand-guessed radii for nested panels. In our card
app: a white "ticket" at radius 16 inside a coloured panel at 24, another
pair at 22 inside 22, tiles at 12 inside 20. Those numbers were picked by
eye at one size and drift apart at any other.
**Step forward?** Yes, and it is the kind that shows. The Wallet-pass look
we are copying is built on exactly this relationship, and doing it by hand
means re-tuning every time padding changes. Costs nothing at runtime.
**Caveat.** The container shape must be a rounded-rectangular shape
(`RoundedRectangle`, `Capsule`, `Circle`).
**Source.** Natalia Panferova, "Corner concentricity in SwiftUI on
iOS 26", nilcoalescing.com, 21 Aug 2025. Read 16 Aug 2026. Apple's own
skills shipped with Xcode 27 do not cover this.
@@ -0,0 +1,36 @@
# Programmatic scrolling
## `ScrollPosition` instead of `ScrollViewReader`
**What it is.** A `ScrollPosition` value held in `@State` and attached with
`.scrollPosition($position)` replaces wrapping content in a
`ScrollViewReader` to get at a proxy. Scrolling is then a method call on
the state — `position.scrollTo(id:)` — and, unlike the proxy, the value
can also be read, so the position is available both ways.
```swift
@State private var position = ScrollPosition()
ScrollView(.horizontal) {
HStack { ForEach(items) { ItemView(item: $0).id($0.id) } }
}
.scrollPosition($position)
```
Related, same family: `.defaultScrollAnchor(.bottom)` for where a view
starts out, and `onScrollGeometryChange(for:of:action:)` (iOS 18) for
following the offset while the user drags.
**What it replaces.** A `ScrollViewReader` wrapped around content purely
to reach `proxy.scrollTo` from a `.task`. In our card list that is the
filter chip strip, which scrolls the active chip into view.
**Step forward?** Modest but real. One layer of nesting disappears and the
scroll position stops being write-only. Not urgent — the existing code
works — so worth doing when that view is touched for another reason.
**Available since.** iOS 17, so nothing blocks it at our deployment
target. `onScrollGeometryChange` needs iOS 18.
**Source.** Natalia Panferova, "Modern SwiftUI APIs for programmatic
scrolling", nilcoalescing.com, 19 May 2026. Read 16 Aug 2026.
@@ -0,0 +1,31 @@
# Known, not yet usable
Things worth having, blocked on a deployment target. Kept so nobody
rediscovers them from scratch, and so the workarounds they replace can be
deleted the day the target moves.
## Adaptive toolbars (iOS 27)
**What it is.** Explicit control over how a toolbar collapses when it runs
out of room: `visibilityPriority` on a `ToolbarItem` (`.low`, `.automatic`,
`.high`, or custom levels declared relative to those), an explicit
`ToolbarOverflowMenu` for what should go into the overflow, and
`ToolbarItem(placement: .topBarPinnedTrailing)` for what must never move.
Related modifiers control minimisation on scroll.
**What it replaces.** A workaround we already carry: `.secondaryAction`
put our view-options menu into the system's own overflow, where it needed
two taps to open, so it was rebuilt as an ordinary primary-action button
with a hand-placed `ToolbarSpacer`. `visibilityPriority` plus
`ToolbarOverflowMenu` is the supported way to say what we meant.
**Step forward?** Yes, and it removes a comment explaining a hack.
**Blocked on.** Deployment target iOS 26. Either raise it or gate with
`#available`, which for a toolbar layout is more trouble than waiting.
**Source.** Natalia Panferova, "Adaptive SwiftUI toolbars in iOS 27",
nilcoalescing.com, 9 Aug 2026. Read 16 Aug 2026. Apple's
`swiftui-whats-new-27` skill covers the same APIs in more depth — prefer
it once the target moves; this entry exists for the "what of ours does it
replace" note.