Swiftpack.co - Package - thoughtbot/Argo

Argo Carthage compatible Reviewed by Hound

Argo is a library that lets you extract models from JSON or similar structures in a way that's concise, type-safe, and easy to extend. Using Argo, you won't need to write validation code to ensure that incoming data is of the right type, or to make sure required data fields aren't turning up empty. Argo uses Swift's expressive type system to do that for you, and reports back explicit failure states in case it doesn't find what you've told it to expect.

Argo is the Greek word for swift and the name of the ship used by Jason, son of Aeson, of the Argonauts. Aeson is the JSON parsing library in Haskell that inspired Argo, much like Aeson inspired his son Jason.

Version Compatibility

Note that we're aggressive about pushing master forward along with new versions of Swift. Therefore, we highly recommend against pointing at master, and instead using one of the releases we've provided.

Here is the current Swift compatibility breakdown:

| Swift Version | Argo Version | | ------------- | ------------ | | 4.X | master | | 3.X | 4.X | | 2.2, 2.3 | 3.X | | 2.0, 2.1 | 2.X | | 1.2 - 2.0 | 1.X | | 1.1 | 0.3.X |

Installation

Carthage

Add the following to your Cartfile:

github "thoughtbot/Argo"

Then run carthage update.

Follow the current instructions in Carthage's README for up to date installation instructions.

Note that if you are using newer versions of Argo, you will need to link both Argo.framework and Runes.framework into your app.

CocoaPods

Add the following to your Podfile:

pod 'Argo'

You will also need to make sure you're opting into using frameworks:

use_frameworks!

Then run pod install with CocoaPods 0.36 or newer.

Git Submodules

I guess you could do it this way if that's your thing.

Add this repo as a submodule, and add the project file to your workspace. You can then link against Argo.framework for your application target.

You will need to do the same for Runes if you are using newer versions of Argo.

Usage tl;dr:

Please note: the example below requires an additional, external module named Curry which lets us use the curry function to curry User.init.

It also imports Runes, which is a dependency of Argo in newer versions. If you are using an older version of Argo, you might not need that import.

import Argo
import Curry
import Runes

struct User {
  let id: Int
  let name: String
  let email: String?
  let role: Role
  let companyName: String
  let friends: [User]
}

extension User: Decodable {
  static func decode(_ json: JSON) -> Decoded<User> {
    return curry(User.init)
      <^> json <| "id"
      <*> json <| "name"
      <*> json <|? "email" // Use ? for parsing optional values
      <*> json <| "role" // Custom types that also conform to Decodable just work
      <*> json <| ["company", "name"] // Parse nested objects
      <*> json <|| "friends" // parse arrays of objects
  }
}

// Wherever you receive JSON data:

let json: Any? = try? NSJSONSerialization.JSONObjectWithData(data, options: [])

if let j: Any = json {
  let user: User? = decode(j)
}

For more information, see the Documentation

Contributing

See the CONTRIBUTING document. Thank you, contributors!

License

Argo is Copyright (c) 2015 thoughtbot, inc. It is free software, and may be redistributed under the terms specified in the LICENSE file.

About

thoughtbot

Argo is maintained and funded by thoughtbot, inc. The names and logos for thoughtbot are trademarks of thoughtbot, inc.

We love open source software! See our other projects or look at our product case studies and hire us to help build your iOS app.

Github

link
Stars: 3467

Dependencies

Releases

5.0: Swift Compatibility - 2020-05-22 02:16:53

Yes I did get tired of my lazy naming scheme.

5.0 adds explicit support for Swift 5 across all dependency management solutions. There are no other user-facing changes.

4.2: four point two - 2020-05-22 01:46:05

This release (which never hit master, weirdly enough) adds support for the Swift 4.2 and 5.0 toolchains.

4.1.2: The Iteration Generation - 2017-01-24 18:40:08

  • [FIXED]: Now using Iterator instead of Generator in our definition of decode for Collections. This was renamed in Swift 3.0, and honestly I'm not positive how this was compiling the way it was.

4.1.1: An Actual Useable Library - 2016-12-05 19:51:47

  • [FIXED]: Fixed compilation when building via Swift Package Manager

4.1: Optional Packages - 2016-11-05 01:06:54

  • [NEW]: Swift Package Manager Support (Gordon Fontenot)
  • [NEW]: Re-introduced Decoded.optional with better, simplified behavior (Tony DiPasquale)
  • [FIXED]: Use NSNumber transformation properties instead of casting to decode number values. This now prevents a crash that could occur with Swift 3.0.1 (Gordon Fontenot)

