Model:
enum TaskType: Int, Codable {
case upcoming = 0
case inProgress
case testing
case completed
var title: String {
switch self {
case .upcoming:
return "Upcoming"
case .inProgress:
return "In Progress"
case .testing:
return "Testing"
case .completed:
return "Completed"
}
}
}
struct TasksModel: Encodable, Decodable {
var upcomingArray: [TaskInfo]
var inProgressArray: [TaskInfo]
var testingArray: [TaskInfo]
var completedArray: [TaskInfo]
}
struct TaskInfo: Codable, Equatable, Identifiable {
var id: String
var title: String
var description: String
var taskStatus: TaskType
var taskDate = Date()
}
VM:
class HomeVM: ObservableObject {
@Published var tasksArray: TasksModel
self.tasksArray = TasksModel.init(upcomingArray: [], inProgressArray: [], testingArray: [], completedArray: [])
}
So I want a function like below where it receives the id (taskID) for the search and I want to locate the record with that id and I can change the value of the taskStatus from what it is to another (i.e.: from upcoming to testing).
func inProgressSetTask(taskID: String) {
@StateObject var viewModel = HomeVM()
if let index = viewModel.tasksArray.inProgressArray.first(where: taskID) {
// Complete code to change taskStatus
}
print("InProgress Set ID# \(taskID)")
}
But this way I’m trying, it displays an error saying that can’t convert from String to expected ‘(TaskInfo). I would be trying this code if let index to each array in TasksArray (inProgressArray, CompletedArray, etc), is there any way to look into all arrays at once ?
Appreciate any help.
CodePudding user response:
You are attempting to compare a String
to a TaskInfo
, because the elements of an inProgressArray
are of type TaskInfo
. What you need to do is drill into the array and get to the .id
. That is simple to do. In the .first(where:)
, you simply pass a closure of $0.id == taskID
.
if let index = viewModel.tasksArray.inProgressArray.first(where: { $0.id == taskID } ) {
CodePudding user response:
you could try the following example code to achieve what you want:
(note, you should have @StateObject var viewModel = HomeVM()
outside of the func inProgressSetTask(taskID: String) {...}
or pass it in as a parameter)
EDIT-1:
func inProgressSetTask(taskID: String) {
print("InProgress Set ID# \(taskID)")
// with index, using `firstIndex`
if let index = viewModel.tasksArray.inProgressArray.firstIndex(where: {$0.id == taskID}) {
// do something with the index
viewModel.tasksArray.inProgressArray[index].title = "xxx"
}
// with TaskInfo, using `first`
if var taskInfo = viewModel.tasksArray.inProgressArray.first(where: {$0.id == taskID}) {
// do something with the taskInfo
taskInfo.title = "xxx"
}
// with all arrays of TaskInfo, use the `func setTaskFromAll(...)` in `HomeVM`
}
class HomeVM: ObservableObject {
@Published var tasksArray: TasksModel = TasksModel.init(upcomingArray: [], inProgressArray: [], testingArray: [], completedArray: [])
func setTaskFromAll(taskID: String) {
if let index = tasksArray.inProgressArray.firstIndex(where: {$0.id == taskID}) {
tasksArray.inProgressArray[index].title = "inProgress"
} else {
if let index = tasksArray.completedArray.firstIndex(where: {$0.id == taskID}) {
tasksArray.completedArray[index].title = "completed"
} else {
if let index = tasksArray.testingArray.firstIndex(where: {$0.id == taskID}) {
tasksArray.testingArray[index].title = "testing"
} else {
if let index = tasksArray.upcomingArray.firstIndex(where: {$0.id == taskID}) {
tasksArray.upcomingArray[index].title = "upcoming"
}
}
}
}
}
}