Parsable is a small Swift library that adds lightweight JSON encoding and decoding helpers to any Codable model.
- Keeps conformance lightweight:
extension Model: Parseable {} - Provides primary throwing APIs for decoding and encoding
- Supports configured
JSONDecoderandJSONEncoderinstances - Keeps the original nil-returning helpers for compatibility
- Lets you configure or disable compatibility-helper logging
Add Parsable to the dependencies section of your Package.swift:
dependencies: [
.package(url: "https://github.com/makoni/parsable.git", from: "1.0.0"),
]import Foundation
import Parsable
struct APIError: Codable {
let error: String
let code: Int
let date: Date
}
extension APIError: Parseable {}
let jsonData = Data("{\"error\":\"Not Found\",\"code\":404,\"date\":1713171900}".utf8)
let decodedError = try APIError.decode(from: jsonData)
let encodedError = try decodedError.encoded()Use the throwing APIs when you want the underlying encoding or decoding error:
let decodedModel = try APIError.decode(from: jsonData)
let encodedData = try decodedModel.encoded()For Unix timestamps in milliseconds:
let decodedModel = try APIError.decode(
from: jsonData,
dateDecodingStrategy: .millisecondsSince1970
)
let encodedData = try decodedModel.encoded(
dateEncodingStrategy: .millisecondsSince1970
)If you need key strategies or any other JSONDecoder / JSONEncoder configuration, pass your own instance:
struct APIResponse: Codable {
let errorMessage: String
let statusCode: Int
}
extension APIResponse: Parseable {}
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let responseData = Data("{\"error_message\":\"Not Found\",\"status_code\":404}".utf8)
let response = try APIResponse.decode(from: responseData, using: decoder)
let encoder = JSONEncoder()
encoder.keyEncodingStrategy = .convertToSnakeCase
let encodedResponse = try response.encoded(using: encoder)The original API is still available as deprecated nil-returning convenience methods:
let decodedModel = APIError.decodeFromData(data: jsonData)
let encodedData = APIError.encode(fromEncodable: APIError(error: "Not Found", code: 404, date: .now))Those helpers return nil and forward failures to ParsableConfiguration.failureLogger when logging is enabled. Prefer the throwing APIs in new code when you need to inspect errors.
Deprecated compatibility helpers log failures through ParsableConfiguration.failureLogger, which is enabled by default.
ParsableConfiguration.failureLogger = { error, context in
print("Parsable warning: \(context.file):\(context.line) \(error.localizedDescription)")
}
ParsableConfiguration.disableFailureLogging()
ParsableConfiguration.enableDefaultFailureLogging()Hosted documentation: https://spaceinbox.me/docs/parsable/documentation/parsable/
The DocC source lives in Sources/Parsable/Documentation.docc.