[api-upload-refactor] Add test target, relax decode constraints, add HTTPBody + MultipartForm

- Package: new LCEssentialsTests target (runs on iOS simulator)
- JSONDecoder.decode: T: Codable -> T: Decodable & Sendable (4 overloads);
  remove try! in decode(fromURL:); honour encoding param in decode(_:using:)
- Propagate & Sendable to Data.object, Dictionary.toObjetct, API.request return
- LCEHTTPBody: HTTPBody protocol, JSONBody, FormURLEncodedBody, RawBody, factories
- LCEMultipartForm: multipart builder, OutputStream-streamed serialize(),
  in-memory + on-disk file parts, ported mimeType(for:)
- Tests: StubURLProtocol harness + 15 tests
This commit is contained in:
Daniel Arantes Loverde
2026-08-29 16:59:08 -03:00
parent db696b5a34
commit e89935a69c
14 changed files with 688 additions and 22 deletions

View File

@@ -44,8 +44,8 @@ extension JSONDecoder {
/// - LoverdeCo: Decode JSON Data to Object
///
/// - Parameter data: Data
/// - returns: Object: Codable/Decodable
public static func decode<T: Codable>(data: Data) throws -> T {
/// - returns: Object: Decodable & Sendable
public static func decode<T: Decodable & Sendable>(data: Data) throws -> T {
var error = NSError(domain: "", code: 0)
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .useDefaultKeys
@@ -70,28 +70,24 @@ extension JSONDecoder {
/// - LoverdeCo: Decode JSON String to Object
///
/// - Parameter json: String
/// - returns: Object: Codable/Decodable
public static func decode<T: Codable>(_ json: String, using encoding: String.Encoding = .utf8) throws -> T {
var error = NSError()
if let jsonData = json.data(using: .utf8) {
do {
return try decode(data: jsonData)
} catch {
throw error
}
/// - returns: Object: Decodable & Sendable
public static func decode<T: Decodable & Sendable>(_ json: String, using encoding: String.Encoding = .utf8) throws -> T {
guard let jsonData = json.data(using: encoding) else {
let msg = "Could not convert string to \(encoding) data for \(T.self)"
throw NSError.createErrorWith(code: 0, description: msg, reasonForError: msg)
}
throw error
return try decode(data: jsonData)
}
/// - LoverdeCo: Decode JSON URL to Object
///
/// - Parameter url: URL
/// - returns: Object: Codable/Decodable
public static func decode<T: Codable>(fromURL url: URL) throws -> T {
return try decode(data: try! Data(contentsOf: url))
/// - returns: Object: Decodable & Sendable
public static func decode<T: Decodable & Sendable>(fromURL url: URL) throws -> T {
return try decode(data: Data(contentsOf: url))
}
public static func decode<T: Codable>(dictionary: Any) throws -> T {
public static func decode<T: Decodable & Sendable>(dictionary: Any) throws -> T {
do {
let json = try JSONSerialization.data(withJSONObject: dictionary)
let decoder = JSONDecoder()