{"id":19687750,"url":"https://github.com/luoxiu/schedule","last_synced_at":"2025-10-21T10:48:20.047Z","repository":{"id":47095774,"uuid":"139462154","full_name":"luoxiu/Schedule","owner":"luoxiu","description":"Schedule timing task in Swift using a fluent API. (A friendly alternative to Timer)","archived":false,"fork":false,"pushed_at":"2020-10-06T08:41:56.000Z","size":1008,"stargazers_count":1830,"open_issues_count":9,"forks_count":111,"subscribers_count":29,"default_branch":"master","last_synced_at":"2025-03-01T10:48:29.449Z","etag":null,"topics":["human","timer"],"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-07-02T15:37:13.000Z","updated_at":"2025-02-21T10:31:36.000Z","dependencies_parsed_at":"2022-08-24T03:20:39.675Z","dependency_job_id":null,"html_url":"https://github.com/luoxiu/Schedule","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luoxiu%2FSchedule","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luoxiu%2FSchedule/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luoxiu%2FSchedule/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luoxiu%2FSchedule/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/luoxiu","download_url":"https://codeload.github.com/luoxiu/Schedule/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242877397,"owners_count":20200015,"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":["human","timer"],"created_at":"2024-11-11T18:36:05.607Z","updated_at":"2025-10-21T10:48:14.609Z","avatar_url":"https://github.com/luoxiu.png","language":"Swift","readme":"# Schedule([简体中文](README.zh_cn.md))\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://github.com/luoxiu/Schedule/releases\"\u003e\n  \u003cimg src=\"https://img.shields.io/cocoapods/v/Schedule.svg\"\u003e\n\u003c/a\u003e\n\u003cimg src=\"https://img.shields.io/travis/luoxiu/Schedule.svg\"\u003e\n\u003cimg src=\"https://img.shields.io/codecov/c/github/luoxiu/Schedule.svg\"\u003e\n\u003cimg src=\"https://img.shields.io/badge/support-CocoaPods%20%7C%20Carthage%20%7C%20SwiftPM-brightgreen.svg\"\u003e\n\u003cimg src=\"https://img.shields.io/cocoapods/p/Schedule.svg\"\u003e\n\u003cimg src=\"https://img.shields.io/github/license/luoxiu/Schedule.svg\"\u003e\n\u003c/p\u003e\n\nSchedule is a timing tasks scheduler written in Swift. It allows you run timing tasks with elegant and intuitive syntax.\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"assets/demo.png\" width=\"700\"\u003e\n\u003c/p\u003e\n\n## Features\n\n- [x] Elegant and intuitive API \n- [x] Rich preset rules\n- [x] Powerful management mechanism\n- [x] Detailed execution history\n- [x] Thread safe\n- [x] Complete documentation\n- [x] ~100%+ test coverage\n\n### Why You Should Use Schedule\n\n| Features | Timer | DispatchSourceTimer | Schedule |\n| --- | :---: | :---: | :---: |\n| ⏰ Interval-based Schedule | ✓ | ✓ | ✓ |\n| 📆 Date-based Schedule | ✓ | | ✓ |\n| 🌈 Combined Plan Schedule | | | ✓ |\n| 🗣️ Natural Language Parse | | | ✓ |\n| 🏷 Batch Task Management | | | ✓ |\n| 📝 Execution Record | | | ✓ |\n| 🎡 Plan Reset | | ✓ | ✓ |\n| 🚦 Suspend, Resume, Cancel | | ✓ | ✓ |\n| 🍰 Child-action | | | ✓ |\n\n## Usage\n\n### Overview\n\nScheduling a task has never been so elegant and intuitive, all you have to do is:\n\n```swift\n// 1. define your plan：\nlet plan = Plan.after(3.seconds)\n\n// 2. do your task：\nlet task = plan.do {\n    print(\"3 seconds passed!\")\n}\n```\n\n### Rules\n\n#### Interval-based Schedule\n\nThe running mechanism of Schedule is based on `Plan`, and `Plan` is actually a sequence of `Interval`.\n\nSchedule makes `Plan` definitions more elegant and intuitive by extending `Int` and `Double`. Also, because `Interval` is a built-in type of Schedule, you don't have to worry about it being polluting your namespace.\n\n```swift\nlet t1 = Plan.every(1.second).do { }\n\nlet t2 = Plan.after(1.hour, repeating: 1.minute).do { }\n\nlet t3 = Plan.of(1.second, 2.minutes, 3.hours).do { }\n```\n\n#### Date-based Schedule\n\nConfiguring date-based `Plan` is the same, with the expressive Swift syntax, Schedule makes your code look like a fluent conversation.\n\n```swift\nlet t1 = Plan.at(date).do { }\n\nlet t2 = Plan.every(.monday, .tuesday).at(\"9:00:00\").do { }\n\nlet t3 = Plan.every(.september(30)).at(10, 30).do { }\n\nlet t4 = Plan.every(\"one month and ten days\").do { }\n\nlet t5 = Plan.of(date0, date1, date2).do { }\n```\n\n#### Natural Language Parse\n\nIn addition, Schedule also supports simple natural language parsing. \n\n```swift\nlet t1 = Plan.every(\"one hour and ten minutes\").do { }\n\nlet t2 = Plan.every(\"1 hour, 5 minutes and 10 seconds\").do { }\n\nlet t3 = Plan.every(.friday).at(\"9:00 pm\").do { }\n\nPeriod.registerQuantifier(\"many\", for: 100 * 1000)\nlet t4 = Plan.every(\"many days\").do { }\n```\n\n#### Combined Plan Schedule\n\nSchedule provides several basic collection operators, which means you can use them to customize your own powerful plans.\n\n```swift\n/// Concat\nlet p0 = Plan.at(birthdate)\nlet p1 = Plan.every(1.year)\nlet birthday = p0.concat.p1\nlet t1 = birthday.do { \n    print(\"Happy birthday\")\n}\n\n/// Merge\nlet p3 = Plan.every(.january(1)).at(\"8:00\")\nlet p4 = Plan.every(.october(1)).at(\"9:00 AM\")\nlet holiday = p3.merge(p4)\nlet t2 = holiday.do {\n    print(\"Happy holiday\")\n}\n\n/// First\nlet p5 = Plan.after(5.seconds).concat(Schedule.every(1.day))\nlet p6 = s5.first(10)\n\n/// Until\nlet p7 = P.every(.monday).at(11, 12)\nlet p8 = p7.until(date)\n```\n\n### Management\n\n#### DispatchQueue\n\nWhen calling `plan.do` to dispatch a timing task, you can use `queue` to specify which `DispatchQueue` the task will be dispatched to when the time is up. This operation does not rely on `RunLoop` like `Timer`, so you can call it on any thread.\n\n```swift\nPlan.every(1.second).do(queue: .global()) {\n    print(\"On a globle queue\")\n}\n```\n\n\n#### RunLoop\n\nIf `queue` is not specified, Schedule will use `RunLoop` to dispatch the task, at which point the task will execute on the current thread. **Please note**, like `Timer`, which is also based on `RunLoop`, you need to ensure that the current thread has an **available** `RunLoop`. By default, the task will be added to `.common` mode, you can specify another mode when creating the task.\n\n```swift\nlet task = Plan.every(1.second).do(mode: .default) {\n    print(\"on default mode...\")\n}\n```\n\n#### Timeline\n\nYou can observe the execution record of the task in real time using the following properties.\n\n```swift\ntask.creationDate\n\ntask.executionHistory\n\ntask.firstExecutionDate\ntask.lastExecutionDate\n\ntask.estimatedNextExecutionDate\n```\n\n#### TaskCenter \u0026 Tag\n\nTasks are automatically added to `TaskCenter.default` by default，you can organize them using tags and task center.\n\n```swift\nlet plan = Plan.every(1.day)\nlet task0 = plan.do(queue: myTaskQueue) { }\nlet task1 = plan.do(queue: myTaskQueue) { }\n\nTaskCenter.default.addTags([\"database\", \"log\"], to: task1)\nTaskCenter.default.removeTag(\"log\", from: task1)\n\nTaskCenter.default.suspend(byTag: \"log\")\nTaskCenter.default.resume(byTag: \"log\")\nTaskCenter.default.cancel(byTag: \"log\")\n\nTaskCenter.default.clear()\n\nlet myCenter = TaskCenter()\nmyCenter.add(task0)\n```\n\n\n### Suspend，Resume, Cancel\n\nYou can `suspend`, `resume`, `cancel` a task.\n\n```swift\nlet task = Plan.every(1.minute).do { }\n\n// will increase task's suspensionCount\ntask.suspend()\n\n// will decrease task's suspensionCount,\n// but don't worry about excessive resumptions, I will handle these for you~\ntask.resume()\n\n// will clear task's suspensionCount\n// a canceled task can't do anything, event if it is set to a new plan.\ntask.cancel()\n```\n\n#### Action\n\nYou can add more actions to a task and remove them at any time you want:\n\n```swift\nlet dailyTask = Plan.every(1.day)\ndailyTask.addAction {\n    print(\"open eyes\")\n}\ndailyTask.addAction {\n    print(\"get up\")\n}\nlet key = dailyTask.addAction {\n    print(\"take a shower\")\n}\ndailyTask.removeAction(byKey: key)\n```\n\n## Installation\n\n### CocoaPods\n\n```ruby\n# Podfile\nuse_frameworks!\n\ntarget 'YOUR_TARGET_NAME' do\n  pod 'Schedule', '~\u003e 2.0'\nend\n```\n\n### Carthage\n\n```\ngithub \"luoxiu/Schedule\" ~\u003e 2.0\n```\n\n### Swift Package Manager\n\n```swift\ndependencies: [\n    .package(\n      url: \"https://github.com/luoxiu/Schedule\", .upToNextMajor(from: \"2.0.0\")\n    )\n]\n```\n\n## Contributing\n\nLike **Schedule**? Thanks!!!\n\nAt the same time, I need your help~\n\n### Finding Bugs\n\nSchedule is just getting started. If you could help the Schedule find or fix potential bugs, I would be grateful!\n\n### New Features\n\nHave some awesome ideas? Feel free to open an issue or submit your pull request directly!\n\n### Documentation improvements.\n\nImprovements to README and documentation are welcome at all times, whether typos or my lame English, 🤣.\n\n## Acknowledgement\n\nInspired by Dan Bader's [schedule](https://github.com/dbader/schedule)!\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fluoxiu%2Fschedule","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fluoxiu%2Fschedule","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fluoxiu%2Fschedule/lists"}