Description
In Swift, we all deal with JSON, plists, and various forms of [String: Any]. Marshal believes you don't need a Ph.D. in monads or magic mirrors to deal with these in an expressive and type safe way. Marshal will help you write declarative, performant, error handled code using the power of Protocol Oriented Programming™.
Marshal alternatives and similar libraries
Based on the "JSON" category.
Alternatively, view Marshal alternatives based on common mentions on social networks and blogs.
-
HandyJSON
A handy swift json-object serialization/deserialization library -
AlamofireObjectMapper
An Alamofire extension which converts JSON response data into swift objects using ObjectMapper -
Gloss
[Deprecated] A shiny JSON parsing library in Swift :sparkles: Loved by many from 2015-2021 -
EVReflection
Reflection based (Dictionary, CKRecord, NSManagedObject, Realm, JSON and XML) object mapping with extensions for Alamofire and Moya with RxSwift or ReactiveSwift -
Decodable
[Probably deprecated] Swift 2/3 JSON unmarshalling done (more) right -
JSONHelper
✌ Convert anything into anything in one operation; JSON data into class instances, hex strings into UIColor/NSColor, y/n strings to booleans, arrays and dictionaries of these; anything you can make sense of! -
Genome
A simple, type safe, failure driven mapping library for serializing JSON to models in Swift 3.0 (Supports Linux) -
CodableAlamofire
An extension for Alamofire that converts JSON data into Decodable objects. -
Elevate
Elevate is a JSON parsing framework that leverages Swift to make parsing simple, reliable and composable. -
JSONNeverDie
Auto reflection tool from JSON to Model, user friendly JSON encoder / decoder, aims to never die -
ModelRocket
An iOS framework for creating JSON-based models. Written in Swift. -
Tailor
:necktie:A super fast & convenient object mapper tailored for your needs -
AlamofireJsonToObjects
An Alamofire extension which converts JSON response data into swift objects using EVReflection -
Brick
:droplet: A generic view model for both basic and complex scenarios -
PPJSONSerialization
The Ultimate JSON Serialization for Swift. -
JSONParserSwift
Framework for easily parsing your JSON data directly to Swift object. -
SafeDecoder
A Codable extension to decode arrays and to catch & log all decoding failures
Appwrite - The Open Source Firebase alternative introduces iOS support
* Code Quality Rankings and insights are calculated and provided by Lumnify.
They vary from L1 to L5 with "L5" being the highest.
Do you think we are missing an alternative of Marshal or a related project?
README
[](Logo/Logo.png)
Marshal
In Swift, we all deal with JSON, plists, and various forms of [String: Any]
. Marshal
believes you don't need a Ph.D. in monads or magic mirrors to deal with these in an expressive and type safe way. Marshal
will help you write declarative, performant, error handled code using the power of Protocol Oriented Programming™.
Usage
Extracting values from [String: Any]
using Marshal is as easy as
let name: String = try json.value(for: "name")
let url: URL = try json.value(for: "user.website") // extract from nested objects!
Converting to Models
Unmarshaling is the process of taking an intermediary data format (the marshaled object) and tranforming it into a local representation. Think of marshaling as serialization and unmarshaling as deserialization, or coding and decoding, respectively.
Often we want to take a marshaled object (like [String: Any]
) and unmarshal it into one of our local models—for example we may want to take some JSON and initialize one of our local models with it:
struct User: Unmarshaling {
var id: Int
var name: String
var email: String
init(object: MarshaledObject) throws {
id = try object.value(for: "id")
name = try object.value(for: "name")
email = try object.value(for: "email")
}
}
Now, just by virtue of supplying a simple initializer you can pull your models directly out of [String: Any]
!
let users: [User] = try json.value(for: "users")
That was easy! Thanks, Protocol Oriented Programming™!
Error Handling
Are you the shoot-from-the-hip type that doesn't care about errors? Use try?
to give yourself an optional value. Otherwise, join us law-abiding folks and wrap your code in a do-catch
to get all the juicy details when things go wrong.
Add Your Own Values
Out of the box, Marshal
supports extracting native Swift types like String
, Int
, etc., as well as URL
, anything conforming to Unmarshaling
, and arrays of all the aforementioned types. It does not support extraction of more complex types such as Date
due to the wide variety of date formats, etc.
However, Marshal doesn't just leave you up the creek without a paddle! Adding your own Marshal value type is as easy as extending your type with ValueType
.
extension Date : ValueType {
public static func value(from object: Any) throws -> Date {
guard let dateString = object as? String else {
throw MarshalError.typeMismatch(expected: String.self, actual: type(of: object))
}
// assuming you have a Date.fromISO8601String implemented...
guard let date = Date.fromISO8601String(dateString) else {
throw MarshalError.typeMismatch(expected: "ISO8601 date string", actual: dateString)
}
return date
}
}
By simply implementing value(from:)
, Marshal allows you to immediately do this:
let birthDate: Date = json.value(for: "user.dob")
Protocol Oriented Programming™ strikes again!
Back to the Marshaled Object
We've looked at going from our [String: Any]
into our local models, but what about the other way around?
extension User: Marshaling {
func marshaled() -> [String: Any] {
return {
"id": id,
"name" : name,
"email": email
}
}
}
Now, you might be thinking "but couldn't I use reflection to do this for me automagically?" You could. And if you're into that, there are some other great frameworks for you to use. But Marshal believes mirrors can lead down the road to a world of hurt. Marshal lives in a world where What You See Is What You Get™, and you can easily adapt to APIs that snake case, camel case, or whatever case your backend developers are into. Marshal code is explicit and declarative. But don't just take Marshal's word for it—read the good word towards the end here on the official Swift blog.
Performance
Of course, Marshal wouldn't be the Marshal if it didn't have some of the fastest guns in the West. You should always take benchmarks with a grain of salt, but chew on these benchmarks for a bit anyway.
Contributors
Marshal
began as a blog series on JSON parsing by Jason Larsen, but quickly evolved into a community project. A special thanks to the many people who have contributed at one point or another to varying degrees with ideas and code. A few of them, in alphabetical order:
- Bart Whiteley
- Brian Mullen
- Derrick Hathaway
- Dave DeLong
- Jason Larsen
- Mark Schultz
- Nate Bird
- Tim Shadel
*Note that all licence references and agreements mentioned in the Marshal README section above
are relevant to that project's source code only.