Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 22 additions & 11 deletions .github/workflows/swift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,31 @@ name: Swift

on:
push:
branches: [ main ]
branches: [ "main" ]
pull_request:
branches: [ main ]
env:
DEVELOPER_DIR: /Applications/Xcode_14.2.app/Contents/Developer
branches: [ "main" ]

jobs:
build:
runs-on: ${{ matrix.os }}

strategy:
matrix:
os: [macos-latest]
swift: ["6.0"]

steps:
- uses: actions/checkout@v4

- name: Setup Swift
uses: swift-actions/setup-swift@v2
with:
swift-version: ${{ matrix.swift }}

- run: swift --version

runs-on: macos-latest
- name: Build
run: swift build -v

steps:
- uses: actions/checkout@v2
- name: Build
run: swift build -v
- name: Run tests
run: swift test -v
- name: Run tests
run: swift test -v
6 changes: 0 additions & 6 deletions FormatScript.sh

This file was deleted.

74 changes: 37 additions & 37 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,43 +1,43 @@
// swift-tools-version:5.5
// swift-tools-version:6.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "AsyncWebSocketClient",
platforms: [.iOS(.v13), .macOS(.v12), .watchOS(.v6), .tvOS(.v13)],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "AsyncWebSocketClient",
targets: ["AsyncWebSocketClient"]),
.library(
name: "AsyncWebSocketClientMocks",
targets: ["AsyncWebSocketClientMocks"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
.package(url: "https://github.com/Henryforce/AsyncTimeSequences", from: "0.0.9")
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "AsyncWebSocketClient",
dependencies: [
"AsyncTimeSequences",
]),
.target(
name: "AsyncWebSocketClientMocks",
dependencies: [
"AsyncWebSocketClient",
]),
.testTarget(
name: "AsyncWebSocketClientTests",
dependencies: [
"AsyncWebSocketClient",
"AsyncTimeSequences",
.product(name: "AsyncTimeSequencesSupport", package: "AsyncTimeSequences"),
]),
]
name: "AsyncWebSocketClient",
platforms: [.iOS(.v13), .macOS(.v12), .watchOS(.v6), .tvOS(.v13)],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "AsyncWebSocketClient",
targets: ["AsyncWebSocketClient"]),
.library(
name: "AsyncWebSocketClientMocks",
targets: ["AsyncWebSocketClientMocks"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
.package(url: "https://github.com/Henryforce/AsyncTimeSequences", from: "0.0.9")
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "AsyncWebSocketClient",
dependencies: [
"AsyncTimeSequences"
]),
.target(
name: "AsyncWebSocketClientMocks",
dependencies: [
"AsyncWebSocketClient"
]),
.testTarget(
name: "AsyncWebSocketClientTests",
dependencies: [
"AsyncWebSocketClient",
"AsyncTimeSequences",
.product(name: "AsyncTimeSequencesSupport", package: "AsyncTimeSequences"),
]),
]
)
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

![badge-platforms][] [![badge-spm][]][spm]

This is a package that contains a client behaving as a wrapper for the URLSessionWebSocketTask provided by Apple.
This is a package that contains a client behaving as an async wrapper for the URLSessionWebSocketTask provided by Apple.

## Usage

Expand All @@ -16,7 +16,7 @@ try await client.send(.string("Hello world!")) // Either raw data or strings can
let stream = await client.listenStream() // Returns an AsyncStream of events

