我有一个json响应消息体,看起来像这样。出于我的UI的目的,顶级消息只是列表中的第一条消息。
{
"messageId": "1234-1234-1234",
"jobId": "1234-1234-1234",
"message": "This is the top level message",
"createdDate": "2019-03-18T14:55:21.467",
"user": {},
"messages": [{
"messageId": "1234-1234-1234",
"jobId": "1234-1234-1234",
"message": "This is the a child message",
"createdDate": "2019-03-18T14:55:21.467",
"user": {},
"messages": [],
"attachments": []
},
{
"messageId": "1234-1234-1234",
"jobId": "1234-1234-1234",
"message": "This is the another child message",
"createdDate": "2019-03-18T14:55:21.467",
"user": {},
"messages": [],
"attachments": []
},
{
"messageId": "1234-1234-1234",
"jobId": "1234-1234-1234",
"message": "This is the yet another child message",
"createdDate": "2019-03-18T14:55:21.467",
"user": {},
"messages": [],
"attachments": []
}
],
"attachments": []
}
服务器实体
struct MessageServer: Codable {
let messageId: String
let jobId: String
let message: String
let createdDate: Date
let user: User
let messages: [MessageServer]
let attachments: [FileServer]
init(messageId: String,
jobId: String,
message: String,
createdDate: Date,
user: User,
messages: [MessageServer],
attachments: [FileServer]
) {
self.messageId = messageId
self.jobId = jobId
self.message = message
self.createdDate = createdDate
self.user = user
self.messages = messages
self.attachments = attachments
}
}
应用实体
struct Message: Codable {
let message: String
let createdDate: Date
let displayName: String
let isMine: Bool
let attachments: [File]
init(message: String, createdDate: Date, displayName: String, isMine: Bool, attachments: [File]) {
self.message = message
self.createdDate = createdDate
self.displayName = displayName
self.isMine = isMine
self.attachments = attachments
}
}
在我的服务调用中,我想返回一个Observable消息数组。
func getMessages(sectionID id: String) -> Observable<[Message]> {
return messageServiceEndpoints
.getMessages(for: id)
.map({
$0.map({
Message( /* init message here */ )
})
})
}
有没有办法将其缩小或平面映射到单个阵列?
这不是一个真正的RxSwift问题......你只需要解析JSON:
struct Message: Decodable {
let messageId: String
let message: String
let createdDate: Date
private (set) var messages: [Message]
// and the rest...
var droppedMessages: Message {
var result = self
result.messages = []
return self
}
}
func parseMessages(from data: Data) throws -> [Message] {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyy-MM-dd'T'HH:mm:ss.SSS"
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(dateFormatter)
let response = try decoder.decode(Message.self, from: data)
return [response.droppedMessages] + response.messages
}
我目前通过将此方法添加到我的服务器实体来解决此问题。
/// Creates a single list of [MessageServer] with the parent message at index 0
func flattenMessages() -> [MessageServer] {
var tmpMessages: [MessageServer] = []
let parent = MessageServer(messageId: messageId
jobId: jobId
message: message
createdDate: createdDate
user: user
messages: messages
attachments: attachments)
tmpMessages.append(parent)
return tmpMessages + messages
}
在我的服务电话中获取消息
func getMessages(sectionID id: String) -> Observable<[Message]> {
return laborServiceEndpoints
.getLaborOrderMessages(for: id)
.map({
$0.flattenMessages().map({
Message(message: $0.message,
createdDate: $0.createdDate,
displayName: $0.user.displayName
isMine: $0.user.id == userId,
attachments: $0.attachments.map({ File(name: $0.title,
type: DocumentType(rawString: $0.fileType),
url: $0.url)
})
)
})
})
}