Search code examples
swiftstringuitableviewstructnsuserdefaults

Resolving conflicting struct value types in swift


I have a UITableViewController. Each row is populated from a global array. This global array Describes the title of a task. Each task has some associated variables which are strings.

I want to be able to click on the title of task in the table view controller and have the associated variables linked to that title. The global array will be grow and shrink as the end user appends or removes titles from the global array.

This is made with a struct. The struct contains the specific variables.

The problem occurs in this example in the load function. I cannot load the data because Programs = loadedData Cannot assign value of type '[String]' to type '[Item].

import UIKit



struct Item {
let title:String
let others:[String]
}

  var Programs = [Item]()

  class ProgramList: UIViewController, UITableViewDataSource, UITableViewDelegate{

@IBOutlet weak var programTableView: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()
    load()
}


override func viewDidAppear(_ animated: Bool) {
    programTableView.reloadData()
    save()
}


//saving current state of programs array
func save(){
    UserDefaults.standard.set(Programs, forKey: "notes")
}

//loading saved program array
func load() {
    if let loadedData: [String] = UserDefaults.standard.value(forKey: "notes") as? [String] {
        Programs = loadedData
        programTableView.reloadData()
    }
}


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return Programs.count
}


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
    cell.programTitle.text = Programs[indexPath.row].title
    return cell
}


//Removing Item by swipping left & saving this newly established array
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {

    if editingStyle == UITableViewCell.EditingStyle.delete {
        Programs.remove(at: indexPath.row)
        programTableView.reloadData()
        save()
    }

}

}

Solution

  • You need

    programs = loadedData.map { Item(title:$0,others:[])}
    

    Btw you can make it Codable like

    struct Item:Codable {
    

    and save/load it with encoder/decoder