{"id":19687744,"url":"https://github.com/luoxiu/once","last_synced_at":"2025-04-29T07:34:45.555Z","repository":{"id":62449575,"uuid":"151744792","full_name":"luoxiu/Once","owner":"luoxiu","description":"Minimalist library to manage one-off operations.","archived":false,"fork":false,"pushed_at":"2019-08-31T07:06:24.000Z","size":51,"stargazers_count":47,"open_issues_count":1,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-06T15:59:12.961Z","etag":null,"topics":["once","one-off","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/luoxiu.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-10-05T15:53:34.000Z","updated_at":"2024-05-29T08:06:05.000Z","dependencies_parsed_at":"2022-11-01T23:18:01.759Z","dependency_job_id":null,"html_url":"https://github.com/luoxiu/Once","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luoxiu%2FOnce","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luoxiu%2FOnce/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luoxiu%2FOnce/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luoxiu%2FOnce/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/luoxiu","download_url":"https://codeload.github.com/luoxiu/Once/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224156956,"owners_count":17265588,"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":["once","one-off","swift"],"created_at":"2024-11-11T18:36:04.853Z","updated_at":"2024-11-11T18:36:04.944Z","avatar_url":"https://github.com/luoxiu.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Once([简体中文](README.zh_cn.md))\n\n\u003cp align=\"center\"\u003e\n\n[![Build Status](https://travis-ci.org/luoxiu/Once.svg?branch=master)](https://travis-ci.org/luoxiu/Once)\n![release](https://img.shields.io/github/v/release/luoxiu/Once?include_prereleases)\n![install](https://img.shields.io/badge/install-spm%20%7C%20cocoapods%20%7C%20carthage-ff69b4)\n![platform](https://img.shields.io/badge/platform-ios%20%7C%20macos%20%7C%20watchos%20%7C%20tvos%20%7C%20linux-lightgrey)\n![license](https://img.shields.io/github/license/luoxiu/combinex?color=black)\n\n\u003c/div\u003e\n\nOnce allows you to manage the number of executions of a task using an intuitive API.\n\n\n## Highlight\n\n- [x] Safe\n- [x] Efficient\n- [x] Persistent\n\n## Usage\n\n### Token\n\n`Token` records the number of times the task is executed in memory, which allows the task to be executed only once during the entire lifetime of the app.\n\nYou can think of it as an alternative to `dispatch_once` in OC:\n\n```objectivec\nstatic dispatch_once_t token;\ndispatch_once(\u0026token, ^{\n    // do something only once\n});\n```\n\nThe swift code using `Token` is as follows:\n\n```swift\nlet token = Token.makeStatic()\ntoken.do {\n    // do something only once\n}\n```\n\nOr, more simple：\n\n```swift\nToken.do {\n    // do something only once\n}\n```\n\nYou can also don't use `static`:\n\n```swift\nclass Manager {\n    let loadToken = Token.make()\n\n    func ensureLoad() {\n        loadToken.do {\n            // do something only once per manager.\n        }\n    }\n}\n```\n\n#### PersistentToken\n\nUnlike `run`, `do` will persist the execution history of the task (using `UserDefault`).\n\n`PersistentToken` determines whether this task should be executed based on `Scope` and `TimesPredicate`.\n\n#### Scope\n\n`Scope` represents a time range, it is an enum:\n\n- `.install`: from app installation\n- `.version`: from app update\n- `.session`: from app launch\n- `.since(let since)`: from `since(Date)`\n- `.until(let until)`: to `until(Date)`\n\n#### TimesPredicate\n\n`TimesPredicate` represents a range of times.\n\n```swift\nlet p0 = TimesPredicate.equalTo(1)\nlet p1 = TimesPredicate.lessThan(1)\nlet p2 = TimesPredicate.moreThan(1)\nlet p3 = TimesPredicate.lessThanOrEqualTo(1)\nlet p4 = TimesPredicate.moreThanOrEqualTo(1)\n```\n\n#### do\n\nYou can use `Scope` and `TimesPredicate` to make any plan you want, and, yes, it is thread-safe.\n\n```swift\nlet token = PersistentToken.make(\"showTutorial\")\ntoken.do(in: .version, if: .equalTo(0)) {\n    app.showTutorial()\n}\n\n// or\nlet later = 2.days.later\ntoken.do(in: .until(later), if: .lessThan(5)) {\n    app.showTutorial()\n}\n```\n\n#### done\n\nSometimes your asynchronous task may fail. You don't want to mark the failed task as done. You can:\n\n```swift\nlet token = PersistentToken.make(\"showAD\")\ntoken.do(in: .install, if: .equalTo(0)) { task in\n    networkService.fetchAD { result in\n        if result.isSuccess {\n            showAD(result)\n            task.done()\n        }\n    }\n}\n```\n\nBut at this time, the judgment is no longer absolutely safe - if there are multiple threads checking the token at the same time, but it should rarely happen, 😉.\n\n#### reset\n\nYou can also clear the execution history of a task:\n\n```swift\ntoken.reset()\n```\n\nIt is also permissible to clear the execution history of all tasks, but at your own risk:\n\n```swift\nPersistentToken.resetAll()\n```\n\n## Installation\n\n### CocoaPods\n\n```ruby\npod 'Once', '~\u003e 1.0.0'\n```\n\n### Carthage\n\n```ruby\ngithub \"luoxiu/Once\" ~\u003e 1.0.0\n```\n\n### Swift Package Manager\n\n```swift\ndependencies: [\n    .package(url: \"https://github.com/luoxiu/Once\", .upToNextMinor(from: \"1.0.0\"))\n]\n```\n\n## Contributing\n\nEncounter a bug? want more features? Feel free to open an issue or submit a pr directly!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fluoxiu%2Fonce","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fluoxiu%2Fonce","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fluoxiu%2Fonce/lists"}