{"id":44498107,"url":"https://github.com/iwasrobbed/LazyObject","last_synced_at":"2026-02-25T14:00:57.159Z","repository":{"id":56919638,"uuid":"59387526","full_name":"iwasrobbed/LazyObject","owner":"iwasrobbed","description":"Lazily deserialize JSON into strongly typed Swift objects","archived":false,"fork":false,"pushed_at":"2017-03-27T23:43:16.000Z","size":49,"stargazers_count":11,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-10-23T01:41:55.497Z","etag":null,"topics":["deserialization","deserialize","json","lazy","network","response","swift"],"latest_commit_sha":null,"homepage":null,"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/iwasrobbed.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-05-22T00:22:59.000Z","updated_at":"2022-11-16T07:38:36.000Z","dependencies_parsed_at":"2022-08-21T04:20:18.699Z","dependency_job_id":null,"html_url":"https://github.com/iwasrobbed/LazyObject","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/iwasrobbed/LazyObject","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iwasrobbed%2FLazyObject","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iwasrobbed%2FLazyObject/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iwasrobbed%2FLazyObject/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iwasrobbed%2FLazyObject/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/iwasrobbed","download_url":"https://codeload.github.com/iwasrobbed/LazyObject/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iwasrobbed%2FLazyObject/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29774447,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-24T04:54:30.205Z","status":"ssl_error","status_checked_at":"2026-02-24T04:53:58.628Z","response_time":75,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["deserialization","deserialize","json","lazy","network","response","swift"],"created_at":"2026-02-13T06:02:27.888Z","updated_at":"2026-02-25T14:00:57.152Z","avatar_url":"https://github.com/iwasrobbed.png","language":"Swift","funding_links":[],"categories":["Parsing"],"sub_categories":[],"readme":"## LazyObject\n[![Coverage Status](https://coveralls.io/repos/github/iwasrobbed/LazyObject/badge.svg?branch=master)](https://coveralls.io/github/iwasrobbed/LazyObject?branch=master)\n[![Build Status](https://travis-ci.org/iwasrobbed/LazyObject.svg?branch=master)](https://travis-ci.org/iwasrobbed/LazyObject)\n[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/iwasrobbed/LazyObject/blob/master/LICENSE)\n[![CocoaPods](https://img.shields.io/cocoapods/v/LazyObject.svg?maxAge=2592000)]()\n[![Swift](https://img.shields.io/badge/language-Swift-blue.svg)](https://swift.org)\n\nLazily deserialize JSON into strongly typed Swift objects, with a few getter style options.\n\nIs your app using it? [Let me know!](mailto:rob@desideratalabs.co)\n\n### Installation\n\nQuickly install using [CocoaPods](https://cocoapods.org): \n\n```ruby\npod 'LazyObject'\n```\n\nOr manually install:\n\n1. Clone this repository\n2. Build the LazyObject project\n3. Add the resulting framework file to your project\n4. ?\n5. Profit\n\n### API\n\nLet's look at an example model to show off some of the functionality:\n\n```swift\nclass Bank: LazyObject {\n    var money: Double       { return try! objectFor(#function) } // Automagically converts #function to a \"money\" string\n    var getPaid: Bool?      { return try? objectFor(\"get_paid\") } // Will be nil if called and key/value don't exist\n    var security: [Person]? { return try? objectFor(#function) } // Works with arrays of other LazyObjects as well\n    var debt: Double        { return try! objectFor(\"accounting.books.cooked\") } // Nested key paths are supported \n}\n```\n\nModels are instantiated from JSON dictionaries:\n\n```swift\n// The dictionary passed here is the JSON response\nlet bank = Bank(dictionary: [\"money\": 9999, \"get_paid\": true])\n```\n\nThere is also a convenience extension for instantiating from JSON arrays:\n\n```swift\nlet banks = Bank.fromArray(jsonArrayOfDictionaries)\n```\n\n### Date Formattables\n\nSince many services have varying date formats, LazyObject provides an easy way to specify which standard or custom format you'd like to conform to.\n\n```swift\nclass Retirement: LazyObject, ISO8601Formattable {\n  var date: NSDate?   { return try? dateFor(#function) }\n}\n```\n\n**Note**: For dates, you must specifically use the `dateFor()` method so it will choose the correct formatter from the cache.\n\nAny of your base or sub-classes can conform to *one* of the supported protocols:\n\n* ISO8601Formattable (e.g. \"2016-04-24T14:42:42.424Z\")\n* RFC3339Formattable (e.g. \"2016-04-24T14:42:42Z\")\n* RFC1123Formattable (e.g. \"Sun, 24 Apr 2016 14:42:42 +0000\")\n* RFC850Formattable (e.g. \"Sunday, 24-Apr-16 14:42:42 UTC\")\n* EpochFormattable (e.g. \"1461508962.424\" as a string or 1461508962.424 as a double)\n\nOr you're free to extend `LazyDateFormattable` to create custom date conversions (look at how the above protocols are implemented for an example).\n\nAll formatters above are created once and cached for re-use, and it is recommended you do the same if you create custom formattables since they tend to be expensive to create.\n\n### Key Getter Options\n\nThe `objectFor` method supports a couple variations for key names:\n\n- `#function`: Converts whatever the property name is into a string (e.g. `var help` becomes `\"help\"`). Note that a property name like `myProperty` will be converted to `\"myProperty\"` not `my_property`, so feel free to extend LazyObject if you require that.\n- `keyPath`: Can be a string containing a single key like `first_name` or a key path to a nested value like `location.latitude`\n\n### Optionals\n\nNotice in the example that you can use `try?` to ensure optional safety on the properties. If you're feeling confident, you can use `try!` to force it but you may receive one of a few runtime errors if it doesn't succeed.\n\n### Convertibles\n\nAside from standard JSON data types, the following types are seamlessly supported:\n\n* NSDate\n* NSURL\n* NSNumber\n\n### Custom Convertibles\n\nIf you want to seamlessly convert a custom value, such as to create an `NSNumber` from a string value, you can create your own extensions of `LazyConvertible` like so:\n\n```swift\n// Note: this example is actually already part of the library, so no need to extend NSNumber\n\nimport Foundation\n\nextension NSNumber: LazyConvertible {\n\n    public static func convert(value: AnyObject?) throws -\u003e NSNumber {\n        guard let string = value as? String else {\n            throw LazyMappingError.UnexpectedTypeError(value: value, type: String.self)\n        }\n\n        let formatter = NSNumberFormatter()\n        guard let number = formatter.numberFromString(string) else {\n            throw LazyMappingError.CustomError(message: \"'\\(string)' is not a valid input for NSNumber instantiation\")\n        }\n\n        return number\n    }\n\n}\n```\n\nThis will allow you to seamlessly support any type of valid `NSNumber`, whether from string or from a number value, just by using the normal `objectFor` methods.\n\n### Setting Values\n\nLazyObject is focused mostly on read-only models, but you can still easily expose a setter on the model if necessary:\n\n```swift\nclass Object: LazyObject {\n    var id: NSNumber? {\n        get {\n            return try? objectFor(#function)\n        }\n        set {\n            setObject(newValue, setter: #function)\n        }\n    }\n}\n```\n\nNote: Similar to the [getter methods](#key-getter-options), both the setter `#function` can be used or the `keyPath` can be used to reference the key name to update.\n\n### Supports\nSwift, ARC \u0026 iOS 9+\n\n### A little help from my friends\nPlease feel free to fork and create a pull request for bug fixes or improvements, being sure to maintain the general coding style, adding tests, and adding comments as necessary.\n\n### Credit\nThis library is influenced by [CottonObject](https://github.com/hermiteer/CottonObject) and [Mapper](https://github.com/lyft/mapper)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiwasrobbed%2FLazyObject","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fiwasrobbed%2FLazyObject","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiwasrobbed%2FLazyObject/lists"}