SwiftUI List только с использованием первого элемента данного массива - PullRequest
0 голосов
/ 07 марта 2020

У меня есть простое представление ниже, чтобы отобразить все контакты для пользователя:

struct AllContactsView: View {
    static let withState: some View = AllContactsView().environmentObject(AllContactsProvider())
    @EnvironmentObject var contactsProvider: AllContactsProvider
    let title: UserListType = .selectInvitees

    var body: some View {
        List(self.contactsProvider.invitees) { invite in
            self.row(for: invite)
        }
        .navigationBarTitle(Text(self.title.rawValue))
        .onAppear(perform: self.contactsProvider.fetch)
    }

    func row(for invite: Invitee) -> some View {
        // everything below is only printed out once!
        print(self.contactsProvider.invitees.prettyPrinted) // shows correct array of contacts
        print(type(of: self.contactsProvider.invitees)) // this is indeed an array
        print(invite) // prints out the first item in the array (which is expected on first pass)
        return UserRow(invitee: invite)
    }
}

Я манипулирую массивом CNContacts Я получаю таким образом массив массивов приглашенных, вот что Я пытаюсь отобразить в своем списке:

self?.invitees = contacts.asSimpleContacts.map({ $0.asUser.asInvitee })

Используя следующие поддерживаемые функции и расширения:

// Contact Value simplified so we can pass it around as a value type.
public struct SimpleContact: Hashable, Codable {
    let firstName: String
    let lastName: String
    let emails: [String]
    let phoneNumbers: [PhoneNumber]

    var fullName: String { "\(self.firstName) \(self.lastName)" }

    var asUser: User {
        User(
            id: Constants.unsavedID,
            username: self.fullName,
            picURL: "al",
            email: self.emails.first ?? "",
            phone: self.phoneNumbers.first ?? "",
            created: Date().timeIntervalSince1970
        )
    }
}


extension CNContact {
    /// Returns the `SimpleContact` representation of `self`
    var asSimpleContact: SimpleContact {
        SimpleContact(
            firstName: self.givenName,
            lastName: self.familyName,
            emails: self.emailAddresses.map({ String($0.value) }),
            phoneNumbers: self.phoneNumbers.map({ Authentication.sanitize(phoneNo: $0.value.stringValue) })
        )
    }
}

extension Array where Element == CNContact {
    /// Returns the `SimpleContact` mapping of `self`
    var asSimpleContacts: [SimpleContact] { self.map({ $0.asSimpleContact }) }
}

public struct User: Hashable, Codable, Identifiable {
    public let id: String
    let username: String
    let picURL: String
    let email: String
    let phone: String
    let created: Double

    var asInvitee: Invitee { Invitee(user: self, isGoing: false) }
}

Контакты заполняются в self.contactsProvider.invitees, как ожидается, после self.contactsProvider.fetch(). Однако SwiftUI отображает self.contactsProvider.invitees.count экземпляров self.contactsProvider.invitees.first, а не каждый контакт. Я сравнил свой подход ниже с другими примерами онлайн и, похоже, не могу понять, где я ошибся. Я решил, что проблема заключается где-то в манипулировании контактами - когда я предоставляю поддельный массив приглашенных, все работает, как ожидалось, несмотря на то, что все компилируется и работает, как ожидается, без насмешек, а печать и отладка ничего не показывают.

Любая помощь будет оценена.

1 Ответ

0 голосов
/ 08 марта 2020

Для всех, кто сталкивался с чем-то похожим, проблема заключалась в том, что идентификатор, с которым я создавал объекты, не был уникальным. Любопытно, что это будет ожидаемое поведение, если эта ошибка сделана, но это то, что было.

...