Search code examples
iosswiftxcoderestore

Saving Information Across ViewControllers


I would like to maintain my var removedIDs = [String]() even when I exit a viewController. I have checked off "Use Storyboard ID" for all Restoration IDs in my StoryBoard. Yet when I navigate away from my viewController, I still lose the contents of removedIDs.

In my AppDelegate, I have written:

func application(_ application: UIApplication, shouldSaveApplicationState coder: NSCoder) -> Bool {
    return true
}

func application(_ application: UIApplication, shouldRestoreApplicationState coder: NSCoder) -> Bool {
    return true
} 

And in my MainTextView, the controller that holds removedIds, I have the extension:

extension MainTextView {
override func encodeRestorableState(with coder: NSCoder) {
    super.encodeRestorableState(with: coder)
    coder.encode(removedIDs, forKey: "removed")
}

override func decodeRestorableState(with coder: NSCoder) {
    func decodeRestorableState(with coder: NSCoder) {
        super.decodeRestorableState(with: coder)
        removedIDs = coder.decodeObject(forKey: "removed") as? [String] ?? []
    }
  }
}

I might add that the contents of removedIDs is filled through the following report function:

 func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
    let more = UITableViewRowAction(style: .default, title: "Report") { action, index in
            self.removedIDs!.append(self.comments[indexPath.row].snap)

What piece of the restoration state process am I missing to allow Xcode to hold my IDs?


Solution

  • What you are trying to do is to save application state, while you really need to save some application data. To do that you can use UserDefaults.

    For example something like this:

    var removedIds: [String]? {
        get { return UserDefaults.standard.value(forKey: "removedIds") as? [String] }
        set {
            if newValue != nil {
                UserDefaults.standard.set(newValue, forKey: "removedIds")
            }
            else {
                UserDefaults.standard.removeObject(forKey: "removedIds")
            }
        }
    }
    
    public func add(removedId: String) {
    
        guard var list = removedIds else { // Nothing saved yet
            removedIds = [removedId] // Save array with 1 item
            return
        }
    
        list.append(removedId) // Add new item
        removedIds = list // Save
    }
    

    And then you can:

    1. Add an item to the list of stored IDs:

      add(removedId: self.posts[indexPath.row].id)
      
    2. You can also overwrite list:

      removedIds = [self.posts[indexPath.row].id]
      
    3. Get list of previously saved removed ids:

      var x = removedIds
      
    4. Removed all IDs from storage:

      removedIds = nil