如何在swift 4中的httpBody中发送字符串值和json值

时间:2018-04-02 10:16:31

标签: json swift string encoding

我有一个条件,我必须在字符串中发送两个body值,在JSON中发送另一个值

我的结构:

struct AttendancePost : Codable {
    let acad_id :String
    let school_id :String
    let class_id:String
    let section_id:String
    let stdid:String
    var status:String
    let attendant_id:String

}

我已在模型中以这种方式插入数据:

let singldata = AttendancePost(acad_id: data.acad_id!, school_id: SCHOOL_ID, class_id: self.classFID, section_id: self.secID, stdid: data.stdid!, status: "1", attendant_id: savedsesuid!)

self.dataToPost.append(singldata)

var dataToPost =  [AttendancePost]()


let jsonEncoder = JSONEncoder()
    let jsonData = try? jsonEncoder.encode(dataToPost)
    let postData = try? JSONSerialization.data(withJSONObject: jsonData, options: JSONSerialization.WritingOptions.prettyPrinted)

    let theBody = "attendance_details=\(jsonData)" + "&user_id=\(savedsesuid!)" + "&school_id=" + SCHOOL_ID

    request.httpBody = theBody.data(using: .utf8)

我收到了这个错误:

'NSInvalidArgumentException', reason: '*** +[NSJSONSerialization dataWithJSONObject:options:error:]: Invalid top-level type in JSON write'

1 个答案:

答案 0 :(得分:2)

问题

此代码存在一些问题,首先,您要将singldata附加到名为dataToPost的类(或类型)属性。然后,您将创建一个同名的本地变量(即dataToPost),该变量使用AttendancePost类型的空数组进行初始化。然后,在使用使用{J}创建的JSON的dataToPost尝试不必要且未使用的JSONEncoder转换之前,将此局部变量postData(包含空数组)传递给JSONSerialization编码器,这是引发错误的地方。

解决方案

引发错误是因为您使用的是来自JSONEncoder的数据,而不是基础对象(例如字典或数组),用于JSONObject值。删除或注释

let postData = try? JSONSerialization.data(withJSONObject: jsonData, options: JSONSerialization.WritingOptions.prettyPrinted)

并且错误将消失。但这不会是你问题的终结。首先,您应该按如下方式构造代码的正文部分:

let jsonEncoder = JSONEncoder()
    let jsonData = try? jsonEncoder.encode(dataToPost)
    var theBody = Data()    
    if let a = "attendance_details=".data(using: .utf8) {
       theBody.append(a)
    }

    theBody.append(jsonData)

    let str = "&user_id=\(savedsesuid!)" + "&school_id=" + SCHOOL_ID
    if let b = str.data(using: .utf8) {
        theBody.append(b)
    }

    request.httpBody = theBody

最后,如果简化为:

,前三行代码在这种情况下会更有意义
let dataToPost = AttendancePost(acad_id: data.acad_id!, school_id: SCHOOL_ID, class_id: self.classFID, section_id: self.secID, stdid: data.stdid!, status: "1", attendant_id: savedsesuid!)

如上所述,目前您的代码将空数组传递给JSONEncoder实例。

注意:此代码未经测试并从内存中写入,但出现的任何编译器警告都应该是简单的解决方法。