John Hubler John Hubler - 10 months ago 35
JSON Question

Need help preparing JSON in Swift from mixed sources for PHP

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 "[" + {$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: "") 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\"},




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

Answer Source

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] {

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