Swift3 和 JSON
Posted
技术标签:
【中文标题】Swift3 和 JSON【英文标题】:Swift3 and JSON 【发布时间】:2016-10-23 09:23:41 【问题描述】:我正在尝试从我的服务器解析 JSON,但出现了奇怪的行为。
这是我的网络处理代码:
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()
那我这样称呼它:
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)*****************")
然后我在检查器中得到以下输出:
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])
我的问题在这里:
["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"
]
我真的看不明白为什么 ios 没有正确解析 JSON,现在我无法引用 busCategories
【问题讨论】:
【参考方案1】:如果我的理解是正确的,
dictionary["busCategories"]
不是[String:Any],而是[[String:Any]],换句话说,它是字典数组,而不是字典,因此
if let busCategoriesDict = dictionary["busCategories"] as? [String : Any]
永远不会成功。
【讨论】:
【参考方案2】:不是 iOS 不能正确解析 JSON。是你。 ;-)
从输出中可以看出
可选(["busCategories": <__>NSArrayI 0x6080000a7440>
busCategories
是一个数组。
使用你的类型别名JSON
来明确。
if let dictionary = json
if let busCategoriesArray = dictionary["busCategories"] as? [JSON]
for busCategory in busCategoriesArray
let busCatName = busCategory["busCatName"] as! String
print(busCatName)
【讨论】:
100% 正确,完美运行,3 天后,你花了 2 分钟以上是关于Swift3 和 JSON的主要内容,如果未能解决你的问题,请参考以下文章
swift3 中的 SecKeyRawSign 和 SecKeyRawVerify