Уменьшить или отобразить ответ json на один массив - PullRequest
1 голос
/ 30 марта 2019

У меня есть тело ответа json, которое выглядит следующим образом.В целях моего пользовательского интерфейса сообщение верхнего уровня - это только первое сообщение в списке.

{
    "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
}

}

В моем сервисном звонке яхотел бы просто вернуть наблюдаемый массив сообщений.

func getMessages(sectionID id: String) -> Observable<[Message]> {
    return messageServiceEndpoints
        .getMessages(for: id)
        .map({
            $0.map({
                Message( /* init message here */ )
             })
         })
}

Есть ли способ уменьшить или отобразить это до одного массива?

Ответы [ 2 ]

1 голос
/ 31 марта 2019

Это на самом деле не вопрос 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
}
0 голосов
/ 31 марта 2019

В настоящее время я решил эту проблему, добавив этот метод к своему объекту сервера.

/// 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)
                        })
                    )
                })
            })
    }
...