Global NSMutableString - iphone

I have a tabbed views where I need to select various options from different tabbed views which should be appended in the same string. For this I want to use a NSMutableString.
After all the options are selected and string is formed as required. I want to access this NSMutableString in the next view which is not tabbed. I think for this I need to declare the NSMutableString as a global variable?
Can someone please help me with this. I am new to objective-c and xcode. Thank you. Any help is much appreciated!

You can make it a property of your app delegate
You can use a singleton
You can use NSUserDefaults
You can arrange for all of the "interested party" objects to share some common object (with addressability passed during initialization) that contains a field pointing to your string
And probably several others.

Another option would be to have a singleton object, especially useful if you have more than just one variable you want shared.
Here's a good post about doing singletons right: http://lukeredpath.co.uk/blog/a-note-on-objective-c-singletons.html
Basically you'd have write a very simple class something like:
State.h:
#interface State : NSObject
#property (atomic, strong) NSMutableString *mystring;
+ (id)sharedInstance;
#end
State.m:
#import "State.h"
#implementation State
#synthesize mystring;
+ (id)sharedInstance
{
static dispatch_once_t pred = 0;
__strong static id _sharedObject = nil;
dispatch_once(&pred, ^{
_sharedObject = [[self alloc] init]; // or some other init method
});
return _sharedObject;
}
#end
and then whenever you need it you could do:
import "State.h"
[State sharedInstance].mystring
Even simpler you can use singleton macro from here: https://gist.github.com/1057420#gistcomment-63896
I've personally found this pattern to be extremely useful.

