使用 Swift 发出 HTTP GET 请求 5
Making HTTP GET request with Swift 5
我显然错过了一些非常 fundamental/naïve/etc 的东西,但对于我来说,我无法弄清楚如何发出简单的 GET 请求。
我正在尝试使用 Swift 5 发出 HTTP GET 请求。我查看了这些 posts/articles:one, two,但我无法获得 print()
语句来显示任何内容。当我使用断点进行调试时,URLSession.shared.dataTask
部分中的整个部分被跳过。
我正在查看以下代码(来自上面的第一个 link):
func HTTP_Request() {
let url = URL(string: "http://www.whosebug.com")!
let task = URLSession.shared.dataTask(with: url) {(data: Data?, response: URLResponse?, error: Error?) in
guard let data = data else { return }
print(String(data: data, encoding: .utf8)!)
}
task.resume()
}
HTTP_Request()
我是 运行 通过 XCode 创建的 MacOS 命令行项目。
我将不胜感激任何对此的帮助,谢谢。
这对我有用很多次我建议你摘录以备将来使用!
let url = URL(string: "https://google.com")
let task = URLSession.shared.dataTask(with: ((url ?? URL(string: "https://google.com"))!)) { [self] (data, response, error) in
do {
let jsonResponse = try JSONSerialization.jsonObject(with: data!, options: [])
print(jsonResponse)
guard let newValue = jsonResponse as? [String:Any] else {
print("invalid format")
}
}
catch let error {
print("Error: \(error)")
}
task.resume()
}
确保在退出进程之前打印响应,您可以尝试追加
RunLoop.main.run()
或
sleep(UINT32_MAX)
最后确保主线程不会退出。如果要打印响应并立即退出进程,建议使用 DispatchSemaphore
:
let semphare = DispatchSemaphore(value: 0)
func HTTP_Request() {
let url = URL(string: "http://www.whosebug.com")!
let task = URLSession.shared.dataTask(with: url) {(data: Data?, response: URLResponse?, error: Error?) in
guard let data = data else { return }
print(String(data: data, encoding: .utf8)!)
semphare.signal()
}
task.resume()
}
HTTP_Request()
_ = semphare.wait(timeout: .distantFuture)
现在,如果出现错误,您将默默地失败。所以添加一些错误日志记录,例如,
func httpRequest() {
let url = URL(string: "https://www.whosebug.com")! // note, https, not http
let task = URLSession.shared.dataTask(with: url) { data, response, error in
guard
error == nil,
let data = data,
let string = String(data: data, encoding: .utf8)
else {
print(error ?? "Unknown error")
return
}
print(string)
}
task.resume()
}
这至少应该给你一些问题的指示。
其他一些注意事项:
如果是命令行应用程序,您必须认识到应用程序可能会在此异步网络请求完成之前退出。人们通常会启动一个 RunLoop
,用 run(mode:before:)
循环直到网络请求完成,正如 run
documentation.
中所建议的那样
例如,您可以为该例程提供一个完成处理程序,该处理程序将在完成时在主线程上调用。然后你可以使用它:
func httpRequest(completion: @escaping () -> Void) {
let url = URL(string: "https://www.whosebug.com")! // note, https, not http
let task = URLSession.shared.dataTask(with: url) { data, response, error in
defer {
DispatchQueue.main.async {
completion()
}
}
guard
error == nil,
let data = data,
let string = String(data: data, encoding: .utf8)
else {
print(error ?? "Unknown error")
return
}
print(string)
}
task.resume()
}
var finished = false
httpRequest {
finished = true
}
while !finished {
RunLoop.current.run(mode: .default, before: .distantFuture)
}
在标准的 macOS 应用程序中,您必须在“应用程序沙盒”功能中启用传出(客户端)连接。
如果是游乐场,则必须设置needsIndefiniteExecution
。
默认情况下,macOS 和 iOS 应用禁用 http
请求,除非您在 Info.plist
中启用“允许任意加载”。这不适用于命令线应用程序,但如果您尝试在标准 macOS/iOS 应用程序中执行此操作,您应该意识到这一点。
在这种情况下,您应该只使用 https
并完全避免这种考虑。
我显然错过了一些非常 fundamental/naïve/etc 的东西,但对于我来说,我无法弄清楚如何发出简单的 GET 请求。
我正在尝试使用 Swift 5 发出 HTTP GET 请求。我查看了这些 posts/articles:one, two,但我无法获得 print()
语句来显示任何内容。当我使用断点进行调试时,URLSession.shared.dataTask
部分中的整个部分被跳过。
我正在查看以下代码(来自上面的第一个 link):
func HTTP_Request() {
let url = URL(string: "http://www.whosebug.com")!
let task = URLSession.shared.dataTask(with: url) {(data: Data?, response: URLResponse?, error: Error?) in
guard let data = data else { return }
print(String(data: data, encoding: .utf8)!)
}
task.resume()
}
HTTP_Request()
我是 运行 通过 XCode 创建的 MacOS 命令行项目。
我将不胜感激任何对此的帮助,谢谢。
这对我有用很多次我建议你摘录以备将来使用!
let url = URL(string: "https://google.com")
let task = URLSession.shared.dataTask(with: ((url ?? URL(string: "https://google.com"))!)) { [self] (data, response, error) in
do {
let jsonResponse = try JSONSerialization.jsonObject(with: data!, options: [])
print(jsonResponse)
guard let newValue = jsonResponse as? [String:Any] else {
print("invalid format")
}
}
catch let error {
print("Error: \(error)")
}
task.resume()
}
确保在退出进程之前打印响应,您可以尝试追加
RunLoop.main.run()
或
sleep(UINT32_MAX)
最后确保主线程不会退出。如果要打印响应并立即退出进程,建议使用 DispatchSemaphore
:
let semphare = DispatchSemaphore(value: 0)
func HTTP_Request() {
let url = URL(string: "http://www.whosebug.com")!
let task = URLSession.shared.dataTask(with: url) {(data: Data?, response: URLResponse?, error: Error?) in
guard let data = data else { return }
print(String(data: data, encoding: .utf8)!)
semphare.signal()
}
task.resume()
}
HTTP_Request()
_ = semphare.wait(timeout: .distantFuture)
现在,如果出现错误,您将默默地失败。所以添加一些错误日志记录,例如,
func httpRequest() {
let url = URL(string: "https://www.whosebug.com")! // note, https, not http
let task = URLSession.shared.dataTask(with: url) { data, response, error in
guard
error == nil,
let data = data,
let string = String(data: data, encoding: .utf8)
else {
print(error ?? "Unknown error")
return
}
print(string)
}
task.resume()
}
这至少应该给你一些问题的指示。
其他一些注意事项:
如果是命令行应用程序,您必须认识到应用程序可能会在此异步网络请求完成之前退出。人们通常会启动一个
中所建议的那样RunLoop
,用run(mode:before:)
循环直到网络请求完成,正如run
documentation.例如,您可以为该例程提供一个完成处理程序,该处理程序将在完成时在主线程上调用。然后你可以使用它:
func httpRequest(completion: @escaping () -> Void) { let url = URL(string: "https://www.whosebug.com")! // note, https, not http let task = URLSession.shared.dataTask(with: url) { data, response, error in defer { DispatchQueue.main.async { completion() } } guard error == nil, let data = data, let string = String(data: data, encoding: .utf8) else { print(error ?? "Unknown error") return } print(string) } task.resume() } var finished = false httpRequest { finished = true } while !finished { RunLoop.current.run(mode: .default, before: .distantFuture) }
在标准的 macOS 应用程序中,您必须在“应用程序沙盒”功能中启用传出(客户端)连接。
如果是游乐场,则必须设置
needsIndefiniteExecution
。默认情况下,macOS 和 iOS 应用禁用
http
请求,除非您在Info.plist
中启用“允许任意加载”。这不适用于命令线应用程序,但如果您尝试在标准 macOS/iOS 应用程序中执行此操作,您应该意识到这一点。在这种情况下,您应该只使用
https
并完全避免这种考虑。