Pewarta Proxy

πŸ“‹ Server Request & Proxy Logs

Loading active proxy settings...
Developed by Khairul Adha (adhexa.id)
Mengambil log server...

βš™οΈ Pengaturan Proxy Target

Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Repository files navigation

Hi there πŸ‘‹

This package is generic code for decode and encode JSON data, as part of reading and writing data to local storage. Data are tasks, logrecords and user configuration.

DecodeEncodeGeneric Documentation

A Swift package for encoding and decoding JSON data with support for strings, files, and remote URLs.

Overview

DecodeEncodeGeneric provides a type-safe, generic approach to working with JSON in Swift. It handles common encoding/decoding scenarios while providing detailed error information and flexible configuration options.

Features

  • Generic decoding from strings, files, URLs, and raw Data
  • Generic encoding to strings, files, and Data
  • Configurable JSON encoder/decoder with custom strategies
  • Comprehensive error handling with descriptive error messages
  • Support for both single objects and arrays
  • Async/await support for remote URL fetching
  • Result-based API alternatives
  • Pretty-printing convenience methods

DecodeGeneric

Initialization

// Basic initialization
let decoder = DecodeGeneric()

// Custom configuration
let decoder = DecodeGeneric(
    urlSession: .shared,
    jsonDecoder: JSONDecoder(),
    dateDecodingStrategy: .iso8601,
    keyDecodingStrategy: .convertFromSnakeCase
)

Decoding from Strings

let jsonString = """
{
    "name": "John",
    "age": 30
}
"""

struct Person: Decodable {
    let name: String
    let age: Int
}

do {
    let person = try decoder.decode(Person.self, fromString: jsonString)
    print(person.name) // "John"
} catch {
    print("Error: \(error.localizedDescription)")
}

Decoding Arrays from Strings

let jsonArray = """
[
    {"name": "John", "age": 30},
    {"name": "Jane", "age": 25}
]
"""

do {
    let people = try decoder.decodeArray(Person.self, fromString: jsonArray)
    print(people.count) // 2
} catch {
    print("Error: \(error)")
}

Decoding from Files

do {
    let person = try decoder.decode(Person.self, fromFile: "/path/to/file.json")
    // or for arrays
    let people = try decoder.decodeArray(Person.self, fromFile: "/path/to/array.json")
} catch {
    print("Error: \(error)")
}

Decoding from URLs (Async)

Requires macOS 12.0+ or iOS 15.0+

do {
    let person = try await decoder.decode(
        Person.self, 
        fromURL: "https://api.example.com/person"
    )
    
    // or for arrays
    let people = try await decoder.decodeArray(
        Person.self,
        fromURL: "https://api.example.com/people"
    )
} catch {
    print("Error: \(error)")
}

Decoding from Data

let jsonData: Data = // ... your data
do {
    let person = try decoder.decode(Person.self, from: jsonData)
    // or for arrays
    let people = try decoder.decodeArray(Person.self, from: jsonData)
} catch {
    print("Error: \(error)")
}

EncodeGeneric

Initialization

// Basic initialization
let encoder = EncodeGeneric()

// Custom configuration
let encoder = EncodeGeneric(
    jsonEncoder: JSONEncoder(),
    outputFormatting: [.prettyPrinted, .sortedKeys],
    dateEncodingStrategy: .iso8601,
    keyEncodingStrategy: .convertToSnakeCase
)

// Pretty-printed convenience initializer
let prettyEncoder = EncodeGeneric.prettyPrinted()

Encoding to Data

struct Person: Encodable {
    let name: String
    let age: Int
}

let person = Person(name: "John", age: 30)

do {
    let data = try encoder.encode(person)
    // or for arrays
    let people = [person]
    let arrayData = try encoder.encodeArray(people)
} catch {
    print("Error: \(error)")
}

Encoding to String

do {
    let jsonString = try encoder.encodeToString(person)
    print(jsonString) // {"name":"John","age":30}
    
    // Pretty-printed string
    let prettyString = try encoder.encodeToPrettyString(person)
    
    // Array to string
    let arrayString = try encoder.encodeArrayToString([person])
} catch {
    print("Error: \(error)")
}

Encoding to File

do {
    try encoder.encode(person, toFile: "/path/to/output.json")
    
    // With atomic write option (default is true)
    try encoder.encode(person, toFile: "/path/to/output.json", atomically: true)
    
    // Array to file
    try encoder.encodeArray([person], toFile: "/path/to/array.json")
} catch {
    print("Error: \(error)")
}

Result-Based API

For situations where you prefer Result types over throwing functions:

let result = encoder.encodeResult(person)
switch result {
case .success(let data):
    print("Encoded successfully")
case .failure(let error):
    print("Error: \(error)")
}

let stringResult = encoder.encodeToStringResult(person)
switch stringResult {
case .success(let jsonString):
    print(jsonString)
case .failure(let error):
    print("Error: \(error)")
}

Error Handling

DecodeError

The package provides comprehensive error types with descriptive messages:

  • .invalidStringEncoding - Failed to encode string as UTF-8 data
  • .invalidURL - Invalid URL string
  • .invalidFilePath - Invalid file path
  • .decodingFailed(Error) - JSON decoding failed with underlying error
  • .fileReadFailed(Error) - Failed to read file with underlying error

EncodeError

  • .encodingFailed(Error) - JSON encoding failed with underlying error
  • .fileWriteFailed(Error) - Failed to write file with underlying error
  • .invalidFilePath - Invalid file path
  • .stringConversionFailed - Failed to convert data to UTF-8 string

Advanced Usage

Custom Date Strategies

let decoder = DecodeGeneric(
    dateDecodingStrategy: .iso8601
)

let encoder = EncodeGeneric(
    dateEncodingStrategy: .iso8601
)

Custom Key Strategies

let decoder = DecodeGeneric(
    keyDecodingStrategy: .convertFromSnakeCase
)

let encoder = EncodeGeneric(
    keyEncodingStrategy: .convertToSnakeCase
)

Custom URLSession

let config = URLSessionConfiguration.default
config.timeoutIntervalForRequest = 30
let customSession = URLSession(configuration: config)

let decoder = DecodeGeneric(urlSession: customSession)

Internals (Maintainers)

  • Decoding flows through decodeData/decodeDataArray helpers so all entry points share the same error mapping to DecodeError.
  • Encoding uses some Encodable for tighter type safety while still accepting any codable type; arrays use the same helper for consistent failures.
  • prettyPrinted() builds an encoder with sorted keys and pretty print for deterministic output without altering the primary encoder configuration.
  • File helpers guard empty paths up-front and return .invalidFilePath; IO and string conversion errors surface as typed EncodeError/DecodeError for clearer logging and tests.

Requirements

  • Swift 5.7+
  • macOS 10.15+ / iOS 13.0+ (for basic functionality)
  • macOS 12.0+ / iOS 15.0+ (for async URL decoding)

Thread Safety

Both DecodeGeneric and EncodeGeneric are marked as final classes. The underlying JSONDecoder and JSONEncoder are thread-safe for read operations, but you should create separate instances for concurrent encoding/decoding operations.

License

MIT

Author

Thomas Evensen

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages