{"id":18332483,"url":"https://github.com/cellular/localstorage-swift","last_synced_at":"2025-04-06T03:33:47.412Z","repository":{"id":56905732,"uuid":"146599717","full_name":"cellular/localstorage-swift","owner":"cellular","description":"iOS, tvOS, watchOS storage for persisting small data sets","archived":false,"fork":false,"pushed_at":"2025-02-28T12:49:00.000Z","size":13829,"stargazers_count":5,"open_issues_count":1,"forks_count":2,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-03-21T16:21:23.283Z","etag":null,"topics":["cocoapods","codable","ios","storage","swift","tvos","watchos","xcode"],"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/cellular.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":"2018-08-29T12:55:14.000Z","updated_at":"2025-02-28T12:48:15.000Z","dependencies_parsed_at":"2022-08-20T19:20:16.410Z","dependency_job_id":null,"html_url":"https://github.com/cellular/localstorage-swift","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/cellular%2Flocalstorage-swift","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cellular%2Flocalstorage-swift/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cellular%2Flocalstorage-swift/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cellular%2Flocalstorage-swift/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cellular","download_url":"https://codeload.github.com/cellular/localstorage-swift/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247430838,"owners_count":20937873,"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":["cocoapods","codable","ios","storage","swift","tvos","watchos","xcode"],"created_at":"2024-11-05T19:39:12.216Z","updated_at":"2025-04-06T03:33:42.714Z","avatar_url":"https://github.com/cellular.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- markdownlint-disable MD002 MD033 MD041 --\u003e\n\u003ch1 align=\"center\"\u003e\n  \u003ca href=\"https://cellular.de\"\u003e\n    \u003cimg src=\"./.github/cellular.svg\" width=\"300\" max-width=\"50%\"\u003e\n  \u003c/a\u003e\n  \u003cbr\u003eLocalStorage\u003cbr\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://swift.org\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/swift-5.1-orange.svg?style=flat\" alt=\"Swift Version\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"http://travis-ci.com/cellular/localstorage-swift/\"\u003e\n        \u003cimg src=\"https://img.shields.io/travis/com/cellular/localstorage-swift.svg\" alt=\"Travis Build\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://codecov.io/gh/cellular/localStorage-swift\"\u003e\n        \u003cimg src=\"https://codecov.io/gh/cellular/localStorage-swift/branch/master/graph/badge.svg\" alt=\"Coverage Report\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://cocoapods.org/pods/CellularLocalStorage\"\u003e\n        \u003cimg src=\"https://img.shields.io/cocoapods/v/CellularLocalStorage.svg\" alt=\"CocoaPods Compatible\"\u003e\n    \u003c/a\u003e    \n\u003c/p\u003e\n\n\u003c!-- markdownlint-enable MD033 --\u003e\n\n## Example\n\nTo run the example project, clone the repo and open Example/Example.xcodproj with Xcode 11+.\n\n#### 1. Choose a model to persist\n\n``` swift\n/// Make model Codable to use default Decoder and Encoder\nstruct User: Codable {\n\n    let name: String\n\n    init(name: String) {\n        self.name = name\n    }\n}\n\n```\n#### 2. Create an LocalStorage.Manager instance and register storages\n\n```swift\n\n// Identifies existing Storages. Used internally for easy storage access through LocalStorage.Manager.\nenum Identifier: String {\n     case user\n\n    // Path to store data to.\n    var path: String {\n      switch self {\n        case .user: return \"example.storage.user\"\n      }\n    }\n }\n\n// Storage persisting data to user storage to  key 'path'\nlet defaultsStorage = UserDefaultsStorage(userDefaults: UserDefaults.standard, path: Identifier.user.path)\n// Wrap defaultsStorage with CachedStorage for faster access.\nlet userStorage = CachedStorage(storage: defaultsStorage)\n\n// Dictionary containing all storages handled by Manager instance\nlet storages = [Identifier.user.rawValue: userStorage]\n\n// DispatchLock to allow multiple reads but single write operations on storages. It will perform all\n// operations on a concurrent DispatchQueue. It is also possible to simply use a NSLock, which may be\n// easier to handle due to reduced thread states. On the downside NSLock has a lower performance on read\n// operations than a DispatchLock.\nlet lock = DispatchLock(queue: DispatchQueue(label: \"example.queue.storage\", attributes: .concurrent))\n\n// Serial queue for async handling. Enables sequential dispatching of completion blocks.\n// Needed for required behaviour in example app.\n// NOTE: Default Manager(storages: _, lock: _) uses a concurrent queue.\nlet asyncQueue = DispatchQueue(label: \"async.queue\")\n\nlet manager = Manager(storages: storages, lock: lock, asyncQueue: asyncQueue)\n```\n\n#### 3. Save user\n\n```swift\n\nlet user = User(name: \"Bernd\")\nlet encoder = FoundationEncoder\u003cUser\u003e(encoder: JSONEncoder())\n// Prefer async access over sync access\n// Sync access := manager.append(_, using: _) -\u003e Result\u003cT, Error\u003e\nmanager.async.append(user, to: Identifier.user.rawValue, using: encoder) { result in\n    switch result {\n    case .success(let savedUser):\n        print(\"\\(savedUser.name)\")\n    case .failure(let error):\n        print(error)\n    }\n}\n```\n\n#### 4. Load stored user list\n```swift\nlet decoder = FoundationDecoder\u003cUser\u003e(decoder: JSONDecoder())\n// Prefer async access over sync access\n// Sync access := manager.all(from: _, using: _) -\u003e Result\u003c[T], Error\u003e\nmanager.async.all(from: Identifier.user.rawValue, using: decoder) { result in\n   switch result {\n   case .success(let user):\n       user.forEach { print(\"\\($0.name)\") }\n   case .failure(let error):\n       print(error)\n   }\n}\n```\n## Requirements\n- Swift 5.0+\n- iOS 11.0+\n- tvOS 11.0+\n- watchOS 5.0+\n\n## Installation\n\n### [Swift Package Manager](https://swift.org/package-manager/)\n\n```swift\n  dependencies: [\n        .package(url: \"https://github.com/cellular/cellular-swift.git\", from: \"6.0.0\")\n    ]\n```\n\n### [CocoaPods](http://cocoapods.org)\n\n```ruby\npod \"CellularLocalStorage\"\n```\n\n## License\n\nCellularLocalStorage is released under the MIT license. [See LICENSE](https://github.com/cellular/localstorage-swift/blob/master/LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcellular%2Flocalstorage-swift","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcellular%2Flocalstorage-swift","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcellular%2Flocalstorage-swift/lists"}