4.0.0: Swift 3 and Multi-Error Debugging - 2016-10-13 00:31:57

Official Swift 3.0 release!

  • [NEW]: Now you can see all the decoding failures at once! Thanks @klaaspieter
  • [Bug Fix]: Optional decoding now behaves as expected. Thanks @pteasima for finding this.

Thanks @gfontenot, @alexwlchan, @mbrandonw, @gcox, and @klaaspieter for all the changes that went into this release!

3.1: unsigned unmastered. - 2016-07-29 01:49:41

3.1 adds support for decoding UInt and UInt64 types. UInt can only be decoded JSON.Number instances, and UInt64 can be decoded from JSON.Number as well as JSON.String. This follows the patterns already set up by Int and Int64.

Thanks to @gcox for this addition!

3.0.3: Now With Different XML - 2016-07-22 14:54:08

3.0.3 adds improved support for Xcode 8 by slightly modifying the xml in ways that it suggests (Thanks @ikesyo!)

3.0.2: Xcode optimizations - 2016-07-20 14:56:38

This release is a back-port of our support for enabling whole module optimization (currently supported on master, but unreleased), as well as support for Xcode 8 using Swift 2.3.

3.0.1: NumberWang - 2016-04-08 19:52:21

Argo 3.0 changed the way Booleans were decoded and in doing so, accidentally broke JSON parsing for APIs that didn't quite follow the JSON spec. Specifically, @jshier noted that it's moderately common for APIs to return 1 or 0 instead of true or false..

To address this, we've re-added the capability of Argo to recognize Bool values represented in the JSON as numbers.

3.0: Less is more - 2016-04-06 17:09:46

The goal for Argo 3.0 was to work on simplifying some of the complexity by removing extraneous API and improving consistency between Argo and other libraries (including the Swift standard lib). In addition, we've added support for Swift 2.2.

Breaking Changes

New

Non-Breaking Changes

  • Update errors for RawRepresentable types. - Paul Young
  • Remove CustomStringConvertible constraint on typeMismatch function - Dapeng Gao
  • Use an autoclosure for the rhs of <|> - Gordon Fontenot
  • Generalize the type for sequence taking a dict - Gordon Fontenot

Misc

  • (hopefully) the entire public API now has inline documentation!

Huge thank you to everyone that submitted PRs, opened issues, and reviewed code for this release!

2.3.0: An _Even_ Faster Boat - 2016-03-11 16:40:50

After some really fantastic work by @jshier and @RuiAAPeres, we were able to track down some serious performance issues related to our (internal) use of reduce. @jshier was able to remove all instances of reduce in favor of using for in loops, and ended up with a 2600% improvement in performance. This release is to get that into users hands while we work on moving towards version 3.0, which should introduce even more performance increases as well as reducing the complexity of the library.

  • [FIXED]: Aforementioned performance improvement (Jon Shier and Rui Peres)
  • [NEW]: We've audited the codebase to use @noescape where appropriate (Sid Raval)
  • [NEW]: DecodeError is now Hashable (Matt Diephouse)

2.2.0: Look Ma, I'm on TV! - 2015-10-27 02:16:52

Argo 2.2.0 is out!

[NEW]: Add materialize function for creating Decoded from try, thanks @paulyoung [NEW]: Add tvOS scheme, thanks @nickygerritsen

[IMPROVEMENT]: Improve documentation that Curry is a separate framework, thanks @gilesvangruisen [IMPROVEMENT]: Remove workaround for memory bug in older versions of Swift, thanks @paulyoung

[BUG FIX]: Fix signing errors with simulator builds, thanks @gfontenot

Yay! :tada:

2.1.0: A Little Bit of This and A Little Bitcode of That - 2015-10-03 00:30:10

Argo 2.1.0 coming at you!

[NEW]: decodeWithRootKey convenience function for easy root key decoding [NEW]: Custom error case Decoded.Custom(String) [NEW]: Failure Coalescing Operator for Decoded, thanks @gfontenot [NEW]: catDecoded for Decoded, thanks @gfontenot [NEW]: DecodeError convenience accessor in Decoded, thanks @jshier [NEW]: Default Decodable implementations for String and Int RawRepresentable enums, thanks @swizzlr

