Skip to content

Instantly share code, notes, and snippets.

@trickart
Created February 6, 2026 06:44
Show Gist options
  • Select an option

  • Save trickart/410540c01ebc23d567e3a5135975b49a to your computer and use it in GitHub Desktop.

Select an option

Save trickart/410540c01ebc23d567e3a5135975b49a to your computer and use it in GitHub Desktop.
Network FrameworkのNWConnectionをasync/awaitで使うためのextension
//
// NWConnection+Concurrency.swift
// AsyncNetwork
//
// Created by trickart on 2026/02/06.
//
import Foundation
import Network
public extension NWConnection {
func start(queue: DispatchQueue) async throws {
try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Void, Error>) in
stateUpdateHandler = { [weak self] state in
switch state {
case .setup, .waiting, .preparing:
break
case .ready:
self?.stateUpdateHandler = nil
continuation.resume()
case .failed(let error):
self?.stateUpdateHandler = nil
continuation.resume(throwing: error)
case .cancelled:
break
@unknown default:
break
}
}
}
}
func receive(minimumIncompleteLength: Int, maximumLength: Int) async throws -> Data? {
try await withCheckedThrowingContinuation { continuation in
self.receive(minimumIncompleteLength: minimumIncompleteLength, maximumLength: maximumLength) { data, _, _, error in
if let error = error {
continuation.resume(throwing: error)
return
} else {
continuation.resume(returning: data)
}
}
}
}
func receiveStream(minimumIncompleteLength: Int, maximumLength: Int) -> AsyncThrowingStream<Data?, Error> {
return AsyncThrowingStream<Data?, Error> { continuation in
@Sendable func receiveRecursively() {
self.receive(minimumIncompleteLength: minimumIncompleteLength, maximumLength: maximumLength) { data, _, isComplete, error in
if let error = error {
continuation.finish(throwing: error)
return
}
continuation.yield(data)
if isComplete {
continuation.finish()
} else {
receiveRecursively()
}
}
}
receiveRecursively()
}
}
func send(content: Data?) async throws {
try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Void, Error>) in
send(content: content, completion: .contentProcessed({ error in
if let error {
continuation.resume(throwing: error)
} else {
continuation.resume()
}
}))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment