У меня есть простое представление ниже, чтобы отобразить все контакты для пользователя:
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
, а не каждый контакт. Я сравнил свой подход ниже с другими примерами онлайн и, похоже, не могу понять, где я ошибся. Я решил, что проблема заключается где-то в манипулировании контактами - когда я предоставляю поддельный массив приглашенных, все работает, как ожидалось, несмотря на то, что все компилируется и работает, как ожидается, без насмешек, а печать и отладка ничего не показывают.
Любая помощь будет оценена.