[IMPROVEMENT]: Documentation!!!!, thanks @jnutting & @gfontenot [IMPROVEMENT]: Extend CollectionType instead of Array, thanks @gfontenot & @gilesvangruisen [IMPROVEMENT]: Extend DictionaryLiteralConvertable instead of Dictionary, thanks @gilesvangruisen

[BUG FIX]: Fix bitcode error when submitting app, thanks @dmcrodrigues

Big win!

1.0.5: Argo 1.0.4 & Runes 2.0 - 2015-09-21 17:56:26

This release changed the Runes dependency to keep it in Runes 2.0. This prevents Carthage from pulling Runes 3 when using Argo 1.0.4.

2.0.0: All For One and Argo 2 for All! - 2015-09-18 21:02:52

Argo 2.0.0 is out!!

  • [NEW]: Swift 2.0 support
  • [NEW]: watchOS targets, thanks @JaviSoto
  • [NEW]: Alternative operator <|> for providing defaults or alternatives, thanks @terhechte
  • [NEW]: Add DecodeError enum for easier conversion to Result, thanks @gfontenot
  • [NEW]: dematerialize function to throw when Decoded is a DecodeError, thanks @paulyoung
  • [NEW]: Default Decodable implementations for String and Int RawRepresentable enums, thanks @swizzlr
  • [IMPROVEMENT]: Remove Box & Runes dependency, thanks @sync & @gfontenot
  • [IMPROVEMENT]: Exposed flatReduce & decodeJSON functions, thanks @edwardaux
  • [IMPROVEMENT]: Performance and Memory impact, thanks @paulyoung
  • [IMPROVEMENT]: Argo operators are overloaded to return Optional as well as Decoded

And thank you to all those not mentioned above for you commits to help Argo 2.0.0 become reality! @sidraval, @nickygerritsen, @lowell, and @jdhealy

ford_dance

1.0.4 - Public Sequence Number One - 2015-07-15 17:31:59

Make sequence public for use with complex decoding.

1.0.3: A Faster Boat - 2015-05-26 17:58:31

Added performance enhancements to make decoding faster.

1.0.2: Better Descriptions for a Better Tomorrow - 2015-05-20 21:43:07

This adds Printable conformance to Decoded for easier debugging using println.

1.0.1: If You Gaze Into .Null, .Null Gazes Also Into You - 2015-05-01 19:06:09

Always decode JSON.Null into Decoded.MissingKey(keyName).

1.0.0: The Golden Fleece - 2015-04-27 22:54:29

The official 1.0.0 release of Argo. Includes a new Decoded type that allows you to retain decoding failure information for debugging purposes. Also, the new global decode function helps you quickly decode your model objects from the AnyObject returned from NSJSONSerialization.

0.4.3: Beta 3 compatibility - 2015-03-13 14:57:23

This is a small compatibility release for Swift 1.2 Beta 3. The only change is that we've internally updated to Runes 1.2.1, which removed the (now) duplicate definitions of flatMap.

0.4.2: :punch: :32bit: - 2015-02-18 16:31:58

This release adds a workaround for compiler issues in Swift 1.2 on 32 bit systems that causes an EXC_BAD_ACCESS crash when using partial application of static generic protocol functions, which is just about the weirdest phrase I've ever had to say out loud.

0.3.4: Pinball Wizard - 2015-02-17 16:48:00

This release pins Runes to 1.1.1 for Carthage. This ensures that the pre-built binaries installed with Carthage are compatible with Swift 1.1

0.3.3: Swift 1.1 support for Floats - 2015-02-16 16:51:50

This is a bug fix update for Swift 1.1 that corresponds to the 0.4.1 release for Swift 1.2

0.4.1: They All Float Down Here - 2015-02-16 16:40:47

This adds JSONDecodable support for Float properties. Not sure why we didn't do this earlier.

As an added bonus, we've also enabled the ability to use Argo inside app extensions.

0.4.0: Back to the Future - 2015-02-16 16:33:47

This release adds support for Swift 1.2

0.3.2: Pure - 2015-02-16 15:58:45

We're now using the version of pure that comes with Runes.

0.3.1: Functionally Fixing Bugs - 2015-02-16 15:55:49

We were using flatMap in a few places that we should have used map. This boneheaded mistake was causing segfaults for some users so we went ahead and fixed it.

0.3.0: Dependencies for your Dependencies - 2015-02-16 15:52:42

This release removes the functional operators from Argo, and extracts them to Runes. This should help avoid duplicate operator definitions by introducing a common dependency for libraries that want to use these operators.