Agent skills for iOS, iPadOS, Swift, SwiftUI, and modern Apple framework development.
71
89%
Does it follow best practices?
Impact
—
No eval scenarios have been run
Advisory
Suggest reviewing before use
Additional patterns and examples that extend the core SKILL.md. Refer to this file for deeper Codable patterns, advanced result builder techniques, and supplementary collection/formatting recipes.
@dynamicMemberLookup Wrapperenum Shape: Codable {
case circle(radius: Double)
case rectangle(width: Double, height: Double)
enum CodingKeys: String, CodingKey {
case type, radius, width, height
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
switch self {
case .circle(let radius):
try container.encode("circle", forKey: .type)
try container.encode(radius, forKey: .radius)
case .rectangle(let width, let height):
try container.encode("rectangle", forKey: .type)
try container.encode(width, forKey: .width)
try container.encode(height, forKey: .height)
}
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let type = try container.decode(String.self, forKey: .type)
switch type {
case "circle":
let radius = try container.decode(Double.self, forKey: .radius)
self = .circle(radius: radius)
case "rectangle":
let width = try container.decode(Double.self, forKey: .width)
let height = try container.decode(Double.self, forKey: .height)
self = .rectangle(width: width, height: height)
default:
throw DecodingError.dataCorruptedError(
forKey: .type, in: container,
debugDescription: "Unknown shape type: \(type)")
}
}
}// Configure decoder for specific date formats
let decoder = JSONDecoder()
// ISO 8601 (most common for APIs)
decoder.dateDecodingStrategy = .iso8601
// Unix timestamp (seconds since epoch)
decoder.dateDecodingStrategy = .secondsSince1970
// Custom format
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
formatter.locale = Locale(identifier: "en_US_POSIX")
decoder.dateDecodingStrategy = .formatted(formatter)
// Multiple formats in one payload
decoder.dateDecodingStrategy = .custom { decoder in
let container = try decoder.singleValueContainer()
let string = try container.decode(String.self)
let iso = ISO8601DateFormatter()
if let date = iso.date(from: string) { return date }
let fallback = DateFormatter()
fallback.dateFormat = "yyyy-MM-dd"
fallback.locale = Locale(identifier: "en_US_POSIX")
if let date = fallback.date(from: string) { return date }
throw DecodingError.dataCorruptedError(
in: container, debugDescription: "Cannot decode date: \(string)")
}// JSON: { "coordinates": [37.7749, -122.4194] }
struct Location: Decodable {
let latitude: Double
let longitude: Double
enum CodingKeys: String, CodingKey {
case coordinates
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
var coords = try container.nestedUnkeyedContainer(forKey: .coordinates)
latitude = try coords.decode(Double.self)
longitude = try coords.decode(Double.self)
}
}Skip invalid elements instead of failing the entire array:
struct LossyArray<Element: Decodable>: Decodable {
let elements: [Element]
init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
var result: [Element] = []
while !container.isAtEnd {
if let element = try? container.decode(Element.self) {
result.append(element)
} else {
_ = try? container.decode(AnyCodable.self) // skip invalid
}
}
elements = result
}
}
private struct AnyCodable: Decodable {}@dynamicMemberLookup WrapperType-safe access to arbitrary JSON:
@dynamicMemberLookup
struct JSONValue: Decodable {
private let storage: [String: Any]
subscript(dynamicMember key: String) -> JSONValue? {
guard let value = storage[key] as? [String: Any] else { return nil }
return JSONValue(storage: value)
}
func string(for key: String) -> String? {
storage[key] as? String
}
func int(for key: String) -> Int? {
storage[key] as? Int
}
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
guard let dict = try container.decode([String: AnyCodableValue].self)
.mapValues({ $0.value }) as? [String: Any] else {
throw DecodingError.typeMismatch(
[String: Any].self,
.init(codingPath: decoder.codingPath,
debugDescription: "Expected dictionary"))
}
storage = dict
}
}A practical example of a custom result builder:
@resultBuilder
struct HTMLBuilder {
static func buildBlock(_ components: String...) -> String {
components.joined(separator: "\n")
}
static func buildOptional(_ component: String?) -> String {
component ?? ""
}
static func buildEither(first component: String) -> String {
component
}
static func buildEither(second component: String) -> String {
component
}
static func buildArray(_ components: [String]) -> String {
components.joined(separator: "\n")
}
}
func div(@HTMLBuilder content: () -> String) -> String {
"<div>\n\(content())\n</div>"
}
func p(_ text: String) -> String { "<p>\(text)</p>" }
func h1(_ text: String) -> String { "<h1>\(text)</h1>" }
let html = div {
h1("Welcome")
p("Hello, world!")
if showDetails {
p("Details here")
}
}Transform the accumulated result at the end:
@resultBuilder
struct AttributedStringBuilder {
static func buildBlock(_ components: AttributedString...) -> AttributedString {
components.reduce(into: AttributedString()) { $0.append($1) }
}
static func buildFinalResult(_ component: AttributedString) -> Text {
Text(component)
}
}@propertyWrapper
struct AppStorage<Value> {
let key: String
let defaultValue: Value
let store: UserDefaults
var wrappedValue: Value {
get { store.object(forKey: key) as? Value ?? defaultValue }
set { store.set(newValue, forKey: key) }
}
init(wrappedValue: Value, _ key: String, store: UserDefaults = .standard) {
self.key = key
self.defaultValue = wrappedValue
self.store = store
}
}
// Usage
struct Settings {
@AppStorage("onboarding_complete") var onboardingComplete = false
@AppStorage("preferred_theme") var theme = "system"
}@propertyWrapper
struct Validated<Value> {
private var value: Value
private let validator: (Value) -> Bool
private(set) var isValid: Bool
var wrappedValue: Value {
get { value }
set {
value = newValue
isValid = validator(newValue)
}
}
var projectedValue: Bool { isValid }
init(wrappedValue: Value, _ validator: @escaping (Value) -> Bool) {
self.value = wrappedValue
self.validator = validator
self.isValid = validator(wrappedValue)
}
}
// Usage
struct SignUpForm {
@Validated({ $0.count >= 3 }) var username = ""
@Validated({ $0.contains("@") && $0.contains(".") }) var email = ""
var canSubmit: Bool { $username && $email }
}import RegexBuilder
struct LogEntry {
let timestamp: String
let level: String
let message: String
}
let logRegex = Regex {
Capture(as: Reference<Substring>(\.self)) { /\[.+?\]/ }
" "
Capture(as: Reference<Substring>(\.self)) {
ChoiceOf { "INFO"; "WARN"; "ERROR"; "DEBUG" }
}
": "
Capture(as: Reference<Substring>(\.self)) { OneOrMore(.any) }
}let ipOctet = Regex {
ChoiceOf {
Regex { "25"; ("0"..."5") }
Regex { "2"; ("0"..."4"); .digit }
Regex { Optionally { ("0"..."1") }; .digit; Optionally { .digit } }
}
}
let ipAddress = Regex {
ipOctet; "."; ipOctet; "."; ipOctet; "."; ipOctet
}Create reusable format styles for domain types:
struct FileSize {
let bytes: Int64
}
struct FileSizeFormatStyle: FormatStyle {
typealias FormatInput = FileSize
typealias FormatOutput = String
func format(_ value: FileSize) -> String {
ByteCountFormatter.string(fromByteCount: value.bytes, countStyle: .file)
}
}
extension FormatStyle where Self == FileSizeFormatStyle {
static var fileSize: FileSizeFormatStyle { .init() }
}
// Usage
let size = FileSize(bytes: 1_500_000)
size.formatted(.fileSize) // "1.5 MB"// chunks(ofCount:) -- Swift Algorithms package
import Algorithms
let batches = items.chunks(ofCount: 10)
for batch in batches {
try await upload(batch)
}
// windows(ofCount:) -- sliding window
let movingAverages = values.windows(ofCount: 3).map { window in
window.reduce(0, +) / Double(window.count)
}
// adjacentPairs() -- process consecutive elements
for (previous, current) in values.adjacentPairs() {
if current > previous * 2 {
print("Spike detected")
}
}func processResponse(_ data: Data) throws -> User {
guard let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
let userData = json["user"] as? [String: Any],
let name = userData["name"] as? String,
let id = userData["id"] as? Int
else {
throw ParseError.invalidFormat
}
// Use Codable instead when practical -- this is for mixed/dynamic JSON
return User(id: id, name: name)
}
// Guard with where clause
func processItems(_ items: [Item]) {
for item in items {
guard case .active(let config) = item.status,
config.isEnabled,
!config.isExpired
else { continue }
activate(item, with: config)
}
}protocol DataStore {
associatedtype StoreError: Error
func save(_ data: Data) throws(StoreError)
func load(id: String) throws(StoreError) -> Data
}
struct FileStore: DataStore {
enum StoreError: Error {
case notFound, permissionDenied, diskFull
}
func save(_ data: Data) throws(StoreError) {
// ...
}
func load(id: String) throws(StoreError) -> Data {
guard fileExists(id) else { throw .notFound }
// ...
}
}Apple documents DefaultStringInterpolation as the type used while building interpolated strings, and supports extending it with custom appendInterpolation(...) overloads.
extension DefaultStringInterpolation {
mutating func appendInterpolation(json value: some Encodable) {
let encoder = JSONEncoder()
encoder.outputFormatting = [.prettyPrinted, .sortedKeys]
if let data = try? encoder.encode(value),
let string = String(data: data, encoding: .utf8) {
appendLiteral(string)
}
}
mutating func appendInterpolation(ordinal value: Int) {
let formatter = NumberFormatter()
formatter.numberStyle = .ordinal
if let result = formatter.string(from: value as NSNumber) {
appendLiteral(result)
}
}
}
print("Config: \(json: settings)")
print("You placed \(ordinal: 3)")// Publisher that never fails
let publisher: AnyPublisher<String, Never> = Just("hello").eraseToAnyPublisher()
// Phantom type preventing construction
enum Locked {}
enum Unlocked {}
struct Door<State> {
private init() {}
}
extension Door where State == Unlocked {
func open() { /* ... */ }
}
// Generic constraint meaning "this case cannot happen"
func absurd<T>(_ never: Never) -> T {
// No body needed -- Never has no values, so this is never called
}skills
accessorysetupkit
references
activitykit
references
adattributionkit
references
alarmkit
references
app-clips
app-intents
references
app-store-optimization
app-store-review
apple-on-device-ai
appmigrationkit
references
audioaccessorykit
references
authentication
references
avkit
references
background-processing
references
browserenginekit
references
callkit
references
carplay
references
cloudkit
references
contacts-framework
references
core-bluetooth
references
core-data
core-motion
references
core-nfc
references
coreml
references
cryptokit
references
cryptotokenkit
references
debugging-instruments
device-integrity
references
dockkit
references
energykit
references
eventkit
references
financekit
references
focus-engine
gamekit
references
healthkit
references
homekit
references
ios-accessibility
ios-localization
ios-networking
ios-simulator
references
mapkit
metrickit
references
musickit
references
natural-language
references
paperkit
references
passkit
references
pdfkit
references
pencilkit
references
permissionkit
references
photokit
push-notifications
realitykit
references
relevancekit
references
scenekit
references
sensorkit
references
speech-recognition
spritekit
references
storekit
swift-api-design-guidelines
swift-architecture
swift-charts
references
swift-codable
swift-concurrency
swift-formatstyle
swift-language
swift-security
references
swift-testing
swiftdata
swiftlint
swiftui-animation
swiftui-gestures
references
swiftui-layout-components
swiftui-liquid-glass
references
swiftui-patterns
swiftui-performance
swiftui-uikit-interop
swiftui-webkit
tabletopkit
references
tipkit
references
vision-framework
weatherkit
references
widgetkit
references