{"id":34243931,"url":"https://github.com/thatfactory/cgkstatemachine","last_synced_at":"2025-12-16T05:15:31.096Z","repository":{"id":88897426,"uuid":"387038541","full_name":"thatfactory/cgkstatemachine","owner":"thatfactory","description":"A custom GKStateMachine subclass that allows GKState changes to be observed via Combine 🔀 ","archived":false,"fork":false,"pushed_at":"2025-12-09T12:52:39.000Z","size":22,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-10T13:04:07.811Z","etag":null,"topics":["combine","gameplaykit","state-machine","swift"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thatfactory.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-07-17T21:20:29.000Z","updated_at":"2025-12-09T12:52:43.000Z","dependencies_parsed_at":"2025-12-10T13:04:12.021Z","dependency_job_id":null,"html_url":"https://github.com/thatfactory/cgkstatemachine","commit_stats":null,"previous_names":["thatfactory/cgkstatemachine"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/thatfactory/cgkstatemachine","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thatfactory%2Fcgkstatemachine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thatfactory%2Fcgkstatemachine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thatfactory%2Fcgkstatemachine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thatfactory%2Fcgkstatemachine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thatfactory","download_url":"https://codeload.github.com/thatfactory/cgkstatemachine/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thatfactory%2Fcgkstatemachine/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27759672,"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","status":"online","status_checked_at":"2025-12-16T02:00:10.477Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["combine","gameplaykit","state-machine","swift"],"created_at":"2025-12-16T05:15:27.834Z","updated_at":"2025-12-16T05:15:31.086Z","avatar_url":"https://github.com/thatfactory.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![swift-version](https://img.shields.io/badge/swift-6.2-ea7a50.svg?logo=swift\u0026logoColor=white)](https://developer.apple.com/swift/)\n[![xcode-version](https://img.shields.io/badge/xcode-26.2-50ace8.svg?logo=xcode\u0026logoColor=white)](https://developer.apple.com/xcode/)\n[![spm-ready](https://img.shields.io/badge/spm-ready-b68f6a.svg?logo=gitlfs\u0026logoColor=white)](https://developer.apple.com/documentation/xcode/swift-packages)\n[![platforms](https://img.shields.io/badge/platforms-iOS%20%7C%20iPadOS%20%7C%20macOS%20%7C%20Mac%20Catalyst%20%7C%20tvOS-lightgrey.svg?logo=apple\u0026logoColor=white)](https://en.wikipedia.org/wiki/List_of_Apple_operating_systems)\n[![license](https://img.shields.io/badge/license-MIT-67ac5b.svg?logo=googledocs\u0026logoColor=white)](https://en.wikipedia.org/wiki/MIT_License)\n[![release](https://github.com/thatfactory/gcoverseer/actions/workflows/release.yml/badge.svg)](https://github.com/thatfactory/gcoverseer/actions/workflows/release.yml)\n\n# CGKStateMachine 🔀\nA **custom** [`GKStateMachine`](https://developer.apple.com/documentation/gameplaykit/gkstatemachine) subclass that allows [GKState](https://developer.apple.com/documentation/gameplaykit/gkstate) changes to be observed using [Combine](https://developer.apple.com/documentation/combine).\n\n## Usage Examples\n```swift\n// Create a state machines of `CGKStateMachine` type.\nlet cgkStateMachine = CGKStateMachine(\n    states: [\n        FirstState(),\n        SecondState()\n    ]\n)\n\n// Create states of `CGKState` type.\nclass FirstState: CGKState {}\nclass SecondState: CGKState {}\n\n// Sink `publishedState`.\nvar cancellables = Set\u003cAnyCancellable\u003e()\n\ncgkStateMachine.publishedState\n    .sink { state in\n        // React here 👈🏻👈🏻👈🏻\n    }\n    .store(in: \u0026cancellables)\n\n// Enter states and get notified.\ncgkStateMachine.enter(FirstState.self)\ncgkStateMachine.enter(SecondState.self)\n\n```\n## Notice\nApple implemented a `publisher(for:)` on `NSObject`.  \nThis publisher allows for subscribing to KVO changes on classes that inherit from `NSObject`.\n\n`GKStateMachine` inherits from `NSObject`.  \nSo in theory one could try using:\n\n```swift\ngkStateMachine.publisher(for: \\.currentState).sink { state in\n    ...\n}\n```\n... however it doesn't seem that `GKStateMachine` is KVO-compliant.  \nIn my experience, with the above approach only the first state gets published.  \n\nThat's why `CGKStateMachine` was created.\n\n## Integration\n### Xcode\nUse Xcode's [built-in support for SPM](https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app).\n\n*or...*\n\n### Package.swift\nIn your `Package.swift`, add `CGKStateMachine` as a dependency:\n```swift\ndependencies: [\n    .package(\n        url: \"https://github.com/thatfactory/cgkstatemachine\",\n        from: \"0.1.0\"\n    )\n]\n```\n\nAssociate the dependency with your target:\n```swift\ntargets: [\n    .target(\n        name: \"YourTarget\",\n        dependencies: [\n            .product(\n                name: \"CGKStateMachine\",\n                package: \"cgkstatemachine\"\n            )\n        ]\n    )\n]\n```\n\nRun: `swift build`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthatfactory%2Fcgkstatemachine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthatfactory%2Fcgkstatemachine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthatfactory%2Fcgkstatemachine/lists"}