ios - Swift 将 JSON 解析为模型对象

标签 ios json swift parsing

我这里有这个方法,它完全按照我的需要返回了我的数据:

func getTestData() -> [Any]?
    {
        return [GradingData(lot: "lot", andColumns: "andColumns", SLAIssuedFinalGrading: true, SLAIssuedFinalGradingDate: "SLAIssuedFinalGradingDate", CityApprovalIssued: true, CityCommentReceived: false, GradingRepair: "GradingRepair", CurbStopRepair: "CurbStopRepair", SplashPadDownSpout: "SplashPadDownSpout", RYCBOtherRepairs: "RYCBOtherRepairs", Comments: "Comments", columnCamera: "", DepositReceived: false), GradingData(lot: "lot", andColumns: "andColumns2", SLAIssuedFinalGrading: false, SLAIssuedFinalGradingDate: "SLAIssuedFinalGradingDate", CityApprovalIssued: false, CityCommentReceived: false, GradingRepair: "GradingRepair", CurbStopRepair: "CurbStopRepair", SplashPadDownSpout: "SplashPadDownSpout", RYCBOtherRepairs: "RYCBOtherRepairs", Comments: "Comments", columnCamera: "", DepositReceived: false)]
    }

现在我正在尝试调用 API 并返回与此完全相同的结构:

func GetLandGradingData(_ community: String, completion: @escaping (_ result: [GradingData]) -> Void)
    {

        let escapedCommunity = community.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)

        let urlComponents = NSURLComponents(string: webservice + "?community=" + escapedCommunity!);
        urlComponents?.user = appDelegate.username;
        urlComponents?.password = appDelegate.password;

        let url = urlComponents?.url;

        let returnedData = [GradingData]()

        URLSession.shared.dataTask(with: url!, completionHandler: {
            (data, response, error) in

            if(error != nil){

                completion(returnedData)

            }else{

                do{

                    let json = try JSONSerialization.jsonObject(with: data!, options:.allowFragments) as! [GradingData]

                    OperationQueue.main.addOperation({

                        completion(json)

                    })

                }catch let error as NSError{

                    print(error)
                    completion(returnedData)

                }
            }

        }).resume()

    }

我的问题是该方法未返回与 getTestData 方法相同的结构,附件是有关 getTestData 返回内容和此 api 方法调用返回内容的屏幕截图。

enter image description here enter image description here

这是我的整个类(class):

@objcMembers class GradingData : NSObject {

    /**
     Define lot Column String
     */
    var lot: String?
    /**
     Define Address Column String
     */
    var address: String?
    /**
     Define SLA Issued Final Grading Column String
     */
    var SLAIssuedFinalGrading = false
    /**
     Define SLA Issued Final Grading Date Column String
     */
    var SLAIssuedFinalGradingDate: String?
    /**
     Define City Approval Issued Column String
     */
    var CityApprovalIssued = false
    /**
     Define City Comment Received Column String
     */
    var CityCommentReceived = false
    /**
     Define Grading Repair Column String
     */
    var GradingRepair: String?
    /**
     Define Curb Stop Repair Column String
     */
    var CurbStopRepair: String?
    /**
     Define Splash Pad or Down Spout Column String
     */
    var SplashPadDownSpout: String?
    /**
     Define RYCB or Other Repairs Column String
     */
    var RYCBOtherRepairs: String?
    /**
     Define Comments Column String
     */
    var Comments: String?
    /**
     Define Camera Column String
     */
    var columnCamera: String?
    /**
     Define Deposit Received Column String
     */
    var DepositReceived = false


    /**
     Inital call to class
     */
    init(lot: String?, andColumns address: String?, SLAIssuedFinalGrading: Bool?, SLAIssuedFinalGradingDate: String?, CityApprovalIssued: Bool?, CityCommentReceived: Bool?, GradingRepair: String?, CurbStopRepair: String?, SplashPadDownSpout: String?, RYCBOtherRepairs: String?, Comments: String?, columnCamera: String?, DepositReceived: Bool?) {

        super.init()

        //Set lot string

        self.lot = lot

        //Set Address Column string

        self.address = address

        //Set SLA Issued Final Grading Column string

        self.SLAIssuedFinalGrading = SLAIssuedFinalGrading!

        //Set SLA Issued Final Grading Date Column string

        self.SLAIssuedFinalGradingDate = SLAIssuedFinalGradingDate

        //Set City Approval Issued Column string

        self.CityApprovalIssued = CityApprovalIssued!

        //Set City Comment Received Column string

        self.CityCommentReceived = CityCommentReceived!

        //Set Grading Repair Column string

        self.GradingRepair = GradingRepair

        //Set Curb Stop Repair Column string

        self.CurbStopRepair = CurbStopRepair

        //Set Splash Pad or Down Spout Column string

        self.SplashPadDownSpout = SplashPadDownSpout

        //Set RYCB or Other Repairs Column string

        self.RYCBOtherRepairs = RYCBOtherRepairs

        //Set Comments Column string

        self.Comments = Comments

        //Set Camera Column string

        self.columnCamera = columnCamera

        //Set Deposit Received Column string

        self.DepositReceived = DepositReceived!

    }
}

这是我来自 API 的数据:

