TDLibKit

CI

TDLibKit 是 TDLib 的原生 Swift 封装,支持 iOS、macOS、watchOS、tvOS 和 visionOS。

基于预构建的多平台 TDLibFramework 实现的 TDLib 和使用 tl2swift 生成的源码驱动。

安装

Xcode

  1. 安装最新版 Xcode
  2. Project > Swift Packages 中添加 https://github.com/Swiftgram/TDLibKit 作为 SPM 依赖项。这可能需要一段时间,因为它会从 TDLibFramework 依赖项下载大约 300mb 的二进制 zip 文件。
  3. TDLibKit 添加为你的 target 依赖项。
  4. 开始编码!

Cocoapods

集成需要类似于 TDLibFramework Cocoapods & Flutter 指南 的适配。

用法

库提供了基于不同方法的多个 API 接口

创建客户端 Manager

import TDLibKit
let manager = TDLibClientManager()

确保只创建一个 TDLibClientManager,因为 td_receive 只能从单个线程调用。

Manager 会自动轮询新更新,我们将在下面处理每个客户端。

创建客户端 & 处理更新

let client = manager.createClient(updateHandler: { /* data: Data, client: TDLibCLient */
    do {
        let update = try $1.decoder.decode(Update.self, from: $0)
        switch update {
            case .updateNewMessage(let newMsg):
                switch newMsg.message.content {
                    case .messageText(let text):
                        print("Text Message: \(text.text.text)")
                    default:
                        break
                }
            case .updateMessageEdited:
                break
                
            // ... etc

            default:
                print("Unhandled Update \(update)")
                break
        }
    } catch {
        print("Error in update handler \(error.localizedDescription)")
    }
})

同步请求

仅适用于文档中具有 "Can be called synchronously (可以同步调用)" 的方法

let query = SetLogVerbosityLevel(newVerbosityLevel: 5)
do {
    let result = try client.execute(query: DTO(query))
    if let resultDict = result {
        print("Response: \(resultDict)")
    } else {
        print("Empty result")
    }
} catch {
    print("Error in SetLogVerbosityLevel request \(error.localizedDescription)")
}

异步请求

Async/Await

do {
    let chatHistory = try await client.getChatHistory(
        chatId: chatId,
        fromMessageId: 0,
        limit: 50,
        offset: 0,
        onlyLocal: false // Request remote messages from server
    )

    for message in chatHistory.messages {
    switch message.content {
        case .messageText(let text):
            print(text.text.text)
            
        case .messageAnimation:
            print("<Animation>")
            
        case .messagePhoto(let photo):
            print("<Photo>\n\(photo.caption.text)")
            
        case .messageSticker(let sticker):
            print(sticker.sticker.emoji)
            
        case .messageVideo(let video):
            print("<Video>\n\(video.caption.text)")
            
            // ...
            
        default:
            print("Unknown message content \(message.content)")
        }
    }
} catch {
    print("Error in getChatHistory \(error)")
}

Completion Handlers

try? client.getChatHistory(
    chatId: chatId,
    fromMessageId: 0,
    limit: 50,
    offset: 0,
    onlyLocal: false, // Request remote messages from server
    completion: { result in
        // Handle Errors
        if case .failure(let error) = result {
            print("Error in getChatHistory request \(error.localizedDescription)")
        } else if let messages = try? result.get().messages {
            // Handle messages
            for message in messages {
                switch message.content {
                case .messageText(let text):
                    print(text.text.text)
                    
                case .messageAnimation:
                    print("<Animation>")
                    
                case .messagePhoto(let photo):
                    print("<Photo>\n\(photo.caption.text)")
                    
                case .messageSticker(let sticker):
                    print(sticker.sticker.emoji)
                    
                case .messageVideo(let video):
                    print("<Video>\n\(video.caption.text)")
                    
                    // ...
                    
                default:
                    print("Unknown message content \(message.content)")
                }
            }
        }
    }
)

日志记录

你可以传递带有 Logger 类型的附加参数来记录 "send, receive, execute" 和自定义条目。

import TDLibKit
public final class StdOutLogger: TDLibLogger {
    
    let queue: DispatchQueue
    
    public init() {
        queue = DispatchQueue(label: "Logger", qos: .userInitiated)
    }
    
    public func log(_ message: String, type: LoggerMessageType?) {
        queue.async {
            var fisrtLine = "---------------------------"
            if let type = type {
                fisrtLine = ">> \(type.description): ---------------"
            }
            print("""
                \(fisrtLine)
                \(message)
                ---------------------------
                """)
        }
    }
}


let manager = TDLibClientManager(logger: StdOutLogger())

关闭客户端

为确保数据完整性,你必须在应用程序终止时正确关闭所有客户端,可以使用

let client = manager.createClient()
try? client.close(completion: { _ in })

或者使用阻塞函数

manager.closeClients()

构建

你可以在 Github Actions 文件中找到更多关于构建过程的信息。

鸣谢

许可证

MIT