You can use NSUserDefaults for this:
To save: (call before next view loaded in previous view class)
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:yourString forKey:#"KEYNAMEHERE"];
[defaults synchronize];
To retrieve (call when next view is loaded in the next view's class)
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableString *string = [defaults objectForKey:#"KEYNAMEHERE"];

Related

storing data common to more than one view controllers

I know there are many ways for storing data like property list,archiving etc..but other than that is there any other way for storing very small amount of data,which is common to different view controllers(like a common class for storing all the data)?.
Try this
NSUserDefaults
when you want to save small amounts of data such as High Scores, Login Information, and program state.
saving
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
// saving an NSString
[prefs setObject:#"TextToSave" forKey:#"keyToLookupString"];
// saving an NSInteger
[prefs setInteger:42 forKey:#"integerKey"];
// saving a Double
[prefs setDouble:3.1415 forKey:#"doubleKey"];
// saving a Float
[prefs setFloat:1.2345678 forKey:#"floatKey"];
[prefs synchronize];
Retrieving
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
// getting an NSString
NSString *myString = [prefs stringForKey:#"keyToLookupString"];
// getting an NSInteger
NSInteger myInt = [prefs integerForKey:#"integerKey"];
// getting an Float
float myFloat = [prefs floatForKey:#"floatKey"];
We can do it by creating a singleton class and shared instance
Yes, you can define the required fields in form of an array. Now make sure that the form will provide you an identity and there is some validation through session etc. A a hook to your controller to sense the form submission every time with a particular flag (hidden). So the tablename and CRUD instruction will be provided to this function and every common CRUD functionality will be handled by this single function. By defining the required fields will let you ignore the extra ones like input buttons and many hidden fields.
use NSUserDefault to store values.
Yes you can declare in forms of NSMutableArray or NSMutableDictionary and access it any Viewcontrollers. You need to create a file as NSObject class and in
.h
+(NSMutableDictionary *)ImageCollection;
in .m file
+(NSMutableDictionary *)ImageCollection
{
static NSMutableDictionary *thestring =nil;
#synchronized([Global class]) // in a single threaded app you can omit the sync block
{
if (thestring ==nil) {
thestring=[[NSMutableDictionary alloc]init];
}
}
return thestring;
}
In any View Controllers include that NSObject class file
[[Global ImageCollection]setObject:#"Sample" forKey:#"Dictionary"]; //just example you can save string,image,array anything as you like
Hope this helps .. !!!
Use shared memory, to store and share common data between views.

Setting property values programmatically in objective c

I have a file Variables.m for storing properties that I can use in all classes within my app. Now I would like to set a value for one of the properties (say username) in class A and I would like it to be available to all the other classes (B,C,D,E..) in my app like a constant. ie. once they initialize a Variables object (say var) in class B, if they issue var.username, they should get the username that I set in class A.
In effect instead of hardcoding a username value, I want to set it programmatically and have all the classes see the value that I just set. Can I achieve this without passing the Variables object around whenever I navigate to a class?
Alternatively, you can use NSUserDefaults
Set variable in class A:
NSString *usernameToSave = #"John Doe";
[[NSUserDefaults standardUserDefaults] setObject:usernameToSave forKey:#"userName"];
Read variable in any class:
NSString *userName = [[NSUserDefaults standardUserDefaults] objectforKey:#"userName"];
Apart from being simple, this has the advantage (or not) that it's persistent across app restarts.
It has the disadvantage that it's not very secure; for passwords and the like you should use Keychain Services as described here.
Create a singelton class that has the appropriate getters and setters for the items you want it to store.
You can then just reference that single instance from any other class.
For example in your Variables class create a class method like so:
+(Variables*)sharedVariables{
static Variables *myVariables = nil;
if (myVariables != nil){
return myVariables;
}
myVariables = [[Variables alloc]init];
return myVariables;
}
If you want a better implementation then google objective C singleton class implementation.
:)
to use this from your other classed you would just type:
[Variables sharedVariables].whatever
You can use Singleton pattern. Like this.
#interface MySingleton : NSObject
{
NSString *username;
}
#property (nonatomic, retain) NSString *username;
+ (MySingleton *) sharedInstance;
#end
#implementation MySingleton
#synthesyse username;
static MySingleton *sMySingleton = nil;
+ (MySingleton *) sharedInstance
{
#synchronized(self)
{
if (sMySingleton == nil)
{
sMySingleton = [NSAllocateObject([self class], 0, NULL) init];
}
}
return sMySingleton;
}
#end

Adding NSString to NSMutableArray substitutes the previous NSString

I'm basically trying to add a new string to my NSMutableArray using this code in ViewWillAppear
NSUserDefaults *favBooksDefaults = [NSUserDefaults standardUserDefaults];
self.favBook = [favBooksDefaults stringForKey:#"favBook"];
self.favBookList = [[NSMutableArray alloc]init];
[self.favBookList addObject:favBook];
Of course, while I do this, I want to preserve ALL the previous strings that were present in the Array. Because when I add a new string for the NSUserDefaults and then to the Array, it simply substitutes the old one.
Why is that and how can I save all the objects?
Thanks in advance.
Mr Br.'s answer is correct:
In your header file declare favBookList as a property and include a book adding method:
#interface yourViewController : UIViewController {
NSMutableArray *favBookList;
}
-(void)addBook;
#property (nonatomic, retain) NSMutableArray *favBookList;
In your viewDidLoad method, initialize favBookList. Don't forget #synthesize!
-(void)viewDidLoad {
self.favBookList = [[NSMutableArray alloc] init];
[super viewDidLoad];
}
Now you are free to add a book from your user defaults at any time.
-(void)addBook{
self.favBook = [[NSUserDefaults standardUserDefaults] stringForKey:#"favBook"];
[favBookList addObject:favBook];
}
When you alloc and init a new NSMutableArray object you will have an empty array with no values in it. It doesn't substitute it as there is nothing to substitute in there. It just adds the NSSString as the first value. This of course happens EVERY time you alloc/init a new instance of NSMutableArray.
SOLUTION: Make the NSMutableArray a instance variable of your view controller. alloc/init it once (e.g. in the viewDidLoad). Every time viewWillAppear gets called you can add values without reinitializing a new NSMutableArray.
NSMutableArray *newArray = [[NSMutableArray alloc] initWithArray:oldArray];
[newArray replaceObjectAtIndex:oldObjectIndex withObject:newObject] // if you want to replace oldObject with newObject;
[newArray addObject:newObject] // if you want to add object to the array;
If i get it right you want to replace the old object with new one?
NSUserDefaults *favBooksDefaults = [NSUserDefaults standardUserDefaults];
self.favBook = [favBooksDefaults stringForKey:#"favBook"];
if ([self.favBookList indexOfObject:self.favBook] != NSNotFound) {
[self.favBookList addObject:favBook];
}
You should also init your favBookList in viewDidLoad method:
self.favBookList = [NSMutableArray array];

NSUserDefaults - storing basic settings

I have a flipView application. On the FlipView I keep settings for the MainView and would like to use NSUserDefaults to store 2 integers for the MainView. I will use those integers in the main application. Is there some basic code that can implement what I'm trying to do?
I'd like to store the information on the FlipView (if changed) and have a default setting when the program is first run in the MainView.
Also, will I need to release the NSUserDefaults object once I'm finished using it?
check out below code, I had wrapped and make easy for you,
you can use below codes by:
import "Settings.h" in any code where you want to use, (maybe AppDelegate.m) in your case. then
to set value, use
[Settings setSetting:#"AUTOLOGIN" value:#"1"];
[Settings setSetting:#"OTHERPROPERTY" value:#"100"];
and remember that, store pointer datatype only,
to get setting value:
[Settings getSetting:#"AUTOLOGIN"];
here below there are two files, Setting.h and Setting.m , make those
header file is :
#import <Foundation/Foundation.h>
#interface Settings : NSObject {
}
+(id) getSetting:(NSString *)key;
+(void) setSetting:(NSString *)key value:(id)v;
#end
- and implementation file is
#import "Settings.h"
#implementation GCCSettings
static NSMutableDictionary *settings = nil;
+(id) getSetting:(NSString *)key{
if(settings == nil){
settings = [[NSMutableDictionary alloc] initWithDictionary:
[[NSUserDefaults standardUserDefaults] dictionaryForKey:#"settings"]
];
}
return [settings objectForKey:key];
}
+(void) setSetting:(NSString *)key value:(id)v{
[settings setValue:v forKey:key];
[[NSUserDefaults standardUserDefaults] setObject:settings forKey:#"settings"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
#end
and finally don't release any objects, which you had not allocated using(new, init, retain etc).
You can store the integer with
[[NSUserDefaults standardUserDefaults] setInteger:1 forKey:#"theKey"] and retrive it with [[NSUserDefaults standardUserDefautls] integerForKey:#"theKey"]. That's really all you need to handle an integer with user defaults.
You don't release the NSUserDefaults object. It's a singleton, so only one will be created for the life of your app. You also don't own it which means you wouldn't be releasing it.

Problem with NSUserDefaults and deallocated Instance

I'm having a problem with NSUserDefaults. I've followed the steps in the books as closely as I can for my app, but still get the same problem.
I am getting a
*** -[NSUserDefaults integerForKey:]: message sent to deallocated instance 0x3b375a0
error when I try and load in the settings. Here is the code that I have, it is in the App Delegate class.
- (void)applicationDidFinishLaunching:(UIApplication *)application {
recordingController = [[RecordingTableViewController alloc] initWithStyle:UITableViewStylePlain];
[recordingController retain];
// Add the tab bar controller's current view as a subview of the window
[window addSubview:tabBarController.view];
[self loadSettings];
}
-(void)loadSettings
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSNumber loop = [defaults objectForKey:#"loop_preference"];
NSNumber play = [defaults objectForKey:#"play_me_preference"];
NSNumber volume = [defaults objectForKey:#"volume_preference"];
}
As you can see I am not trying to do anything with the values yet, but I get the error on the line reading in the loop preference. I also get it if I try and read an NSString.
Any suggestions would be greatly appreciated.
Thanks
Peter
Since NSNumber is an object, it seems likely to me that you want:
NSNumber *loop = [defaults objectForKey:#"loop_preference"];
NSNumber *play = [defaults objectForKey:#"play_me_preference"];
NSNumber *volume = [defaults objectForKey:#"volume_preference"];
(Add asterisks * after NSNumber and before the variable names.) Though this does not seem directly related to your error message, it's the only apparent quirk in your code.