doushan2224
2016-09-24 21:09
浏览 47

需要帮助从PHP的混合源中为Swift准备JSON

I will try to be as thorough as possible with this question.

To start, I have the following struct defined in my code:

struct LogInfo {
    var logNumber: Int
    var species: String
    var diameter: Float
    var formClass: Int
    var numLogs: Float
    var boardFootage: Double

    static func jsonArray(array : [LogInfo]) -> String {
        return "[" + array.map {$0.jsonRepresentation}.joinWithSeparator(",") + "]"
    }

    var jsonRepresentation : String {
        return "{\"logNumber\":\"\(logNumber)\",\"species\":\"\(species)\",\"diameter\":\"\(diameter)\",\"formClass\":\"\(formClass)\",\"numLogs\":\"\(boardFootage)\"}"
    }
}

This basically creates a JSON representation of the defined struct.

In another part of my code, I am composing a JSON string with the following:

let sessionConfig = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: sessionConfig, delegate: nil, delegateQueue: nil)

guard let URL = NSURL(string: "http://logster.dynamiscms.com/jsonTest.php") else {return}

let request = NSMutableURLRequest(URL: URL) 
request.HTTPMethod = "POST"

// Headers
request.addValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")


//Get the JSON Array from the Struct
let jsonArray = LogInfo.jsonArray(logArray)


// Compose the JSON Body
let bodyObject = [
    "propertyOwner": "\(propertyOwner)",
    "propertyID": "\(propertyID)",
    "scaledBy": "\(scaledBy)",
    "acres": "\(acres)",
    "notes": "\(notes)",
    "logDetails": jsonArray
]

Everything up to this point basically takes 5 variables that were passed into my segue, and then appends the JSON that was prepared in the struct.

I want to pass that JSON that I compiled to a PHP script, which will then parse that JSON and eventually store it into a database.

I am not getting any errors in my code - but the JSON is not being prepared properly, which is causing me to be unable to parse through it in PHP.

Based on this code, I AM able to parse the first five values (propertyOwner, propertyID, scaledBy, acres and notes) with PHP. However, when I get into the array of details, I cannot get into those nested values.

It looks like when I pass it into my PHP script, it is spitting out this as the JSON (which I realize is not valid JSON):

[
    "notes": "This is a test.",
    "propertyID": "Beam Residence",
    "acres": "1",
    "scaledBy": "Andy Spencer",
    "propertyOwner": "Jim Beam",
    "logDetails": "
        {\"logNumber\":\"1\",\"species\":\"White Pine\",\"diameter\":\"18.0\",\"formClass\":\"78\",\"numLogs\":\"124.56227\"},

        {\"logNumber\":\"2\",\"species\":\"Hemlock\",\"diameter\":\"17.0\",\"formClass\":\"78\",\"numLogs\":\"147.0589725\"},

        {\"logNumber\":\"3\",\"species\":\"Spruce\",\"diameter\":\"21.0\",\"formClass\":\"82\",\"numLogs\":\"335.9106016\"}"

]

Is anybody able to help me make sense of what I am missing?

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • doumizhi0809 2016-09-24 21:54
    已采纳

    Generally, you should not create a JSON String by yourself. You need to escape special characters, add " to both ends..., it's not so simple.

    And you should not create a string representation of JSON for intermediate values. With a slight mistake, the intermediate value is converted to a single JSON String. This is your case.

    (Your bodyData may be converted to valid JSON, but logDetails in it becomes a single string in PHP, which you do not expect.)

    Change jsonArray(_:) and jsonRepresentation like this:

    (If you need to use those method and property returning String somewhere else, re-implement them with proper names.)

    static func jsonArray(array : [LogInfo]) -> [AnyObject] {
        return array.map{$0.jsonRepresentation}
    }
    
    var jsonRepresentation : [String: AnyObject] {
        return [
            "logNumber": logNumber, //<- or `String(logNumber)`
            "species": species,
            "diameter": diameter, //<- or `String(diameter)`
            "formClass": formClass, //<- or `String(formClass)`
            "numLogs": numLogs, //<- or `String(numLogs)`
            "boardFootage": boardFootage //<- or `String(boardFootage)`
        ]
    }
    

    (Many things depends on your PHP side. Usually numeric values are not sent as JSON String to PHP, but if your PHP code needs them as string, you need to enclose numeric values with String(...).)

    And to make your bodyObject:

    let jsonArray = LogInfo.jsonArray(logArray)
    
    let bodyObject: [String: AnyObject] = [
        "propertyOwner": propertyOwner,
        "propertyID": propertyID,
        "scaledBy": scaledBy,
        "acres": acres, //<- or `String(acres)`
        "notes": notes,
        "logDetails": jsonArray
    ]
    
    已采纳该答案
    打赏 评论
  • doumianfeng5065 2016-09-24 21:55

    Basically you've got multiple errors. Here is what you want in the end:

    {
        "notes":"This is a test.",
        "propertyID":"Beam Residence",
        "acres":"1",
        "scaledBy":"Andy Spencer",
        "propertyOwner":"Jim Beam",
        "logDetails":[
            {"logNumber":"1","species":"White Pine","diameter":"18.0","formClass":"78","numLogs":"124.56227"},
            {"logNumber":"2","species":"Hemlock","diameter":"17.0","formClass":"78","numLogs":"147.0589725"},
            {"logNumber":"3","species":"Spruce","diameter":"21.0","formClass":"82","numLogs":"335.9106016"}
        ]
    }
    

    You get there:

    1. Change the wrapping brackets to {}
    2. Replace \" with "
    3. Wrap the logDetails with [] and not with ""

    Let me know if you need help with the code.

    打赏 评论

相关推荐 更多相似问题