Reason - Example - Installation
identifier <-- json["id"]
name <-- json["name"]
stats <-- json["stats"]Because parsing JSON in Swift is full of unecessary if lets, obvious casts and nil-checks
There must be a better way
Arrow is part of freshOS iOS toolset. Try it in an example App! Download Starter Project
By using a simple arrow operator that takes care of the boilerplate code for us.
Json mapping code becomes concise and maintainable โค๏ธ
- Infers types
- Leaves your models clean
- Handles custom & nested models
- Dot and array syntax
- Pure Swift, Simple & Lightweight
struct Profile {
var identifier = 0
var name = ""
var link:NSURL?
var weekday:WeekDay = .Monday
var stats = Stats()
var phoneNumbers = [PhoneNumber]()
}{
"id": 15678,
"name": "John Doe",
"link": "https://apple.com/steve",
"weekdayInt" : 3,
"stats": {
"numberOfFriends": 163,
"numberOfFans": 10987
},
"phoneNumbers": [{
"label": "house",
"number": "9809876545"
}, {
"label": "cell",
"number": "0908070656"
}, {
"label": "work",
"number": "0916570656"
}]
}var profile = Profile()
// Int
if let id = json["id"] as? Int {
profile.identifier = id
}
// String
if let name = json["name"] as? String {
profile.name = name
}
// NSURL
if let link = json["link"] as? String, url = NSURL(string:link) {
profile.link = link
}
// Enum
if let weekdayInt = json["weekdayInt"] as? Int, weekday = WeekDay(rawValue:weekdayInt) {
profile.weekday = weekday
}
// Custom nested object
if let statsJson = json["stats"] as? AnyObject {
if let numberOfFans = statsJson["numberOfFans"] as? Int {
profile.stats.numberOfFans = numberOfFans
}
if let numberOfFriends = statsJson["numberOfFriends"] as? Int {
profile.stats.numberOfFriends = numberOfFriends
}
}
// Array of custom nested object
if let pns = json["phoneNumbers"] as? [AnyObject] {
for pn in pns {
phoneNumbers.append(PhoneNumber(json: pn))
}
}extension Profile:ArrowParsable {
mutating func deserialize(_ json: JSON) {
identifier <-- json["id"]
link <-- json["link"]
name <-- json["name"]
weekday <-- json["weekdayInt"]
stats <- json["stats"]
phoneNumbers <-- json["phoneNumbers"]
}
}let profile = Profile()
profile.deserialize(json)The Swift Package Manager (SPM) is now the official way to install Arrow. The other package managers are now deprecated as of 5.1.2 and won't be supported in future versions.
Xcode > File > Swift Packages > Add Package Dependency... > Paste https://github.com/freshOS/Arrow
github "freshOS/Arrow"
target 'MyApp'
pod 'Arrow'
use_frameworks!
Notice earlier we typed :
stats <-- json["stats"]That's because we created and extension "Stats+Arrow.swift" enabling us to use the Arrow Operator
// Stats+Arrow.swift
import Foundation
extension Stats:ArrowParsable {
mutating func deserialize(json: JSON) {
numberOfFriends <-- json["numberOfFriends"]
numberOfFans <-- json["numberOfFans"]
}
}- DO I have to use the <-- for my sub models
- Nope, you could write it like so if you wanted :
stats.numberOfFriends <-- json["stats.numberOfFriends"]
stats.numberOfFans <-- json["stats.numberOfFans"]// Configure Global Date Parsing with one of those
Arrow.setDateFormat("yyyy-MM-dd'T'HH:mm:ssZZZZZ")
Arrow.setUseTimeIntervalSinceReferenceDate(true)
Arrow.setDateFormatter(aDateFormatter)
// Then later dates can be parsed form custom date format or timestamps automatically ๐
let json:JSON = JSON(["date": "2013-06-07T16:38:40+02:00", "timestamp": 392308720])
date1 <-- json["date"]
date2 <-- json["timestamp"]createdAt <-- json["created_at"]?.dateFormat("yyyy-MM-dd'T'HH:mm:ssZZZZZ")
createdAt <-- json["created_at"]?.dateFormatter(aCustomDateFormatter)Just provide it on a case per case basis ! ๐
value <-- json["nested.nested.nested.nestedValue"]value <-- json[12]value <-- json[1]?["someKey"]?[2]?["something.other"]if let collection = json.collection {
for jsonEntry in collection {
//Do something
}
}- Swift 2 -> version 2.0.3
- Swift 3 -> version 3.0.5
- Swift 4 -> version 4.0.0
- Swift 4.1 -> version 4.1.0
- Swift 4.2 -> version 4.2.0
- Swift 5.0 -> version 5.0.0
- Swift 5.1 -> version 5.1.0
- Swift 5.1.3 -> version 5.1.1
- Swift 5.3 -> version 6.0.0
This wouldn't exist without YannickDot, Damien-nd and maxkonovalov
Like the project? Offer coffee or support us with a monthly donation and help us continue our activities :)
Become a sponsor and get your logo on our README on Github with a link to your site :)
