alickbass / SwiftyJSONModel

Better way to use SwiftyJSON with custom models
MIT License
29 stars 11 forks source link
json json-model-mapping protocol-oriented swiftyjson type-safe

SwiftyJSONModel

A microframework that helps to use Swifty JSON with your custom models in a easy and type-safe way

Carthage compatible Build Status codecov

Motivation:

The full motivation and description is here

For the following JSON:

{
  "name": "John",
  "age": 25,
  "isMarried": false,
  "height": 170.0,
  "address": {
    "city": "San-Fransisco",
    "country": "USA"
  },
  "hobbies": ["bouldering", "guitar", "swift:)"]
}

to map to the following model:

struct Person {
    let name: String
    let age: Int
    let isMarried: Bool
    let height: Double
    let city: String
    let country: String
    let hobbies: [String]?
}

Instead of the following:

extension Person {
    init?(jsonDict: [String: Any]) {
        guard let name = jsonDict["name"] as? String,
            let age = jsonDict["age"] as? Int,
            let isMarried = jsonDict["isMarried"] as? Bool,
            let height = jsonDict["height"] as? Double,
            let address = jsonDict["address"] as? [String: Any],
            let city = address["city"] as? String,
            let country = address["country"] as? String
            else {
            return nil
        }

        self.name = name
        self.age = age
        self.isMarried = isMarried
        self.height = height
        self.city = city
        self.country = country
        hobbies = jsonDict["hobbies"] as? [String]
    }
}

We get the following:

import SwiftyJSONModel

extension Person: JSONModelType {
    enum PropertyKey: String {
        case name, age, isMarried, height, hobbies
        case address, country, city
    }

    init(object: JSONObject<PropertyKey>) throws {
        name = try object.value(for: .name)
        age = try object.value(for: .age)
        isMarried = try object.value(for: .isMarried)
        height = try object.value(for: .height)
        city = try object.value(for: .address, .city) // Accessing nested json
        country = try object.value(for: .address, .country) // Accessing nested json
        hobbies = try object.value(for: .hobbies)
    }

    var dictValue: [PropertyKey : JSONRepresentable?] {
        return [
            .name: name,
            .age: age,
            .isMarried: isMarried,
            .height: height,
            .city: city,
            .country: country,
            .hobbies: hobbies?.jsonRepresantable,
        ]
    }
}

What we improved:

Integration

CocoaPods (iOS 8+)

You can use CocoaPods to install SwiftyJSONModel by adding it to your Podfile:

platform :ios, '8.0'
use_frameworks!

target 'MyApp' do
pod 'SwiftyJSONModel'
end

Note that this requires CocoaPods version 36, and your iOS deployment target to be at least 8.0:

Carthage (iOS 8+)

You can use Carthage to install SwiftyJSONModel by adding it to your Cartfile:

github "alickbass/SwiftyJSONModel"