如何在 swift 中搜索 JSON 文件?
How to segue a JSON file in swift?
我正在构建一个应用程序,人们需要在其中填写表格,然后它会创建一个 HTTP post,其中 API 将 return 一个 Json 文件发送到包含我需要的数据的应用程序。访问 API 一切正常,但我想在另一个视图控制器中解析数据。如何从另一个视图控制器访问 JSON 文件?
let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
guard error == nil else {
return
}
guard let data = data else {
return
}
do {
//create json object from data
if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
print(json)
^^^^^^^
How do I take this JSON file to the next view controller so I dont have to do the parsing below?
let jsonData = json
let ratesJson = jsonData["rates"]!
let rates = ratesJson as! NSArray
print("Rates: \(rates)")
print("*************")
print(rates.count)
print("*************")
for item in 0..<rates.count {
let specificRate = rates[item]
let price = (specificRate as AnyObject)["amount_local"]!
let provider = (specificRate as AnyObject)["provider"]!
print("--\(item)--")
print("Price: \(price!)")
print("Provider: \(provider!)")
}
}
} catch let error {
print(error.localizedDescription)
}
})
状态通常是导致程序错误的原因之一。我认为你在这里问的是状态。
我会做的是编写一个通用函数(Swift
在很多情况下鼓励函数式编程,看看:swift map, filter etc. 处理 HTTP 请求并返回闭包中的数据。
此闭包将存在于您希望 json 对象进入的视图控制器中,从而解决您访问所述数据的问题。
现在我也不认为这是正确的方法。我会为您返回的特定数据创建一个对象,例如 "struct Person" 或您需要的任何内容。
这有两个优点:
- 在 swift
3.1
中,您可以使用自定义 init()
方法来安全地解析 JSON(记住,可选值!)并相应地填充结构数据
- 在 swift
4.0
和 Xcode9.0
您将能够变形您刚刚创建的结构以符合 Codable
和 Decodable
协议json 解析将大大简化,如此处解释:ultimate swift json guide
希望对您有所帮助。
根据你的评论,我假设你的意图是实际传递一个 JSON 对象,而不是 JSON 文件到下一个视图控制器。
因此,您只需将 JSON 对象传递给您的 segue,并将其作为 属性 分配给下一个视图控制器。
由于问题非常开放,这里有一个可能的解决方案和解释。
示例:
//Sample snippet from code from question
if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
performSegue(withIdentifier: "MySegue", sender: json);
}
override func prepare(for segue: UIStoryboardSegue!, sender: Any?) {
if (segue.identifier == "MySegue") {
let vc = segue.destinationViewController as! RandomViewController
vc.json = sender as! [String:Any];
}
}
我正在构建一个应用程序,人们需要在其中填写表格,然后它会创建一个 HTTP post,其中 API 将 return 一个 Json 文件发送到包含我需要的数据的应用程序。访问 API 一切正常,但我想在另一个视图控制器中解析数据。如何从另一个视图控制器访问 JSON 文件?
let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in
guard error == nil else {
return
}
guard let data = data else {
return
}
do {
//create json object from data
if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
print(json)
^^^^^^^
How do I take this JSON file to the next view controller so I dont have to do the parsing below?
let jsonData = json
let ratesJson = jsonData["rates"]!
let rates = ratesJson as! NSArray
print("Rates: \(rates)")
print("*************")
print(rates.count)
print("*************")
for item in 0..<rates.count {
let specificRate = rates[item]
let price = (specificRate as AnyObject)["amount_local"]!
let provider = (specificRate as AnyObject)["provider"]!
print("--\(item)--")
print("Price: \(price!)")
print("Provider: \(provider!)")
}
}
} catch let error {
print(error.localizedDescription)
}
})
状态通常是导致程序错误的原因之一。我认为你在这里问的是状态。
我会做的是编写一个通用函数(Swift
在很多情况下鼓励函数式编程,看看:swift map, filter etc. 处理 HTTP 请求并返回闭包中的数据。
此闭包将存在于您希望 json 对象进入的视图控制器中,从而解决您访问所述数据的问题。
现在我也不认为这是正确的方法。我会为您返回的特定数据创建一个对象,例如 "struct Person" 或您需要的任何内容。
这有两个优点:
- 在 swift
3.1
中,您可以使用自定义init()
方法来安全地解析 JSON(记住,可选值!)并相应地填充结构数据 - 在 swift
4.0
和Xcode9.0
您将能够变形您刚刚创建的结构以符合Codable
和Decodable
协议json 解析将大大简化,如此处解释:ultimate swift json guide
希望对您有所帮助。
根据你的评论,我假设你的意图是实际传递一个 JSON 对象,而不是 JSON 文件到下一个视图控制器。
因此,您只需将 JSON 对象传递给您的 segue,并将其作为 属性 分配给下一个视图控制器。
由于问题非常开放,这里有一个可能的解决方案和解释。
示例:
//Sample snippet from code from question
if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
performSegue(withIdentifier: "MySegue", sender: json);
}
override func prepare(for segue: UIStoryboardSegue!, sender: Any?) {
if (segue.identifier == "MySegue") {
let vc = segue.destinationViewController as! RandomViewController
vc.json = sender as! [String:Any];
}
}