Swift добавление в массив пользовательских объектов и сортировка их - PullRequest
0 голосов
/ 05 ноября 2018

Я создаю коллекционное представление, которое показывает кому-то его «канал», который включает в себя его комплименты, лайки, ответы и отправку. У меня есть объект с именем Feed, который состоит из массива комплиментов, массива лайков, массива ответов и массива отправленных. Каждый объект в этих меньших массивах имеет свойство date_created.

Я знаю, как заполнить представление коллекции, основанное на одном массиве, отсортированном по датам, но как я могу загрузить представление коллекции с каждым лайком, ответом, комплиментом и отправленным из четырех массивов, основываясь на их отправленной дате?

Возможно ли добавить каждый из этих объектов в один массив? Если да, то как я могу пройти через этот массив и отсортировать все в нем?

struct Feed: Decodable {
    let likes: [Like]
    let replies: [Reply]
    let compliments: [Compliment]
    let sent: [Compliment]
}

struct Like: Decodable {
    let id: Int
    let user: QuickUser
    let created_at: String
}

struct Reply: Decodable {
    let parent: Compliment
    let content: String
    let created_at: String
}

struct Compliment: Decodable {
    let id: Int
    let content: String
    let sender: QuickUser

    let created_at: String

    let is_liked: Bool
    let recipient: QuickUser
    let is_public: Bool
}

func getFeed() {
    UserServices.getInboxFeed { feed in
        guard let feed = feed else {
            self.showOkayAlert(title: "Oops!", message: "We are having trouble loading your inbox.", completion: nil)
            return
        }
        self.feed = feed

        DispatchQueue.main.async {
            //load collection view here
        }
    }
}

Макет того, как будет выглядеть представление коллекции mockup

1 Ответ

0 голосов
/ 05 ноября 2018

Ну, чтобы решить эту проблему, я создал фиктивный протокол, который содержит общие свойства, которыми они все обладают.

в этом случае это было created_at, и я предполагаю, что это должно быть в формате даты.

однако следующим шагом было создание расширения Feed, которое содержит function

, который возвращает последний объект, который подтверждает фиктивную protocol, которую я вызвал, это LatestAction,

Он в основном сортирует каждый массив по date и возвращает первый элемент.

в нашем случае самая последняя date,

после этого создает [LatestAction], сортирует его снова таким же образом и возвращает первый элемент, который является LatestAction.

Соблюдайте код ниже.

struct QuickUser: Codable {

}

struct Feed: Decodable {
    let likes: [Like]
    let replies: [Reply]
    let compliments: [Compliment]
    let sent: [Compliment]
}
extension Feed {
    func latestAction() -> LatestAction {
        let latestLike = self.likes.sorted(by: { $0.created_at.compare($1.created_at) == .orderedDescending }).first!
        let latestReply = self.replies.sorted(by: { $0.created_at.compare($1.created_at) == .orderedDescending }).first!
        let latestComp = self.compliments.sorted(by: { $0.created_at.compare($1.created_at) == .orderedDescending }).first!
        let latestActions: [LatestAction] = [latestReply, latestLike, latestComp].sorted(by: { $0.created_at.compare($1.created_at) == .orderedDescending })
        return latestActions.first!
    }

}
protocol LatestAction  {
    var created_at: Date { get }
}

struct Like: Decodable, LatestAction {

    let id: Int
    let user: QuickUser
    let created_at: Date
}

struct Reply: Decodable, LatestAction {

    let parent: Compliment
    let content: String
    let created_at: Date
}

struct Compliment: Decodable, LatestAction {

    let id: Int
    let content: String
    let sender: QuickUser

    let created_at: Date

    let is_liked: Bool
    let recipient: QuickUser
    let is_public: Bool
}



// Simply used like this
var latest = feed.latestAction() 

Мы еще не закончили, если вы проверили тип latest, он сказал бы LatestAction и мог получить доступ только к одному свойству там, которое created_at,

Теперь для последней части мы собираемся TypeCast Object.

if let latest = feed.latestAction() as? Like {
    // used as Like
} else if let latest = feed.latestAction() as? Compliment {
    // used as Compliment
} else if let latest = feed.latestAction() as? Reply {
    // used as reply
}
...