我正在尝试从API接收数据,我可以将其作为字符串接收,但是当我尝试将其放入数组或列表中时不起作用 这是我的代码。
这是模型
class DecodeRecipe: Codable {
struct Response: Codable {
struct Result: Codable {
var id: Int?
var title: String?
var image: String?
var readyInMinutes: Int?
}
var results: [result] = []
}
}
这是从API接收字符串的代码
class APIRequest {
static let instance = APIRequest()
var query: String = ""
var url: String = ""
var testString: String = ""
func setURL(_ url: String) -> Void {
self.url = url
}
func setQuery(_ query: String) -> Void {
self.query = query
}
func getReturn(completed: @escaping(decodeRecipe.response) -> Void?) {
// TODO MAJOR!
// Expressions are not allowed at top level will occur otherwise
//
let headers = [
"x-rapidapi-host": "spoonacular-recipe-food-nutrition-v1.p.rapidapi.com",
"x-rapidapi-key": "e44daac5e0mshc682df24497a89fp1c4513jsn7067934f0b9b"
]
let request = NSMutableURLRequest(url: NSURL(string: "https://spoonacular-recipe-food-nutrition-v1.p.rapidapi.com/recipes/search?number=1&query=\(query)")! as URL,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers
let session = URLSession.shared
var myStruct = decodeRecipe.response.result()
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error!)
} else {
if let data = data, let dataString = String(data: data, encoding: .utf8) {
myStruct.title = dataString
do{
print(dataString)
let decoder = try JSONDecoder().decode(decodeRecipe.response.self, from: data)
completed(decoder)
}
catch{
print(error)
completed([])
}
}
}
})
dataTask.resume()
}
}
希望对此有所回应。问题可能是结构的结构,但我不确定如何执行
示例JSON响应
{
"results":[
{
"id":485365,
"title":"Chicken Spinoccoli – Breaded Stuffed Chicken Breast With Spinach, Broccoli and Cheese",
"readyInMinutes":65,
"servings":4,
"image":"chicken-spinoccoli-breaded-stuffed-chicken-breast-with-spinach-broccoli-and-cheese-485365.jpg",
"imageUrls":[
"chicken-spinoccoli-breaded-stuffed-chicken-breast-with-spinach-broccoli-and-cheese-485365.jpg"
]
}
],
"baseUri":"https://spoonacular.com/recipeImages/",
"offset":0,
"number":1,
"totalResults":326,
"processingTimeMs":361,
"expires":1575604426682,
"isStale":false
}
答案 0 :(得分:1)
首先,封闭类DecodeRecipe
是多余的。不用了并将所有结构成员声明为常量
struct Response: Codable {
struct Result: Codable {
let id: Int
let title: String
let image: String
let readyInMinutes: Int
}
let results: [Result]
}
第二个使用新的Result
API才能在同一对象中返回结果和错误
class APIRequest {
static let instance = APIRequest()
var query: String = ""
var url: String = ""
var testString: String = ""
func getReturn(completed: @escaping (Result<Response, Error>) -> Void) {
// TODO MAJOR!
// Expressions are not allowed at top level will occur otherwise
//
let headers = [
"x-rapidapi-host": "spoonacular-recipe-food-nutrition-v1.p.rapidapi.com",
"x-rapidapi-key": "e44daac5e0mshc682df24497a89fp1c4513jsn7067934f0b9b"
]
var request = URLRequest(url: URL(string: "https://spoonacular-recipe-food-nutrition-v1.p.rapidapi.com/recipes/search?number=1&query=\(query)")!,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers
let session = URLSession.shared
let dataTask = session.dataTask(with: request) { (data, response, error) -> Void in
if let error = error { completed(.failure(error)); return }
do {
let result = try JSONDecoder().decode(Response.self, from: data!)
completed(.success(result))
} catch {
completed(.failure(error))
}
}
dataTask.resume()
}
}
并调用它
let request = APIRequest.instance
request.query = "Pizza"
request.getReturn { result in
switch result {
case .success(let result): print(result)
case .failure(let error): print(error)
}
}
答案 1 :(得分:0)
看来您的完成处理程序无效。
此代码有效:
let data = """
{
"results":[
{
"id":485365,
"title":"Chicken Spinoccoli – Breaded Stuffed Chicken Breast With Spinach, Broccoli and Cheese",
"readyInMinutes":65,
"servings":4,
"image":"chicken-spinoccoli-breaded-stuffed-chicken-breast-with-spinach-broccoli-and-cheese-485365.jpg",
"imageUrls":[
"chicken-spinoccoli-breaded-stuffed-chicken-breast-with-spinach-broccoli-and-cheese-485365.jpg"
]
}
],
"baseUri":"https://spoonacular.com/recipeImages/",
"offset":0,
"number":1,
"totalResults":326,
"processingTimeMs":361,
"expires":1575604426682,
"isStale":false
}
""".data(using: .utf8)!
class decodeRecipe: Codable {
struct response: Codable {
struct result: Codable {
var id: Int?
var title: String?
var image: String?
var readyInMinutes: Int?
}
var results: [result] = []
}
}
do {
let res = try JSONDecoder().decode(decodeRecipe.response.self, from: data)
print(res)
} catch {
print(error)
}
结果:
响应(结果:[__lldb_expr_13.decodeRecipe.response.result(id: 可选(485365),标题:可选(“鸡菠菜–面包屑 酿的鸡胸肉配菠菜,西兰花和奶酪”),图片: 可选(“鸡肉菠菜面包夹心鸡胸配菠菜西兰花和奶酪-485365.jpg”),readyInMinutes:可选(65))))
但是您呼叫的completed([])
不是@escaping(decodeRecipe.response) -> Void?
我建议返回nil
:completed(nil)
而不是空数组。
并使用@escaping(decodeRecipe.response?) -> Void?
顺便说一句,使用大写字母作为每种类型名称的首字母。