Passing NSString from one ViewController to other's VC NSMutableArray - iphone

I'm a starting iOS developer and I would like to get the idea of NSMutableArray.
Specifically, I want to pass NSString value from one VC to NSMutableArray, belonging to another view controller. I also want that NSMutableArray to populate UITableView on its view. Any ideas how to do this?
For example, I have this action that the user triggers from within 1st view
- (IBAction)addToFav:(id)sender {
}
And I want to pass a value of NSString myBookString to the NSMutableArray array in the 2nd view.
The task is fairly simple, but I can't quite understand why you can't pass the values to NSMutableArray outside this - (void)insertObject:(id)anObject atIndex:(NSUInteger)index method mentioned in Apple's reference docs.
Thanks in advance!
EDIT: My views are different VC belonging to UITabBar and to UINavigationController at the same time

You need a communication between two controllers. There are several solutions. Pick one of the following. I recommend delegate.
From http://www.hollance.com/
When you have two objects A and B, say two view controllers, that you want to make talk to each other, you can choose from the following options:
NSNotificationCenter.
This is anonymous one-to-many communication. Object A posts a notification to the NSNotificationCenter, which then distributes it to any other objects listening for that notification, including Object B. A and B do not have to know anything about each other, so this is a very loose coupling. Maybe a little too loose…
KVO (Key-Value Observing).
One object observes the properties of another. This is a very tight
coupling, because Object B is now peeking directly into Object A. The
advantage of KVO is that Object A doesn’t have to be aware of this at
all, and therefore does not need to send out any notifications — the
KVO mechanism takes care of this behind the scenes.
Direct pointers.
Object A has a pointer to Object B and directly sends it messages
when something of interest happens. This is the tightest coupling
possible because A and B cannot function without each other. In the
case of view controllers you generally want to avoid this.
Delegates
Object B is a delegate of Object A. In this scenario, Object A does
not know anything about Object B. It just knows that some object
performs the role of its delegate and it will happily send messages
to that delegate, but it doesn’t know — or care — that this is Object
B. The delegate pattern is often the preferred way to communicate
between view controllers, but it takes some work to set up.
Blocks.
Essentially the same approach as delegates, except that Object B now
gives Object A one or more blocks (closures) to be executed when
certain events take place. There is no formal delegate protocol and
the only thing that Object A sees of Object B is the blocks it is
given.

NSMutableArray is just that, a standard mutable array implementation. It has all of the functionality you would expect from one in any other language/framework. docs.
What is the problem with the way adding elements to an array works? You can also just do [array addObject:object] if you don't mind adding it to the tail.
To answer the rest of your question, there are many ways to transfer data from one controller to another. How is your navigation set up? Are you using a UITabBarController, or a UINavigationController? How are the views related to each other? If they are nested, you can pass data directly from one to another. If not, you could use something like your app delegate to hold the data and pass it around.

Related

Setting multiple delegates for passing multiple view controllers right way?

So I'm using multiple delegates to pass trough data, but I don't know if it's the right way. I only want to maintain 1 main object to be sure that if a user exists/closes the app the edit data is saved when not in the VC1. By using the delegates now I'm sure the data is in the main object and all is well. Could you guys send me in the right direction and tell me if this is the way to go? Thanks in advance!
VC1:
Main object, holds all data that needs to be saved
Delegate for VC2
VC2:
Specific object overview from VC1
Delegate for VC3
Delegate function called -> PassDataToVC1(editsForSpecificObject)
VC3:
Edit's data from specific object. -> Gives
Delegate function called -> PassDataToVC2(edits)
Maybe even a 4th VC depending what I'm going to do.
What you're doing is basically correct for the architecture you have chosen:
If you have a rule that only VC1 knows the full data and can save it, then you need to pass changes in the data back to VC1.
If you have a rule that the way to pass the data back to VC1 is to use a protocol-and-delegate architecture, then you have to make VC1 the delegate for your protocol(s). There is nothing wrong with a single object (your VC1) being extended to adopt multiple protocols; that, indeed, is a standard Swift pattern.
However, I would argue that the reason this feels ugly to you is that those are not very good rules. I'll address them in reverse order:
Why delegation? In modern Swift, there are cleaner ways to pass data around. Modern app architectures are typically reactive, meaning that a handler of data is a publisher of the changes in that data, and the central store of the data subscribes to those publishers. Thus the data store can hear directly of any changes without the view controllers having to send those changes to anyone in particular.
Why a view controller? This is arguably the weakest point in your architecture. What business is it of a view controller to know anything about the data store and the mechanism for saving it? You should have a separate data store object retained by some securely persistent object such as the app delegate. This object stores and gatekeeps the data, and knows (or has a service helper who knows) how to persist it. You can use dependency injection to hand a reference to this object to every view controller — which also has the added benefit of making your code eminently testable. Even better, if you accompany this idea with the use of reactiveness that I outlined in the previous paragraph, you will have a clean "touch-free" architecture that just works, where every object does its own job and no other.

