{"id":2997,"url":"https://github.com/nickoneill/Pantry","last_synced_at":"2025-08-03T12:31:59.393Z","repository":{"id":62450461,"uuid":"45002662","full_name":"nickoneill/Pantry","owner":"nickoneill","description":"The missing light persistence layer for Swift","archived":false,"fork":false,"pushed_at":"2018-05-30T12:21:06.000Z","size":139,"stargazers_count":832,"open_issues_count":15,"forks_count":55,"subscribers_count":19,"default_branch":"master","last_synced_at":"2024-05-30T02:37:32.593Z","etag":null,"topics":[],"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/nickoneill.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":"2015-10-26T22:58:27.000Z","updated_at":"2024-05-30T02:37:32.594Z","dependencies_parsed_at":"2022-11-01T23:17:09.737Z","dependency_job_id":null,"html_url":"https://github.com/nickoneill/Pantry","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickoneill%2FPantry","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickoneill%2FPantry/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickoneill%2FPantry/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickoneill%2FPantry/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nickoneill","download_url":"https://codeload.github.com/nickoneill/Pantry/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228543252,"owners_count":17934450,"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":[],"created_at":"2024-01-05T20:16:28.528Z","updated_at":"2024-12-07T00:31:12.290Z","avatar_url":"https://github.com/nickoneill.png","language":"Swift","funding_links":[],"categories":["Utility","Uncategorized","Other"],"sub_categories":["Web View","Uncategorized","Other free courses","Mathematics"],"readme":"## If you're planning on using Swift 4 in the near future, please consider using the new [Codable](https://developer.apple.com/documentation/swift/codable) protocols which provide the same functionality as Pantry in the core Swift library. Pantry will not be supported going forward.\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"http://raquo.net/images/banner-pantry.png\" alt=\"Storage\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/platform-iOS%208%2B-blue.svg?style=flat\" alt=\"Platform: iOS 8+\" /\u003e\n    \u003ca href=\"https://developer.apple.com/swift\"\u003e\u003cimg src=\"https://img.shields.io/badge/language-swift3-f48041.svg?style=flat\" alt=\"Language: Swift 3\" /\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/Carthage/Carthage\"\u003e\u003cimg src=\"https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat\" alt=\"Carthage compatible\" /\u003e\u003c/a\u003e\n    \u003ca href=\"https://cocoapods.org/pods/Pantry\"\u003e\u003cimg src=\"https://cocoapod-badges.herokuapp.com/v/Pantry/badge.png\" alt=\"CocoaPods compatible\" /\u003e\u003c/a\u003e\n    \u003ca href=\"http://cocoadocs.org/docsets/Pantry\"\u003e\u003cimg src=\"https://img.shields.io/cocoapods/metrics/doc-percent/Pantry.svg\" alt=\"Docs\" /\u003e\u003c/a\u003e\n    \u003cimg src=\"http://img.shields.io/badge/license-MIT-lightgrey.svg?style=flat\" alt=\"License: MIT\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"#installation\"\u003eInstallation\u003c/a\u003e\n  • \u003ca href=\"https://github.com/nickoneill/Pantry/issues\"\u003eIssues\u003c/a\u003e\n  • \u003ca href=\"#license\"\u003eLicense\u003c/a\u003e\n\u003c/p\u003e\n\n#### Please join us in [issues](https://github.com/nickoneill/Pantry/issues) if you'd like to help us get to 1.0. And read about more [use cases for Pantry](https://medium.com/ios-os-x-development/the-missing-light-persistence-layer-for-swift-35ce75d02d47).\n\nPantry is a lightweight way to persist structs containing user data, cached content or other relevant objects for later retrieval.\n\n```swift\nlet someCustomStruct = SomeCustomStruct(...)\nPantry.pack(someCustomStruct, \"user_data\")\n\n... later ...\n\nif let unpackedCustomStruct: SomeCustomStruct = Pantry.unpack(\"user_data\") {\n  print(\"got my data out\",unpackedCustomStruct)\n} else {\n  print(\"there was no struct data to get\")\n}\n```\n\nYou can store:\n* [x] Structs\n* [x] Strings, Ints and Floats (our default types)\n* [x] Arrays of structs and default types\n* [x] Nested structs\n* [ ] Nested Arrays\n* [x] Classes\n* [x] Arrays of classes and default types\n* [x] Nested classes\n* [x] Enums with raw types\n\nCheck out [the tests](https://github.com/nickoneill/Pantry/blob/master/PantryTests/) for a detailed look at the varied types you can easily store.\n\n## Compatibility\n\nPantry requires iOS 8+ and is compatible with **Swift 3** projects. Please use release `0.2.2` for the final Swift 2.x supported version, or the `swift2` branch. Objective-C support is unlikely.\n\n## Installation\n\nInstallation for [Carthage](https://github.com/Carthage/Carthage) is simple enough:\n\n`github \"nickoneill/Pantry\" ~\u003e 0.3`\n\nAs for [CocoaPods](https://cocoapods.org), use this to get the latest release:\n\n```ruby\nuse_frameworks!\n\npod 'Pantry'\n```\n\nAnd `import Pantry` in the files you'd like to use it.\n\n## Usage\n\n### Basic types\nPantry provides serialization of some basic types (`String`, `Int`, `Float`, `Bool`) with no setup. You can use it as a simple expiring cache like this:\n\n```swift\nif let available: Bool = Pantry.unpack(\"promptAvailable\") {\n    completion(available: available)\n} else {\n    anExpensiveOperationToDetermineAvailability({ (available) -\u003e () in\n      Pantry.pack(available, key: \"promptAvailable\", expires: .Seconds(60 * 10))\n      completion(available: available)\n    })\n}\n```\n\n### Automagic Persistent Variables\nUse Swift's get/set to automatically persist the value of a variable on write and get the latest value on read.\n\n```swift\nvar autopersist: String? {\n    set {\n        if let newValue = newValue {\n            Pantry.pack(newValue, key: \"autopersist\")\n        }\n    }\n    get {\n        return Pantry.unpack(\"autopersist\")\n    }\n}\n\n...later...\n\nautopersist = \"Hello!\"\n// restart app, reboot phone, etc\nprint(autopersist) // Hello!\n```\n\n### Structs\nAdd the `Storable` protocol to any struct you want stored and then ensure they comply by implementing an `init` method that gets each property from the warehouse, and a `toDictionary` method that converts the other way:\n```swift\nstruct Basic: Storable {\n    let name: String\n    let age: Float\n    let number: Int\n\n    init(warehouse: Warehouseable) {\n        self.name = warehouse.get(\"name\") ?? \"default\"\n        self.age = warehouse.get(\"age\") ?? 20.5\n        self.number = warehouse.get(\"number\") ?? 10\n    }\n\n    func toDictionary() -\u003e [String : Any] {\n        return [ \"name\": self.name, \"age\": self.age, \"number\": self.number ]\n    }\n}\n```\n\nGetters always provide an optional value, leaving you the opportunity to fill in a default if a value isn't available. This makes for hassle-free property additions to your structs.\n\n### Classes\n\nClasses are also supported and can be setup the same way Structs are however the init method must be marked `required` in this case. Class inheritance and nested `Storable` properties are also possible:\n```swift\nclass ModelBase: Storable {\n    let id: String\n\n    required init(warehouse: Warehouseable) {\n        self.id = warehouse.get(\"id\") ?? \"default_id\"\n    }\n\n    func toDictionary() -\u003e [String : Any] {\n        return [ \"id\": self.id ]\n    }\n}\n\nclass BasicClassModel: ModelBase {\n    let name: String\n    let age: Float\n    let number: Int\n\n    required init(warehouse: Warehouseable) {\n        self.name = warehouse.get(\"name\") ?? \"default\"\n        self.age = warehouse.get(\"age\") ?? 20.5\n        self.number = warehouse.get(\"number\") ?? 10\n\n        super.init(warehouse: warehouse)\n    }\n\n    func toDictionary() -\u003e [String : Any] {\n        var dictionary = super.toDictionary()\n        dictionary[\"name\"] = self.name\n        dictionary[\"age\"] = self.age\n        dictionary[\"number\"] = self.number\n        return dictionary\n    }\n}\n```\n\n## Also\n\nPantry works great with network data when paired with a JSON struct decoder such as [Unbox](https://github.com/JohnSundell/Unbox). Download JSON, decode it with Unbox, save it with Pantry and have it available for as long as you need. The architecture of Pantry is heavily influenced by Unbox, it's worth a look in any case.\n\n## License\n\nPantry uses the MIT license. Please file an issue if you have any questions or if you'd like to share how you're using this tool.\n\n## ack\n\nPantry \"can icon\" by [CDH from the Noun Project](https://thenounproject.com/term/soup-can/49680/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnickoneill%2FPantry","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnickoneill%2FPantry","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnickoneill%2FPantry/lists"}