Created
August 15, 2020 02:07
-
-
Save YusukeHosonuma/0a39266dd5c2232d6d0a42f826adb8e6 to your computer and use it in GitHub Desktop.
NWPathMonitor を Combine の Publisher として扱えるようにする拡張
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SwiftUI | |
import Network | |
final class ViewModel: ObservableObject { | |
@Published var status: NWPath.Status = .satisfied | |
init() { | |
NWPathMonitor() | |
.publisher() | |
.map { $0.status } | |
.assign(to: &$status) | |
} | |
} | |
struct ContentView: View { | |
@StateObject var viewModel = ViewModel() | |
var body: some View { | |
if viewModel.status == .satisfied { | |
Text("オンラインなう!") | |
} else { | |
Text("オフラインだぉ・・・") | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Combine | |
import Foundation | |
import Network | |
extension NWPathMonitor { | |
func publisher(queue: DispatchQueue = DispatchQueue.main) -> NWPathMonitor.Publisher { | |
Publisher(monitor: self, queue: queue) | |
} | |
final class Subscription<S: Subscriber>: Combine.Subscription where S.Input == NWPath { | |
private let subscriber: S | |
private let monitor: NWPathMonitor | |
private let queue: DispatchQueue | |
private var isStarted = false | |
init(subscriber: S, monitor: NWPathMonitor, queue: DispatchQueue) { | |
self.subscriber = subscriber | |
self.monitor = monitor | |
self.queue = queue | |
} | |
func request(_ demand: Subscribers.Demand) { | |
precondition(demand == .unlimited, "This subscription is only supported to `Demand.unlimited`.") | |
guard !isStarted else { return } | |
isStarted = true | |
monitor.pathUpdateHandler = { [unowned self] path in | |
_ = self.subscriber.receive(path) | |
} | |
monitor.start(queue: queue) | |
} | |
func cancel() { | |
monitor.cancel() | |
} | |
} | |
struct Publisher: Combine.Publisher { | |
typealias Output = NWPath | |
typealias Failure = Never | |
private let monitor: NWPathMonitor | |
private let queue: DispatchQueue | |
init(monitor: NWPathMonitor, queue: DispatchQueue) { | |
self.monitor = monitor | |
self.queue = queue | |
} | |
func receive<S>(subscriber: S) where S : Subscriber, Self.Failure == S.Failure, Self.Output == S.Input { | |
let subscription = Subscription(subscriber: subscriber, monitor: monitor, queue: queue) | |
subscriber.receive(subscription: subscription) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Special thanks!
https://qiita.com/meSummery/items/9d096162a351e2e922c5