<Reports>
<CityApprovalIssued>false</CityApprovalIssued>
<CityCommentReceived>false</CityCommentReceived>
<Comments></Comments>
<CurbStopRepair></CurbStopRepair>
<DepositReceived>false</DepositReceived>
<GradingRepair></GradingRepair>
<RYCBOtherRepairs></RYCBOtherRepairs>
<SLAIssuedFinalGrading>false</SLAIssuedFinalGrading>
<SLAIssuedFinalGradingDate/>
<SplashPadDownSpout></SplashPadDownSpout>
<address>123 Fake Street</address>
<lot>A0001</lot>
</Reports>
<Reports>
<CityApprovalIssued>false</CityApprovalIssued>
<CityCommentReceived>false</CityCommentReceived>
<Comments></Comments>
<CurbStopRepair></CurbStopRepair>
<DepositReceived>false</DepositReceived>
<GradingRepair></GradingRepair>
<RYCBOtherRepairs></RYCBOtherRepairs>
<SLAIssuedFinalGrading>false</SLAIssuedFinalGrading>
<SLAIssuedFinalGradingDate/>
<SplashPadDownSpout></SplashPadDownSpout>
<address>125 Fake Street</address>
<lot>A0002</lot>
</Reports>

这来自 ASP.NET MVC API Controller :<ArrayOfReports xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/App.Models">

这是我这样做时得到的结果:

let string = String(data: data!, encoding: .utf8)

print(string as Any)

Optional("[{\"lot\":\"A0001\",\"address\”:\”123 Fake Street\”,\”SLAIssuedFinalGrading\":false,\"SLAIssuedFinalGradingDate\":\"\",\"CityApprovalIssued\":false,\"CityCommentReceived\":false,\"GradingRepair\":\"                                                                                                                                                                                                                                                               \",\"CurbStopRepair\":\"                                                                                                                                                                                                                                                               \",\"SplashPadDownSpout\":\"                                                                                                                                                                                                                                                               \",\"RYCBOtherRepairs\":\"                                                                                                                                                                                                                                                               \",\"Comments\":\"                                                                                                                                                                                                                                                               \",\"DepositReceived\":false},{\"lot\":\"A0002\",\"address\":\"125 Fake Street\",\"SLAIssuedFinalGrading\":false,\"SLAIssuedFinalGradingDate\":\"\",\"CityApprovalIssued\":false,\"CityCommentReceived\":false,\"GradingRepair\":\"                                                                                                                                                                                                                                                               \",\"CurbStopRepair\":\"                                                                                                                                                                                                                                                               \",\"SplashPadDownSpout\":\"                                                                                                                                                                                                                                                               \",\"RYCBOtherRepairs\":\"                                                                                                                                                                                                                                                               \",\"Comments\":\"                                                                                                                                                                                                                                                               \",\"DepositReceived\":false}]")

最佳答案

首先响应数据确实是JSON,XML输出有点困惑。

您可能不需要从 NSObject 继承的类,在大多数情况下,尤其是在 iOS 中,一个结构就足够了。

除了键columnCamera外,所有键都存在于所有记录中,因此将所有属性声明为非可选且没有默认值,并将columnCamera声明为可选,并将所有属性声明为常量 (let) 如果它们不会改变。

不需要显式的 init 方法。

添加了 CodingKeys 以将大部分键转换为小写。

struct GradingData : Decodable {

    private enum CodingKeys : String, CodingKey {
        case lot, address, SLAIssuedFinalGrading
        case SLAIssuedFinalGradingDate
        case cityApprovalIssued = "CityApprovalIssued"
        case cityCommentReceived = "CityCommentReceived"
        case gradingRepair = "GradingRepair"
        case curbStopRepair = "CurbStopRepair"
        case splashPadDownSpout = "SplashPadDownSpout"
        case RYCBOtherRepairs, comments = "Comments"
        case columnCamera, depositReceived = "DepositReceived"
    }

    let lot: String
    let address: String
    let SLAIssuedFinalGrading : Bool
    let SLAIssuedFinalGradingDate: String
    let cityApprovalIssued : Bool
    let cityCommentReceived : Bool
    let gradingRepair : String
    let curbStopRepair : String
    let splashPadDownSpout : String
    let RYCBOtherRepairs : String
    let comments : String
    let columnCamera : String?
    let depositReceived : Bool

}

然后解码JSON

....

var returnedData = [GradingData]()
URLSession.shared.dataTask(with: url!, completionHandler: {(data, response, error) in
     if error != nil {
         print(error!)
         completion(returnedData)
     } else {
         do {
            returnedData = try JSONDecoder().decode([GradingData].self, from: data!)
            DispatchQueue.main.async {
                completion(returnedData)
            }
         } catch {
             print(error)
             completion(returnedData)
         }
     }
 }).resume()

关于ios - Swift 将 JSON 解析为模型对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49930039/

相关文章:

iOS - NSUserDefaults 值为 'valueForKey' 返回 null 但不是 null

java - 解析 C# 中以 JSON 发送的 DateTime 类型

swift - 设置 UIImageView 宽度、高度、长宽比和约束 X、Y

SwiftUI - PageView - 在不同的 View 中传递

ios - 允许导航并不优先于 iOS 上的允许意图

ios - 在iOS中的Facebook登录中检查是否已在此应用程序中注册

ios - Swift 2.2 AVPlayer 错误处理

arrays - 错误下标

javascript - 循环数据对象并输出每个对象的对象文件名和消息

swift - 如何从 url 加载 UIImage?