axiom-swift-modern

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Modern Swift Idioms

现代Swift惯用写法

Purpose

用途

Claude frequently generates outdated Swift patterns from its training data. This skill corrects the most common ones — patterns that compile fine but use legacy APIs when modern equivalents are clearer, more efficient, or more correct.
Philosophy: "Don't repeat what LLMs already know — focus on edge cases, surprises, soft deprecations." (Paul Hudson)
Claude的训练数据中经常会生成过时的Swift代码模式。本指南用于修正最常见的这类问题——这些模式虽然可以正常编译,但使用了遗留API,而对应的现代等效写法更清晰、更高效或者更准确。
理念:「不要重复LLM已经知道的内容——聚焦边界场景、意外问题、软废弃特性。」(Paul Hudson)

Modern API Replacements

现代API替换

Old PatternModern SwiftSinceWhy
Date()
Date.now
5.6Clearer intent
filter { }.count
count(where:)
5.0Single pass, no intermediate allocation
replacingOccurrences(of:with:)
replacing(_:with:)
5.7Swift native, no Foundation bridge
CGFloat
Double
5.5Implicit bridging; exceptions: optionals, inout, ObjC-bridged APIs
Task.sleep(nanoseconds:)
Task.sleep(for: .seconds(1))
5.7Type-safe Duration API
DateFormatter()
.formatted()
/
FormatStyle
5.5No instance management, localizable by default
String(format: "%.2f", val)
val.formatted(.number.precision(.fractionLength(2)))
5.5Type-safe, localized
localizedCaseInsensitiveContains()
localizedStandardContains()
5.0Handles diacritics, ligatures, width variants
"\(firstName) \(lastName)"
PersonNameComponents
with
.formatted()
5.5Respects locale name ordering
"yyyy-MM-dd"
with DateFormatter
try Date(string, strategy: .iso8601)
5.6Modern parsing (throws); use "y" not "yyyy" for display
contains()
on user input
localizedStandardContains()
5.0Required for correct text search/filtering
旧写法现代Swift写法起始版本原因
Date()
Date.now
5.6意图更清晰
filter { }.count
count(where:)
5.0单次遍历,无中间内存分配
replacingOccurrences(of:with:)
replacing(_:with:)
5.7Swift原生实现,无需Foundation桥接
CGFloat
Double
5.5隐式桥接;例外情况:可选值、inout参数、ObjC桥接API
Task.sleep(nanoseconds:)
Task.sleep(for: .seconds(1))
5.7类型安全的Duration API
DateFormatter()
.formatted()
/
FormatStyle
5.5无需实例管理,默认支持本地化
String(format: "%.2f", val)
val.formatted(.number.precision(.fractionLength(2)))
5.5类型安全,支持本地化
localizedCaseInsensitiveContains()
localizedStandardContains()
5.0支持变音符号、连字、宽度变体处理
"\(firstName) \(lastName)"
配合
.formatted()
使用
PersonNameComponents
5.5遵循地区姓名排序规则
"yyyy-MM-dd"
搭配 DateFormatter
try Date(string, strategy: .iso8601)
5.6现代解析能力(支持抛出异常);展示场景请使用"y"而非"yyyy"
对用户输入调用
contains()
localizedStandardContains()
5.0正确实现文本搜索/过滤的必要写法

Modern Syntax

现代语法

Old PatternModern SwiftSince
if let value = value {
if let value {
5.7
Explicit
return
in single-expression
Omit
return
;
if
/
switch
are expressions
5.9
Circle()
in modifiers
.circle
(static member lookup)
5.5
import UIKit
alongside
import SwiftUI
Often not needed — SwiftUI re-exports most UIKit/AppKit types. Retain for UIKit-only APIs (
UIApplication
, etc.)
5.5
旧写法现代Swift写法起始版本
if let value = value {
if let value {
5.7
单表达式中显式写
return
省略
return
if
/
switch
属于表达式
5.9
修饰符中写
Circle()
.circle
(静态成员查找)
5.5
同时
import UIKit
import SwiftUI
通常不需要——SwiftUI会重新导出大部分UIKit/AppKit类型。仅在使用UIKit专属API(如
UIApplication
等)时保留导入
5.5

Foundation Modernization

Foundation现代化

Old PatternModern FoundationSince
FileManager.default.urls(for: .documentDirectory, ...)
URL.documentsDirectory
5.7
url.appendingPathComponent("file")
url.appending(path: "file")
5.7
books.sorted { $0.author < $1.author }
(repeated)
Conform to
Comparable
, call
.sorted()
"yyyy"
in date format for display
"y"
— correct in all calendar systems
旧写法现代Foundation写法起始版本
FileManager.default.urls(for: .documentDirectory, ...)
URL.documentsDirectory
5.7
url.appendingPathComponent("file")
url.appending(path: "file")
5.7
重复使用
books.sorted { $0.author < $1.author }
遵循
Comparable
协议,直接调用
.sorted()
展示用日期格式中写
"yyyy"
"y"
——在所有日历系统中都正确

SwiftUI Convenience APIs Claude Misses

Claude遗漏的SwiftUI便捷API

  • ContentUnavailableView.search(text: searchText)
    (iOS 17+) automatically includes the search term — no need to compose a custom string
  • LabeledContent
    in Forms
    (iOS 16+) provides consistent label alignment without manual HStack layout
  • confirmationDialog()
    must attach to triggering UI
    — Liquid Glass morphing animations depend on the source element
  • ContentUnavailableView.search(text: searchText)
    (iOS 17+)自动包含搜索词——无需手动拼接自定义字符串
  • 表单中的
    LabeledContent
    (iOS 16+)无需手动写HStack布局即可实现一致的标签对齐效果
  • confirmationDialog()
    必须挂载到触发的UI元素上
    ——毛玻璃变形动画依赖源元素定位

Common Claude Hallucinations

Claude常见幻觉

These patterns appear frequently in Claude-generated code:
  1. Creates
    DateFormatter
    instances inline
    — Use
    .formatted()
    or
    FormatStyle
    instead. If a formatter must exist, make it
    static let
    .
  2. Uses
    DispatchQueue.main.async
    — Use
    @MainActor
    or
    MainActor.run
    . Never GCD. (See
    axiom-swift-concurrency
    for full guidance.)
  3. Uses
    CGFloat
    for SwiftUI parameters
    Double
    works everywhere since Swift 5.5 implicit bridging.
  4. Generates
    guard let x = x else
    — Use
    guard let x else
    shorthand.
  5. Returns explicitly in single-expression computed properties — Omit
    return
    .
这些模式在Claude生成的代码中频繁出现:
  1. 内联创建
    DateFormatter
    实例
    ——请改用
    .formatted()
    FormatStyle
    。如果必须使用formatter,请声明为
    static let
  2. 使用
    DispatchQueue.main.async
    ——请使用
    @MainActor
    MainActor.run
    ,永远不要使用GCD。(完整指南请参考
    axiom-swift-concurrency
  3. SwiftUI参数使用
    CGFloat
    ——自Swift 5.5隐式桥接支持以来,
    Double
    可在所有场景下正常使用。
  4. 生成
    guard let x = x else
    写法
    ——请使用
    guard let x else
    简写。
  5. 单表达式计算属性中显式写return——省略
    return
    即可。

Resources

资源

Skills: axiom-swift-performance, axiom-swift-concurrency, axiom-swiftui-architecture
相关技能:axiom-swift-performance, axiom-swift-concurrency, axiom-swiftui-architecture