-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
GitOrigin-RevId: a79b90748b0e978610a0da2f7e7bfa8b40a44c03
- Loading branch information
Showing
5 changed files
with
511 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
xcuserdata/ | ||
*workspace/ | ||
td/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# TDLib swift MacOS example | ||
|
||
TDLib should be prebuilt and installed to local subdirectory `td/`: | ||
``` | ||
cd <path to TDLib sources> | ||
mkdir build | ||
cd build | ||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=../example/swift/td .. | ||
cmake --build . --target install | ||
``` | ||
|
||
Then you can open and build the exampe with XCode. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
import Foundation | ||
|
||
class TdClient { | ||
typealias Client = UnsafeMutableRawPointer | ||
var client = td_json_client_create()! | ||
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 | ||
var closing = false | ||
|
||
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_json_client_send(self.client, 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 | ||
|
||
} | ||
|
||
func close() { | ||
closing = true | ||
} | ||
init() { | ||
} | ||
deinit { | ||
td_json_client_destroy(client) | ||
} | ||
func run(updateHandler: @escaping (Dictionary<String,Any>)->()) { | ||
updateF = updateHandler | ||
tdlibMainLoop.async { [weak self] in | ||
while (true) { | ||
if let s = self { | ||
if s.closing { | ||
break | ||
} | ||
if let res = td_json_client_receive(s.client,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) | ||
} | ||
} | ||
} | ||
} | ||
|
||
|
||
} | ||
|
||
// Just an example of usage | ||
func to_json(_ obj: Any) -> String { | ||
do { | ||
let obj = try JSONSerialization.data(withJSONObject: obj) | ||
return String(data: obj, encoding: .utf8)! | ||
} catch { | ||
return "" | ||
} | ||
|
||
} | ||
func myReadLine() -> String { | ||
while (true) { | ||
if let line = readLine() { | ||
return line | ||
} | ||
} | ||
} | ||
|
||
|
||
td_set_log_verbosity_level(2); | ||
var client = TdClient() | ||
func updateAuthorizationState(authState : Dictionary<String, Any>) { | ||
switch(authState["@type"] as! String) { | ||
case "authorizationStateWaitTdlibParameters": | ||
client.queryAsync(query:[ | ||
"@type":"setTdlibParameters", | ||
"parameters":[ | ||
"use_message_database":true, | ||
"use_secret_chats":true, | ||
"api_id":94575, | ||
"api_hash":"a3406de8d171bb422bb6ddf3bbd800e2", | ||
"system_language_code":"en", | ||
"device_model":"Desktop", | ||
"system_version":"Unknown", | ||
"application_version":"1.0", | ||
"enable_storage_optimizer":true | ||
] | ||
]); | ||
case "authorizationStateWaitEncryptionKey": | ||
client.queryAsync(query: ["@type":"checkDatabaseEncryptionKey", "key":"cucumber"]) | ||
|
||
case "authorizationStateWaitPhoneNumber": | ||
print("Enter your phone: ") | ||
let phone = myReadLine() | ||
client.queryAsync(query:["@type":"setAuthenticationPhoneNumber", "phone_number":phone], f:checkAuthError) | ||
|
||
case "authorizationStateWaitCode": | ||
var first_name : String = "" | ||
var last_name: String = "" | ||
var code : String = "" | ||
if let is_registered = authState["is_registered"] as? Bool, is_registered { | ||
} else { | ||
print("Enter your first name : ") | ||
first_name = myReadLine() | ||
print("Enter your last name: ") | ||
last_name = myReadLine() | ||
} | ||
print("Enter (sms) code: ") | ||
code = myReadLine() | ||
client.queryAsync(query:["@type":"checkAuthenticationCode", "code":code, "first_name":first_name, "last_name":last_name], f:checkAuthError) | ||
case "authorizationStateWaitPassword": | ||
print("Enter password: ") | ||
let password = myReadLine() | ||
client.queryAsync(query:["@type":"checkAuthenticationPassword", "password":password], f:checkAuthError) | ||
case "authorizationStateReady": | ||
() | ||
default: | ||
assert(false, "TODO: Unknown auth state "); | ||
|
||
} | ||
} | ||
|
||
func checkAuthError(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(authState: update["authorization_state"] as! Dictionary<String, Any>) | ||
} | ||
} | ||
|
||
while true { | ||
sleep(1) | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
// | ||
// Copyright Aliaksei Levin ([email protected]), Arseny Smirnov ([email protected]) 2014-2018 | ||
// | ||
// 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) | ||
// | ||
// | ||
// Use this file to import your target's public headers that you would like to expose to Swift. | ||
// | ||
|
||
#include "td/telegram/td_json_client.h" | ||
#include "td/telegram/td_log.h" |
Oops, something went wrong.