write-swift – skill Lập trình cho agent AI
Write and review modern Swift with value types, concurrency, protocols, API design, memory management, and testing.
Cài skill write-swift bằng một lệnh
Chọn công cụ bạn đang dùng, copy lệnh và dán vào terminal. Skill sẽ nằm trong thư mục skills của công cụ đó và sẵn sàng dùng ở phiên làm việc tiếp theo.
Claude Code
mkdir -p ~/.claude/skills && curl -fsSL https://skill.dn1nguoi.com/z/write-swift-fe4d6.tgz | tar xz -C ~/.claude/skills
Gọi trong Claude Code: /write-swift – rồi mô tả công việc bạn muốn làm.
Codex
mkdir -p ~/.codex/skills && curl -fsSL https://skill.dn1nguoi.com/z/write-swift-fe4d6.tgz | tar xz -C ~/.codex/skills
Gọi trong Codex: $write-swift – rồi mô tả công việc bạn muốn làm.
Hermes Agent
mkdir -p ~/.hermes/skills && curl -fsSL https://skill.dn1nguoi.com/z/write-swift-fe4d6.tgz | tar xz -C ~/.hermes/skills
Gọi trong Hermes Agent: /write-swift – rồi mô tả công việc bạn muốn làm.
DeepSeek
mkdir -p ~/.deepcode/skills && curl -fsSL https://skill.dn1nguoi.com/z/write-swift-fe4d6.tgz | tar xz -C ~/.deepcode/skills
Gọi trong DeepSeek: /write-swift – rồi mô tả công việc bạn muốn làm.
Nội dung SKILL.md
Nội dung SKILL.md gốc bằng tiếng Anh.
Write Swift
AAS adaptation of [emilkowalski/skills](https://github.com/emilkowalski/skills/tree/a81dbca07f2217b7103e510c0f13f8d5b017afc9/skills/write-swift) at a81dbca07f2217b7103e510c0f13f8d5b017afc9. Copyright Emil Kowalski; MIT license retained in LICENSE.
Initial Response
When this skill is first invoked without a specific question, respond only with:
> I'm ready to help you write modern Swift, the way the language wants to be written.
Do not provide any other information until the user asks a question.
How to write Swift the way the language wants to be written, current through Swift 6.4.
Compatibility baseline: Swift 6.3; version-gated guidance through Swift 6.4. [Swift 6.4 was released on September 15, 2026](https://www.swift.org/blog/swift-6.4-released/). Rows marked ⚠ require checking the project’s compiler, language mode, SDK and deployment target before adoption; prefer the older form when the installed toolchain does not support the feature. Examples are illustrative and have not all been compiled against every supported configuration. Concurrency guidance assumes the Swift 6.2 model — if the project is on 6.1 or earlier, §3's rules about async and @concurrent do not apply.
The through-line: Swift is a progressive-disclosure language. Start with the simplest, most static, most single-threaded thing that works, and buy dynamism — concurrency, reference semantics, existentials, unsafe pointers — only where you can point at the reason. Every rule below is an application of that.
Model this hierarchy of defaults. Move down a level only with a reason you can state:
| Need | Reach for | Move down only when |
| ------------ | ----------------------- | ---------------------------------------------------------- |
| Data | struct / enum | you need identity, sharing, or inheritance |
| Abstraction | concrete type | you have repeated code across types |
| Polymorphism | some P (generic) | you need heterogeneous storage → any P |
| Execution | main actor, synchronous | profiling shows a hang → async → @concurrent → actor |
| Memory | Array, String | profiling shows the cost → InlineArray, Span |
| Safety | safe API | C interop or a measured hot path → Unsafe* |
---
1. Model data with value types
Value types are the default in Swift, not a special case.
- Default to
structandenum. Useclassonly for identity, shared mutable state, inheritance, or resource lifetime. A window, a database connection, an entity stored in a rendering engine — those have identity. APoint, aDrink, aMaterialdoes not. letby default;varonly when you mutate. This is the same discipline assomebeforeanyand value before reference: start narrow, widen with cause.- A struct with a mutable reference-type property is neither a value nor a reference. Copies share the object; mutations leak across copies. Either keep the referenced type immutable, expose only computed properties that forward to it, or make it a
privatestored property behind copy-on-write. - Copy-on-write is how you get out-of-line storage _and_ value semantics. Wrap a final class in a struct and check
isKnownUniquelyReferenced(&storage)before mutating; copy first if it isn't. This is exactly howArray,String, andDictionarywork. - Enums are the tool for "a fixed set of things" and for mutually exclusive state. Replacing a pile of optional stored properties (
isSharing,selectedRows,shareTarget) with oneenum Statemakes invalid combinations unrepresentable and makes state change atomic instead of a sequence of property writes you can forget to finish. - Composing values yields a value. A struct whose stored properties are all value types has value semantics for free — which is what makes undo, diffing, and state restoration a single code path instead of one per property.
struct Material { // value semantics preserved
var roughness: Double
private var _texture: Texture // a class
var color: Color {
get { _texture.color }
set {
if !isKnownUniquelyReferenced(&_texture) { _texture = Texture(copying: _texture) }
_texture.color = newValue
}
}
}Noncopyable types (~Copyable) express unique ownership: a file descriptor, a bank transfer, an open resource. Suppressing the copy turns "you must not run this twice" from an assertion into a compile error, and makes deinit on a struct meaningful. Mark the finishing method consuming so the compiler proves it's the last use. Parameter ownership becomes explicit: borrowing (read-only, the default), consuming (takes it away), inout/mutating (temporary write access).
---
2. Errors and optionals — make the failure paths visible
Swift error handling rests on three points: sources of error are marked so they can't surprise you; errors carry enough context to act on; and recoverable errors are different from programmer mistakes.
- Recoverable →
throw. Programmer mistake →precondition/fatalError. A failed network call keeps the program running. An out-of-bounds index means the code is wrong and must halt before the bug becomes a security issue. - Enums with associated values make the best error types.
case duplicateFriend(String)beatscase duplicateFriend— the context is the whole point. guardfor error conditions, because it forces the exit path.if letfor the ordinary unwrap.- Typed throws (
throws(MyError)) are for internal functions, error-forwarding generic code, and constrained environments where boxingany Erroris too costly. For public API, untypedthrowspreserves your freedom to change the error type later. Note the unification:throwsisthrows(any Error), and non-throwing isthrows(Never)— which is what letsmapabstract over both. - Force-unwrap only where you can state the invariant, and prefer a failing
#require/preconditionwith a message over a bare!.
---
3. Concurrency: stay single-threaded until profiling says otherwise
This is the section agents get wrong most often, because the model changed in Swift 6.2.
Start every app entirely on the main thread. Single-threaded code goes a long way, and most apps never need to leave it.
The progression, in order. Do not skip steps.
1. Single-threaded on the main actor. No concurrency at all. Fine for most apps.
2. async/await to hide latency (network, disk). Still no concurrency of your own — SDK APIs like URLSession.data(from:) offload on your behalf.
3. @concurrent to move _your_ expensive work off the main thread — only after Instruments shows a hang.
4. actor to move _state_ off the main actor — only when too much main-actor state is forcing tasks to hop back constantly.
Turn on the right build settings first. Enable Approachable Concurrency in every project. For app modules and UI-facing modules, also set Default Actor Isolation to MainActor — it's the default for new app projects in Xcode 26, and it deletes most of your @MainActor annotations. In a package: swiftSettings: [.defaultIsolation(MainActor.self)]. Do not set main-actor-by-default for a general-purpose library — libraries should ship nonisolated APIs and let clients decide where work runs.
The rule that changed
In Swift 6.2, marking a function async does _not_ move it off the current actor. It runs where it was called from. This is what makes "the most natural code to write" data-race free by default.
@concurrent— always switches to the concurrent thread pool. Use it on _your_ CPU-heavy work.nonisolated— runs wherever it's called from. This is the right default for library APIs, because the caller decides.nonisolatedon a type makes all its members nonisolated (Swift 6.1+).- Neither one — stays on the caller's actor.
nonisolated struct PhotoProcessor { // decoupled from the main actor
@concurrent // guaranteed to run in the background
func process(_ data: Data) async -> ProcessedPhoto {
async let sticker = extractSticker(data) // two independent jobs, in parallel
async let colors = extractColors(data)
return await ProcessedPhoto(sticker: sticker, colors: colors)
}
}- Profile before you offload. Use Instruments (Time Profiler, hangs). If the code can be made faster without concurrency, always do that first. Concurrency has real cost — task allocation, scheduling, and reasoning.
- Don't spawn a task for trivial work. A child task to read a
UserDefaultsvalue costs more than it saves. - One task per end-to-end operation. Work that must happen in order
… (nội dung đầy đủ có trong gói tải về)
Skill liên quan
- yes-md – Quản trị AI 6 lớp: cổng an toàn, gỡ lỗi dựa trên bằng chứng, phát hiện hành vi làm việc…
- zapier-make-patterns – Xây dựng quy trình tự động không cần code trở nên dễ dàng. Zapier và Make (trước đây là…
- zcode-delegate – Giao tác vụ lập trình cho Z.AI ZCode CLI chỉ khi người dùng yêu cầu rõ ràng, trong khi…
- zod-validation-expert – Chuyên gia về Zod — thư viện kiểm tra schema ưu tiên TypeScript. Bao gồm parse, lỗi tùy…
- zustand-store-ts – Tạo store Zustand theo các mẫu đã thiết lập, với kiểu TypeScript và middleware phù hợp.
- ab-testing – Khi người dùng muốn lên kế hoạch, thiết kế hoặc triển khai A/B test hoặc thử nghiệm…
- adaptyv – Dùng Adaptyv Bio Foundry API và Python SDK để thiết kế thí nghiệm mô tả protein, ước…
- ab-test-setup – Khi người dùng muốn lên kế hoạch, thiết kế hoặc triển khai A/B test hoặc thử nghiệm…