【发布时间】:2020-09-28 10:03:08
【问题描述】:
我正在编写一个连接在线翻译 API 的翻译应用程序。由于 API 的大小限制,我编写了我的程序,一次发送一个句子,然后将翻译连接在一起。我已经循环了
let serialQueue = DispatchQueue(label: "translationQueue")
for line in lines {
serialQueue.async {
print("line is: " + line)
var jpText = String(line)
if jpText.isEmpty {
jpText = "\n"
}
let escapedStr = jpText.addingPercentEncoding(withAllowedCharacters: (NSCharacterSet.urlQueryAllowed))
let urlStr:String = ("https://api.mymemory.translated.net/get?q="+escapedStr!+"&langpair="+langStr!)
let url = URL(string: urlStr)
// Creating Http Request
let request = NSURLRequest(url: url!)
// If empty, don't feed to translator.
if escapedStr!.isEmpty {
//translatedLines.append("\n")
self.enTextView.text = translatedLines
}
else {
let configuration = URLSessionConfiguration.default
configuration.waitsForConnectivity = true
let defaultSession = URLSession(configuration: configuration, delegate: self, delegateQueue: nil)
var dataTask: URLSessionDataTask?
let group = DispatchGroup()
group.enter()
dataTask?.cancel()
dataTask = defaultSession.dataTask(with: request as URLRequest) { [weak self] data, response, error in
if let error = error {
// self?.errorMessage += "DataTask error: " + error.localizedDescription + "\n"
print("DataTask error: " + error.localizedDescription + "\n")
} else if
let data = data,
let response = response as? HTTPURLResponse,
response.statusCode == 200 {
let jsonDict: NSDictionary!=((try! JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers)) as! NSDictionary)
// if(jsonDict.value(forKey: "responseStatus") as! NSNumber == 200){
let responseData: NSDictionary = jsonDict.object(forKey: "responseData") as! NSDictionary
group.leave()
var translatedString = String()
translatedString = responseData.object(forKey: "translatedText") as! String
let data = translatedString.data(using: .utf8)
let options: [NSAttributedString.DocumentReadingOptionKey: Any] = [
.documentType: NSAttributedString.DocumentType.html,
.characterEncoding: String.Encoding.utf8.rawValue
]
guard let attributedString = try? NSAttributedString(data: data!, options: options, documentAttributes: .none) else {
return
}
let decodedString = attributedString.string
print("decoded: " + decodedString)
translatedLines.append(decodedString)
translatedLines.append("\n")
DispatchQueue.main.async {
self?.enTextView.text = translatedLines
}
}
}
dataTask?.resume()
group.wait()
}
}
}
但是翻译输出的顺序是随机的。我大致了解正在发送并发请求。但是我可以在我的 for 循环中做些什么来确保整个发送/接收在移动到下一次迭代之前发生?
【问题讨论】:
-
序列化异步。最简单的方法是调度组加等待加通知。我个人会使用 Combine Framework,但这更难。
-
请在回复中详细说明。
标签: json swift http concurrency urlsession