{"id":1728,"url":"https://github.com/utahiosmac/Marshal","last_synced_at":"2025-08-02T04:32:27.441Z","repository":{"id":47459247,"uuid":"52461877","full_name":"utahiosmac/Marshal","owner":"utahiosmac","description":"Marshaling the typeless wild west of [String: Any]","archived":false,"fork":false,"pushed_at":"2023-08-10T06:28:04.000Z","size":805,"stargazers_count":697,"open_issues_count":25,"forks_count":63,"subscribers_count":19,"default_branch":"master","last_synced_at":"2024-04-23T19:18:31.190Z","etag":null,"topics":["apple-tv","apple-watch","ios","json","mac","swift"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/utahiosmac.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2016-02-24T17:41:09.000Z","updated_at":"2024-04-03T01:41:38.000Z","dependencies_parsed_at":"2023-02-14T14:46:35.828Z","dependency_job_id":"1cb1826c-6665-4461-a3b3-c97a611477ce","html_url":"https://github.com/utahiosmac/Marshal","commit_stats":{"total_commits":172,"total_committers":20,"mean_commits":8.6,"dds":0.7034883720930232,"last_synced_commit":"eeed9576270c93acf2cc5166f664d394075461d3"},"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/utahiosmac%2FMarshal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/utahiosmac%2FMarshal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/utahiosmac%2FMarshal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/utahiosmac%2FMarshal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/utahiosmac","download_url":"https://codeload.github.com/utahiosmac/Marshal/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228439110,"owners_count":17920018,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apple-tv","apple-watch","ios","json","mac","swift"],"created_at":"2024-01-05T20:15:54.394Z","updated_at":"2024-12-06T08:31:32.166Z","avatar_url":"https://github.com/utahiosmac.png","language":"Swift","funding_links":[],"categories":["Parsing"],"sub_categories":["JSON","Other free courses"],"readme":"![](Logo/Logo.png)\n\n![License](https://img.shields.io/dub/l/vibe-d.svg)\n![Carthage](https://img.shields.io/badge/Carthage-compatible-brightgreen.svg)\n![Platforms](https://img.shields.io/badge/Platform-iOS%20%7C%20watchOS%20%7C%20tvOS%20%7C%20OS%20X-lightgrey.svg)\n[![Build Status](https://travis-ci.org/utahiosmac/Marshal.svg?branch=master)](https://travis-ci.org/utahiosmac/Marshal)\n[![codebeat badge](https://codebeat.co/badges/8a60765a-0a0f-47b4-8bca-d75adc462836)](https://codebeat.co/projects/github-com-utahiosmac-marshal)\n\n# Marshal\n\nIn 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™__.\n\n## Usage\n\nExtracting values from `[String: Any]` using Marshal is as easy as\n\n```swift\nlet name: String = try json.value(for: \"name\")\nlet url: URL = try json.value(for: \"user.website\") // extract from nested objects!\n```\n\n## Converting to Models\n\n[Unmarshaling](https://en.wikipedia.org/wiki/Marshalling_(computer_science)) 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.\n\nOften 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:\n\n```swift\nstruct User: Unmarshaling {\n    var id: Int\n    var name: String\n    var email: String\n\n    init(object: MarshaledObject) throws {\n        id = try object.value(for: \"id\")\n        name = try object.value(for: \"name\")\n        email = try object.value(for: \"email\")\n    }\n}\n```\n\nNow, just by virtue of supplying a simple initializer you can *pull your models directly out of `[String: Any]`*!\n\n```swift\nlet users: [User] = try json.value(for: \"users\")\n```\n\nThat was easy! Thanks, Protocol Oriented Programming™!\n\n## Error Handling\n\nAre 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.\n\n\n## Add Your Own Values\n\nOut 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.\n\nHowever, 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`.\n\n```swift\nextension Date : ValueType {\n    public static func value(from object: Any) throws -\u003e Date {\n        guard let dateString = object as? String else {\n            throw MarshalError.typeMismatch(expected: String.self, actual: type(of: object))\n        }\n        // assuming you have a Date.fromISO8601String implemented...\n        guard let date = Date.fromISO8601String(dateString) else {\n            throw MarshalError.typeMismatch(expected: \"ISO8601 date string\", actual: dateString)\n        }\n        return date\n    }\n}\n```\n\nBy simply implementing `value(from:)`, Marshal allows you to immediately do this:\n\n```swift\nlet birthDate: Date = json.value(for: \"user.dob\")\n```\n\nProtocol Oriented Programming™ strikes again!\n\n## Back to the Marshaled Object\n\nWe've looked at going from our `[String: Any]` into our local models, but what about the other way around?\n\n```swift\nextension User: Marshaling {\n    func marshaled() -\u003e [String: Any] {\n        return {\n            \"id\": id,\n            \"name\" : name,\n            \"email\": email\n        }\n    }\n}\n```\n\nNow, 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.](https://developer.apple.com/swift/blog/?id=37)\n\n# Performance\n\nOf 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](https://github.com/bwhiteley/JSONShootout) for a bit anyway.\n\n\n# Contributors\n\n`Marshal` began as a [blog series on JSON parsing by Jason Larsen](http://jasonlarsen.me/2015/10/16/no-magic-json-pt3.html), 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:\n\n* Bart Whiteley\n* Brian Mullen\n* Derrick Hathaway\n* Dave DeLong\n* Jason Larsen\n* Mark Schultz\n* Nate Bird\n* Tim Shadel\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Futahiosmac%2FMarshal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Futahiosmac%2FMarshal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Futahiosmac%2FMarshal/lists"}