我是使用Swift进行编程的新手,因此决定尝试使用一个简单的脚本访问http://data-plate.herokuapp.com上的API。 JSON响应应该只是一个字符串。但是,当我通过在终端中通过运行./main.swift作为脚本来运行以下脚本时,无法运行该脚本。该项目是作为命令终端工具完成的。 URLSession.shared.dataTask内的所有内容均未打印过,并且我看不到任何错误。我正在使用最新的MacOS Catalina。
#!/usr/bin/swift
import Foundation
let url = "http://data-plate.herokuapp.com/";
let task = URLSession.shared.dataTask(with: URL(string: url)!, completionHandler: { data, response, error in
guard let data = data,error == nil else {
print("RIP")
return
}
print("HELLO")
// have data
var result: Response?
do {
try result = JSONDecoder().decode(Response.self, from: data)
print(result as Any)
} catch {
print("Failed to convert \(error.localizedDescription)")
}
guard let json = result else {
return
}
print(json.Status)
})
task.resume()
struct Response: Codable {
let Status: String
}
任何帮助都是有帮助的,因为这对于我的应用创意至关重要。
答案 0 :(得分:1)
您的dataTask
是异步操作,因此您可能要使用Semaphore
等到操作完成。
import Foundation
let url = "http://data-plate.herokuapp.com/";
let semaphore = DispatchSemaphore(value: 0)
let task = URLSession.shared.dataTask(with: URL(string: url)!, completionHandler: { data, response, error in
guard let data = data,error == nil else {
print("RIP")
return
}
print("HELLO")
// have data
var result: Response?
do {
try result = JSONDecoder().decode(Response.self, from: data)
print(result as Any)
} catch {
print("Failed to convert \(error.localizedDescription)")
}
guard let json = result else {
return
}
print(json.Status)
semaphore.signal()
})
task.resume()
semaphore.wait()
struct Response: Codable {
let Status: String
}
第二个问题:
如果我在另一个文件中定义Response结构并尝试运行上面的脚本,则会在终端中收到“错误:使用未声明的类型'Response'”。我应该以某种方式导入该结构还是确保它已初始化?
如果您有多个源文件,建议您使用swiftc
命令行(与swift
命令行不同)将应用程序编译为单个可执行文件。然后,您可以正常运行该可执行文件。
swiftc file1.swift file2.swift file3.swift -o out
,然后运行可执行文件:
./out
使用swiftc
时,请不要忘记使用@main
注释让Swift知道源的哪一部分将是入口点。
@main
struct YouStruct {
static func main() {
task.resume()
semaphore.wait()
}
}
您可以在任何文件中使用@main
批注,但是请确保在源文件中仅出现一个@main
。
@main
可从Swift5.3获得。如果您想支持较早版本的Swift,则可能要使用较旧的方式(main.swift
将成为您的程序入口点)。