如何对对象内部的对象使用 Codable 编码
How to use Codable encode with object inside object
我正在使用我的对象负载处理 JSON 负载。但我在对象内部编码对象时遇到问题。
我的 Payload class 是这个
class ConversationPayload :BaseObject {
var title : String? = ""
var messageDict: MessagePayload = MessagePayload()
var participants: [Int32] = []
var type: String = ""
enum CodingKeys: String, CodingKey {
case title = "title"
case messageDict = "message"
case participants = "participants"
case type = "type"
}
override func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
if title != nil {
try container.encode(title, forKey: .title)
}
try container.encode(messageDict, forKey: .messageDict)
try container.encode(participants, forKey: .participants)
try container.encode(type, forKey: .type)
}
}
class MessagePayload: BaseObject {
var body : String = ""
var isVideocallInvite: Bool = false
var attachmentsPayload: MessageAttachmentPayload? = nil
enum CodingKeys: String, CodingKey {
case body = "body"
case isVideocallInvite = "is_videocall_invite"
case attachmentsPayload = "attachment"
}
override func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(body, forKey: .body)
try container.encode(isVideocallInvite, forKey: .isVideocallInvite)
if attachmentsPayload != nil {
try container.encode(attachmentsPayload, forKey: .attachmentsPayload)
}
}
}
class MessageAttachmentPayload: BaseObject {
var photo : String = ""
var photoType : String = "jpg"
}
BaseObject 是这个
class BaseObject:Codable{}
我想在 json 有效载荷中得到的是这样的
{"message": {"body": "body_string", "is_videocall_invite": 1}, "participants" : [user-id], "type" : "converstation_type","title":"title"}
有人知道我的负载有什么问题吗class?在 Codable 上还不是很熟悉。提前致谢。
问题是什么?我刚刚测试了你的 class,它有一些小问题,但它确实符合可编码的标准,并且编码没有问题。
操场上:
var conversation = ConversationPayload()
var message = MessagePayload()
message.body = "message body"
message.isVideocallInvite = true
var attachment = MessageAttachmentPayload()
attachment.photo = "attachment_file"
message.attachmentsPayload = attachment
conversation.messageDict = message
conversation.title = "Title"
conversation.participants = [1, 2, 3, 4]
conversation.type = "Conversation Type"
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let data = try! encoder.encode(conversation)
print(String(data: data, encoding: .utf8)!)
输出如下所示:
{
"participants" : [
1,
2,
3,
4
],
"message" : {
"is_videocall_invite" : true,
"attachment" : {
"photo" : "attachment_file",
"photoType" : "jpg"
},
"body" : "message body"
},
"title" : "Title",
"type" : "Conversation Type"
}
我在 MessageAttachmentPayload
class 中添加了 encode
和 CodingKey
来对值进行编码。
这不正是您所期待的吗?
我不确定你在这里有什么限制,但我会简化所有这些。使 JSON 数据模型尽可能接近 JSON。
struct ConversationJsonModel: Codable {
var title: String?
var message: MessageJsonModel
var participants: [Int]
var type: String
}
struct MessageJsonModel: Codable {
var body: String
var is_videocall_invite: Int
var attachment: AttachmentJsonModel?
}
struct AttachmentJsonModel: Codable {
var photo: String
var photo_type: String // <-- assuming photo_type is the JSON member name.
}
如果您需要视图模型或其他类型的本地数据模型,那么这两部分是分开的。
class BaseObject {}
class ConversationPayload: BaseObject {
var title : String? = ""
var messageDict: MessagePayload = MessagePayload()
var participants: [Int32] = []
var type: String = ""
func makeConversationJsonModel() -> ConversationJsonModel {
ConversationJsonModel(title: title,
message: messageDict.makeMessageJsonModel(),
participants: participants.map { Int([=11=]) },
type: type)
}
}
class MessagePayload: BaseObject {
var body : String = ""
var isVideocallInvite: Bool = false
var attachmentsPayload: MessageAttachmentPayload? = nil
func makeMessageJsonModel() -> MessageJsonModel {
MessageJsonModel(body: body,
is_videocall_invite: isVideocallInvite ? 1 : 0,
attachment: attachmentsPayload?.makeAttachmentJsonModel())
}
}
class MessageAttachmentPayload: BaseObject {
var photo : String = ""
var photoType : String = "jpg"
func makeAttachmentJsonModel() -> AttachmentJsonModel {
AttachmentJsonModel(photo: photo, photo_type: photoType)
}
}
最后,对您的 JSON
进行编码
let conversationPayload = ConversationPayload()
let json = try? JSONEncoder().encode(conversationPayload.makeConversationJsonModel())
这允许 JSON 表示和有效载荷模型之间的清晰分离。例如,在JSON中,is_videocall_invite
是一个Int
(0或1);同时,在有效负载模型中,isVideocallInvite
是 Bool
.
我正在使用我的对象负载处理 JSON 负载。但我在对象内部编码对象时遇到问题。
我的 Payload class 是这个
class ConversationPayload :BaseObject {
var title : String? = ""
var messageDict: MessagePayload = MessagePayload()
var participants: [Int32] = []
var type: String = ""
enum CodingKeys: String, CodingKey {
case title = "title"
case messageDict = "message"
case participants = "participants"
case type = "type"
}
override func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
if title != nil {
try container.encode(title, forKey: .title)
}
try container.encode(messageDict, forKey: .messageDict)
try container.encode(participants, forKey: .participants)
try container.encode(type, forKey: .type)
}
}
class MessagePayload: BaseObject {
var body : String = ""
var isVideocallInvite: Bool = false
var attachmentsPayload: MessageAttachmentPayload? = nil
enum CodingKeys: String, CodingKey {
case body = "body"
case isVideocallInvite = "is_videocall_invite"
case attachmentsPayload = "attachment"
}
override func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(body, forKey: .body)
try container.encode(isVideocallInvite, forKey: .isVideocallInvite)
if attachmentsPayload != nil {
try container.encode(attachmentsPayload, forKey: .attachmentsPayload)
}
}
}
class MessageAttachmentPayload: BaseObject {
var photo : String = ""
var photoType : String = "jpg"
}
BaseObject 是这个
class BaseObject:Codable{}
我想在 json 有效载荷中得到的是这样的
{"message": {"body": "body_string", "is_videocall_invite": 1}, "participants" : [user-id], "type" : "converstation_type","title":"title"}
有人知道我的负载有什么问题吗class?在 Codable 上还不是很熟悉。提前致谢。
问题是什么?我刚刚测试了你的 class,它有一些小问题,但它确实符合可编码的标准,并且编码没有问题。
操场上:
var conversation = ConversationPayload()
var message = MessagePayload()
message.body = "message body"
message.isVideocallInvite = true
var attachment = MessageAttachmentPayload()
attachment.photo = "attachment_file"
message.attachmentsPayload = attachment
conversation.messageDict = message
conversation.title = "Title"
conversation.participants = [1, 2, 3, 4]
conversation.type = "Conversation Type"
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let data = try! encoder.encode(conversation)
print(String(data: data, encoding: .utf8)!)
输出如下所示:
{
"participants" : [
1,
2,
3,
4
],
"message" : {
"is_videocall_invite" : true,
"attachment" : {
"photo" : "attachment_file",
"photoType" : "jpg"
},
"body" : "message body"
},
"title" : "Title",
"type" : "Conversation Type"
}
我在 MessageAttachmentPayload
class 中添加了 encode
和 CodingKey
来对值进行编码。
这不正是您所期待的吗?
我不确定你在这里有什么限制,但我会简化所有这些。使 JSON 数据模型尽可能接近 JSON。
struct ConversationJsonModel: Codable {
var title: String?
var message: MessageJsonModel
var participants: [Int]
var type: String
}
struct MessageJsonModel: Codable {
var body: String
var is_videocall_invite: Int
var attachment: AttachmentJsonModel?
}
struct AttachmentJsonModel: Codable {
var photo: String
var photo_type: String // <-- assuming photo_type is the JSON member name.
}
如果您需要视图模型或其他类型的本地数据模型,那么这两部分是分开的。
class BaseObject {}
class ConversationPayload: BaseObject {
var title : String? = ""
var messageDict: MessagePayload = MessagePayload()
var participants: [Int32] = []
var type: String = ""
func makeConversationJsonModel() -> ConversationJsonModel {
ConversationJsonModel(title: title,
message: messageDict.makeMessageJsonModel(),
participants: participants.map { Int([=11=]) },
type: type)
}
}
class MessagePayload: BaseObject {
var body : String = ""
var isVideocallInvite: Bool = false
var attachmentsPayload: MessageAttachmentPayload? = nil
func makeMessageJsonModel() -> MessageJsonModel {
MessageJsonModel(body: body,
is_videocall_invite: isVideocallInvite ? 1 : 0,
attachment: attachmentsPayload?.makeAttachmentJsonModel())
}
}
class MessageAttachmentPayload: BaseObject {
var photo : String = ""
var photoType : String = "jpg"
func makeAttachmentJsonModel() -> AttachmentJsonModel {
AttachmentJsonModel(photo: photo, photo_type: photoType)
}
}
最后,对您的 JSON
进行编码let conversationPayload = ConversationPayload()
let json = try? JSONEncoder().encode(conversationPayload.makeConversationJsonModel())
这允许 JSON 表示和有效载荷模型之间的清晰分离。例如,在JSON中,is_videocall_invite
是一个Int
(0或1);同时,在有效负载模型中,isVideocallInvite
是 Bool
.