{"id":32150735,"url":"https://github.com/dean151/rulekit","last_synced_at":"2025-10-21T10:18:56.110Z","repository":{"id":195350156,"uuid":"692777211","full_name":"Dean151/RuleKit","owner":"Dean151","description":"TipKit style API to call a closure, or trigger a NSNotification based on events and condition.","archived":false,"fork":false,"pushed_at":"2024-11-03T14:55:24.000Z","size":38,"stargazers_count":58,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-10-01T14:49:46.977Z","etag":null,"topics":["ios","ipados","macos","notificationcenter","swift","swift-package-manager","tipkit","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/Dean151.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["Dean151"]}},"created_at":"2023-09-17T14:54:42.000Z","updated_at":"2025-08-25T19:29:34.000Z","dependencies_parsed_at":"2024-02-03T12:23:35.162Z","dependency_job_id":"d083699e-1079-4bfe-8826-0680e2358158","html_url":"https://github.com/Dean151/RuleKit","commit_stats":null,"previous_names":["dean151/rulekit"],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/Dean151/RuleKit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dean151%2FRuleKit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dean151%2FRuleKit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dean151%2FRuleKit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dean151%2FRuleKit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Dean151","download_url":"https://codeload.github.com/Dean151/RuleKit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dean151%2FRuleKit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280242037,"owners_count":26296898,"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-10-21T02:00:06.614Z","response_time":58,"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":["ios","ipados","macos","notificationcenter","swift","swift-package-manager","tipkit","tvos","watchos","xcode"],"created_at":"2025-10-21T10:18:55.071Z","updated_at":"2025-10-21T10:18:56.102Z","avatar_url":"https://github.com/Dean151.png","language":"Swift","readme":"# RuleKit\n\nTipKit style API to trigger an arbitrary closure, or a NSNotification based on events and condition.\n\n## Usecases\n- To open your Paywall from time to time\n- To prompt your user to add an App Store review\n- Watching and sending achievements to Game Center with GameKit\n- Show a shortcut available for an action that is often performed by a user\n- ...\n\n## Requirements\n- Swift 5.9+ (Xcode 15+)\n- iOS 14+, iPadOS 14+, tvOS 14+, watchOS 7+, macOS 11+\n\n## Installation\n\nInstall using Swift Package Manager\n```\ndependencies: [\n    .package(url: \"https://github.com/Dean151/RuleKit.git\", from: \"0.5.0\"),\n],\ntargets: [\n    .target(name: \"MyTarget\", dependencies: [\n        .product(name: \"RuleKit\", package: \"RuleKit\"),\n    ]),\n]\n```\n\nAnd import it:\n```swift\nimport RuleKit\n```\n\n\n## How to use?\n\nRuleKit is about one thing: invoking a closure, or trigger a NSNotification when a set of rules are fulfilled!\n\n- Configure RuleKit when your application starts\n```swift\ntry RuleKit.configure(storeLocation: .applicationDefault)\n```\n- Create \"events\" to trigger RuleKit\n```swift\nextension RuleKit.Event {\n    public static let appStarted: Self = \"appStarted\"\n    public static let entityCreated: Self = \"itemCreated\"\n    public static let promptAttempt: Self = \"promptAttempt\"\n}\n```\n- Create a custom notification to be triggered by RuleKit\n```swift\nimport Foundation\n\nextension Notification.Name {\n    static let requestReviewPrompt = Notification.Name(\"RequestReviewPrompt\")\n}\n```\n- Implement your logic of when your custom notification is triggered\n```swift\nimport StoreKit\nimport SwiftUI\n\nstruct ContentView: View {\n    @Environment(\\.requestReview)\n    private var requestReview\n\n    var body: View {\n        Text(\"Hello, World!\")\n            .onReceive(NotificationCenter.default.publisher(for: .requestReviewPrompt)) { _ in\n                requestReview()\n                RuleKit.Event.promptAttempt.sendDonation()\n            }\n    }\n}\n```\n- Register your business rules that should trigger your closure, or your notification\n```swift\nRuleKit.setRule(\n    triggering: requestReviewNotification, \n    options: [.triggerFrequency(.monthly)], \n    .allOf([\n        .event(.promptAttempt) {\n            $0.donations.last?.version != .current\n        },\n        .anyOf([\n            .event(.entityCreated) { _ in\n                MyStore.shared.entityCount \u003e= 5\n            },\n            .allOf([\n                .event(.appStarted) {\n                    $0.donations.count \u003e= 3\n                },\n                .event(.entityCreated) { _ in\n                    MyStore.shared.entityCount \u003e= 3\n                }\n            ])\n        ])\n    ])\n)\n```\n- Donate those events at proper places in your app\n```swift\n// Asynchronously\nRuleKit.Event.appStarted.sendDonation()\n// Synchronously\nawait RuleKit.Event.entityCreated.donate()\n```\n- As soon as an event is donated, if all the rules are fulfilled, the notification will be sent\n- If required, reset an event donations to zero:\n```swift\n// Asynchronously\nRuleKit.Event.appStarted.resetDonations()\n// Synchronously\nawait RuleKit.Event.appStarted.reset()\n```\n\n### Available stores:\n- `.applicationDefault`: Will use the default Document folder of your app\n- `.groupContainer(identifier: String)`: Will store your event donations in the shared AppGroup container\n- `.url(URL)`: Provide your own URL. It should be a directory URL.\n\n### Available options:\n- `.triggerFrequency(_)`: Throttle down notification donation or using given period\n- `.dispatchQueue(_)`: Choose the DispatchQueue you want your notification to be sent from. Defaults to main queue.\n- `.delay(for: _)` and `.delay(nanoseconds: _)`: Delay the trigger of a specific notification after it was fulfilled.\n\n### Event.Donations properties available in the condition closure:\n- `count`: the number of times an event have been donated\n- `first` and `last`: the first and last retrieved donation (date + version)\n\n## Contribute\nYou are encouraged to contribute to this repository, by opening issues, or pull requests for bug fixes, improvement requests, or support.\nSuggestions for contributing:\n-  Improving documentation\n-  Adding some automated tests 😜\n-  Adding some new rules, options or properties for more use cases\n","funding_links":["https://github.com/sponsors/Dean151"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdean151%2Frulekit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdean151%2Frulekit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdean151%2Frulekit/lists"}