ExarotonAPI

API,用于 Exaroton (Swift)

用法 🤩

这个 Swift 包包含以下产品

  1. ExarotonHTTP: 使用 swift-openapi-generatorexaroton openapi spec 生成的 httpclient,你可以使用 Swagger Editor 查看 OpenAPI Spec

  2. ExarotonWebSocket: WebSocket 功能

HTTPClient

添加依赖: ExarotonHTTP

import PackageDescription

let package = Package(
    ...
    dependencies: [
        .package(url: "https://github.com/wangzhizhou/ExarotonAPI.git", branch: "main"),
    ],
    targets: [
        .target(
            name: "Your Target Name",
            dependencies: [
                .product(name: "ExarotonHTTP", package: "ExarotonAPI"),
                ...
            ]),
    ]
    ...
)

使用 ExarotonHTTP

import Foundation
import ExarotonHTTP
import OpenAPIRuntime
import OpenAPIURLSession

@main
struct HttpUsageDemo {
    static func main() async throws {

        let yourAccountToken = ProcessInfo.processInfo.environment["TOKEN"] ?? ""

        let client = Client(
            serverURL: try! Servers.server1(),
            transport: URLSessionTransport(),
            middlewares: [AuthenticationMiddleware(token: yourAccountToken)]
        )
        let response = try await client.getAccount()

        switch response {
        case .ok(let ok):
            if let data = try ok.body.json.data,
               let name = data.name {
                print("account: \(name)")
            }
        case .forbidden(let forbidden):
            let json = try forbidden.body.json
            print(json.error ?? "")
        case .undocumented(let statusCode, let unknownPayload):
            print("statusCode:\(statusCode), payload: \(unknownPayload)")
        }
    }
}

更多用例

WebSocketClient

添加依赖: ExarotonWebSocket

import PackageDescription

let package = Package(
    ...
    dependencies: [
        .package(url: "https://github.com/wangzhizhou/ExarotonAPI.git", branch: "main"),
    ],
    targets: [
        .target(
            name: "Your Target Name",
            dependencies: [
                .product(name: "ExarotonWebSocket", package: "ExarotonAPI"),
                ...
            ]),
    ]
    ...
)

使用 ExarotonWebSocket

import Foundation
import ExarotonWebSocket
import Starscream

@main
struct WebSocketUsageDemo {

    static func main() async throws {
        
        let socket = ExarotonWebSocketAPI(
            token: ProcessInfo.processInfo.environment["TOKEN"] ?? "your_account_token",
            serverId: ProcessInfo.processInfo.environment["SERVER"] ?? "your_server_id",
            delegate: ServerEventHandler()
        )
        
        socket.client.connect()
        try await wait(for: socket.timeout)

        let consoleStreamMessage = ExarotonMessage(
            stream: .console,
            type: StreamType.start,
            data: ["tail": 2]
        )
        socket.client.write(stringData: try consoleStreamMessage.toData) {
            print("console stream start completed!")
        }

        try await wait(for: socket.timeout)
        socket.client.disconnect()
    }

    static func wait(for minutes: Double) async throws {
        try await Task.sleep(nanoseconds: UInt64(1_000_000_000 * minutes))
    }
}

final class ServerEventHandler: ExarotonServerEventHandlerProtocol {

    func onReady(serverID: String?) {
        print("server ready: \(serverID ?? "")")
    }

    func onConnected() {
        print("server connected")
    }

    func onDisconnected(reason: String?) {
        print("server disconnected: \(reason ?? "")")
    }

    func onKeepAlive() {
        print("server keep alive")
    }

    func onStatusChanged(_ info: ExarotonWebSocket.Server?) {
        if let info {
            print("status: \(info)")
        }
    }

    func onStreamStarted(_ stream: ExarotonWebSocket.StreamCategory?) {
        if let stream {
            print("stream started: \(stream)")
        }
    }

    func onStreamStopped(_ stream: StreamCategory?) {
        if let stream {
            print("stream stopped: \(stream)")
        }
    }

    func onConsoleLine(_ line: String?) {
        if let line {
            print("console line: \(line)")
        }
    }

    func onTick(_ tick: ExarotonWebSocket.Tick?) {
        if let tick {
            print("tick: \(tick)")
        }
    }

    func onStats(_ stats: ExarotonWebSocket.Stats?) {
        if let stats {
            print("stats: \(stats)")
        }
    }

    func onHeap(_ heap: ExarotonWebSocket.Heap?) {
        if let heap {
            print("heap: \(heap)")
        }
    }

    // MARK: WebSocketDelegate
    func didReceive(event: Starscream.WebSocketEvent, client: any Starscream.WebSocketClient) {
        // all events, if you need process them your self
    }
}

更多用例

开发 👨🏻‍💻

如果你想为此项目做贡献,你可以使用你的 Mac 设备并安装 Xcode(>= 15.3) 开始

运行以下 shell 命令来获取项目并使用 Xcode 编辑器打开它

$ git clone https://github.com/wangzhizhou/ExarotonAPI.git
$ cd ExarotonAPI && xed .

当你使用 Xcode 打开项目,并且依赖项被拉取到本地后,你可以打开 target schema

schema

将环境变量 TOKEN SERVER POOL (你的密钥) 添加到 schema 中

xcode schema env vars



然后你可以使用快捷键: CMD+U 运行所有单元测试,或者你可以从 Product -> Test 菜单运行测试

如果一切顺利,你将看到单元测试运行并成功或失败,如下所示

unit tests