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

时间:2016-09-24 21:09:02

标签: php arrays json swift xcode

我将尽力使用这个问题尽可能彻底。

首先,我在我的代码中定义了以下结构:

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)\"}"
    }
}

这基本上创建了定义的struct的JSON表示。

在我的代码的另一部分中,我正在使用以下内容编写JSON字符串:

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
]

到目前为止,所有内容基本上都需要传递给我的segue的5个变量,然后附加在结构中准备的JSON。

我想将我编译的JSON传递给PHP脚本,然后解析该JSON并最终将其存储到数据库中。

我的代码中没有出现任何错误 - 但JSON没有正确准备,这导致我无法在PHP中解析它。

基于此代码,我能够使用PHP解析前五个值(propertyOwner,propertyID,scaledBy,acres和notes)。但是,当我进入细节数组时,我无法进入那些嵌套值。

看起来当我将它传递给我的PHP脚本时,它就像JSON(我意识到它是无效的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\"}"

]

有人能帮助我理解我所缺少的东西吗?

2 个答案:

答案 0 :(得分:1)

通常,您不应该自己创建JSON字符串。你需要转义特殊字符,将"添加到两端......,它不是那么简单。

您不应为中间值创建JSON的字符串表示形式。稍有错误,中间值将转换为单个JSON字符串。这是你的情况。

(您的bodyData可能会转换为有效的JSON,但其中的logDetails将成为PHP中的单个字符串,您不会期望这样做。)

像这样更改jsonArray(_:)jsonRepresentation

(如果你需要在其他地方使用那些返回String的方法和属性,请用适当的名称重新实现它们。)

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)`
    ]
}

(很多事情取决于你的PHP方面。通常数值不会作为JSON字符串发送给PHP,但如果你的PHP代码需要它们作为字符串,你需要用String(...)括起数值。)

制作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
]

答案 1 :(得分:0)

基本上你有多个错误。这就是你想要的结果:

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

你到达那里:

  1. 将包围括号更改为{}
  2. 替换\&#34;与&#34;
  3. 用[]包装logDetails而不用#34;&#34;
  4. 包裹

    如果您需要有关代码的帮助,请与我们联系。