Understanding the MVC design pattern in Cocoa Touch

Usually I just put together an app in any random way, as long as it works, but this means I don't pay any attention to any design patterns. My application currently makes extensive use of global variables (I carry an instance of my AppDelegate in every view controller to access properties I declared in my AppDelegate.h). Although it does what I want it to do, I've read this is not a good design practice.
So I want to start making my code "legit". However, I can't imagine my app right now without global variables. They are so important to the well-being of the app, but this must mean I'm doing something wrong, right? I just can't imagine how else I'd do some things. Take for example this:
You have two view controllers here, a SideViewController and a MainViewController. Using global variables, such as say if the entire application had one shared instance of SideViewController and MainViewController (appDelegate.sideViewController and appDelegate.mainViewController), I can easily communicate between the two view controllers, so that if I press "News Feed" in my SideViewController, I can tell my MainViewController to reload it's view.
I can't imagine, however, how this would be done if these were not global variables? If an event occurs in my SideViewController, how would I notify my MainViewController, in a way that is in accordance with design standards?
I can't imagine, however, how this would be done if these were not
global variables? If an event occurs in my SideViewController, how
would I notify my MainViewController, in a way that is in accordance
with design standards?
The same way you do it now, except that the SideViewController gets its reference to the MainViewController from a different place.
How are these two view controllers created? It's likely that it happens in one of two ways:
One of the objects creates the other. In this case, maybe the MainViewController creates the SideViewController.
Some other object, such as the app delegate or another view controller, creates them both.
In the first case, the MainViewController has a reference to the SideViewController as soon as it creates it. It can store that reference in one of its own instance variables, so that it can always send messages to the SideViewController that it created. Similarly, the MainViewController can give the SideViewController a reference to itself (that is, to the MainViewController), and the SideViewController can store that and use it in the future to talk to its MainViewController.
The second case is similar -- if the app delegate (or some other object) creates both MainViewController and SideViewController, that object knows about both objects and can configure each with a reference to the other.
In both cases, the objects in question are able to communicate with each other just as easily as they ever did and there's no need for a global variable.
What I've explained above is perhaps the simplest way to accomplish what you asked for -- communication between two objects. There are a number of patterns that can be used to refine the relationship between those objects to make your code even better:
delegation: Give SideViewController a delegate property, and define some protocol that establishes what SideViewController expects of its delegate. Implement that protocol in MainViewController. Make your MainViewController instance the SideViewController's delegate. SideViewController doesn't need to know exactly what type its delegate is -- it only cares that it's delegate implements the required protocol. This makes it easy to use SideViewController with something other than MainViewController if that opportunity arises, or to use it in a different project.
notifications: SideViewController may not even need a delegate -- it can simply broadcast notifications about certain events to any object that happens to be listening. This is particularly effective if more than one object might need to know about something that happens in SideViewController, or if the objects that care about SideViewController's actions might change.
MVC: Instead of telling MainViewController that something has changed, SideViewController just changes the data in the model. Whenever the MainViewController's view appears (or any other view controller's view, for that matter), the controller reads the data from the model and redisplays itself.
If you're interested, you might want to pick up a copy of Erik Buck's Cocoa Design Patterns, which explains these patterns and many others in great detail. Don't feel like you have to learn it all at once, or that it's all too much trouble. Learn a little bit at a time and see how it improves (or doesn't) your projects.

Passing Several NSStrings to another view - Iphone

In my iPhone app, the user will be making multiple NSStrings. Once these are made, I need to pass them to another view completely in the app. How can i do this? All I know at the moment os I can't access objects or variables declared in one view, in another. Thanks.
One way would be to follow the MVC (model view controller) design pattern. Whichever controllers are responsible for your respective views can then store and retrieve the NSStrings from/to a common data model object.
As to how you can make the strings stored in an object visible to the outside, the easiest way is to use Objective-C properties to save you from writing the accessor methods yourself.
I hope this helps with your problem or at least gets you started in the right direction.
Place the strings in a data model object (the M of the MVC pattern), with accessor methods (getter and setters, which can be automagicly created by properties). Then create and place that model object in some central location, a controller common to all views requiring that data, or the appDelegate, a reference for which can be found from any view.
Josh,
I would add to the MVC thing, that still you can do this in several ways.
What I would do for example, is to make your other "View Controller" (MVC), to "observe" when does the user create a new string, and to fetch it accordingly. In that way you would reduce coupling and it will be a cleaner implementation.
Another way would be to create a "delegate" so that the First View controller, "notifies" or calls the delegate method that you created, each time the user creates a new string ( again reducing coupling )

Design pattern for Core Data iPhone App

Im building an app that will use a Core Data model. I pretty new at Objective C and my usual design patterns does not really apply on Core Data and Objective C, at least I can't seem to find examples that confirms they will.
I have been through the Apple Developer examples and different sources on the intertubes.
It seems that to leverage Core Data I need to pass the managedObjectContext to each of my viewControllers, have the viewController implement the NSFetchedResultsControllerDelegate and then implement each of the methods for doing a fetch and subsequently implement
NSFetchedResultsChangeInsert
NSFetchedResultsChangeDelete
NSFetchedResultsChangeMove
NSFetchedResultsChangeUpdate
This adds approximately 100+ lines of code in each viewController and it is 90% the same code I write again and again. Plus I have to pass everything around and keep track of it's memory footprint.
In other languages I would build a singleton model of a few classes that held methods for maintaining and delivering data upon request, available from anywhere. It seems I can't take that approach in Objective C. If I where to build a static Class that took a managedObjectContext and returned me what I needed, I would still have to pass the managedObjectContext around to every view and it wouldn't be asynchronously like when I implement delegate methods that just gets called when a result is ready.
I hope this makes sense and that someone can either confirm that there is no other reasonable way to do it or help point me in a direction for wrapping this up in a good way.
Thanks:)
Core Data is not nearly as complicated as you describe.
Generally, an iPhone app has a "main" managed object context, which is generally owned by the app delegate. So long as you can get the app delegate (hint: [[UIApplication sharedApplication] delegate]) you have access to the managed object context. I like to define a static global variable to hold a reference to my app delegate to make life easier.
There's generally a one-to-one correspondence between NSFetchedResultsController instances and UITableView instances. Aside from populating table views, it's exceedingly rare that you would need an NSFetchedResultsController. If you have a number of similar views (e.g. a tab bar that lets you view the same data in different ways a la the iPod app), it would behoove you to create a single base class that configures the NSFetchedResultsController and derive your specific view controllers from that.
Now, when you create view controllers to edit an object, it's generally a good idea to do that in a separate managed object context. If the user cancels, you just discard the context and the changes go away. Again, you don't really need an NSFetchedResultsController for this because these views are only concerned with a single object.
When you're done editing, you save: the managed object context. The objects that manage your other managed object contexts should implement the NSFetchedResultsControllerDelegate methods to keep the table view in sync. Again, this can be implemented in a base class so you can generalize this functionality for related view controllers.
Do you absolutely have to use a CoreData model, or would something using a NSCoder (NSArchiver, NSKeyedArchiver, etc) work? I've found that CoreData is overkill for most applications.
Also, could you clarify why you can't take an approach using singletons? I've used singleton factories in a number of applications without issues. It's fairly easy to define class-level methods that operate on a shared (singleton) instance.

Passing variables through classes in Objective-C

In my scenario I have 2 view controllers, one tied to the main view and one that is connected to the first one as a subview.
Now let's say that my App Delegate class wants to pass a string to the subview controller. What is the best practice to achieve this? If I wanted to pass it to the 1st controller i could just say something like
[self.firstController getStringInCustomFunction:[NSString stringWithFormat:#"200%d", 9]];
Also keep in mind that this call might have to be asynchronous.
Coming from ActionScript, normally I would just add and event listener and move my variables though events. What's the equivalent in objective-c?
Coming from ActionScript, normally I would just add and event listener and move my variables though events. What's the equivalent in objective-c?
Take a look at NSNotificationCenter.
Specifically, postNotificationName:object:userInfo, wherein you create an NSNotification that includes an NSDictionary of objects you pass inside userInfo.
On the other end, you have another object that is registered to "hear" an NSNotification of a specific name. That other object calls whatever method is specified in the registration. You might unpackage the userInfo dictionary in this method, to retrieve the object of interest.