From cfda789ba465b22d5a3f781bd3ba40971cf98a9c Mon Sep 17 00:00:00 2001 From: Sami Samhuri Date: Sun, 15 Jun 2025 08:46:19 -0700 Subject: [PATCH] WIP: readme and changelog --- CHANGELOG.md | 14 ++++++++++++-- Readme.md | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c528ad..18e217a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,18 @@ # Changelog -## [2.0.1] - Unreleased +## [2.1.0] - Unreleased -[2.0.1]: https://github.com/samsonjs/Osiris/compare/2.0.0...main +### Added +- **Codable support for JSON** - First-class support for encoding and decoding Codable types +- **New convenience methods** `HTTPRequest.postJSON(_:body:)` and `HTTPRequest.putJSON(_:body:)` for Codable requests +- **Response decoding methods** `HTTPResponse.decode(_:using:)` and `HTTPResponse.tryDecode(_:using:)` with JSONDecoder support +- **Codable body property** on HTTPRequest that takes precedence over parameters dictionary + +### Enhanced +- **RequestBuilder** now supports JSONEncoder for Codable bodies alongside existing JSONSerialization +- **Comprehensive test coverage** for all Codable functionality with 14 new tests + +[2.1.0]: https://github.com/samsonjs/Osiris/compare/2.0.0...main ## [2.0.0] - 2025-06-15 diff --git a/Readme.md b/Readme.md index e3cc8d4..48aee3a 100644 --- a/Readme.md +++ b/Readme.md @@ -99,6 +99,45 @@ request.addHeader(name: "x-custom", value: "42") request.addMultipartJPEG(name: "avatar", image: UIImage(), quality: 1, filename: "avatar.jpg") ``` +### Codable Support + +For modern Swift applications, Osiris provides first-class support for `Codable` types with JSON encoding and decoding: + +```swift +// Define your models +struct Person: Codable, Sendable { + let name: String + let email: String + let age: Int +} + +// POST request with Codable body +let person = Person(name: "Jane Doe", email: "jane@example.net", age: 30) +let request = HTTPRequest.postJSON(url, body: person) + +// Build and send the request +let urlRequest = try RequestBuilder.build(request: request) +let task = URLSession.shared.dataTask(with: urlRequest) { data, response, error in + let httpResponse = HTTPResponse(response: response, data: data, error: error) + + switch httpResponse { + case .success(_, _): + // Decode the response + let updatedPerson = try httpResponse.decode(Person.self) + print("Updated person: \(updatedPerson)") + + // Or use the optional variant + if let person = httpResponse.tryDecode(Person.self) { + print("Decoded person: \(person)") + } + case .failure(let error, _, _): + print("Request failed: \(error)") + } +} +``` + +The Codable body takes precedence over the parameters dictionary, so you can safely use both without conflicts. + You can build a `URLRequest` from an `HTTPRequest` instance using `RequestBuilder`: ```swift @@ -135,6 +174,8 @@ The response provides convenient properties: - `headers`: a dictionary of headers - `bodyString`: the response body as a `String` - `dictionaryFromJSON`: the decoded body for JSON responses +- `decode(_:using:)`: decode the response body as a Codable type (throws on failure) +- `tryDecode(_:using:)`: decode the response body as a Codable type (returns nil on failure) - `underlyingResponse`: the optional `HTTPURLResponse` for direct access ### FormEncoder