Skills Plugins MCP Prompt Model 博客 我的中心
Development #data #api

swift-codable

Implement Swift Codable models for JSON and property-list encoding and decoding with JSONDecoder, JSONEncoder, CodingKeys, and custom init(from:) or encode(to:). Use when parsing API responses, remapping keys, flattening nested JSON, handling date or data decoding strategies, decoding heterogeneous arrays, or integrating Codable with URLSession, SwiftData, or UserDefaults.

DeepseekModel Curated skill Quality Excellent · 90 v1.0.0

Get

https://deepseekmodel.com/api/download.php?id=dpearson2699-swift-ios-skills-skills-swift-codable-skill-md&format=skill
Download .skill Standard format with system_prompt and model_config, ready for any agent framework
The actual content of the system_prompt field in the .skill file.
name swift-codable description Implement Swift Codable models for JSON and property-list encoding and decoding with JSONDecoder, JSONEncoder, CodingKeys, and custom init(from:) or encode(to:). Use when parsing API responses, remapping keys, flattening nested JSON, handling date or data decoding strategies, decoding heterogeneous arrays, or integrating Codable with URLSession, SwiftData, or UserDefaults. Swift Codable Encode and decode Swift types using Codable ( Encodable & Decodable ) with JSONEncoder , JSONDecoder , and related APIs. Targets Swift 6.3 / iOS 26+. Contents Decode and Verify Workflow Basic Conformance Custom CodingKeys Custom Decoding and Encoding Nested and Flattened Containers Heterogeneous Arrays Date Decoding Strategies Data and Key Strategies Lossy Array Decoding Single Value Containers Default Values for Missing Keys Encoder and Decoder Configuration Codable with URLSession Codable with SwiftData Codable with UserDefaults Common Mistakes Review Checklist References Decode and Verify Workflow Decode representative success, missing, null, malformed, acronym-key, and date fixtures. On failure, inspect DecodingError , its codingPath , and the raw payload. Correct only the mismatched model, key, container, or strategy; do not hide contract failures with lossy decoding. Rerun fixtures and encode/decode round trips where both directions are part of the contract. Basic Conformance When all stored properties are themselves Codable , the compiler synthesizes conformance automatically: struct User : Codable { let id: Int let name: String let email: String let isVerified: Bool } let user = try JSONDecoder ().decode( User . self , from: jsonData) let encoded = try JSONEncoder ().encode(user) Prefer Decodable for read-only API responses and Encodable for write-only. Use Codable only when both directions are required. Custom CodingKeys Rename JSON keys without writing a custom decoder by declaring a CodingKeys enum: struct Product : Codable { let id: Int let displayName: String let imageURL: URL let priceInCents: Int enum CodingKeys : String , CodingKey { case id case displayName = "display_name" case imageURL = "image_url" case priceInCents = "price_in_cents" } } Every stored property must appear in the enum. Omitting a property from CodingKeys excludes it from encoding/decoding -- provide a default value or compute it separately. Custom Decoding and Encoding Override init(from:) and encode(to:) for transformations the synthesized conformance cannot handle: struct Event : Codable { let name: String let timestamp: Date let tags: [ String ] enum CodingKeys : String , CodingKey { case name, timestamp, tags } init ( from decoder : Decoder ) throws { let container = try decoder.container(keyedBy: CodingKeys . self ) name = try container.decode( String . self , forKey: .name) // Decode Unix timestamp as Double, convert to Date let epoch = try container.decode( Double . self , forKey: .timestamp) timestamp = Date (timeIntervalSince1970: epoch) // Default to empty array when key is missing tags = try container.decodeIfPresent([ String ]. self , forKey: .tags) ?? [] } func encode ( to encoder : Encoder ) throws { var container = encoder.container(keyedBy: CodingKeys . self ) try container.encode(name, forKey: .name) try container.encode(timestamp.timeIntervalSince1970, forKey: .timestamp) try container.encode(tags, forKey: .tags) } } Nested and Flattened Containers Use nestedContainer(keyedBy:forKey:) to navigate and flatten nested JSON: // JSON: { "id": 1, "location": { "lat": 37.7749, "lng": -122.4194 } } struct Place : Decodable { let id: Int let latitude: Double let longitude: Double enum CodingKeys : String , CodingKey { case id, location } enum LocationKeys : String , CodingKey { case lat, lng } init ( from decoder : Decoder ) throws { let container = try decoder.container(keyedBy: CodingKeys . self ) id = try container.decode( Int . self , forKey: .id) let location = try container.nestedContainer( keyedBy: LocationKeys . self , forKey: .location) latitude = try location.decode( Double . self , forKey: .lat) longitude = try location.decode( Double . self , forKey: .lng) } } Chain multiple nestedContainer calls to flatten deeply nested structures. Also use nestedUnkeyedContainer(forKey:) for nested arrays. Heterogeneous Arrays Load Advanced Codable Patterns for discriminator-based mixed arrays. Date Decoding Strategies Configure JSONDecoder.dateDecodingStrategy to match your API: let decoder = JSONDecoder () // ISO 8601 (e.g., "2024-03-15T10:30:00Z") decoder.dateDecodingStrategy = .iso8601 // Unix timestamp in seconds (e.g., 1710499800) decoder.dateDecodingStrategy = .secondsSince1970 // Custom DateFormatter let formatter = DateFormatter () formatter.dateFormat = "yyyy-MM-dd" formatter.locale = Locale (identifier: "en_US_POSIX" ) formatter.timeZone = TimeZone (secondsFromGMT: 0 ) decoder.dateDecodingStrategy = .formatted(formatter) // Custom closure for multiple formats decoder.dateDecodingStrategy = .custom { decoder in let container = try decoder.singleValueContainer() let string = try container.decode( String . self ) if let date = ISO8601DateFormatter ().date(from: string) { return date } throw DecodingError .dataCorruptedError( in: container, debugDescription: "Cannot decode date: \(string) " ) } Set the matching strategy on JSONEncoder : encoder.dateEncodingStrategy = .iso8601 Data and Key Strategies let decoder = JSONDecoder () decoder.dataDecodingStrategy = .base64 // Base64-encoded Data fields decoder.keyDecodingStrategy = .convertFromSnakeCase // simple keys only; not URL/ID spelling // {"user_name": "Alice"} maps to `var userName: String` -- no CodingKeys needed let encoder = JSONEncoder () encoder.dataEncodingStrategy = .base64 encoder.keyEncodingStrategy = .convertToSnakeCase Use key strategies only for mechanical snake_case-to-camelCase mappings. convertFromSnakeCase maps by spelling, not Swift acronym/initialism policy: image_url , base_uri , and user_id match imageUrl , baseUri , and userId only. If the Swift model uses imageURL , baseURI , or userID , declare explicit CodingKeys ; the strategy will not synthesize those names. Lossy Array Decoding Use lossy arrays only when partial success is part of the product contract; load Lossy Arrays . Single Value Containers Use singleValueContainer() for type-safe primitive wrappers; see Single-Value Wrappers . Default Values for Missing Keys Stored defaults do not make synthesized decoding tolerate missing nonoptional keys. Load Missing-Key Defaults when the contract assigns explicit fallback behavior to missing or null values. Encoder and Decoder Configuration Keep matching strategies at the transport/file-format boundary. Load Encoder Configuration for nonconforming floats and property-list guidance. Codable with URLSession func fetchUser ( id : Int ) async throws -> User { let url = URL (string: "https://api.example.com/users/ \(id) " ) ! let (data, response) = try await URLSession .shared.data(from: url) guard let http = response as? HTTPURLResponse , ( 200 ... 299 ).contains(http.statusCode) else { throw APIError .invalidResponse } let decoder = JSONDecoder () decoder.keyDecodingStrategy = .convertFromSnakeCase decoder.dateDecodingStrategy = .iso8601 return try decoder.decode( User . self , from: data) } // Generic API envelope. Configure a decoder inside this helper because // fetchUser's decoder is out of scope. struct APIResponse < T : Decodable >: Decodable { let data: T let meta: Meta ? struct Meta : Decodable { let page: Int ; let totalPages: Int } } func decodeUsersEnvelope ( from data : Data ) throws -> [ User ] { let decoder = JSONDecoder () decoder.keyDecodingStrategy = .convertFromSnakeCase decoder.dateDecodingStrategy = .iso8601 return try decoder.decode( APIResponse <[ User ]>. self , from: data).data } Codable with SwiftData Keep schema values typed and route persistence design to swiftdata ; see Persistence Boundaries . Codable with UserDefaults Use primitives for small preferences. Load Persistence Boundaries for a small Codable RawRepresentable / @AppStorage handoff; use a real persistence layer for larger or durable data. Common Mistakes 1. Not handling missing defaulted fields: // DON'T -- crashes if key is absent let value = try container.decode( String . self , forKey: .bio) // DO -- falls back when the key is absent or null let value = try container.decodeIfPresent( String . self , forKey: .bio) ?? "" 2. Failing entire array when one element is invalid: // DON'T -- one bad element kills the whole decode let items = try container.decode([ Item ]. self , forKey: .items) // DO -- decode elements individually only when partial success is allowed 3. Date strategy mismatch: // DON'T -- default strategy expects Double, but API sends ISO string let decoder = JSONDecoder () // dateDecodingStrategy defaults to .deferredToDate // DO -- set strategy to match your API format decoder.dateDecodingStrategy = .iso8601 4. Force-unwrapping decoded optionals: // DON'T let user = try? decoder.decode( User . self , from: data) print (user ! .name) // DO guard let user = try? decoder.decode( User . self , from: data) else { return } 5. Using Codable when only Decodable is needed: // DON'T -- unnecessarily constrains the type to also be Encodable struct APIResponse : Codable { let id: Int ; let message: String } // DO -- use Decodable for read-only API responses struct APIResponse : Decodable { let id: Int ; let message: String } 6. Manual CodingKeys for simple snake_case APIs: // DON'T -- verbose boilerplate for every model enum CodingKeys : String , CodingKey { case userName = "user_name" case avatarUrl = "avatar_url" } // DO -- configure once on the decoder for simple cases decoder.keyDecodingStrategy = .convertFromSnakeCase // Keep CodingKeys for `imageURL`, `baseURI`, `userID`, and similar names. Review Checklist Types conform to Decodable only when encoding is not needed decodeIfPresent used with defaults for optional or missing keys keyDecodingStrategy = .convertFromSnakeCase used for simple snake_case APIs, with CodingKeys retained for acronym spellings dateDecodingStrategy matches the API date format Arrays of unreliable data use lossy decoding to skip invalid elements Custom init(from:) validates and transforms data instead of post-decode fixups JSONEncoder.outputFormatting includes .sortedKeys for deterministic test output Wrapper types (UserID, etc.) use singleValueContainer for clean JSON Generic APIResponse<T> wrapper used for consistent API envelope handling No force-unwrapping of decoded values Persistence boundary is explicit: SwiftData only for compatible noncomputed model properties, @AppStorage /UserDefaults only for small primitive or RawRepresentable preferences References Advanced Codable patterns -- mixed arrays, lossy decoding, wrappers, defaults, configuration, and persistence boundaries Codable -- protocol combining Encodable and Decodable JSONDecoder -- decodes JSON data into Codable types JSONEncoder -- encodes Codable types as JSON data CodingKey -- protocol for encoding/decoding keys JSONDecoder.KeyDecodingStrategy.convertFromSnakeCase -- snake-case conversion behavior and limitations Encoding and Decoding Custom Types -- Apple guide on custom Codable conformance Using JSON with Custom Types -- Apple sample code for JSON patterns Preserving your app's model data across launches -- SwiftData model property compatibility
Keywords that activate this skill. Click one to copy it.

This skill does not provide trigger words.

The downloaded .skill package contains the following fields.
Field Description
formatFormat tag (skill/v1)
skill_idUnique skill ID
nameSkill name
versionVersion
descriptionDescription
categoryCategories (array)
trigger_wordsTrigger words
tagsTags
sourceSource
source_urlSource URL (this page)
exported_atExported at (set per download)
system_promptSystem prompt body
model_configModel config: provider / model / temperature / max_tokens / top_p
examplesExamples
install_guideImport guide for Coze / Dify / Claude / custom frameworks
The same skill can be exported in different platform formats.
.skill Standard format with system_prompt and model_config, ready for any agent framework Download
.skillpro Enhanced format with scripts, tools, dependencies and hooks Download
.json Plain JSON export with system_prompt and model parameters only Download
Coze Markdown with frontmatter, for Coze platform import Download
Dify Dify DSL, import directly after creating an app Download

每日精选 Skill 推荐,免费送到你邮箱

输入邮箱,每天接收一个精选 AI Agent 技能推荐。完全免费,持续更新。

验证码 --

提交后我们会发送一封确认邮件,点击邮件里的链接才会开始收信。

完全免费,取消任意时间。我们不会发送垃圾邮件。