initial
This commit is contained in:
189
td/example/swift/src/main.swift
Normal file
189
td/example/swift/src/main.swift
Normal file
@@ -0,0 +1,189 @@
|
||||
//
|
||||
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
// TDLib Client Swift binding
|
||||
class TdClient {
|
||||
var client_id = td_create_client_id()
|
||||
let tdlibMainLoop = DispatchQueue(label: "TDLib")
|
||||
let tdlibQueryQueue = DispatchQueue(label: "TDLibQuery")
|
||||
var queryF = Dictionary<Int64, (Dictionary<String,Any>)->()>()
|
||||
var updateF: ((Dictionary<String,Any>)->())?
|
||||
var queryId: Int64 = 0
|
||||
|
||||
func queryAsync(query: [String: Any], f: ((Dictionary<String,Any>)->())? = nil) {
|
||||
tdlibQueryQueue.async {
|
||||
var newQuery = query
|
||||
|
||||
if f != nil {
|
||||
let nextQueryId = self.queryId + 1
|
||||
newQuery["@extra"] = nextQueryId
|
||||
self.queryF[nextQueryId] = f
|
||||
self.queryId = nextQueryId
|
||||
}
|
||||
td_send(self.client_id, to_json(newQuery))
|
||||
}
|
||||
}
|
||||
|
||||
func querySync(query: [String: Any]) -> Dictionary<String,Any> {
|
||||
let semaphore = DispatchSemaphore(value:0)
|
||||
var result = Dictionary<String,Any>()
|
||||
queryAsync(query: query) {
|
||||
result = $0
|
||||
semaphore.signal()
|
||||
}
|
||||
semaphore.wait()
|
||||
return result
|
||||
}
|
||||
|
||||
init() {
|
||||
}
|
||||
|
||||
deinit {
|
||||
}
|
||||
|
||||
func run(updateHandler: @escaping (Dictionary<String,Any>)->()) {
|
||||
updateF = updateHandler
|
||||
tdlibMainLoop.async { [weak self] in
|
||||
while (true) {
|
||||
if let s = self {
|
||||
if let res = td_receive(10) {
|
||||
let event = String(cString: res)
|
||||
s.queryResultAsync(event)
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func queryResultAsync(_ result: String) {
|
||||
tdlibQueryQueue.async {
|
||||
let json = try? JSONSerialization.jsonObject(with: result.data(using: .utf8)!, options:[])
|
||||
if let dictionary = json as? [String:Any] {
|
||||
if let extra = dictionary["@extra"] as? Int64 {
|
||||
let index = self.queryF.index(forKey: extra)!
|
||||
self.queryF[index].value(dictionary)
|
||||
self.queryF.remove(at: index)
|
||||
} else {
|
||||
self.updateF!(dictionary)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func to_json(_ obj: Any) -> String {
|
||||
do {
|
||||
let obj = try JSONSerialization.data(withJSONObject: obj)
|
||||
return String(data: obj, encoding: .utf8)!
|
||||
} catch {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var client = TdClient()
|
||||
|
||||
// start the client by sending request to it
|
||||
client.queryAsync(query: ["@type":"getOption", "name":"version"])
|
||||
|
||||
func myReadLine() -> String {
|
||||
while (true) {
|
||||
if let line = readLine() {
|
||||
return line
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func updateAuthorizationState(authorizationState: Dictionary<String, Any>) {
|
||||
switch(authorizationState["@type"] as! String) {
|
||||
case "authorizationStateWaitTdlibParameters":
|
||||
client.queryAsync(query:[
|
||||
"@type":"setTdlibParameters",
|
||||
"database_directory":"tdlib",
|
||||
"use_message_database":true,
|
||||
"use_secret_chats":true,
|
||||
"api_id":94575,
|
||||
"api_hash":"a3406de8d171bb422bb6ddf3bbd800e2",
|
||||
"system_language_code":"en",
|
||||
"device_model":"Desktop",
|
||||
"application_version":"1.0"
|
||||
]);
|
||||
|
||||
case "authorizationStateWaitPhoneNumber":
|
||||
print("Enter your phone number: ")
|
||||
let phone_number = myReadLine()
|
||||
client.queryAsync(query:["@type":"setAuthenticationPhoneNumber", "phone_number":phone_number], f:checkAuthenticationError)
|
||||
|
||||
case "authorizationStateWaitEmailAddress":
|
||||
print("Enter your email address: ")
|
||||
let email_address = myReadLine()
|
||||
client.queryAsync(query:["@type":"setAuthenticationEmailAddress", "email_address":email_address], f:checkAuthenticationError)
|
||||
|
||||
case "authorizationStateWaitEmailCode":
|
||||
var code: String = ""
|
||||
print("Enter email code: ")
|
||||
code = myReadLine()
|
||||
client.queryAsync(query:["@type":"checkAuthenticationEmailCode", "code":["@type":"emailAddressAuthenticationCode", "code":code]], f:checkAuthenticationError)
|
||||
|
||||
case "authorizationStateWaitCode":
|
||||
var code: String = ""
|
||||
print("Enter (SMS) code: ")
|
||||
code = myReadLine()
|
||||
client.queryAsync(query:["@type":"checkAuthenticationCode", "code":code], f:checkAuthenticationError)
|
||||
|
||||
case "authorizationStateWaitRegistration":
|
||||
var first_name: String = ""
|
||||
var last_name: String = ""
|
||||
print("Enter your first name: ")
|
||||
first_name = myReadLine()
|
||||
print("Enter your last name: ")
|
||||
last_name = myReadLine()
|
||||
client.queryAsync(query:["@type":"registerUser", "first_name":first_name, "last_name":last_name], f:checkAuthenticationError)
|
||||
|
||||
case "authorizationStateWaitPassword":
|
||||
print("Enter password: ")
|
||||
let password = myReadLine()
|
||||
client.queryAsync(query:["@type":"checkAuthenticationPassword", "password":password], f:checkAuthenticationError)
|
||||
|
||||
case "authorizationStateReady":
|
||||
()
|
||||
|
||||
case "authorizationStateLoggingOut":
|
||||
print("Logging out...")
|
||||
|
||||
case "authorizationStateClosing":
|
||||
print("Closing...")
|
||||
|
||||
case "authorizationStateClosed":
|
||||
print("Closed.")
|
||||
|
||||
default:
|
||||
assert(false, "TODO: Unexpected authorization state");
|
||||
}
|
||||
}
|
||||
|
||||
func checkAuthenticationError(error: Dictionary<String, Any>) {
|
||||
if (error["@type"] as! String == "error") {
|
||||
client.queryAsync(query:["@type":"getAuthorizationState"], f:updateAuthorizationState)
|
||||
}
|
||||
}
|
||||
|
||||
client.run {
|
||||
let update = $0
|
||||
print(update)
|
||||
if update["@type"] as! String == "updateAuthorizationState" {
|
||||
updateAuthorizationState(authorizationState: update["authorization_state"] as! Dictionary<String, Any>)
|
||||
}
|
||||
}
|
||||
|
||||
while true {
|
||||
sleep(1)
|
||||
}
|
||||
9
td/example/swift/src/td-Bridging-Header.h
Normal file
9
td/example/swift/src/td-Bridging-Header.h
Normal file
@@ -0,0 +1,9 @@
|
||||
//
|
||||
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#include "td/telegram/td_json_client.h"
|
||||
#include "td/telegram/td_log.h"
|
||||
Reference in New Issue
Block a user