简体   繁体   English

Swift3和JSON

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM