Use data in multiple view controllers under a tabbarcontroller - ios

I have a songs = [Song]() array of song objects being generated in the first view controller of my tab bar.
How can i use this array in the other view controllers of the UITabBarController?
I need to show this in my initial view controller, a table containing all songs, but also need to use this data in a second view controller, a table containing only favourite songs.

I think a good solution would be to create another class for managing the songs data. Basically, you want to add a model for your view controller to look at. In this new class, you may decide you want to use a singleton to provide the exact same data to every object viewing the data. This is similar to what core data does, and is something I think you should consider using (core data works with xml). But, by having a class other than your view controller manage your data, any view controller (or any other object) that needs access to the data need only ask the data class for it.

Related

Performing a FetchRequest from another view controller

In my new Swift app I am using a slide side menu with SWRevealViewcontroller.
On the rear view controller there are several fetch requests to retrieve the number of core data objects that meet some conditions. On the front view controller, the app user can create new core data objects.
In the normal way of using the app, the app user creates or modified the core data objects, and later he/she can reveal the rear view controller to see the number of objects of each type.
Please take a look of the two view controllers:
Front view controller:
If the user taps on the +button, a new object is created.
if the user taps on the menu button, the rear view controller is shown, as you may see in the image:
And now, finally my question: As you may see in the image, both view controllers are loaded and showed. I want to know if it is possible that on this scenario, with both view controllers on screen, if the +button is tapped on the right view controller, could I implement a way to perform the fetch requests on the left view controller to update the count of the objects of each type?
I have solved it using a NSTimer on the rear view controller. I guess this is not the best solution, but it works. If the user taps on the +button to create a new object, the timer launches the fetch request to update the number of objects from each type.

Accessing the next object in managedObjectContext from my detailView

I have a simple application that uses Core Data / ManageObjectContext. It works very similar to Apple's sample app. The fetchedResultsController grabs the objects and builds out a table view. When I click it sends the Object at that index to the detail view. Simple.
What I want to do is access the next Object from my current detail view so that I need not return to the table view to move through to the next detail view.
I've seen some similar questions but the answers suggest creating a mutable array which seems to defeat the purpose of core data and managed objects.
Thanks!
Use NSFetchedResultsController
/* Returns the fetched object at a given indexPath.
*/
- (id)objectAtIndexPath:(NSIndexPath *)indexPath;
Note:
Creating a mutable array does not necessarily defeat Core Data nor NSManagedObjectContext, but it definitely would defeat the caching mechanism provided by NSFetchedResultsController.
What you're trying to achieve is to present the same data in a bit different way, so you can use same data source based on NSFetchedResultsController. You can easily get index of passed object so you'll be able to navigate between next/prev objects.
Set up a property that refers to the master view controller on the detail view controller, or make the master view controller a delegate of the detail and make it follow a protocol with a suitable method.
Either way, the master view controller will receive a message from the detail view controller and when an action you specify takes place, you could just set the detailItem again on the detail view controller to the next item in your model.
This is assuming you maintain a reference to the index of the current detail item, and a reference to your detail view controller.

Using one Property List (.plist) for multiple View Controllers

Can I , or is it feasible to use one Property List file to include data that I have to use in multiple view controllers.?
The data in my .plist file is hierarchically arranged, and as I go down the hierarchy the data at different levels is to be used in different view controllers. The view controllers are embed in a Navigation Controller.
If this is not appropriate, is there a different way ?
If yes then what all ways are there in which I can do the needful. Thanks for your time.
It is possible to read the file in every view and update the view controller. Instead of reading the file every time, go for a shared data source which would read content on initializing. You can query this class from different view controller in navigation controller hierarchy to fetch respective data to be displayed in that screen.

Data source for PageViewController - usage of arrays/dictionaries to store view controllers in data source

I am implementing a scroll style page view controller for my app, based on the page based application template.
In the data source class, I am storing the list of view controllers in a dictionary (could also use array I guess) so that I can reuse them if the user swipes back to a view controller they already viewed. There are about 15 total view controllers in the page view controller.
I wonder if this is a good idea compared to calling the story board instantiateViewControllerWithIdentifier each time. (I understand the pageviewcontroller itself stores its own array of view controllers anyway.)
I could instead just store the model object in the dictionary or array and instantiate the view controller and pass in the model object after calling instantiateViewControllerWithIdentifier.
I am interested in what is likely to be the better approach.

TableView index from rootcontroller to detailcontroller (UINavigationController)

My root view is a grouped tableview. When the user selects a row, i want to be able to retain which row was selected to give to the detailcontroller for loading the correct data.
All the navigation is working fine, I just don't want to have to create a global variable to just retain the index. Is there a built in method for the navcontroller or something?
You can either set a property in you detail view controller before it is pushed giving info about the row selected so it can influence the behaviour of the detail view controller, or it is possible to access the parent view controller directly from the detail view controller with:
#property(nonatomic, readonly) UIViewController *parentViewController
I prefer the first option - you can write a custom init... method, to supply the data for the detail view controller when it's created.
There isn't a builtin way as such, you should try and make the view controllers de-coupled as possible so they can be re-used and are resistent to changes elsewhere in the app.
This is a useful quote from the View Controller Programming Guide for iOS:
With the exception of view controllers managing leaf data, each custom view controller must provide a way for the user to navigate to the next level of the data hierarchy. A view controller that displays a list of items can use taps in a given table cell to display the next level of data. For example, when a user selects a photo album from the top-level list, the Photos application creates a new photo album view controller. The new view controller is initialized with enough information about the album for it to present the relevant photos.
I wanted to follow up with how I ended up coding this. I'm still somewhat new to Obj-C, so some concepts I haven't dealt with or come across, so if this is old hat, sorry.
You can create your data element in the child controller and pass the data 1 for 1 directly to that element by accessing its property.
ParentController.h
NSDictionary *myData;
ChildController.h
NSDictionary *childData;
// This would get called in the parent controller where appropriate
// but before the child controller is presented
ChildController.childData = myData;
This is obviously very stripped down, but the idea works. Just take your data and pass it to the property before calling it and it will be there once the child view is presented. Hope this helps.

Resources