繁体   English   中英

解析 API 对 swift 中的 JSON 的响应

[英]Parse API response to JSON in swift

将 API 响应字符串解析为 JSON 时出错。 以下是我的 JSON 回复

"\t\n{\"status\":0,\"msg\":\"success\",\"data\":{\"numberOfOrder\":3256,\"title_name\":\"URIBA DEALS\",\"title_desc\":\"您附近的商店和服务的优惠和折扣\",\"deals\":[{\"DealID\":\"200\",\"BusinessID\": \"279\",\"DealType\":\"specialoffer\",\"business_type\":\"vegetables\",\"ImageURL\":\"\",\"CategoryID\":\"1111 \",\"categoryType\":\"\",\"ProductID\":\"0\",\"Priority\":\"-48\",\"Status\":\"1\" ,\"CreatedAt\":\"2019-11-19 07:57:32\",\"PromoCode\":\"\",\"Offer\":\"0\",\"OfferType\" :\"0\",\"分行\":\"Kharadi(EON)\",\"NewLogo\":\"http:\/\/aiotechnology.in\/AmanoraKatta\/AdminPanel\/deals_new_img\/ 1574148777.jpg\",\"userAcquisitionStatus\":\"0\",\"maxOrder\":\"0\",\"minOrder\":\"0\",\"userAcquisitionDiscount\":\" 0\",\"dealFrom\":\"0000-00-00 00:00:00\",\"dealTo\":\"0000-00-00 00:00:00\",\"deal_description\ ":\"洋葱 @ 17 卢比半公斤(从 Amanora 办公室挑选洋葱)(每人限 1 公斤)\",\"from_time\":\"00:00:00\",\"to_time\":\ "00:00:00\",\"from_date\":\"0000-00-00\",\"to_d 吃了\":\"0000-00-00\",\"deal_delivery_charges\":\"9\",\"app_Version\":\"0\",\"walletAmount\":\"0\", \"name\":\"UriBA Vegetables Kharadi\",\"delivery_status_flag\":\"0\",\"delivery_days_after\":\"1\",\"business_address\":\"Kharadi, Pune\ ",\"min_order_amt\":\"12\",\"纬度\":\"18.5578469\",\"经度\":\"73.9449945\",\"delivery_timings\":\"上午 9 点到 9 点PM\",\"CST\":\"0\",\"GST\":\"0\",\"DELI_CHRGS\":\"0\",\"PACK_CHRGS\":\"2\ ",\"displayimage\":\"1571221633.jpg\",\"logo_icon\":\"\",\"business_margin\":\"0\",\"business_margin_flag\":\"0\" }}]}}

下面是我的代码

