Reputation: 9419
So I have a table view with a list of items. Only users with the highest permission levels can delete these items. When the user swipes a table view cell with the intent to delete it editActionsOptionsForRowAt
is called. I check the user permission in this delegate method by making a server call (asynchronous). The problem is that I need this info fast, plus this code doesn't compile because I can't return the delete item in a closure. What can I do to fix this?
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]? {
// ...
APIContentService.getUserPermission(projectKey: projectKey, stepKey: stepKey, userKey: userKey) { (accessLevel) in
if let level = accessLevel {
if level == .admin {
return [delete] // show delete item – COMPILER ERROR, can't return this in a closure
} else {
//
return [] // don't show anything
}
}
}
// ...
}
Upvotes: 0
Views: 222
Reputation: 285069
As you noticed yourself you cannot return something from an asynchronous task.
You have to get the user permission in viewDidLoad
and save the state in a property.
Then return the edit action(s) depending on that property.
I would even implement canEditRowAt
and return true
or false
depending on that property.
Upvotes: 1
Reputation: 4355
Calling API call in table view
delegate for delete action is not seems like a good design. What happens if the API request fails or take a long time to process due to some reasons.
It will be great if you can call API in advance and then just compare the values in delete action. It will be more interactive to the user.
If you can't call API in advance then show an Activity Indicator
when API calls and hide it in its response. It will help you to handle all scenarios
Upvotes: 1
Reputation: 318794
In short, don't try. The delegate method needs to return immediately with a valid result. You could do tricks with semaphores or dispatch groups to block the delegate method from returning until you get a result from the server but that is a really bad idea.
The proper solution is to get the permission once in viewDidLoad
. Save the result in a property. Then reference that property in your delegate method.
The user's permission is not going to change each time the table view wants to know the edit actions for each row while the user is on this screen. So you should only need to get the permission once each time the user views this screen.
Upvotes: 2