Skip to content

Repository files navigation

SwiftJSONi

CI StatusVersionLicensePlatform

Why SwiftJSONi?

The traditional way of handling JSON in Swift is so cumbersome and requires many lines of code. For example, consider a JSON response from a API for bakery items,

{
"items": {
"item": [
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters": {
"batter": [
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
]
},
"topping": [
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
}
]
}
}

To get the type of 4th topping in first item, the safest Swift code looks like,

if let json = try? JSONSerialization.jsonObject(with: jsonData, options: .allowFragments) as? [String: Any],
let items = object["items"] as? [String: Any],
let item = items["item"] as? [[String: Any]],
let firstItem = item.first,
let toppings = firstItem["topping"] as? [[String: Any]],
toppings.count >= 3,
let type = toppings[3]["type"] as? String
{
print(type)
}

It involves lots of typecasting and safe index checks due to Swift's strict typecast and array index policies. To achieve the same with SwiftJSONi, the code looks like,

if let json = JSON(data: jsonData),
let type = json["items"]["item"][0]["topping"][3]["type"].string
{
print(type)
}

That's it!! It is so safe and readable. No need to worry about type casting and array index checks. It is all done automatically.

Installation

SwiftJSONi is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod'SwiftJSONi'

Usage

Initialization

import SwiftJSONi
let data: Data? // Response from API
let json = JSON(data: data) // Returns JSON?
let any: Any? // Value of Any type
let json = JSON(any) // Returns JSON?
let dictionary: [String: Any]
let json = JSON(dictionary) // Returns JSON
let validatedJSON = JSON(validateObject: dictionary) // Returns JSON? // Returns 'nil' when a value for key has unsupported JSON type.

Accessing values

Consider the bakery items JSON in the above example. Accessing the 'id' of first item be like,

let firstItem = json["items"]["item"][0] let id = firstItem["id"].string

Difference between .string and .stringValue is,

.string - Returns the String value if available else returns nil

.stringValue - Returns the String value if available else returns default value i.e "" (empty String)

So, getting the 'ppu' of first item belike,

let ppu = firstItem["ppu"].floatValue 

Methods

For String,

stringReturns the String value if available else returns nil
stringValueReturns the String value if available else returns default value i.e "" (empty String)

For Int,

intReturns the Int value if available else returns nil
intValueReturns the Int value if available else returns default value i.e 0

For Float,

floatReturns the Float value if available else returns nil
floatValueReturns the Float value if available else returns default value i.e 0.0

For Double,

doubleReturns the Double value if available else returns nil
doubleValueReturns the Double value if available else returns default value i.e 0.0

For Bool,

boolReturns the Bool value if available else returns nil
boolValueReturns the Bool value if available else returns default value i.e false

For JSON Object,

jsonObjectReturns [String: JSON]?
jsonObjectValueReturns [String: JSON] else [:]

For JSON Array,

jsonArrayReturns [JSON]?
jsonArrayValueReturns [JSON] else []

For Array,

arrayReturns [Any?]
arrayValueReturns [Any?] else []

For Dictionary,

dictionaryReturns [String: Any]?
dictionaryValueReturns [String: Any] else [:]

Type Checks

Since JSON is a custom type, typecasting it to primitive types always fails, i.e,

let name = json["name"] as? String // Always fails.

So is,

if json["name"] is String { // Condition always fails.
// Do something
}

Hence, SwiftJSONi uses inbuilt properties to check the type of values. Only these types will be accepted by JSON. Any other user-defined types cannot be used as JSON value.

isNullReturns true if the value is nil.
isStringReturns true if the value is String.
isIntReturns true if the value is Int.
isFloatReturns true if the value is Float.
isDoubleReturns true if the value is Double.
isBoolReturns true if the value is Bool.
isJsonObjectReturns true if the value is [String: JSON].
isJsonArrayReturns true if the value is [JSON].
isArrayReturns true if the value is [Any?].
isDictionaryReturns true if the value is [String: Any].

So the above situations can be handled as,

if json["name"].isString {
// Do something
}

Debugging

debugPrint() is used to pretty print the JSON in console. description is the valid JSON String for the corresponding JSON.

Author

Akaash Dev, heatblast.akaash@gmail.com

License

SwiftJSONi is available under the MIT license. See the LICENSE file for more info.

About

A Light weight Swift JSON Model, that allows to use JSON the way it has to be

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages