Swift - 序列化包含对象数组的对象并使用 alamofire 发送

Posted

技术标签:

【中文标题】Swift - 序列化包含对象数组的对象并使用 alamofire 发送【英文标题】:Swift - Serialize object containing array of objects and send with alamofire 【发布时间】:2020-09-06 17:25:59 【问题描述】:

我需要使用 Alamofire 发送带有类作为参数的发布请求。 我的班级包含其他班级的数组,因此我被卡住了。

class CreateRecordData
    var RecordDate: String?
    var RecordType: String?
    var SubType: String?
    var Name: String?
    var MovementRecords: [RecordMovementData]?
    var MeasurementId: Int?
    var SensorType: String?



class RecordMovementData
    var FrameRate: Int?
    var JointType: String?
    var Samples: [MovementSampleData]?
    var RecordId: Int?




class MovementSampleData 
    var Id: Int?
    var TimeStamp: Int64?
    var X: Float?
    var Y: Float?
    var Z: Float?

我是 swift 的新手,有一段时间无法完成这项工作。

解决这个问题的方法是什么。

我需要 CreateRecordData 类使用 alamofire 作为参数发送。

谢谢

添加 Encodable 后的类

class CreateRecordData: Encodable
    var RecordDate: String?
    var RecordType: String?
    var SubType: String?
    var Name: String?
    var AudioRecords: [AudioData]?
    var MovementRecords: [RecordMovementData]?
    var MeasurementId: Int?
    var SensorType: String?

    enum CodingKeys: String, CodingKey 
        case RecordDate
        case RecordType
        case SubType
        case Name
        case AudioRecords
        case MovementRecords
        case MeasurementId
        case SensorType
    
    func encode(to encoder: Encoder) throws 
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(RecordDate, forKey: .RecordDate)
        try container.encode(RecordType, forKey: .RecordType)
        try container.encode(SubType, forKey: .SubType)
        try container.encode(Name, forKey: .Name)
        try container.encode(AudioRecords, forKey: .AudioRecords)
        try container.encode(MovementRecords, forKey: .MovementRecords)
        try container.encode(MeasurementId, forKey: .MeasurementId)
        try container.encode(SensorType, forKey: .SensorType)
    


class RecordMovementData: Encodable
    var FrameRate: Int?
    var JointType: String?
    var Samples: [MovementSampleData]?
    var RecordId: Int?

    enum CodingKeys: String, CodingKey
        case FrameRate
        case JointType
        case Samples
        case RecordId
    
    func encode(to encoder: Encoder) throws
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(FrameRate, forKey: .FrameRate)
        try container.encode(JointType, forKey: .JointType)
        try container.encode(Samples, forKey: .Samples)
        try container.encode(RecordId, forKey: .RecordId)
    



class MovementSampleData: Encodable 
    var Id: Int?
    var TimeStamp: Int64?
    var X: Float?
    var Y: Float?
    var Z: Float?

    enum CodingKeys: CodingKey
        case Id
        case TimeStamp
        case X
        case Y
        case Z
    
    func encode(to encoder: Encoder) throws
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(Id, forKey: .Id)
        try container.encode(TimeStamp, forKey: .TimeStamp)
        try container.encode(X, forKey: .X)
        try container.encode(Y, forKey: .Y)
        try container.encode(Z, forKey: .Z)
    

还有一点要提。 a 不要直接使用 CreateRecordData 作为参数。我使用该类的数据创建字典,如下所示:

let recordParams: [String:Any] = [
            "RecordDate": recordData.RecordDate!,
            "RecordType": recordData.RecordType!,
            "SubType": recordData.SubType!,
            "Name": recordData.Name!,
            "AudioRecords": "",
            "MovementRecords": recordData.MovementRecords!,
            "MeasurementId": "\(recordData.MeasurementId!)",
            "SensorType": recordData.SensorType!
        ]

        AF.request("https://repac-fe-v1-webapp.azurewebsites.net/api/record",method: .post, parameters: recordParams, encoding: JSONEncoding.default, headers: header).responseJSON  response in

        

这也可能有问题

【问题讨论】:

您的服务器需要什么样的编码?你已经尝试了什么?你看过Codable 协议了吗? developer.apple.com/documentation/foundation/… @gcharita 需要 Json 编码。我尝试了 Codable 协议,但在 JSON 写入中出现错误无效类型。我会仔细查看您发送的链接 请发布您的Codable 代码以找出缺少的内容。 @gcharita 我编辑了帖子,我假设我只需要在我的课程中使用 Encodable 来完成我需要做的事情。在此之后我仍然有同样的错误 【参考方案1】:

由于 JSON 中的键与模型属性的名称相同,因此您可以在模型类中省略 CodingKeys 枚举。此外,由于您没有在编码中进行自定义操作,因此您可以完全省略 encode(to:) 函数的实现:

class AudioData: Encodable 
    // This class is missing from the posted code


class CreateRecordData: Encodable 
    var RecordDate: String?
    var RecordType: String?
    var SubType: String?
    var Name: String?
    var AudioRecords: [AudioData]?
    var MovementRecords: [RecordMovementData]?
    var MeasurementId: Int?
    var SensorType: String?


class RecordMovementData: Encodable 
    var FrameRate: Int?
    var JointType: String?
    var Samples: [MovementSampleData]?
    var RecordId: Int?


class MovementSampleData: Encodable 
    var Id: Int?
    var TimeStamp: Int64?
    var X: Float?
    var Y: Float?
    var Z: Float?

使用Encodable 对象作为参数的发布请求比您想象的要简单。您只需调用request 方法,该方法将encoder 而非encoding 作为参数:

let recordParams = CreateRecordData() // Set the class values here

AF.request(
    "https://repac-fe-v1-webapp.azurewebsites.net/api/record",
    method: .post,
    parameters: recordParams,
    encoder: JSONParameterEncoder.default,
    headers: header
).responseJSON  response in
    

【讨论】:

以上是关于Swift - 序列化包含对象数组的对象并使用 alamofire 发送的主要内容,如果未能解决你的问题,请参考以下文章

解析对象数组并填充表格视图单元格 Swift

在 Swift 中用数组序列化我自己的对象的更优雅的方法是啥

在 Swift 中使用 Alamofire 发送包含字典对象数组的字典对象时会发生奇怪的行为?

将 swift 数组转换为对象以进行 json 序列化

检查Swift数组是不是包含对象实例[重复]

Swift 4 - SwiftyJson 比较数组并合并找到的值