在Linux上尝试使用Swift快速访问牛津词典api时,我发现了一个障碍。我正在做某些错误,但我无法确定它是什么。在这一点上,我怀疑与基本操作系统有关。因此,请考虑bash代码:
curl -X GET --header 'Accept: text/plain' --header 'app_id: 8a7dd147' --header 'app_key: 7e7d022fbce6d8d4523eac3baa5bd04c' 'https://od-api.oxforddictionaries.com/api/v1/entries/en/ace'
哪个返回单词Ace的json数据。现在,在Ubuntu 18.04上,我尝试以下操作:
import Foundation
//var request = URLRequest(url: URL(string: "https://od-api.oxforddictionaries.com/api/v1/entries/en/love")!)
// TODO: replace with your own app id and app key
let appId = "8a7dd147"
let appKey = "7e7d022fbce6d8d4523eac3baa5bd04c"
let language = "en"
let word = "Ace"
let word_id = word.lowercased() //word id is case sensitive and lowercase is required
let url = URL(string: "https://od-api.oxforddictionaries.com/api/v1/entries/en/love")! // \(language)/\(word_id)")!
var request = URLRequest(url: url)
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.addValue(appId, forHTTPHeaderField: "app_id")
request.addValue(appKey, forHTTPHeaderField: "app_key")
//request.addValue("application/json", forHTTPHeaderField: "Content-Type")
print("passed request addValue")
let session = URLSession.shared
_ = session.dataTask(with: request, completionHandler: { data, response, error in
if let response = response,
let data = data,
let jsonData = try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) {
print("about to give you a response")
print(response)
print(jsonData)
} else {
print(error)
print(NSString.init(data: data!, encoding: String.Encoding.utf8.rawValue))
}
}).resume()
或以下内容:
import Foundation
let params: [String: String] = ["app_id": "8a7dd147", "app_key": "7e7d022fbce6d8d4523eac3baa5bd04c"]
var request = URLRequest(url: URL(string: "https://od-api.oxforddictionaries.com/api/v1/entries/en/love")!)
request.httpMethod = "GET"
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.addValue("8a7dd147", forHTTPHeaderField: "app_id")
request.addValue("7e7d022fbce6d8d4523eac3baa5bd04c", forHTTPHeaderField: "app_key")
URLSession.shared.dataTask(with: request, completionHandler: { data, response, error -> Void in
print(response!)
do {
let json = try JSONSerialization.jsonObject(with: data!)
print(json)
print("we did it!")
} catch {
print("error")
}
}).resume()
//task.resume()
但是没有人返回单词“ love”的json信息。我一直在尝试调试它,无法弄清楚出了什么问题。
答案 0 :(得分:1)
URLSession
在后台线程上执行操作。并且当您结束多线程程序的主线程时,所有线程都被终止(除了在Java之类的某些语言中,您可以设置Daemon线程,该线程可能是其他线程,但是在该程序结束之后才结束程序)线程)。
因此,您的解决方案是延长主线程的生命周期,例如:
let group = DispatchGroup.init()
group.enter() // Use this before making anything that needs to be waited for
// This manually add one to operation count in the dispatch group
URLSession.shared.dataTask(with: request, completionHandler: { data, response, error -> Void in
defer { // Defer makes all ends of this scope make something, here we want to leave the dispatch.
// This is executed when the scope ends, even if with exception.
group.leave() // Manually subtract one from the operation count
}
print(response!)
do {
let json = try JSONSerialization.jsonObject(with: data!)
print(json)
print("we did it!")
} catch {
print("error")
}
}).resume()
group.wait() // Wait for group to end operations.
但是更好的是,您不会阻塞现实生活中的应用程序(例如,Web应用程序)中的主线程,因此您的应用程序通常比请求的寿命更长,因此您无需进行干预,但尽量避免阻止用户(sleep
,DispatchGroup.wait
阻止用户,除非在后台线程中,等等。)
答案 1 :(得分:0)
您也可以使用以下代码:
// Avoid closing this project for 40 seconds
RunLoop.main.run(until: Date(timeIntervalSinceNow: 40))