How to migrate data between views using Tab Bar Controller (swift)

0

I have a Tab Bar Controller with 3 buttons. How do I take an array, loaded from data stored in Core Data, from a view (button 1) to another view (button 2)?

    
asked by anonymous 15.10.2016 / 00:01

2 answers

0

Ok, there are some ways to do this.

I think the best of them is you create a class that will be shared between all the views in your app. This class can store data structures and methods that are general to the app and for which there is a great chance you need to call in multiple places.

In order to share an instance it is necessary to create a "static" property (it is a variable associated with the class) that can be called from anywhere.

I have a habit of calling this shared class from AppModel, or BusinessModel, or GameModel, because I usually use it to store all the data relative to the app template, regardless of views and viewControllers.

For example:

class AppModel {
    static let sharedInstance = AppModel()
    var sharedArray: [String]?
}

Create this class in your own file, for example AppModel.swift.

In this class we create the sharedInstance shared variable. Anywhere in the app you can call AppMode.sharedInstance you will get the same instance.

In this way, in tab 1 you can edit the sharedArray as follows:

AppModel.sharedInstance.sharedArray = ["1", "2", "3"]

And in tab 2 you can access the data using

AppModel.sharedInstance.sharedArray

Another way (which I do not prefer) is to navigate through the TabController to access the data. I think this approach is bad because it breaks if you make any changes to the app structure, but for the sake of completeness I describe below.

Suppose you have a tabBar controller with two tabs, each tab containing a custom viewController called for example Custom1ViewController and Custom2ViewController, each containing a property called "array" and you want to copy this array from tab 1 to tab 2.

if let viewControllers = tabBarController?.viewControllers {
    if let c1vc = viewControllers[0] as? Custom1ViewController, let c2vc = viewControllers[1] as? Custom2ViewController {
        c2vc.array = c1vc.array    
}

The problem is that if for example you put a UINavigationController as the root of a tab, you need to navigate to the first view controller of that navigation controller to access your Custom1ViewController. For example:

if let viewControllers = tabBarController?.viewControllers {
        if let nvc = viewControllers[0] as? UINavigationController, let c1vc = nvc.viewControllers.first {    
}

And it gets worse if you need to access data even more internal to the class hierarchy.

In short: Use a shared class! : -)

    
17.10.2016 / 03:10
0

I suggest that:

  • This data is persistently saved somewhere where both environments have access (eg CoreData, SQLite, Realm, UserDefaults, Property Lists, etc.)
  • You use Key-Value Observing for this (it's a smart way to indirectly observe changes in one object and inform another). More on KVO: link
  • Use NotificationCenter to report these changes (it works like KVO). More on Notification Center: link
  • Either of these ways you will preserve the encapsulation of your code, which will leave it clean.

        
    06.03.2017 / 21:26