{"id":19110072,"url":"https://github.com/hkellaway/asynctaskperformer","last_synced_at":"2025-02-22T11:18:34.973Z","repository":{"id":77939322,"uuid":"139989444","full_name":"hkellaway/AsyncTaskPerformer","owner":"hkellaway","description":"Performs lists of asynchronous tasks synchronously :arrow_right_hook:","archived":false,"fork":false,"pushed_at":"2018-11-24T20:27:55.000Z","size":72,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"develop","last_synced_at":"2025-01-03T03:45:30.783Z","etag":null,"topics":["asynchronous-tasks","ios","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/hkellaway.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-07-06T13:34:46.000Z","updated_at":"2021-03-27T13:30:50.000Z","dependencies_parsed_at":"2023-04-06T23:53:04.211Z","dependency_job_id":null,"html_url":"https://github.com/hkellaway/AsyncTaskPerformer","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hkellaway%2FAsyncTaskPerformer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hkellaway%2FAsyncTaskPerformer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hkellaway%2FAsyncTaskPerformer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hkellaway%2FAsyncTaskPerformer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hkellaway","download_url":"https://codeload.github.com/hkellaway/AsyncTaskPerformer/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240163753,"owners_count":19758058,"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":["asynchronous-tasks","ios","swift"],"created_at":"2024-11-09T04:23:31.516Z","updated_at":"2025-02-22T11:18:34.953Z","avatar_url":"https://github.com/hkellaway.png","language":"Swift","readme":"# AsyncTaskPerformer\n\nPerforms lists of asynchronous tasks synchronously :arrow_right_hook:\n\n## Features \n[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg)](https://github.com/Carthage/Carthage)\n\n## Getting Started\n\n[Download AsyncTaskPerformer](https://github.com/hkellaway/AsyncTaskPerformer/archive/master.zip) and perform a `pod install` on the included `Demo` app to see AsyncTaskPerformer in action\n\n### Swift Version\n\nAsyncTaskPerformer is currently compatible with Swift 4.2.\n\n### Installation with CocoaPods\n\n```ruby\npod 'AsyncTaskPerformer', :git =\u003e 'https://github.com/hkellaway/AsyncTaskPerformer.git', :tag =\u003e '0.1.0'\n```\n\n### Installation with Carthage\n\n```\ngithub \"hkellaway/AsyncTaskPerformer\"\n```\n\n## Usage\n\nAsyncTaskPerformer takes lists of asynchronous tasks and processes them in order. It can do so for multiple uses cases:\n\n* The list of asynchronous tasks should be processed in order with a single completion point - but without concern for if errors occur in any nor require a typed result (Use [SynchronousDispatchGroup](#SynchronousDispatchGroup))\n* The list of asynchronous tasks should be processed in order, report their result using the same type, and have a single completion point - the completion point must report the result of attempting each task in order, either with an error or the final typed result (Use [SynchronousOperationQueue](#SynchronousOperationQueue))\n\n## SynchronousDispatchGroup\n\n`SynchronousDispatchGroup` uses a `DispatchGroup` to synchronize its list of asynchrnous tasks. It is better used for tasks that don't need to be typed and don't need to halt execution if an error occurs. Let's look at an example of usage.\n\nFirst, create tasks that conform to `AsyncTask`. Let's imagine a task that prints out \"Hello World\" - we'll give our tasks an `id` so we can confirm they're processing in order.\n\n``` swift\nstruct SayHelloTask: AsyncTask {\n    \n    let id: Int\n    \n    func execute(completion: @escaping () -\u003e Void) {\n        print(\"Hello World \\(id)\")\n        completion()\n    }\n    \n}\n\n```\n\nThe critical aspect of an `AsyncTask` is that it independently knows how ot `execute` a piece of work.\n\nNext, create a `SynchronousDispatchGroup` and give it a list of `AsyncTasks`s to perform, as well as a single completion point.\n\n\n``` swift\nlet tasks: [AsyncTask] = [SayHelloTask(id: 1), SayHelloTask(id: 2), SayHelloTask(id: 3) ]\nlet synchronousDispatchGroup = SynchronousDispatchGroup()\n\nsynchronousDispatchGroup.executeTasks(tasks) {\n    print(\"Goodbye\")\n}\n\n```\n\nThe output from this will be:\n\n```\nHello World 1\nHello World 2\nHello World 3\nGoodbye\n```\n\n\n### SynchronousOperationQueue\n\n`SynchronousOperationQueue` uses an `OperationQueue` to synchronize its list of asynchrnous tasks. It is better used for tasks that have a specific type which the tasks perform work on in-order. For example, in an e-commerce application we might need to remove Items from the Bag one-by-one and report the state of the Bag after each successful removal.\n\nIf an error is encountered in the midst of processing the tasks, the rest of the tasks are cancelled and the completion is called early.\n\nLet's imagine we have an `api` that, when given an `itemID` will `removeFromBag` the provided `Item` and report back the resulting state of the `Bag` (or, an error if the Item was not present in the Bag).\n\nFirst, create an operation that inherits from `AsyncOperationWithCompletion`.\n\n``` swift\nfinal class RemoveItemFromBagOperation: AsyncOperationWithCompletion\u003cBag\u003e {\n\n    let itemID: Int\n    let api: ECommAPI\n    \n    init(id: Int, api: FakeAPI) {\n        self.id = id\n        self.api = api\n    }\n    \n    override func main() {\n        api.removeFromBag(item: itemID) { [weak self] (updatedBag, error) in\n            self?.completion?(updatedBag, error)\n            self?.finish()\n        }\n    }\n    \n}\n\n```\n\nThe critical aspect of `AsyncOperationWithCompletion` is that it calls its own `completion` closure then calls `finish()`.\n\nNext, create a `SynchronousOperationQueue` and give it a list of tasks to perhaps - as well as a starting value and a single completion point.\n\n``` swift\nlet currentBag = Bag(items: [Item(id: 1), Item(id: 2), Item(id: 3), Item(id: 4)])\nlet itemsToRemove = [2, 4]\nlet operations = itemsToRemove.map { RemoveItemFromBagOperation(itemID: $0, api: api) }\nlet synchronousOperationQueue = SynchronousOperationQueue(defaultValue: currentBag)\n\nsynchronousOperationQueue.executeOperations(operations) { (finalBag, error) in\n    if let error = error {\n        print(\":()\n    } else {\n        print(\"Updated Bag: \" + finalBag)\n    }\n}\n\n```\n\nThe result from this, if all API calls completed successfully, would be the Bag updated such that Item 2 and Item 4 have been removed.\n\n## Credits\n\nAsyncTaskPerformer was created by [Harlan Kellaway](http://harlankellaway.com).\n\n## License\n\nAsyncTaskPerformer is available under the MIT license. See the [LICENSE](https://raw.githubusercontent.com/hkellaway/AsyncTaskPerformer/master/LICENSE) file for more info.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhkellaway%2Fasynctaskperformer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhkellaway%2Fasynctaskperformer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhkellaway%2Fasynctaskperformer/lists"}