最近、自分でTelegram Bot APIを書き込もうとしました。しかし、このプロジェクトは、URLSession(以前のNSURLSession)の問題でレンガの壁に当たったようです。次のようにURLSessionから受信したデータを取得する方法を教えてください。
コール構造は次のとおりです。
理想的getMe() -> getData() -> NSURLSession
、私は、プロセスへの適用のために戻っgetMe()
に渡さNSURLSession
から返されたデータを持っていると思います。しかし、これは私が試した方法では可能ではありませんでした。
以下は私が使用しているコードです。 synthesiseURL()
は、Telegram Bot APIでアクションを実行するために、アプリケーションがセッションを開くURLを生成します。 synthesiseURL()
によって生成されたURLのテンプレートはhttps://api.telegram.org/bot\(token)/\(tgMethod)
です。
// NSURLSession getData: gets data from Telegram Bot API
func getData(tgMethod: String, arguments: [String] = [String](), caller: String = #function) {
let url = synthesiseURL(tgMethod: "getMe"), request = NSMutableURLRequest(url: url)
var receivedData = String()
let session = URLSession.shared.dataTask(with: request as URLRequest) { data, response, err in
if err != nil {print(err!.localizedDescription); return}
DispatchQueue.main.async {
receivedData = String(data: data!, encoding: String.Encoding.nonLossyASCII)!
print(receivedData)
}
}
session.resume()
}
私は戻っ機能getMe
に、ボットAPIの応答が含まれているreceivedData
を、渡すためにgetData
を取得しようとしてきました。
func getMe() -> String {
HTTPInterface(botToken: token).get(tgMethod: "getMe")
return [???] // here's where the data from getData() should come
}
私はメインスレッドに完了ハンドラ、コールバック、非同期呼び出しなどを試してみましたが、予想通り、いずれも(空の文字列を返しますgetMe()
)働いているように見えません。
なぜそうであり、修正できますか?
あなたの答えをありがとう!あなたが提案した閉鎖に関して、私はこのデータをどのようにしてメインスレッド上で処理すべきですか? 'getMe()'が返り値として使うために 'getMe()'にデータを渡すことは可能でしょうか? – perhapsmaybeharry
@perhapsmaybeharry 'getMe()'関数の中でディスパッチセマフォのようなものを使うと、 'getMe()'がURLSessionからの応答を得るまで実行を一時停止し、その答えを戻り値として使うことができます。しかし、これは主なスレッドをブロックし、応答が返ってくるまでUIをフリーズする可能性があります(悪い考え方)。最善の方法は、 'getMe()'を呼び出すコードがクロージャー内を通過するようにすることです。これは、 'getMe()'が非同期的に完了したときにString結果で実行されるべきで、 'getMe()関数。私は見る。 –
その意味で、私は非同期補完ハンドラを使うつもりだと思います。ご協力いただきありがとうございます! – perhapsmaybeharry