在 Swift 3 中正确格式化 JSON 对象

Posted

技术标签:

【中文标题】在 Swift 3 中正确格式化 JSON 对象【英文标题】:Properly formatting JSON object in Swift 3 【发布时间】:2017-03-01 19:26:14 【问题描述】:

我在运行 Node.js 的服务器上获取格式正确的 JSON 对象时遇到问题。我将我的 API 设置为接收 JSON 对象并将其存储在数据库中。当我从邮递员(如下所示)向它发送一个 POST 请求时,这很有效,但是当我从 ios 发送它时它会抛出一个奇怪的错误。举个例子:

显示的第一个 json 对象是从邮递员发送的。第二个来自 iOS(使用 Swift 3)。该错误实际上使服务器崩溃,说:

AssertionError: Error: key          "firstname":"testFirstName","lastname":"testLastName","email":"testemail123@gmail.com","username":"testusername123", == null

我不确定为什么会这样。我认为它与创建对象的方式有关?这是我用来创建对象的快速代码:

let infoDictionary = [
            "username":  UserNameField.text!,
            "password":  PasswordField.text!,
            "firstname": FirstNameField.text!,
            "lastname":  LastNameField.text!,
            "email":     EmailField.text!
        ]

        // Whole block = send above dictionary as JSON to server:
        if JSONSerialization.isValidJSONObject(infoDictionary) 
            do 
                let jsonObject = try JSONSerialization.data(withJSONObject: infoDictionary,
                                                            options: .prettyPrinted)

然后我将它附加到 http 正文中。请注意,这些字段来自我打开并放入字典的应用程序 UI 中的文本字段。当我以 swift 将它作为字符串打印出来时,它以正确的格式出现,当我实际将它发送到我的服务器时出现了问题。

编辑:每个请求的完整 URL 请求如下:

do 
                let jsonObject = try JSONSerialization.data(withJSONObject: infoDictionary,
                                                            options: .prettyPrinted)
                // Create Post request
                let url = URL(string: "websiteurl")
                var request = URLRequest(url: url!)
                request.httpMethod = "POST"

                // Append JSON object
                request.httpBody = jsonObject

                // Send request
                let task = URLSession.shared.dataTask(with: request)  data, response, error in
                    guard let data = data, error == nil else 
                        print(error?.localizedDescription ?? "No Data")
                        return
                    
                    let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
                    if let responseJSON = responseJSON as? [String: Any] 
                        print(responseJSON)
                    
                
                task.resume() // Sends the request
             catch 
                print(error.localizedDescription)
            
        

【问题讨论】:

您是否必须将 infoDictionary 传递给 AlamoFire,而不是 jsonObject? 我没有使用 AlamoFire,使用 URLRequest / URLSession 手动发出 HTTP 请求。所以我使用 URLRequest 创建请求,然后将 json 对象添加到该请求的正文中。 对不起!!我以为我在某处读过“AlamoFire”——不知道为什么。但无论如何:显然你的 jsonObject 被包装到另一个 JSON 字符串中。请添加如何创建 URLRequest 的代码。 刚刚添加了我用来发出请求的代码! 看起来不错。也许您必须将 http Content-Type 设置为 "application/json" ? 【参考方案1】:

请求正文很好,它包含一个有效的 JSON 对象,但是 显然,服务器将 HTTP 正文解释为 string 并包装 它进入另一个 JSON 对象。请注意,“text/plain”是默认值 HTTP 请求的内容类型 (https://www.rfc-editor.org/rfc/rfc2045#section-5.2)。

解决方法是显式设置内容类型:

request.addValue("application/json", forHTTPHeaderField: "Content-type")

【讨论】:

以上是关于在 Swift 3 中正确格式化 JSON 对象的主要内容,如果未能解决你的问题,请参考以下文章

iOS - 使用 Swift 在每个表格视图单元格中获取 JSON 提要

在 Swift 3 中将数据从 JSON 传递到表格视图单元格

使用 SWIFT 3 的单元格不显示没有 html 标记的更新 JSON

涉及 JSON 解析以及静态和动态 UITableView 单元格的 Swift3 项目 - 使其更加面向对象

在 Swift 3 中正确解析 JSON

在 Swift 3 中正确解析 JSON