Swiftpack.co - Package - freshOS/Arrow
Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.

Arrow

Arrow

Language: Swift 5 Platform: iOS 8+ SPM compatible Carthage compatible Cocoapods compatible Build Status codebeat badge License: MIT Release version

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

Try it

Arrow is part of freshOS iOS toolset. Try it in an example App! Download Starter Project

How

By using a simple arrow operator that takes care of the boilerplate code for us.
Json mapping code becomes concise and maintainable ❤️

Why use Arrow

  • ☑ Infers types
  • ☑ Leaves your models clean
  • ☑ Handles custom & nested models
  • ☑ Dot and array syntax
  • ☑ Pure Swift, Simple & Lightweight

Example

Swift Model

struct Profile {
    var identifier = 0
    var name = ""
    var link:NSURL?
    var weekday:WeekDay = .Monday
    var stats = Stats()
    var phoneNumbers = [PhoneNumber](https://raw.github.com/freshOS/Arrow/master/)
}

JSON File

{
    "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"
    }]
}

Before (Chaos)

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))
    }
}

After 🎉🎉🎉

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"]
    }
}

Usage

let profile = Profile()
profile.deserialize(json)

Installation

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.

Swift Package Manager

Xcode > File > Swift Packages > Add Package Dependency... > Paste https://github.com/freshOS/Arrow

Carthage - Deprecated

github "freshOS/Arrow"

CocoaPods - Deprecated

target 'MyApp'
pod 'Arrow'
use_frameworks!

How Does That Work

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"]
    }
}

Flexible you said

  • 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"]

Date Parsing

Globally

// 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"]

On a per-key basis

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 ! 🎉

Accessing JSON values

Nested values

value <-- json["nested.nested.nested.nestedValue"]

Object at index

value <-- json[12]

Combine both

value <-- json[1]?["someKey"]?[2]?["something.other"]

Looping on Array

if let collection = json.collection {
    for jsonEntry in collection {
        //Do something
    }
}

Swift Version

  • 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

Acknowledgements

This wouldn't exist without YannickDot, Damien-nd and maxkonovalov

Backers

Like the project? Offer coffee or support us with a monthly donation and help us continue our activities :)

Sponsors

Become a sponsor and get your logo on our README on Github with a link to your site :)

Github

link
Stars: 354

Releases

Swift 5.3 & iOS 9 minimum target - 2020-09-23T08:06:09

Swift Package Manager - 2019-12-24T10:44:04

Swift Package Manager is now the official way to install Arrow. 🎉 Legacy package managers Carthage & Cocoapods are now deprecated in favour of the official way.

Updates Package.swift - 2019-12-23T16:31:04

  • Updates Package.swift

XCode 5.3 & Swift 5.1.3 - 2019-12-13T09:45:18

  • Builds with Xcode 5.3 & Swift 5.1.3

Xcode11 & Swift 5.1 - 2019-09-30T11:00:30

  • Xcode11 & Swift 5.1

Xcode 10.2 & Swift 5 - 2019-04-24T19:56:04

Updates the code to swift 5 🎉

Swift 4.2 & Xcode 10 - 2018-09-18T16:06:49

  • Migrates to Swift 4.2 & Xcode 10 🚀

Swift 4.1 & Xcode 9.3 - 2018-04-10T13:01:25

  • Updated for Swift 4.1 & Xcode 9.3

Swift 4 & Xcode9 - 2017-09-28T12:28:07

Migrates the codeBase to swift 4 :)

Framework built with Xcode 8.3.1 - 2017-04-13T12:21:16

Finer Date Parsing - 2017-02-18T12:24:57

Date Parsing can now use DateFormatter objects allowing for finer control Suggested by @glaurent 👏

Introduces ArrowInitilizable - 2016-11-14T11:49:51

Introduces ArrowInitilizable protocol

3.0.2 - 2016-11-08T07:46:08

  • Make init(json:) available out of the box for ArrowParsable types
  • Support for Dictionary parsing
  • Support for ArrowParsable + RawRepresentable types
  • Use of Any instead of AnyObject
  • Code improvements

Swift 3 is here ! - 2016-09-15T14:47:24

Array of Enum - 2016-08-07T08:39:26

Adds support for Array of Enum parsing \o/

2.0 is here!! - 2016-04-17T17:51:13

Nested values

value <-- json["nested.nested.nested.nestedValue"]

Object at index

value <-- json[12]

Combine both

value <-- json[1]?["someKey"]?[2]?["something.other"]

Looping on Array

if let collection = json.collection {
    for jsonEntry in collection {
        //Do something
    }
}

Custom Date format

createdAt <-- json["created_at"]?.dateFormat("yyyy-MM-dd'T'HH:mm:ssZZZZZ")