{"id":26120639,"url":"https://github.com/swiftrex/reachabilitymiddleware","last_synced_at":"2026-04-17T14:32:34.176Z","repository":{"id":45875915,"uuid":"247996466","full_name":"SwiftRex/ReachabilityMiddleware","owner":"SwiftRex","description":"SwiftRex Reachability Middleware to keep track on network's availability","archived":false,"fork":false,"pushed_at":"2021-12-16T23:14:55.000Z","size":27,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-10T13:45:54.592Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/SwiftRex.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":"2020-03-17T14:51:32.000Z","updated_at":"2021-11-30T15:10:03.000Z","dependencies_parsed_at":"2022-09-05T15:41:09.229Z","dependency_job_id":null,"html_url":"https://github.com/SwiftRex/ReachabilityMiddleware","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/SwiftRex/ReachabilityMiddleware","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SwiftRex%2FReachabilityMiddleware","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SwiftRex%2FReachabilityMiddleware/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SwiftRex%2FReachabilityMiddleware/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SwiftRex%2FReachabilityMiddleware/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SwiftRex","download_url":"https://codeload.github.com/SwiftRex/ReachabilityMiddleware/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SwiftRex%2FReachabilityMiddleware/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31933055,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-17T12:37:54.787Z","status":"ssl_error","status_checked_at":"2026-04-17T12:37:25.095Z","response_time":62,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":[],"created_at":"2025-03-10T13:43:36.505Z","updated_at":"2026-04-17T14:32:34.150Z","avatar_url":"https://github.com/SwiftRex.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ReachabilityMiddleware\n\n## Actions\n\nControl the Middleware: Dispatch these actions to the Store in order to start or stop the middleware:\n\n```swift\nReachabilityEvent.startMonitoring      // Start the NWPathMonitor and the Middleware actions\nReachabilityEvent.stopMonitoring       // Stop the NWPathMonitor and cease the actions\n```\n\nMiddleware events: these actions will be triggered by the middleware whenever NWPath is notified and differs from current state:\n\n- Related to the network interface\n\n```swift\nReachabilityEvent.connectedToWifi      // The connection is now routed through the wi-fi\nReachabilityEvent.connectedToWired     // The connection is now routed through the wired ethernet\nReachabilityEvent.connectedToCellular  // The connection is now routed through the cellular network\nReachabilityEvent.gotOffline           // The connection was lost and device seems to be offline\n```\n\n- Related to the network cost\n\n```swift\nReachabilityEvent.becameExpensive      // The path uses an interface that is considered expensive, such as Cellular or a Personal Hotspot.\nReachabilityEvent.becameCheap          // The path uses an interface that is considered cheap, such as home Wi-fi or Ethernet.\nReachabilityEvent.becameConstrained    // The path uses an interface in Low Data Mode.\nReachabilityEvent.becameUnconstrained  // The path uses an interface in High Data Mode.\n```\n\n## State\n\n```swift\npublic struct ReachabilityState: Equatable, Codable {\n    public let isMonitoring: Bool                // The Middleware is active, so the NWPathMonitor is observing changes\n    public let connectivity: ConnectedInterface  // What's the latest known interface used to connect, or if it's disconnected\n    public let isExpensive: Bool                 // The path uses an interface that is considered expensive or not\n    public let isConstrained: Bool               // The path uses an interface in Low (constrained) or High (unconstrained) Data Mode.\n}\n\npublic enum ConnectedInterface: String, Equatable, Codable {\n    case cellular   // cellular (3G, LTE, 5G networks)\n    case wifi       // Wi-fi, including Personal Hotpots\n    case wired      // Wired Ethernet\n    case none       // Disconnected\n}\n```\n\n## Combine Publisher\n\n`NWPathMonitorPublisher`:\nPublisher for NWPathMonitor, emitting NWPath for every pathUpdateHandler event. It never fails.\nImportant: it doesn't respect the demand, it's used only in this middleware that asks for unlimited demand, any use in other contexts should consider that the back-pressure will be ignored, with the exception of the first demand different than .none which will kickstart the side-effect, but regardless of how much the demand is sent by the subscriber, the publisher will make it unlimited.\n\n```swift\nlet cancellable = NWPathMonitor().publisher.sink { path in \n    let isEthernet = path.usesInterfaceType(.wiredEthernet)\n    // ...\n}\n```\n\n## Effect Middleware\n\nThis effect middleware has dependency on `ReachabilityMiddlewareDependencies`, which simply wraps a constructor for a `NWPathMonitorPublisher`.\n\nSome examples of how this dependency should be created:\n\n```swift\nlet dep1 = ReachabilityMiddlewareDependencies.production()\nlet dep2 = ReachabilityMiddlewareDependencies.production(requiredInterfaceType: .wifi)\nlet dep3 = ReachabilityMiddlewareDependencies.production(prohibitedInterfaceTypes: [.wifi])\nlet mock = PassthroughSubject\u003cNWPath, Never\u003e()\nlet dep4 = ReachabilityMiddlewareDependencies.forTests(subject: mock)\nlet dep5 = ReachabilityMiddlewareDependencies(pathMonitor: { publisherOfNWPath.eraseToAnyPublisher() })\n```\n\nRegardless of how you created it, you can inject it into the MiddlewareReader. Internally, the middleware will use `dep1.pathMonitor().sink`.\n\n```swift\nlet middleware = EffectMiddleware\u003cReachabilityEvent, ReachabilityEvent, ReachabilityState, ReachabilityMiddlewareDependencies\u003e\n    .reachability\n    .inject(dep1)\n\nlet store = ... // lift and use the middleware\nstore.dispatch(.reachabilitySubState(.startMonitoring))\n```\n\n## Reducer\n\nThe reducer will update your AppState according to the actions received by the middleware.\n\n```swift\nlet reducer = Reducer\u003cReachabilityEvent, ReachabilityState\u003e.reachability\n\nlet store = ... // lift and use the reducer\nstore.dispatch(.reachabilitySubState(.startMonitoring))\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswiftrex%2Freachabilitymiddleware","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fswiftrex%2Freachabilitymiddleware","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswiftrex%2Freachabilitymiddleware/lists"}