Swift - Get array item with an IndexSet

点点圈 提交于 2021-01-28 05:26:21

问题


I have my Contact object:

struct Contact: Codable, Identifiable {
    var id: Int = 0
    var name: String
    var lastName: String
    var phoneNumber: String
}

And in my view I have a list of contacts that will be fetched from a server.

List {
    ForEach(viewModel.contacts) { contact in
        ContactView(contact: contact)
    }
    .onDelete(perform: self.viewModel.delete)
}

When I delete a contact I call my viewModel method delete wich only removes the item from the array. But since I will make a server request to delete a contact, I would like to get info about the item I'm deleting, like the Id.

class ContactsViewModel: ObservableObject {
    @Published contacts = [
        Contact(id: 1, name: "Name 1", lastName: "Last Name 1", phoneNumber: "613456789"),
        Contact(id: 2, name: "Name 2", lastName: "Last Name 2", phoneNumber: "623456789"),
        Contact(id: 3, name: "Name 3", lastName: "Last Name 3", phoneNumber: "633456789"),
        Contact(id: 4, name: "Name 4", lastName: "Last Name 4", phoneNumber: "643456789")
    ]
    func delete(at offsets: IndexSet) {
        self.contacts.remove(atOffsets: offsets)
    }
}

I wonder if I can do something like this:

func delete(at offsets: IndexSet) {
    // Get the contact from array using the IndexSet
    let itemToDelete = self.contacts.get(at: offsets)

    deleteRequest(itemToDelete.id){ success in 
        if success {
            self.contacts.remove(atOffsets: offsets)
        }
    }
}

回答1:


Taking into account that mentioned deleteRequest semantically is asynchronous and there might be, in general, several contacts deleted in one user action, I would do it like below

func delete(at offsets: IndexSet) {

    // preserve all ids to be deleted to avoid indices confusing
    let idsToDelete = offsets.map { self.contacts[$0].id }

    // schedule remote delete for selected ids
    _ = idsToDelete.compactMap { [weak self] id in
        self?.deleteRequest(id){ success in
            if success {
                DispatchQueue.main.async {
                    // update on main queue
                    self?.contacts.removeAll { $0.id == id }
                }
            }
        }
    }
}

Note: also some feedback in UI would be needed marking progressed contacts and disabling user from other manipulations with them till end of corresponding deleteRequest



来源:https://stackoverflow.com/questions/61347408/swift-get-array-item-with-an-indexset

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!