Alamofire.request(url).responseString { response in
        guard response.result.isSuccess,

        let data = response.result.value else
        {
            print("Error while fetching tags: \(String(describing: response.result.error))")
            completion(nil)
            return
        }

    completion(data)

下面是我的 Model Class:

class DealModelRootClass : NSObject, NSCoding{

var data : DealDataModelRootClass!
var msg : String!
var status : Int!

init(fromJson json: JSON!){
    if json.isEmpty{
        return
    }
    let dataJson = json["data"]
    if !dataJson.isEmpty{
        data = DealDataModelRootClass(fromJson: dataJson)
    }
    msg = json["msg"].stringValue
    status = json["status"].intValue
}


func toDictionary() -> [String:Any]
{
    var dictionary = [String:Any]()
    if data != nil{
        dictionary["data"] = data.toDictionary()
    }
    if msg != nil{
        dictionary["msg"] = msg
    }
    if status != nil{
        dictionary["status"] = status
    }
    return dictionary
}


@objc required init(coder aDecoder: NSCoder)
{
    data = aDecoder.decodeObject(forKey: "data") as? DealDataModelRootClass
    msg = aDecoder.decodeObject(forKey: "msg") as? String
    status = aDecoder.decodeObject(forKey: "status") as? Int
}


func encode(with aCoder: NSCoder)
{
    if data != nil{
        aCoder.encode(data, forKey: "data")
    }
    if msg != nil{
        aCoder.encode(msg, forKey: "msg")
    }
    if status != nil{
        aCoder.encode(status, forKey: "status")
    }

}
}

我已经阅读了很多博客但无法解决这个问题。 我是 swift iOS 的新手。

首先使用转换响应,

let JSON = try. JSONSerialization:data(withJSONObject, yourResponseFromApi: options. JSONSerialization.WritingOptions.prettyPrinted)

转换 api 响应后,您可以对其进行解码。

let decode = try. JSONDecoder().decode(YourModelClass,self: from: JSON)

这是正确的 json:

{
"status": 0,
"msg": "success",
"data": {
    "numberOfOrder": 3256,
    "title_name": "URIBA DEALS",
    "title_desc": "Deal & Discount from your nearly shops & services",
    "deals": [{
        "DealID": "200",
        "BusinessID": "279",
        "DealType": "specialoffer",
        "business_type": "vegetables",
        "ImageURL": "",
        "CategoryID": "1111",
        "categoryType": "",
        "ProductID": "0",
        "Priority": "-48",
        "Status": "1",
        "CreatedAt": "2019-11-19 07:57:32",
        "PromoCode": "",
        "Offer": "0",
        "OfferType": "0",
        "Branch": "Kharadi(EON)",
        "NewLogo": "http://aiotechnology.in/AmanoraKatta/AdminPanel/deals_new_img/1574148777.jpg",
        "userAcquisitionStatus": "0",
        "maxOrder": "0",
        "minOrder": "0",
        "userAcquisitionDiscount": "0",
        "dealFrom": "0000-00-00 00:00:00",
        "dealTo": "0000-00-00 00:00:00",
        "deal_description": "Onion @ Rs 17 half kg (Pick Onion From Amanora Office) ( limit 1 kg per person )",
        "from_time": "00:00:00",
        "to_time": "00:00:00",
        "from_date": "0000-00-00",
        "to_date": "0000-00-00",
        "deal_delivery_charges": "9",
        "app_Version": "0",
        "walletAmount": "0",
        "name": "UriBA Vegetables Kharadi",
        "delivery_status_flag": "0",
        "delivery_days_after": "1",
        "business_address": "Kharadi, Pune",
        "min_order_amt": "12",
        "latitude": "18.5578469",
        "longitude": "73.9449945",
        "delivery_timings": "9 AM to 9 PM",
        "CST": "0",
        "GST": "0",
        "DELI_CHRGS": "0",
        "PACK_CHRGS": "2",
        "displayimage": "1571221633.jpg",
        "logo_icon": "",
        "business_margin": "0",
        "business_margin_flag": "0"

    }]
}
}

这是 model:

// This file was generated from JSON Schema using quicktype, do not modify it directly.
// To parse the JSON, add this file to your project and do:
//
//   let dealModel = try? newJSONDecoder().decode(DealModel.self, from: jsonData)

//
// To parse values from Alamofire responses:
//
//   Alamofire.request(url).responseDealModel { response in
//     if let dealModel = response.result.value {
//       ...
//     }
//   }

import Foundation
import Alamofire

// MARK: - DealModel
class DealModel: Codable {
let status: Int?
let msg: String?
let data: DataClass?

init(status: Int?, msg: String?, data: DataClass?) {
    self.status = status
    self.msg = msg
    self.data = data
}
}

//
// To parse values from Alamofire responses:
//
//   Alamofire.request(url).responseDataClass { response in
//     if let dataClass = response.result.value {
//       ...
//     }
//   }

// MARK: - DataClass
class DataClass: Codable {
let numberOfOrder: Int?
let titleName, titleDesc: String?
let deals: [Deal]?

enum CodingKeys: String, CodingKey {
    case numberOfOrder
    case titleName = "title_name"
    case titleDesc = "title_desc"
    case deals
}

init(numberOfOrder: Int?, titleName: String?, titleDesc: String?, deals: [Deal]?) {
    self.numberOfOrder = numberOfOrder
    self.titleName = titleName
    self.titleDesc = titleDesc
    self.deals = deals
}
}

//
// To parse values from Alamofire responses:
//
//   Alamofire.request(url).responseDeal { response in
//     if let deal = response.result.value {
//       ...
//     }
//   }

// MARK: - Deal
class Deal: Codable {
let dealID, businessID, dealType, businessType: String?
let imageURL, categoryID, categoryType, productID: String?
let priority, status, createdAt, promoCode: String?
let offer, offerType, branch: String?
let newLogo: String?
let userAcquisitionStatus, maxOrder, minOrder, userAcquisitionDiscount: String?
let dealFrom, dealTo, dealDescription, fromTime: String?
let toTime, fromDate, toDate, dealDeliveryCharges: String?
let appVersion, walletAmount, name, deliveryStatusFlag: String?
let deliveryDaysAfter, businessAddress, minOrderAmt, latitude: String?
let longitude, deliveryTimings, cst, gst: String?
let deliChrgs, packChrgs, displayimage, logoIcon: String?
let businessMargin, businessMarginFlag: String?

enum CodingKeys: String, CodingKey {
    case dealID = "DealID"
    case businessID = "BusinessID"
    case dealType = "DealType"
    case businessType = "business_type"
    case imageURL = "ImageURL"
    case categoryID = "CategoryID"
    case categoryType
    case productID = "ProductID"
    case priority = "Priority"
    case status = "Status"
    case createdAt = "CreatedAt"
    case promoCode = "PromoCode"
    case offer = "Offer"
    case offerType = "OfferType"
    case branch = "Branch"
    case newLogo = "NewLogo"
    case userAcquisitionStatus, maxOrder, minOrder, userAcquisitionDiscount, dealFrom, dealTo
    case dealDescription = "deal_description"
    case fromTime = "from_time"
    case toTime = "to_time"
    case fromDate = "from_date"
    case toDate = "to_date"
    case dealDeliveryCharges = "deal_delivery_charges"
    case appVersion = "app_Version"
    case walletAmount, name
    case deliveryStatusFlag = "delivery_status_flag"
    case deliveryDaysAfter = "delivery_days_after"
    case businessAddress = "business_address"
    case minOrderAmt = "min_order_amt"
    case latitude, longitude
    case deliveryTimings = "delivery_timings"
    case cst = "CST"
    case gst = "GST"
    case deliChrgs = "DELI_CHRGS"
    case packChrgs = "PACK_CHRGS"
    case displayimage
    case logoIcon = "logo_icon"
    case businessMargin = "business_margin"
    case businessMarginFlag = "business_margin_flag"
}

init(dealID: String?, businessID: String?, dealType: String?, businessType: String?, imageURL: String?, categoryID: String?, categoryType: String?, productID: String?, priority: String?, status: String?, createdAt: String?, promoCode: String?, offer: String?, offerType: String?, branch: String?, newLogo: String?, userAcquisitionStatus: String?, maxOrder: String?, minOrder: String?, userAcquisitionDiscount: String?, dealFrom: String?, dealTo: String?, dealDescription: String?, fromTime: String?, toTime: String?, fromDate: String?, toDate: String?, dealDeliveryCharges: String?, appVersion: String?, walletAmount: String?, name: String?, deliveryStatusFlag: String?, deliveryDaysAfter: String?, businessAddress: String?, minOrderAmt: String?, latitude: String?, longitude: String?, deliveryTimings: String?, cst: String?, gst: String?, deliChrgs: String?, packChrgs: String?, displayimage: String?, logoIcon: String?, businessMargin: String?, businessMarginFlag: String?) {
    self.dealID = dealID
    self.businessID = businessID
    self.dealType = dealType
    self.businessType = businessType
    self.imageURL = imageURL
    self.categoryID = categoryID
    self.categoryType = categoryType
    self.productID = productID
    self.priority = priority
    self.status = status
    self.createdAt = createdAt
    self.promoCode = promoCode
    self.offer = offer
    self.offerType = offerType
    self.branch = branch
    self.newLogo = newLogo
    self.userAcquisitionStatus = userAcquisitionStatus
    self.maxOrder = maxOrder
    self.minOrder = minOrder
    self.userAcquisitionDiscount = userAcquisitionDiscount
    self.dealFrom = dealFrom
    self.dealTo = dealTo
    self.dealDescription = dealDescription
    self.fromTime = fromTime
    self.toTime = toTime
    self.fromDate = fromDate
    self.toDate = toDate
    self.dealDeliveryCharges = dealDeliveryCharges
    self.appVersion = appVersion
    self.walletAmount = walletAmount
    self.name = name
    self.deliveryStatusFlag = deliveryStatusFlag
    self.deliveryDaysAfter = deliveryDaysAfter
    self.businessAddress = businessAddress
    self.minOrderAmt = minOrderAmt
    self.latitude = latitude
    self.longitude = longitude
    self.deliveryTimings = deliveryTimings
    self.cst = cst
    self.gst = gst
    self.deliChrgs = deliChrgs
    self.packChrgs = packChrgs
    self.displayimage = displayimage
    self.logoIcon = logoIcon
    self.businessMargin = businessMargin
    self.businessMarginFlag = businessMarginFlag
}
} 

// MARK: - Helper functions for creating encoders and decoders

func newJSONDecoder() -> JSONDecoder {
let decoder = JSONDecoder()
if #available(iOS 10.0, OSX 10.12, tvOS 10.0, watchOS 3.0, *) {
    decoder.dateDecodingStrategy = .iso8601
}
return decoder
}

