Home

Awesome

<p align="center"> <img src="https://raw.githubusercontent.com/ra1028/Alembic/master/Assets/Alembic_Logo.png" alt="Alembic" width="70%"> </p> <H4 align="center">Functional JSON Parser</H4> </br> <p align="center"> <a href="https://developer.apple.com/swift"><img alt="Swift4" src="https://img.shields.io/badge/language-swift4-orange.svg?style=flat"/></a> <a href="https://travis-ci.org/ra1028/Alembic"><img alt="Build Status" src="https://travis-ci.org/ra1028/Alembic.svg?branch=master"/></a> <a href="https://codebeat.co/projects/github-com-ra1028-alembic"><img alt="CodeBeat" src="https://codebeat.co/badges/09cc20c0-4cba-4c78-8e20-39f41d86c587"/></a> </p> </br> <p align="center"> <a href="https://cocoapods.org/pods/Alembic"><img alt="CocoaPods" src="https://img.shields.io/cocoapods/v/Alembic.svg"/></a> <a href="https://github.com/Carthage/Carthage"><img alt="Carthage" src="https://img.shields.io/badge/Carthage-compatible-yellow.svg?style=flat"/></a> <a href="https://github.com/apple/swift-package-manager"><img alt="Swift Package Manager" src="https://img.shields.io/badge/SwiftPM-compatible-blue.svg"/></a> </p> </br> <p align="center"> <a href="https://developer.apple.com/swift/"><img alt="Platform" src="https://img.shields.io/badge/platform-iOS%20%7C%20OSX%20%7C%20tvOS%20%7C%20watchOS%20%7C%20Linux-green.svg"/></a> <a href="https://github.com/ra1028/Alembic/blob/master/LICENSE"><img alt="Lincense" src="http://img.shields.io/badge/license-MIT-000000.svg?style=flat"/></a> </p>

Feature


Requirements


Installation

CocoaPods

Add the following to your Podfile:

use_frameworks!

target 'TargetName' do
  pod 'Alembic'
end

Carthage

Add the following to your Cartfile:

github "ra1028/Alembic"

Swift Package Manager

Add the following to your Package.swift:

// swift-tools-version:4.0

let package = Package(
    name: "ProjectName",
    dependencies : [
        .package(url: "https://github.com/ra1028/Alembic.git", .upToNextMajor(from: "3"))
    ]
)

Example

In example, parse the following JSON:

{
    "teams": [
        {
            "name": "Team ra1028",
            "url": "https://github.com/ra1028",
            "members": [
                {
                    "name": "Ryo Aoyama",
                    "age": 23
                },
                {
                    "name": "John Doe",
                    "age": 30
                }
            ]
        }
    ]
}

Make the JSON instance from Any, Data or String type JSON object.

// from `Any` type JSON object
let json = JSON(object)
// from JSON Data
let json = try JSON(data: data)
// from JSON String
let json = try JSON(string: string)

Parse value from JSON:

Parse the values type-safely

let memberName: String = try json.value(for: ["teams", 0, "members", 0, "name"])

Parse nullable value

let missingText: String? = try json.option(for: "missingKey")

Parse value from JSON with transforming:

Transform value using various monadic functions.

let teamUrl: URL = try json.parse(String.self, for: ["teams", 0, "url"])
        .filterMap(URL.init(string:))
        .value()

Transform nullable value if exist

let missingUrl: URL? = try json.parse(String.self, for: "missingKey")
        .filterMap(URL.init(string:))
        .option()

Mapping to model from JSON:

All types conforming to Parsable protocol and it's Array, Dictionary can be parsed.

struct Member: Parsable {
    let name: String
    let age: Int

    static func value(from json: JSON) throws -> Member {
        return try .init(
            name: json.value(for: "name"),
            age: json.value(for: "age")
        )
    }
}

extension URL: Parsable {
    public static func value(from json: JSON) throws -> URL {
        guard let url = try URL(string: json.value()) else {
            throw JSON.Error.dataCorrupted(value: json.rawValue, description: "The value was not valid url string.")
        }
        return url
    }
}

struct Team: Parsable {
    let name: String
    let url: URL
    let members: [Member]

    static func value(from json: JSON) throws -> Team {
        return try .init(
            name: json.value(for: "name"),
            url: json.value(for: "url"),
            members: json.value(for: "members")
        )
    }
}
let team: Team = try json.value(for: ["teams", 0])

Tips

The types conformed to Parsable as default.

JSON
String
Int
UInt
Double
Float
Bool
NSNumber
Int8
UInt8
Int16
UInt16
Int32
UInt32
Int64
UInt64
Decimal
Array where Element: Parsable
Dictionary where Key == String, Value: Parsable
Optional where Wrapped: Parsable

Conform to Parsable with initializer

struct Member: ParseInitializable {
    let name: String
    let age: Int

    init(with json: JSON) throws {
        name = try json.value(for: "name")
        age = try json.value(for: "age")
    }
}

Usage Reference Files

Functional operators for value transforming:

Errors

More Example

See the Test files


Playground

  1. Open Alembic.xcworkspace.
  2. Build the Alembic for Mac.
  3. Open Alembic playground in project navigator.

Contribution

Welcome to fork and submit pull requests!

Before submitting pull request, please ensure you have passed the included tests. If your pull request including new function, please write test cases for it.


License

Alembic is released under the MIT License.