I have data that is saved with NSUserDefaults in an array of type "[RiskEntry]".
Let me explain to you what I save here and how the process of loading and saving looks like in my code (I took out code not relevant and I am using Swift3):
Main_ViewController
First: In the class Main_ViewController, I get a text transferred from a popover and save it in an array with NSUserDefaults in riskEntry with key "newTry" (this is just a temporary name ;-)) -> 'func riskText(riskTextTransferred: String)'.
Plan_ViewController
Second: when using a segue to get to the table on Plan_ViewController, the table is filled with the text saved in riskEntry with the key "newTry" (cell.riskTitle.text = savedTitles[indexPath.row].title as String). This all works fine so far.
CustomCell and Plan_ViewController
Third: When the user enters a value in the text field of a cell (consequences.text), the value consequences is updated for the riskEntry. So in the beginning, the array had an empty string for consequences. Now, the entry was updated with a text.
if let index = savedTitle.index(where: {$0.title.contains(identifier)}) {
            savedTitle[index].consequences = consequencesTranferred
The new string is then saved with the key "newTry". This also works like expected.
Main_ViewController
Fourth: Now I dismiss Plan_ViewController to go back to Main_ViewController. When I now try to load my Array in viewWillAppear() with key "newTry", it is empty.
What am I doing wrong? How can I successfully load the updated data from Plan_ViewController in Main_ViewController?
Main_ViewController
class Main_ViewController: UIViewController, UIPopoverPresentationControllerDelegate, UIGestureRecognizerDelegate {
    var riskItemDefaults = UserDefaults.standard
    var riskEntry = [RiskEntry]()
    override func viewWillAppear(_ animated: Bool) {
        if let dataArrayTitle = riskItemDefaults.object(forKey: "newTry") as? [NSData] {  
            var savedTitle = dataArrayTitle.map { RiskEntry(data: $0)! }
            riskItemDefaults.synchronize()
            // CHECKPOINT: all arrays are printed empty...
            print ("savedTitle: ")
            print (savedTitle)
            print ("dataArrayTitle: ")
            print (dataArrayTitle)
        } else {
           print ("nothing")
        }
    }
    // ---------------- delegate function that creates the array items -----------------
    func riskText(riskTextTransferred: String) {
        // CHECKPOINT: Array is saved correctly
        riskEntry = [RiskEntry(title: riskTextTransferred, consequences: "")]
        let encoded = riskEntry.map {$0.encode() }
        riskItemDefaults.set(encoded, forKey: "newTry")
        riskItemDefaults.synchronize()
    }
}
Plan_ViewController
class Plan_VC: UIViewController, UITableViewDelegate, UITableViewDataSource, CustomCellUpdaterDelegate  {
    @IBOutlet weak var tableView: UITableView!
    var riskEntry = [RiskEntry]()
    var riskItemDefaults = UserDefaults.standard
    // ---------------- table settings -----------------
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // load saved data and count number of entries for numberOfSections
        let dataArrayTitles = riskItemDefaults.object(forKey: "newTry") as! [NSData]
        let savedTitles = dataArrayTitles.map { RiskEntry(data: $0)! }
        return savedTitles.count
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = self.tableView!.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CellCustomized
        cell.delegate = self
            // load saved data and insert title in cell label
            let dataArrayTitles = riskItemDefaults.object(forKey: "newTry") as! [NSData]
            let savedTitles = dataArrayTitles.map { RiskEntry(data: $0)! }
            cell.riskTitle.text = savedTitles[indexPath.row].title as String
        return cell
    }
    // ---------------- delegate function from CustomCell -----------------
    func transferData(consequencesTranferred: String, identifier: String) {
        /// load entry
        let dataArrayTitle = riskItemDefaults.object(forKey: "newTry") as! [NSData]
        var savedTitle = dataArrayTitle.map { RiskEntry(data: $0)! }
        riskItemDefaults.synchronize()
        // CHECKPOINT: The entry is loaded correctly
        print("loaded: ")
        print(savedTitle)
        /// filter entry for title contains identifier and update the empty string for consequences
        if let index = savedTitle.index(where: {$0.title.contains(identifier)}) {
            savedTitle[index].consequences = consequencesTranferred
            let encoded = riskEntry.map { $0.encode() }
            riskItemDefaults.set(encoded, forKey: "newTry")
            riskItemDefaults.synchronize()
            // CHECKPOINT: The entry is updated correctly
            print("After updating for consequences: ")
            print(savedTitle)
        }else {
            print ("No title with value identifier to be filtered")
        }
    }
}
CustomCell
// ----------- delegate to transfer entered data to VC ------------
protocol CustomCellUpdaterDelegate {
    func transferData(consequencesTranferred: String, identifier: String)
}
// ---------------- start of calss CellCustomized -----------------
class CustomCell: UITableViewCell, UIPickerViewDataSource, UIPickerViewDelegate, UITextViewDelegate {
    var myColorsClass = myColors()
    var myStylesClass = myStyles()
    var delegate: CustomCellUpdaterDelegate?
    // text fields, text views and picker views
    @IBOutlet weak var riskTitle: UITextView!
    @IBOutlet weak var consequences: UITextView!
    var nameIdentifier = String()
    var textConsequences = String()
    override func awakeFromNib() {
        super.awakeFromNib()
        // initiate textView delegate
        consequences.delegate = self    
    } // nib end
    // ---------------- listener for text view to save input in string when editing is finished -----------------
    func textViewDidEndEditing(_ textView: UITextView) {
            textConsequences = consequences.text
            nameIdentifier = riskTitle.text
            delegate?.transferData(consequencesTranferred: self.textConsequences, identifier: nameIdentifier)
    }
}
 
    