I have the NSMutableArray property in ViewController.h Now i want to get this Array value from appdelegate.
Is it possible can anyone help me to do that.
In viewcontroller.h
#property (nonatomic, retain) NSMutableArray *fullImg;
In viewcontroller.m
#synthesis fullImg;
I also assigned values for fullImg. Now i want to get that value in app delegate.
Thanks in advance.
Move the array declaration from viewController to AppDelegate
In viewController.m do:
top file:
#import "AppDelegate.h"
in place you want to use the array:
AppDelegate *ap = [[UIApplication sharedApplication] delegate];
ap.fullImg // -> USE IT HOW YOU WANT
...
You can put the whole NSMutableArray into NSUserDefaults with a key e.g.
In app delegate:
NSUserDefaults *def=[NSUserDefaults StanderUserDefaults];
[def setObject:fulImg forKey:#"ImageArray"];
In ViewController class:
NSUserDefaults *def=[NSUserDefaults StanderUserDefaults];
NSMutableArray *yourimgarry=[def valueForKey:#"ImageArray"];
When you create the object for viewController class, you can pass the array reference to the viewController by creating new custom constructor. i.e,
//in appdidFinishLaunchingWithOptions
ViewController *viewController = [[ViewController alloc] initWithArray:fullImgArray];
self.window.rootViewController = viewController;
// In ViewController.h
- (id)initWithArray:(NSMutableArray *)fullImgArray;
// In ViewController.m
- (id)initWithArray:(NSMutableArray *)fullImgArray
{
self = [super init];
if (self)
{
self.fulImg = fullImgArray;
}
return self;
}
There are two possibilities.
Using appDelegate. Use a property in app delegate to pass data between ViewContriollers
and AppDelegate.
in first controller
MyAppdeleagte appDelegate=[[UIApplication sharedApplication]delegate];
appDelegate.fullImg=dataToPass;
in the second controller
MyAppdeleagte appDelegate=[[UIApplication sharedApplication]delegate];
data=appDelegate.fullImg;
in AppDelegate
self.fullImg=data;
2.Specifying object Instance.
in your ViewController after allocating the AppDelegate , specify that the object instance in the current viewController is same as the one in AppDelegate. For this declare a NSMutableArray property in AppDelegate.
in AppDelegate.h
#property NSMutableArray *fullImg;
in ViewController.h
MyAppdeleagte appDelegate=[[UIApplication sharedApplication]delegate];
appDeleagte.fullImg=self.fullImg;
Related
Code:
[[UIApplication sharedApplication] delegate];
Through this code how to pass data from one to another.
Basically there is only one instance of 'sharedApplication' (it is a singleton), which means that instances of view controllers that are independent of each other can still talk to the same data object. You can therefore write methods in your sharedApplication delegate which can effectively allow these two view controllers to communicate. For more information please see the Apple documentation.
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplication_Class/
You can use the segue destination view controller for transfar data between controllers.Suppose you have one TextField in one View Controller and you want to pass the Textfield text to another viewController.Then use this it might be helpful.
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
TargetViewController *tvc; //Second view controller Object
tvc = [segue destinationViewController];
tvc.lonetxt = fname.text; //use properties of another view using . operator
tvc.ltwotxt = lname.text;
tvc.lthreetxt = age.text;
tvc.lfourtxt = college.text;
}
Try following:
Interface in Your AppDelegate:
#interface MyAppDelegate : NSObject {
NSString *myString;
}
#property (nonatomic, retain) NSString *myString;
...
#end
and in the .m file for the App Delegate you would write:
#implementation MyAppDelegate
#synthesize myString;
myString = some string;
#end
Then, in viewcontroller.m file you can fetch:
MyAppDelegate *appDelegate = (MyAppDelegate*)[[UIApplication sharedApplication] delegate];
someString = appDelegate.myString; //..to read
appDelegate.myString = some NSString; //..to write
I have an NSMutableArray declared as property in .h and initialized in viewDidLoad in my SPOCVC .m (UIViewController)...
#property (strong, nonatomic) NSMutableArray* SPOCTrackList;
in viewDidLoad
if ([self SPOCTrackList] == nil) {
self.SPOCTrackList = [[NSMutableArray alloc]init];
NSLog(#"SPOTTrackList INITIALIZED");
}
In a separate VC, I'm trying to pass/addObject to SPOCTracklist...
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
SCTrack* selectedTrack = self.trackList[indexPath.row];
[[[SPOCVC sharedInstance]SPOCTrackList]addObject:selectedTrack];
NSLog(#"%lu", (unsigned long)[[[SPOCVC sharedInstance]SPOCTrackList]count]);
So my NSMutableArray is initialized and I can add dummy objects, but why can't I pass it from another VC using singleton or anything, such as...
SPOCVC* spocVC = self.tabBarController.viewControllers[2];
[spocVC.SPOCTrackList addObject:selectedTrack];
Thanks for pointing me in the right direction.
View controllers are only intended to be around while they are on screen. They are not a place to store data. Generally when one view controller talks directly to another view controller that it didn't create, you're doing something wrong.
Move SPOCTrackList to your model and have both view controllers talk to it rather than to each other.
There should never be a "sharedInstance" on a view controller. That's a sure sign that you're abusing the view controller as the model.
What's probably happening in your particular case is that viewDidLoad is running on a completely different SPOCVC than your sharedInstance.
why not use appdelegate to handle this
appdelegate.h
//add property to hold the reference
#property (nonatomic, copy) NSMutableArray *referenceArray;
//share the app delegate
+(AppDelegate *)sharedAppDelegate;
#end
in appdelegate.m
//synthesize the property
#synthesize referenceArray;
//return the actual delegate
+(AppDelegate *)sharedAppDelegate {return (AppDelegate *)[UIApplication sharedApplication].delegate;}
in viewdidload method
//add the delegate
import "appdelegate.h"
//init the array
self.SPOCTrackList = [[NSMutableArray alloc]init];
//Add reference
[AppDelegate sharedAppDelegate].referenceArray = self.SPOCTrackList;
and add anywhere like this
import "appdelegate.h"
[[AppDelegate sharedAppDelegate].referenceArray addobject:object];
I have a main ViewController that contains a desginated class. Within that ViewController there is a Container that is linked to an embed ViewController. Within that embed ViewController I am creating an NSMutableArray. I am not trying to access that array inside the main ViewController. I know that if I use:
create_challenge_peopleSelect *myScript = [[create_challenge_peopleSelect alloc] init];
NSLog(#"%#",myScript.selectedCells);
The NSLog will output null because I am creating a new ViewController and that gets rid of the already set array. So my question is how can I access that array without overwriting it?
UPDATE:
Heres where the NSMutableArray is being created:
create_challenge_peopleSelect.h:
#property (strong, nonatomic) NSMutableArray *selectedCells;
create_challenge_peopleSelect.m:
if([selectedCells containsObject:label.text])
{
cell.accessoryType = UITableViewCellAccessoryNone;
[selectedCells removeObjectIdenticalTo:label.text];
}
else
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[selectedCells addObject:label.text];
}
This class is the container class off the main ViewController
No I want to access the selectedCells within my main ViewController, I have been doing things such as:
create_challenge_peopleSelect *myScript = [[create_challenge_peopleSelect alloc] init];
I would prefer to stay away from the App Delegate If possible.
You seem to be unclear on the difference between classes and instances. OK, so, say we have two NSArrays:
NSArray *a = [[NSArray alloc] initWithObjects:#"hello", #"I", #"am", #"an", #"array", nil];
NSArray *b = [[NSArray alloc] initWithObjects:#"so", #"am", #"I", nil];
If I do a.count, I'll get 5 as the answer because the array contains five objects. Meanwhile, if I do b.count, I'll get 3, because that array contains three objects. It isn't that creating b "gets rid of the already set count". They are separate objects completely unrelated to each other.
Your view controller class is the same way. When you create a different instance, it doesn't overwrite the old one -- it's just not the same object. In order to use the original view controller object, you need to get a reference to it.
So how do you get a reference to it? Well, the general answer is you design your app so that the two objects know about each other. There are lots of specific ways to accomplish this. A lot of people will say "Just stick a reference in the app delegate." That is one thing you can do, but it's not always the best choice. It can get out of control if you just stick everything in your app delegate. Sometimes it's the right answer, often other things are the right answer. Another approach is to have an object that knows about both of those objects introduce them to each other. But sometimes there is no such object. So it's situational.
Basically, instead of creating a new view controller, you need to maintain a pointer to the original.
I suggest storing an instance of your UIViewController in the AppDelegate in order to retain the particular instance of the view controller you've created by making it a global variable.
ex. In the App Delegate.h
#import "ViewController.h"
#class ViewController;
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (nonatomic) ViewController *viewController;
Then from whatever view controllers' .m's from which you need to read/write to the variable, create a pointer to the application's app delegate, ex:
#import "AppDelegate.h"
#interface WhateverViewController ()
AppDelegate *mainDelegate;
- (void)viewDidLoad {
mainDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
}
So wherever you first create that view controller in your code (before ever using it), initialize it using this global variable. ex. If you're using xibs:
mainDelegate.viewController = [[UIViewController alloc] initWithNibName:#"ViewController" bundle:nil];
[self.navigationController pushViewController:mainDelegate.viewController animated:YES];
ex. If you're using storyboards:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"StoryboardName" bundle:nil];
mainDelegate.viewController = [storyboard instantiateViewControllerWithIdentifier:#"viewControllerID"];
[self.navigationController pushViewController:mainDelegate.viewController animated:YES];
(This is assuming it's in a place other than the app delegate in which case the pointer to the App Delegate isn't needed.)
Then when accessing the array from another UIViewController use
mainDelegate.viewController.array
To access the NSMutableArray from one class to another class use following code.
In the first view controller in which u have declared the object of NSMutableArray, declare the property and synthesize for the same as below,
//In FirstViewcontroller.h class,
#property (nonatomic, strong) NSMutableArray *arrData;
//In FirstViewcontroller.m class
#synthesize arrData;
Also FirstViewcontroller object should be global so you can create the object of FirstViewcontroller in app delegate file.
//appdelegate.h
#property (nonatomic, strong) FirstViewcontroller *objFirst;
//appdelegate.m
#synthesize objFirst;
FirstViewcontroller *objFirst=[[FirstViewcontroller alloc]init];
Now in SecondViewcontroller in which you have to access array,
create the share object of Appdelegate file
//SecondViewcontroller.m
AppDelegate *app = (AppDelegate*)[[UIApplication sharedApplication] delegate];
Then use will get the required array as below,
app.objFirst.arrData
This is your required array I hope it will help you.
The basic idea here is that in your original class, the array is referred to by a pointer. Your original class would allocate it and presumably load it. Other parts of your program can be handed the contents of the property, which is a pointer, assign that to their own pointer holder, and use it as if you had declared it there. Please use the above code;
MyClass *aClass = [[MyClass alloc] initWithMyInitStuff];
NSMutableArray *ThatArray = aClass.MyArray;
NSLog("Count of ThatArray: %d", [That.Array count]);
What you've done in the code provided is set a public property for a mutable array...
#property (strong, nonatomic) NSMutableArray *selectedCells;
The NSMutableArray is not "created" by setting that property. At some point in your code you also have to create the NSMutableArray by initialising...
NSMutableArray *selectedCells = [[NSMutableArray alloc] init];
or by using a convenience method such as...
NSMutableArray *selectedCells = [NSMutableArray arrayWithCapacity:(NSUInteger)<initialising capacity>];
or
NSMutableArray *selectedCells = [NSMutableArray arrayWithArray:(NSArray *)<initialising array>];
Initialising an NSMutableArray is often done only once. If it is repeated, the contents are overwritten against the property used to point to the array. As such, a useful location for this is often within the viewDidLoad view controller lifecycle method.
So I've declared this in my appDelegate.h
#property(nonatomic,strong) NSMutableArray *featured;
I've synthesized it like so in my appDelegate.m
#synthesize featured;
When I log that out in the appDelegate with the object stored in there, I get the value it's supposed to have
In a viewController.h file I have declared this
#property(nonatomic,strong) NSMutableArray *featured;
In the viewController.m file I've synthesized it like this
#synthesize featured;
I then print out this line and get a null value
NSLog(#"HERE %#", featured);
That same line prints out the correct value in my appDelegate.m file. I'm completely lost. I've set it up in the way I've done it for a previous class exercise. Thanks in advance!
Edit:
I created the array in appDelegate.m file like so in a method I called loadFeatured
featured = [NSMutableArray array];
for (id dict in tempArray)
{
//NSLog(#"dict=%#",dict);
NSString *shopName = [dict objectForKey:#"shopName"];
NSString *drinkName = [dict objectForKey:#"drinkName"];
NSNumber *likes = [dict objectForKey:#"likes"];
NSNumber *dislikes = [dict objectForKey:#"dislikes"];
NSString *review = [dict objectForKey:#"review"];
Featured *feat = [[Featured alloc] initWithName:shopName drinkName:drinkName likes:likes dislikes:dislikes review:review];
NSLog(#"feat=%#\n\n",feat);
[featured addObject:feat];
}
NSLog(#"there is %d featured",[featured count]);
NSLog(#"HERE %#", featured);
Here is the way, how to access the data stored in the app delegate from your viewcontroller.
You need not synthesize the object in the viewcontroller. Just import your appdelegate file and copy the following code wherever necessary.
NSMutableArray * nArray =[ (AppDelegate*) [[UIApplication sharedApplication] delegate] featured];
The above code gives you the required array from the app delegate.Now you can make use of the nArray object to display the details in the console.
NSLog(#"%#",nArray.description);
It's hard to say how to do this without knowing the structure of your app. You could pass a pointer to the array to your view controller, if you have access to that view controller from the app delegate. The other way is to get a reference to the app delegate in your view controller, and then access its array. That can be done like this:
AppDelegate *appDel = [UIApplication shared application].delegate;
NSArray *myControllerArray = appDel.featured;
You'll need to import your app delegate into your controller's .m file to use this approach.
Since you already declared a property in appDelegate.h you can access it in the other viewController like this:
#import "appDelegate.h"
and you can access the value it by using something like this:
((AppDelegate *)[[UIApplication sharedApplication]delegate]).featured
If you need to access an NSArray or any other object in any class, via AppDelegate, just create a property to access your ViewController, like so, in your AppDelegate class:
#import "ViewController.h"
#property (nonatomic, strong) AppDelegate *appDelegate;
#property (nonatomic, strong) ViewController *viewController;
In your ViewController class:
#import "AppDelegate.h"
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
ViewController *viewControllerREFERENCE = [appDelegate viewController];
Then you'll have access to any value on your ViewController, via AppDelegate.
I hope that helps you.
I think that I am a bit confused about iOS #property getter and setters. I am trying to set an NSString iVar in my AppDelegate.h file from another class so that it can be used by all of the classes in the project?
For example, I am working on an iPhone project that stores an iVar NSString *currentUser in AppDelegate.h. I need to be able to set this through one method in a ViewController.m and then get it through another method in a second ViewController?
Maybe Getter and Setter is the wrong direction of attack all together? I understand that i don't want to alloc init the AppDelegate as the iVar will only exist in that object and I want it accessible to ALL objects in ALL classes?
Please someone set me straight.
All the best,
Darren
Here's the setup for the app delegate.
#interface AppDelegate
{
NSString *__currentUser;
}
#property (monatomic, copy) NSString* currentUser;
#end
#implementation AppDelegate
#synthesize currentUser = __currentUser;
- (void) dealloc
{
[__currentUser release];
[super dealloc];
}
#end
From one view controller, you could set a value for the current user, and from a subsequent view controller, get that value for some nefarious purpose.
#implementation LoginController
- (void) viewDidLoad
{
...
AppDelegate *bob = [[UIApplication sharedApplication] delegate];
[bob setCurrentUser: #"Jim Kirk"];
...
}
#end
In some other view controller that appears later, the value of the current user can be accessed.
#implementation ProfileViewController
- (void) viewDidLoad
{
...
AppDelegate *bob = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSString * user = [bob currentUser];
// insert nefarious purpose for current user value here
...
}
#end