for await event in stream {
print(event) // Print events such as data received, connection opened, connection closed
print(event) // Print events such as data received, connection opened, connection closed
}
```

Expand All @@ -25,11 +25,11 @@ for await event in stream {
You can also send encodable objects to the client:

```swift
struct MyEncodableClass: Encodable {
let title: String
struct MyEncodableObject: Encodable, Sendable {
let title: String
}

let objectToEncode = MyEncodableClass(title: "Title")
let objectToEncode = MyEncodableObject(title: "Title")

try await client.sendJSONData(objectToEncode)
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import Foundation

public protocol AsyncWebSocketClientProtocol {
public protocol AsyncWebSocketClientProtocol: Sendable {
func connect() async throws
func disconnect() async throws
func send(_ data: AsyncWebSocketData) async throws
Expand Down
2 changes: 1 addition & 1 deletion Sources/AsyncWebSocketClient/AsyncWebSocketData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import Foundation

public enum AsyncWebSocketData {
public enum AsyncWebSocketData: Sendable {
case data(Data)
case string(String)
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/AsyncWebSocketClient/AsyncWebSocketEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import Foundation

public enum AsyncWebSocketEvent {
public enum AsyncWebSocketEvent: Sendable {
case socketOpened
case socketClosed(Error?)
case dataReceived(AsyncWebSocketData)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import Foundation

actor StreamGenerator<T> {
actor StreamGenerator<T: Sendable> {
var subscribers = [UUID: AsyncStream<T>.Continuation]()

var value: T { _value }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ protocol URLSessionWebSocketTaskWrapper {
func wrappedResume()
func wrappedCancel(with closeCode: URLSessionWebSocketTask.CloseCode, reason: Data?)
func wrappedSend(
_ message: URLSessionWebSocketTask.Message, completionHandler: @escaping (Error?) -> Void)
_ message: URLSessionWebSocketTask.Message,
completionHandler: @Sendable @escaping (Error?) -> Void
)
func wrappedReceive(
completionHandler: @escaping (Result<URLSessionWebSocketTask.Message, Error>) -> Void)
func wrappedSendPing(pongReceiveHandler: @escaping (Error?) -> Void)
completionHandler: @Sendable @escaping (Result<URLSessionWebSocketTask.Message, Error>) -> Void)
func wrappedSendPing(pongReceiveHandler: @Sendable @escaping (Error?) -> Void)
}

extension URLSessionWebSocketTask: URLSessionWebSocketTaskWrapper {
Expand All @@ -26,16 +28,15 @@ extension URLSessionWebSocketTask: URLSessionWebSocketTaskWrapper {
cancel(with: closeCode, reason: reason)
}

func wrappedSend(_ message: Message, completionHandler: @escaping (Error?) -> Void) {
func wrappedSend(_ message: Message, completionHandler: @Sendable @escaping (Error?) -> Void) {
send(message, completionHandler: completionHandler)
}

func wrappedReceive(completionHandler: @escaping (Result<Message, Error>) -> Void) {
func wrappedReceive(completionHandler: @Sendable @escaping (Result<Message, Error>) -> Void) {
receive(completionHandler: completionHandler)
}

func wrappedSendPing(pongReceiveHandler: @escaping (Error?) -> Void) {

func wrappedSendPing(pongReceiveHandler: @Sendable @escaping (Error?) -> Void) {
sendPing { error in
pongReceiveHandler(error)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
//

import AsyncWebSocketClient
@preconcurrency import Combine
import Foundation

open class AsyncWebSocketClientMock: AsyncWebSocketClientProtocol {
open class AsyncWebSocketClientMock: AsyncWebSocketClientProtocol, @unchecked Sendable {
public var connectWasCalledCount = 0
public func connect() async throws {
connectWasCalledCount += 1
Expand All @@ -31,7 +32,7 @@ open class AsyncWebSocketClientMock: AsyncWebSocketClientProtocol {

let stream = $streamSocketEvent.values
return AsyncStream { continuation in
let cancellableTask = Task {
let cancellableTask = Task { @Sendable in
for await event in stream {
try Task.checkCancellation()
continuation.yield(event)
Expand Down
53 changes: 0 additions & 53 deletions SwiftFormatConfiguration.json

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import Foundation

@testable import AsyncWebSocketClient

final class MockURLSessionWebSocketTaskWrapper: URLSessionWebSocketTaskWrapper {
final class MockURLSessionWebSocketTaskWrapper: URLSessionWebSocketTaskWrapper, @unchecked Sendable
{
init() {}

var resumeWasCalledCount = 0
Expand Down