### Close TDLib Clients Properly in Swift Source: https://context7.com/swiftgram/tdlibkit/llms.txt Demonstrates different methods for closing TDLib clients to ensure data integrity. It includes a non-blocking close with a completion handler, an asynchronous close using async/await (available from iOS 13/macOS 10.15), and a blocking close for all clients via `TDLibClientManager`. The example also shows how to call this on application termination. ```swift // Non-blocking close with completion func closeClientAsync() { do { try client.close(completion: { result in switch result { case .success: print("Client closed successfully") case .failure(let error): print("Close error: \(error)") } }) } catch { print("Failed to initiate close: \(error)") } } // Async/await close @available(iOS 13.0, macOS 10.15, watchOS 6.0, tvOS 13.0, *) func closeClientAsync() async { do { try await client.close() print("Client closed successfully") } catch { print("Failed to close: \(error)") } } // Blocking close for all clients (call on app termination) func closeAllClients() { manager.closeClients() print("All clients closed") } // In app delegate func applicationWillTerminate(_ notification: Notification) { manager.closeClients() } ``` -------------------------------- ### Implement Custom TDLib Logger in Swift Source: https://context7.com/swiftgram/tdlibkit/llms.txt Provides a concrete implementation of the `TDLibLogger` protocol to create a custom logger that monitors TDLib communication. The `StdOutLogger` class logs messages to the console asynchronously using a dedicated queue to avoid blocking the main thread. It includes usage example. ```swift import TDLibKit import Foundation public final class StdOutLogger: TDLibLogger { private let queue: DispatchQueue public init() { queue = DispatchQueue(label: "com.app.tdlib.logger", qos: .userInitiated) } public func log(_ message: String, type: LoggerMessageType?) { queue.async { var header = "----------------------------" if let type = type { header = ">> \(type.description): ---------------" } print(""" \(header) \(message) ---------------------------- """) } } } // Usage let logger = StdOutLogger() let manager = TDLibClientManager(logger: logger) ``` -------------------------------- ### Fetch Chat History with Async/Await in Swift Source: https://context7.com/swiftgram/tdlibkit/llms.txt Retrieves messages from a specified chat using Swift's modern concurrency features (async/await). It fetches a limited number of messages, starting from the latest, and prints details about each message, including its content type (text, photo, video). Dependencies include the TDLibKit client. Handles potential errors during the fetch operation. ```swift @available(iOS 13.0, macOS 10.15, watchOS 6.0, tvOS 13.0, *) func loadChatMessages(chatId: Int64) async { do { let chatHistory = try await client.getChatHistory( chatId: chatId, fromMessageId: 0, // Start from latest message limit: 50, offset: 0, onlyLocal: false // Fetch from server if needed ) print("Loaded (chatHistory.messages?.count ?? 0) messages") for message in chatHistory.messages ?? [] { print("Message ID: (message.id)") print("Date: (Date(timeIntervalSince1970: TimeInterval(message.date)))") print("Is outgoing: (message.isOutgoing)") switch message.content { case .messageText(let text): print("Text: (text.text.text)") case .messagePhoto(let photo): print("Photo with (photo.photo.sizes.count) sizes") if let largestSize = photo.photo.sizes.last { print("Largest: (largestSize.width)x(largestSize.height)") } case .messageVideo(let video): print("Video: (video.video.duration)s, (video.video.width)x(video.video.height)") default: print("Content type: (message.content)") } } } catch { print("Failed to get chat history: (error)") } } ``` -------------------------------- ### Initialize TDLib with Parameters in Swift Source: https://context7.com/swiftgram/tdlibkit/llms.txt Configures TDLib with essential application details and database settings. This includes API credentials obtained from 'my.telegram.org', application version, directory paths for the database and files, and various other configuration options like database usage and test data center preference. It uses a completion handler to report success or failure. ```swift do { try client.setTdlibParameters( apiHash: "your_api_hash_from_my_telegram_org", apiId: 12345678, // Your API ID from my.telegram.org applicationVersion: "1.0.0", databaseDirectory: "/path/to/database", databaseEncryptionKey: "encryption_key".data(using: .utf8), deviceModel: "iPhone 15 Pro", filesDirectory: "/path/to/files", systemLanguageCode: "en", systemVersion: "iOS 17.0", useChatInfoDatabase: true, useFileDatabase: true, useMessageDatabase: true, useSecretChats: true, useTestDc: false, completion: { result in switch result { case .success: print("TDLib parameters set successfully") case .failure(let error): print("Failed to set parameters: \(error)") } } ) } catch { print("Error setting parameters: \(error)") } ``` -------------------------------- ### Generate Swift Sources from TL-Scheme using tl2swift Source: https://github.com/swiftgram/tdlibkit/blob/main/scripts/tl2swift/README.md This command utilizes the `tl2swift` tool to generate Swift source files from a downloaded TDLib TL-scheme. It takes the TL-scheme file and an output directory as arguments. ```shell swift run tl2swift td_api.tl ./output/ ``` -------------------------------- ### Initialize TDLib Client Manager with Logger (Swift) Source: https://github.com/swiftgram/tdlibkit/blob/main/README.md Shows how to instantiate the `TDLibClientManager` with a custom logger implementation. By passing an instance of `StdOutLogger` to the manager, all TDLib operations will be logged according to the custom logger's configuration. This is useful for debugging and monitoring TDLib activity. ```swift let manager = TDLibClientManager(logger: StdOutLogger()) ``` -------------------------------- ### Download TDLib TL-Scheme using curl Source: https://github.com/swiftgram/tdlibkit/blob/main/scripts/tl2swift/README.md This command downloads the TDLib API scheme file (`td_api.tl`) from a remote URL using `curl`. This file is essential for the `tl2swift` tool to generate Swift code. ```shell curl https://raw.githubusercontent.com/tdlib/td/master/td/generate/scheme/td_api.tl -o td_api.tl ``` -------------------------------- ### Execute Synchronous TDLib Requests in Swift Source: https://context7.com/swiftgram/tdlibkit/llms.txt Demonstrates how to execute synchronous TDLib requests, such as setting the log level or checking the TDLib version. This method is suitable for operations that support immediate execution as per TDLib documentation. It utilizes the `client.execute` method and includes error handling. ```swift // Only works for methods marked "Can be called synchronously" in TDLib docs func setLogLevel(level: Int) { let query = SetLogVerbosityLevel(newVerbosityLevel: level) do { if let result = try client.execute(query: query) { print("Log level set: \(result)") } else { print("Empty response") } } catch { print("Failed to set log level: \(error.localizedDescription)") } } // Check TDLib version synchronously func checkVersion() { let query = GetOption(name: "version") do { if let result = try client.execute(query: query), let version = result["value"] as? [String: Any], let versionString = version["value"] as? String { print("TDLib version: \(versionString)") } } catch { print("Failed to get version: \(error)") } } ``` -------------------------------- ### Create TDLibClientManager in Swift Source: https://context7.com/swiftgram/tdlibkit/llms.txt Initializes the TDLibClientManager, which is responsible for the global receive loop and routing updates to individual clients. It's recommended to create only one instance of this manager per application. An optional logger can be provided for debugging. ```swift import TDLibKit // Create manager with optional logger let manager = TDLibClientManager(logger: StdOutLogger()) // Manager automatically starts polling for updates // Only create ONE manager instance per application ``` -------------------------------- ### Execute Synchronous TDLib Requests in Swift Source: https://github.com/swiftgram/tdlibkit/blob/main/README.md Demonstrates how to execute synchronous TDLib API requests for methods that support it. It sends a `SetLogVerbosityLevel` query and handles the potential dictionary response or errors. ```swift 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)") } ``` -------------------------------- ### Generate Swift Sources with TDLib Version and Commit using tl2swift Source: https://github.com/swiftgram/tdlibkit/blob/main/scripts/tl2swift/README.md This command generates Swift source files from a TDLib TL-scheme and optionally embeds the TDLib version and commit hash in the header comments of the generated files. This is useful for tracking the TDLib version used during code generation. ```shell swift run tl2swift td_api.tl ./output/ 1.7.5 73d8fb4 ``` -------------------------------- ### Create TDLibKit Client Manager in Swift Source: https://github.com/swiftgram/tdlibkit/blob/main/README.md Instantiates a TDLibClientManager, which is responsible for managing TDLib clients and polling for updates. It's important to create only one instance of TDLibClientManager as td_receive can only be called from a single thread. ```swift import TDLibKit let manager = TDLibClientManager() ``` -------------------------------- ### Create TDLibClient and Handle Updates in Swift Source: https://context7.com/swiftgram/tdlibkit/llms.txt Creates an individual TDLib client for a distinct Telegram session and defines a handler for receiving and processing updates. The update handler decodes incoming data into TDLib's `Update` type and dispatches based on the update's content, such as new messages or authorization state changes. ```swift let client = manager.createClient(updateHandler: { data, client in do { let update = try client.decoder.decode(Update.self, from: data) switch update { case .updateNewMessage(let newMsg): switch newMsg.message.content { case .messageText(let text): print("Text: \(text.text.text)") case .messagePhoto(let photo): print("Photo caption: \(photo.caption.text)") case .messageSticker(let sticker): print("Sticker emoji: \(sticker.sticker.emoji)") default: print("Other message type") } case .updateAuthorizationState(let authState): switch authState.authorizationState { case .authorizationStateWaitTdlibParameters: print("Waiting for TDLib parameters") case .authorizationStateReady: print("Authorized and ready") case .authorizationStateClosed: print("Client closed") default: break } case .updateMessageEdited(let edited): print("Message \(edited.messageId) edited in chat \(edited.chatId)") default: print("Unhandled update: \(update)") } } catch { print("Decode error: \(error.localizedDescription)") } }) ``` -------------------------------- ### Fetch Chat History with Completion Handlers in Swift Source: https://context7.com/swiftgram/tdlibkit/llms.txt Provides an alternative method to load chat messages using completion handlers, suitable for maintaining backward compatibility with older Swift versions. It asynchronously fetches messages and processes them within a closure, handling success and failure cases. The output includes message IDs and content summaries. ```swift func loadChatMessagesWithCompletion(chatId: Int64) { do { try client.getChatHistory( chatId: chatId, fromMessageId: 0, limit: 50, offset: 0, onlyLocal: false, completion: { result in switch result { case .success(let messages): print("Loaded (messages.messages?.count ?? 0) messages") for message in messages.messages ?? [] { switch message.content { case .messageText(let text): print("[(message.id)] (text.text.text)") case .messageAnimation: print("[(message.id)] ") case .messageSticker(let sticker): print("[(message.id)] (sticker.sticker.emoji)") default: print("[(message.id)] <(type(of: message.content))>") } } case .failure(let error): print("Error loading messages: (error.localizedDescription)") } } ) } catch { print("Failed to send request: (error)") } } ``` -------------------------------- ### Implement Custom TDLib Logger (Swift) Source: https://github.com/swiftgram/tdlibkit/blob/main/README.md Provides a Swift implementation of the `TDLibLogger` protocol to log TDLib messages to standard output. The `StdOutLogger` class uses a dedicated `DispatchQueue` for asynchronous logging, ensuring thread safety and preventing blocking of the main thread. It formats log messages with a type indicator and separators. ```swift 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) --------------------------- """) } } } ``` -------------------------------- ### Fetch Chat History Asynchronously in Swift Source: https://github.com/swiftgram/tdlibkit/blob/main/README.md Shows how to make an asynchronous `getChatHistory` request using Swift's async/await syntax. It retrieves a specified number of messages from a chat and iterates through them, printing text content or indicating other media types. ```swift do { let chatHistory = try await client.getChatHistory( chatId: chatId, fromMessageId: 0, limit: 50, offset: 0, onlyLocal: false ) for message in chatHistory.messages { switch message.content { case .messageText(let text): print(text.text.text) case .messageAnimation: print("") case .messagePhoto(let photo): print("\n\(photo.caption.text)") case .messageSticker(let sticker): print(sticker.sticker.emoji) case .messageVideo(let video): print("