[英]Swift3 and JSON
I am trying to parse JSON from my server, but I am getting strange behaviour. 我正在尝试从服务器解析JSON,但是我的行为越来越奇怪。
This is my network processing Code: 这是我的网络处理代码:
import Foundation
// Input: URLRequest
// Output: returns JSON or raw data
public let DANetworkingErrorDomain = "\(Bundle.main.bundleIdentifier!).NetworkingError"
public let MissingHTTPResponseError: Int = 10
public let UnexpectedResponseError: Int = 20
class NetworkProcessing{
let request: URLRequest
lazy var configuration: URLSessionConfiguration = URLSessionConfiguration.default
lazy var session: URLSession = URLSession(configuration: self.configuration)
init(request: URLRequest) {
self.request = request
}
//Construct a URLSEssion and download data and return the data
// This is multi Threading
typealias JSON = [String : Any]
typealias JSONHandler = (JSON?, HTTPURLResponse?, Error?) -> Void
typealias DataHandler = (Data?, HTTPURLResponse?, Error?) -> Void
func downloadJSON(completion: @escaping JSONHandler){
let dataTask = session.dataTask(with: self.request) {
(data, response, error) in
//Off the main Thread
//Error: missing http response
guard let httpResponse = response as? HTTPURLResponse else {
let userInfo = [NSLocalizedDescriptionKey : NSLocalizedString("Missing HTTP Response", comment: "")]
let error = NSError(domain: DANetworkingErrorDomain, code: MissingHTTPResponseError, userInfo: userInfo)
completion(nil, nil, error as Error)
return
}
//There was a response but no data
if data == nil {
if let error = error{
completion(nil, httpResponse, error)
}
//We have some data
}else{
switch httpResponse.statusCode{
case 200:
//Everything is good Parse the JSON into Foudation Object (array, dictionary..)
do{
let json = try JSONSerialization.jsonObject(with: data!, options: []) as? [String : Any]
completion(json, httpResponse, nil)
} catch let error as NSError {
// The JSON data isn't correct
completion(nil, httpResponse, error)
}
break
// Any other http status code other than 200
default:
print ("Recieved HTTP response code: \(httpResponse.statusCode) = was not handeled in NetworkProcessing.swift")
break
}
}
}
dataTask.resume()
}
// This is raw data not JSON
func downloadData(completion: @escaping DataHandler) {
let dataTask = session.dataTask(with: self.request) {
(data, response, error) in
//Off the main Thread
//Error: missing http response
guard let httpResponse = response as? HTTPURLResponse else {
let userInfo = [NSLocalizedDescriptionKey : NSLocalizedString("Missing HTTP Response", comment: "")]
let error = NSError(domain: DANetworkingErrorDomain, code: MissingHTTPResponseError, userInfo: userInfo)
completion(nil, nil, error as Error)
return
}
//There was a response but no data
if data == nil {
if let error = error{
completion(nil, httpResponse, error)
}
//We have some data
}else{
switch httpResponse.statusCode{
case 200:
//Everything is good Parse the JSON into Foudation Object (array, dictionary..)
completion(data, httpResponse, error)
break
// Any other http status code other than 200
default:
print ("Recieved HTTP response code: \(httpResponse.statusCode) = was not handeled in NetworkProcessing.swift")
break
}
}
}
dataTask.resume()
}
}
Then I call it like so: 然后我这样称呼它:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let baseURL = "http://www.example.com/api/"
let path = "business.php?tag=getBusCategories"
let urlString = "\(baseURL)\(path)"
let url = URL(string: urlString)!
let urlRequest = URLRequest(url: url)
let networkProcessing = NetworkProcessing(request: urlRequest)
networkProcessing.downloadJSON { (json, httpResponse, error) in
print(json)
if let dictionary = json {
if let busCategoriesDict = dictionary["busCategories"] as? [String : Any]{
let busCatName = busCategoriesDict["busCatName"]
print("********************\(busCatName)*****************")
}
}
}
}
}
Then I get the following output in the inspector: 然后,我在检查器中得到以下输出:
Optional(["busCategories": <__NSArrayI 0x6080000a7440>(
{
busCatDescription = "Some description Some Description Some Description";
busCatId = 1;
busCatName = Accommodation;
},
{
busCatDescription = "Some description Some Description Some Description";
busCatId = 3;
busCatName = "Bars & Restaurants";
},
{
busCatDescription = "Some description Some Description Some Description";
busCatId = 17;
busCatName = Beauty;
},
{
busCatDescription = "Some description Some Description Some Description";
busCatId = 4;
busCatName = Computer;
},
{
busCatDescription = Description;
busCatId = 18;
busCatName = Conference;
},
{
busCatDescription = "Some description Some Description Some Description";
busCatId = 6;
busCatName = Entertainment;
},
{
busCatDescription = "Some description Some Description Some Description";
busCatId = 11;
busCatName = "Pets & Animals";
},
{
busCatDescription = "Some description Some Description Some Description";
busCatId = 12;
busCatName = Services;
},
{
busCatDescription = "Some description Some Description Some Description";
busCatId = 10;
busCatName = Stores;
},
{
busCatDescription = Description;
busCatId = 19;
busCatName = Weddings;
}
)
, "success": 1, "error": 0])
my Problem is here: 我的问题在这里:
["busCategories": <__NSArrayI 0x6080000a7440>(
//the JSON looks like this:
{
"error": false,
"success": 1,
"busCategories": [
{
"busCatId": "1",
"busCatName": "Accommodation",
"busCatDescription": "Some description Some Description Some Description"
}, {
"busCatId": "19",
"busCatName": "Weddings",
"busCatDescription": "Description"
}
]
}
I really can't see why iOS is not parsing the JSON correctly, and now I can't reference busCategories
我真的看不到为什么iOS无法正确解析JSON,现在我无法引用
busCategories
If my understanding is correct, 如果我的理解是正确的,
dictionary["busCategories"]
is not [String:Any], but [[String:Any]], in other words, it's and array of dictionaries, not a dictionary, thus 不是[String:Any],而是[[String:Any]],换句话说,它是字典数组,而不是字典,因此
if let busCategoriesDict = dictionary["busCategories"] as? [String : Any]
would never succeed. 永远不会成功。
It's not iOS which does not parse the JSON correctly. 不是iOS不能正确解析JSON。 It's you.
是你。 ;-)
;-)
As you can see from your output 从输出中可以看到
Optional(["busCategories": <__ NSArrayI 0x6080000a7440>
可选([[“ busCategories”:<__ NSArrayI 0x6080000a7440>
busCategories
is an array. busCategories
是一个数组。
Use your type alias JSON
to make it clear. 使用您的类型别名
JSON
使其清晰。
if let dictionary = json {
if let busCategoriesArray = dictionary["busCategories"] as? [JSON] {
for busCategory in busCategoriesArray {
let busCatName = busCategory["busCatName"] as! String
print(busCatName)
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.