pierreafranck
pierreafranck

Reputation: 443

How to Store datas in ViewControllerB when I go back to ViewControllerA

I'm trying to keep store datas in my ViewControllerB when I leave it for another ViewController (A or C).

I don't want to pass datas in each ViewController when I moved but I just want to keep store them in my ViewControllerB.

I can do a protocol delegate for do it but I think a better way is possible.

I have this in my ViewController:

var contacts: [[String : String]] = [[:]]

And I want to keep this datas which are store inside my dictionnary.

I do it for initialize my Dictionnary.

override func viewDidLoad() {
    contacts[0] = ["Name": "Me", "Number": "Hihi I'm not going to show my phone number here"]
    contactsTableView.tableFooterView = UIView()
}

When I go on ViewControllerC and then comeback to VCB it's working, my Dictionnary keep values, but when I go to ViewControllerA and then comeback to B my dictionnary is empty.

For leave ViewControllerC and comeback to B I'm using this method

@IBAction func cancelButtonPressed(_ sender: Any) {
    navigationController?.popViewController(animated: true)
    dismiss(animated: true, completion: nil)
}

EDIT: All navigation code:

ViewControllerA to B:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "showContacts" {
        let vc = segue.destination as! ContactsViewController
    }
}

 @IBAction func contactsButtonPressed(_ sender: Any) {
    self.performSegue(withIdentifier: "showContacts", sender: (Any).self)
}

ViewController B to A:

 @IBAction func saveButtonPressed(_ sender: Any) {
    navigationController?.popViewController(animated: true)
    dismiss(animated: true, completion: nil)
}

ViewController B to C:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "showCreate" {
        let vc = segue.destination as! CreateViewController
        vc.delegate = self
    }
}

@IBAction func addButtonPressed(_ sender: Any) {
    performSegue(withIdentifier: "showCreate", sender: Any?.self)
}

And ViewController C to B:

@IBAction func cancelButtonPressed(_ sender: Any) {
    navigationController?.popViewController(animated: true)
    dismiss(animated: true, completion: nil)
}

I've tried to use it for leave B to A but it's not working, I lose my datas.

How can I keep store values in every case?

Thanks

Upvotes: 1

Views: 85

Answers (4)

PGDev
PGDev

Reputation: 24341

There can be multiple ways to persist data:

  1. Singleton - This method persists data when the app is running, i.e. If you kill the app, the data is lost.

  2. User Defaults

  3. Core Data

  4. Archiving/UnArchiving data and storing it in file

The methods 2, 3 and 4 persists data between multiple app sessions.

Upvotes: 0

Arjun Yadav
Arjun Yadav

Reputation: 1429

Swift 3.0 Code...

When Open First time ViewControllerB then add contacts dictionary in UserDefaults then back ViewControllerA and return open ViewControllerB then check UserDefaults is empty or not empty. if UserDefaults is not empty then retrieve data from UserDefaults and show otherwise set data in UserDefaults

This code add in viewWillAppear Method in ViewControllerB

 if  let data = UserDefaults.standard.object(forKey: key) {
  contacts = NSKeyedUnarchiver.unarchiveObject(with: data)
}
else {
    contacts[0] = ["Name": "Me", "Number": "Hihi I'm not going to show my phone number"]
    let archiver = NSKeyedArchiver.archivedData(withRootObject: contacts)
    UserDefaults.standard.set(archiver, forKey: key)
}

Upvotes: 1

Retterdesdialogs
Retterdesdialogs

Reputation: 3210

Normally you should pass your dictionary from A to B, use the delegate pattern, use core data, archiving or nsuserdefaults.

It really depends on what you want to achieve and for what the data is for.

Not recommended but an easy way to keep the data is to use the singleton pattern.

Create a class and name it for example StoredData:

import Foundation

class StoredData {

   static let sharedInstance = StoredData()

   var contacts: [[String : String]] = [[:]]
}

With that you can access and set your contacts from everywhere using

var contacts = StoredData.sharedInstance.contacts

Or

StoredData.sharedInstance.contacts[0] = ["Name": "Me", "Number": "Hihi I'm not going to show my phone number here"]

Upvotes: 0

jarora
jarora

Reputation: 5762

The issue is that you are creating a new instance of ViewControllerB when opening it from ViewControllerA. If this data is costly to retrieve then, it makes sense to persist the data. Otherwise, you could just fetch it everytime in ViewControllerB's viewDidLoad.

If it's costly to retrieve the data then, you have the following options for persisting the data:

1.UserDefaults 2. Store it in a file on disk using Archiver 3. CoreData

The use cases differ for the above storage options. For NSUserDefaults, you would like to store only light data. After using one of the above storage options, you would check if the data is already present. If it's present then fetch it from your storage or retrieve the data and store it.

Upvotes: 0

Related Questions