func newJSONEncoder() -> JSONEncoder {
let encoder = JSONEncoder()
if #available(iOS 10.0, OSX 10.12, tvOS 10.0, watchOS 3.0, *) {
    encoder.dateEncodingStrategy = .iso8601
}
return encoder
}

// MARK: - Alamofire response handlers

extension DataRequest {
fileprivate func decodableResponseSerializer<T: Decodable>() -> DataResponseSerializer<T> {
    return DataResponseSerializer { _, response, data, error in
        guard error == nil else { return .failure(error!) }

        guard let data = data else {
            return .failure(AFError.responseSerializationFailed(reason: .inputDataNil))
        }

        return Result { try newJSONDecoder().decode(T.self, from: data) }
    }
}

@discardableResult
fileprivate func responseDecodable<T: Decodable>(queue: DispatchQueue? = nil, completionHandler: @escaping (DataResponse<T>) -> Void) -> Self {
    return response(queue: queue, responseSerializer: decodableResponseSerializer(), completionHandler: completionHandler)
}

@discardableResult
func responseDealModel(queue: DispatchQueue? = nil, completionHandler: @escaping (DataResponse<DealModel>) -> Void) -> Self {
    return responseDecodable(queue: queue, completionHandler: completionHandler)
}
}

像这样调用 almofire 请求

Alamofire.request(url, method:.post, parameters: parameters, headers: headers)
        .responseDealModel(completionHandler: { (response) in
            switch response.result {
            case .success(let result):
                print("success")
            case .failure(let error):
                print("fail")
            }
        })
        .responseString { (response) in
            print(response.result.value ?? "NO Response")
    }

用户https://jsonlint.com/验证 json 和快速类型以创建 model。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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