How to access the string data outside the function and class - iphone

I am trying to access the nsstring data out side the function and also outside the class.
How can I access useridStr outside the function and class? This is my code:
-(id)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *loginStatus = [[NSString alloc] initWithBytes:[webData mutableBytes]
length:[webData length] encoding:NSUTF8StringEncoding];
NSDictionary *loginDict = [[loginStatus JSONValue] objectForKey:#"UserDetails"];
NSArray *userId = [loginDict valueForKey: #"userid"];
NSString *useridStr = [userId lastObject];
NSLog(#"--------------....%#", useridStr);
}

NSUserDefaults *pre = [NSUserDefaults standardUserDefaults];
[pre setObject:useridStr forKey:#"useridStr"];
where you want to need string:
NSUserDefaults *pre =[NSUserDefaults standardUserDefaults];
NSString * useridStr =[pre stringForKey:#"useridStr"];
OR
In .h file of anotherView
-(id)initUserInfo:(NSString *)string;
In .m file of anotherView
-(id)initUserInfo:(NSString *)string{
if (self = [super initWithNibName:#"nextView" bundle:nil]) {
useridStr=string
}
return self;
}
In .m File of firstView
-(IBAction)btnNext_TouchUpInside:(id)sender{
nextView *second =[[nextView alloc]initUserInfo:useridStr];
[self presentModalViewController:second animated:NO];
}

What Piyush suggested is also correct. But there is also another way to achieve it.
As he suggested NSUserDefaults to save data you should keep in mind that NSUserDefaults is generally used to save data like preferences which you want it to be stored even after Application is closed by user and you want those data again when you start your application.
So if you want to save data like preferences go for NSUserDefaults. If you want your data to be available throughout your application while its running and you do not need to save them like preferences I would recommend you declare that object globally in Appdelegate file and access them whenever you need. You should not store them as NSUserDefaults because as Apple document says whatever you store in NSUserDefaults it will be saved in user's default database. So that will consume memory of your device. So in short saving everything to NSUserDefaults won't be a good idea if we consider memory managent concepts.

Related

NSUserdefaults for multiuser

In my application, I am using a login form to enter into the application, also using NSUserDefaults to store user preferences, for example:
[storeData setObject:self.loginField.text forKey:#"USEREMAIL"];
[storeData setObject:self.PasswordField.text forKey:#"PASSWORD"];
Like I stored, if a new user logs in the NSUserDefaults stored value will be changed. But I want both preferences (ex:new userid and old userid as well as password). So please explain how to store multiple values for same key?
One way to solve this would be to store a NSDictionary with UserIDs as keys and the passwords as values.
Another option is to use Keychain as it specifically designed for this kind of thing and is also more secure.
Create a Global NSMutableArray and add above details in NSDictionary Objects and Store all Objects in array.This way you will have all user objects.You can get it whenever you want.
first of all create global array with AppDelegate class, for example..
userDefaults = [NSUserDefaults standardUserDefaults];
NSData *dataRepresentingtblArrayForSearch = [userDefaults objectForKey:#"arrScheduleDates"];
if (dataRepresentingtblArrayForSearch != nil) {
NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingtblArrayForSearch];
if (oldSavedArray != nil)
arrScheduleDates = [[NSMutableArray alloc] initWithArray:oldSavedArray];
else
arrScheduleDates = [[NSMutableArray alloc] init];
} else {
arrScheduleDates = [[NSMutableArray alloc] init];
}
[arrScheduleDates retain];
after that when you want to store the new record then get all record from arrScheduleDates array and after that add the new record and after that store like whole array like above..
i hope you understand and its helpful for you...
:)
The absolute easiest way to meet your requirements is to use the user's email address (assuming they're all unique) as the storage key for your dictionary, and the password as the value.
If you need to store more than the password, then the value of the key would be another dictionary with keys and values for the user.
An example of the simple case would look similar to :
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSDictionary *storedUsers = [userDefaults objectForKey:#"userData"];
if (nil == storedUsers) storedUsers = [NSDictionary dictionary];
NSMutableDictionary *mutableStoredUsers = [NSMutableDictionary dictionaryWithDictionary:storedUsers];
NSString *userPassword = [self.PasswordField.text copy]; //add autorelease if you aren't using ARC
NSString *userEmail = [self.loginField.text copy]; //add autorelease if you aren't using ARC
if (nil != userEmail)
{
[mutableStoredUsers setObject:userPassword forKey:userEmail];
}
[userDefaults setObject:[NSDictionary dictionaryWithDictionary:mutableStoredUsers] forKey:#"userData"];
[userDefaults synchronize];
first download and import files of given link
https://github.com/ldandersen/scifihifi-iphone/tree/master/security
then where u want to store user preferences write this code
[SFHFKeychainUtils storeUsername:loginField.text andPassword:PasswordField.text forServiceName:#"dhaya" updateExisting:YES error:&error];
where u want password write this code
NSString *password = [SFHFKeychainUtils getPasswordForUsername:loginField.text andServiceName:#"dhaya" error:&error];
NSLog(#"passwordpassword %#",password);
this will working great....

How To Save Data For Bookmarks?

I'm creating a very simple bookmarks menu for my app. I just need to save 3 strings for each object.
I was thinking of using core data but I don't want this to be connected with my core database for various reasons. Therefore what other easy options do I have? NSUserDefaults or .plist?
I just need to save the 3 strings for each object then load them into a table view to be viewed.
I'd recommend NSUserDefaults - is certainly easier. I tend to only use plist files for static data that I want to be editable as the developer, but from the application want it to be read-only (such as coordinates for objects on an embedded map image).
From your description, you would probably want to store an NSArray containing NSDictionary.
// Get the user defaults object
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
// Load your bookmarks (editable array)
NSMutableArray *bookmarks = [[NSMutableArray alloc]init];
NSArray *bookmarksLoaded = [userDefaults arrayForKey:#"bookmarks"];
if (bookmarksLoaded != nil) {
[bookmarks initWithArray:bookmarksLoaded];
} else {
[bookmarks init];
}
// Add a bookmark
NSMutableDictionary *bookmark = [NSMutableDictionary new];
[bookmark setValue:#"value" forKey:#"name"];
[bookmark setValue:#"value" forKey:#"description"];
[bookmark setValue:#"value" forKey:#"code"];
[bookmarks addObject:bookmark];
// Save your (updated) bookmarks
[userDefaults setObject:bookmarks forKey:#"bookmarks"];
[userDefaults synchronize];
// Memory cleanup
[bookmarks release];

NSUserDefaults not present on first run on simulator

I've got some settings saved in my Settings.bundle, and I try to use them in application:didFinishLaunchingWithOptions, but on a first run on the simulator accessing objects by key always returns nil (or 0 in the case of ints). Once I go to the settings screen and then exit, they work fine for every run thereafter.
What's going on? Isn't the point of using default values in the Settings.bundle to be able to use them without requiring the user to enter them first?
If I got your question right, in your app delegate's - (void)applicationDidFinishLaunching:(UIApplication *)application, set the default values for your settings by calling
registerDefaults:dictionaryWithYourDefaultValues
on [NSUserDefaults standardUserDefaults]
- (void)applicationDidFinishLaunching:(UIApplication *)application {
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:3], #"SomeSettingKey",
#"Some string value", #"SomeOtherSettingKey",
nil];
[ud registerDefaults:dict];
}
These values will only by used if those settings haven't been set or changed by previous executions of your application.
As coneybeare said "You should detect if it is the first load, then store all your defaults initially."
On applicationDidFinishLaunching try to set default value in your preference.
Here is the sample:
NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults];
if([defaults objectForKey:#"YOUR_KEY"] == nil)
{
[defaults setValue:#"KEY_VALUE" forKey:#"YOUR_KEY"];
}
When application will run second time it will come with KEY_VALUE for YOUR_KEY.
Thanks,
Jim.
Isn't the point of using default
values in the Settings.bundle to be
able to use them without requiring the
user to enter them first?
No. The point of the settings bundle is to give the user a place to edit all 3rd Party app settings in a convenient place. Whether or not this centralization is really a good idea is a User Experience issue that is off topic.
To answer your question, you should detect if it is the first load, then store all your defaults initially.
And while we are on the subject, I would also check out In App Settings Kit as it provides your app with a simple way to display your app settings in both places (in-app and Settings.app) with minimal code.
The values in the Settings.bundle are intended for the Settings app to able to fill in default values for your app. They are not used by your own app.
But you can set defaults yourself with the registerDefaults: method of NSUserDefaults. This will not actually set them on disk but just give "defaults for the defaults": they are used when no value has been set by the user yet.
Setting registerDefaults: must be done before any use of the default values. The "applicationDidFinishLaunching:" method that others suggested for this, is too late in most cases. By the time "applicationDidFinishLaunching:" is called, your views have already been loaded from the nib files, and their "viewDidLoad:" methods have been called. And they may typically read user defaults.
To guarantee that the defaults are set before first use, I use the following utility class, which loads the values from the Root.plist file and sets them with "registerDefaults:". You use this class to read user defaults instead of "[NSUserDefaults standardUserDefaults]". Use "[Settings get]" instead.
As a bonus, it also contains a registration method for user default change notifications, because I always forget how that is done.
#import "Settings.h"
#implementation Settings
static bool initialized = NO;
+ (void) setDefaults
{
NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
NSString *settingsBundlePath = [bundlePath stringByAppendingPathComponent:#"Settings.bundle"];
NSBundle *settingsBundle = [NSBundle bundleWithPath:settingsBundlePath];
NSString *settingsPath = [settingsBundle pathForResource:#"Root" ofType:#"plist"];
NSDictionary *settingsDict = [NSDictionary dictionaryWithContentsOfFile:settingsPath];
NSArray *prefSpecifierArray = [settingsDict objectForKey:#"PreferenceSpecifiers"];
NSMutableDictionary *appDefaults = [[NSMutableDictionary alloc] init];
for (NSDictionary *prefItem in prefSpecifierArray)
{
NSString *key = [prefItem objectForKey:#"Key"];
if (key != nil) {
id defaultValue = [prefItem objectForKey:#"DefaultValue"];
[appDefaults setObject:defaultValue forKey:key];
}
}
// set them in the standard user defaults
[[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];
if (![[NSUserDefaults standardUserDefaults] synchronize]) {
NSLog(#"Settings setDefaults: Unsuccessful in writing the default settings");
}
}
+ (NSUserDefaults *)get
{
if (!initialized) {
[Settings setDefaults];
initialized = YES;
}
return [NSUserDefaults standardUserDefaults];
}
+ (void) registerForChange:(id)observer selector:(SEL)method
{
[[NSNotificationCenter defaultCenter] addObserver:observer selector:method name:NSUserDefaultsDidChangeNotification object:nil];
}
+ (void) unregisterForChange:(id)observer
{
[[NSNotificationCenter defaultCenter] removeObserver:observer name:NSUserDefaultsDidChangeNotification object:nil];
}

UserDefaults/KeyedArchiver Frustrations

I'm working on a homework app that uses custom Assignment objects for each assignment. I am trying to store an NSMutableArray (casted to an NSArray via initWithArray:) in standardUserDefaults but I'm having trouble with saving and reloading the array.
I have a table view from which you can choose to add a new assignment (which loads NewAssignmentViewController). When you save the assignment, it is pushed back to an array in AssigmentsViewController. And then you call it every time you load the UITableView which shows the assignments.
Here is the relating code:
-(void)saveToUserDefaults:(NSArray*)myArray{
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
if (standardUserDefaults) {
[standardUserDefaults setObject:[NSKeyedArchiver archivedDataWithRootObject:myArray] forKey:#"Assignments"];
[standardUserDefaults synchronize];
}
}
-(void)retrieveFromUserDefaults{
NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *dataRepresentingSavedArray = [currentDefaults objectForKey:#"Assignments"];
if (dataRepresentingSavedArray != nil) {
NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray];
if ([oldSavedArray count] != 0) {
[assignments setArray:[[NSMutableArray alloc] initWithArray:oldSavedArray]];
}
else {
assignments = [[NSMutableArray alloc] initWithCapacity:100];
}
}
}
-(void)backButtonPressed {
[self saveToUserDefaults:[[NSArray alloc] initWithArray:assignments]];
[self.navigationController popViewControllerAnimated:YES];
}
Please help. It does not load the array but does not give any error. Any tips about UserDefault or KeyedArchiver in general would be greatly appreciated.
Couple of things here:
If I understand you correctly, you're trying store an array whose contents are the assignment objects.
If you want to serialize these objects for storage into NSUserDefaults, the Assignment objects themselves need to conform the NSCoding protocol by overriding these methods:
- (void)encodeWithCoder:(NSCoder *)encoder;
- (id)initWithCoder:(NSCoder *)decoder;
Since you didn't post the code for your Assignment objects, dunno if you did this properly or at all. If you have you should be able to encode the object. See the Archives and Serializations Programming Guide for more.
As for NSUserDefaults, by my read, you're basically trying to store your application's object model there. Not the best idea. NSUserDefaults is best suited for use with light-weight persistent data: basic preferences, strings, scraps of universal data.
What I would do is write out your archived data to a file and load it when your view loads.
Here's some code from Beginning iPhone Development on that subject:
Creating an archive from an object or objects that conforms to NSCoding is relatively easy. First, we create an instance of NSMutableData to hold the encoded data and then create an NSKeyedArchiver instance to archive objects into that NSMutableData instance:
NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
After creating both of those, we then use key-value coding to archive any objects we wish to include in the archive, like this:
[archiver encodeObject:myObject forKey:#”keyValueString”];
Once we’ve encoded all the objects we want to include, we just tell the archiver we’re done, write the NSMutableData instance to the file system, and do memory cleanup on our objects.
[archiver finishEncoding]; BOOL success = [data writeToFile:#”/path/to/archive” atomically:YES];
[archiver release];
[data release];
To reconstitute objects from the archive, we go through a similar process. We create an NSData instance from the archive file and create an NSKeyedUnarchiver to decode the data:
NSData *data = [[NSData alloc] initWithContentsOfFile:path];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
After that, we read our objects from the unarchiver using the same key that we used to archive the object:
self.object = [unarchiver decodeObjectForKey:#”keyValueString”];
You'd also need to get your application's documents directory to save and load the files.
It's a wildly useful book, full of drop in code snippets. The chapter on persistence might be helpful for you. You might be much happier using Core Data for this task, come to think of it.
I'm not sure if this will fix your problem, but you don't have to pull the array out of Defaults as NSData. Check the NSUserDefaults reference and you'll see that Arrays are valid default objects.

iPhone One Time Events Programming

How can I make my application display something only when they first launch the application for the first time. Example: They open up my app, an alert comes up, saying something like, "Do you want to play the tutorial?" Then, if they close the app, then re-open it, it won't show up again.
Thanks
I'd recommend using NSUserDefaults:
- (void)openOneTime
{
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
static const NSString* kKey = #"One Time Key";
NSObject* keyValue = [defaults objectForKey:kKey];
if (keyValue == nil)
{
[self doMyOneTimeThing]; // pop a dialog, etc...
}
// Adds an object for our key which will get found the next time around,
// bypassing the above code block. The type and value of the object is
// not important; what matters more is that an object exists for that
// key at all.
[defaults setBool:YES forKey:kKey];
}
More tips on storing data persistently:
Method 1: Use the global user preferences system. You can do this, but it might be considered slightly hacky because it is designed to store user preferences, and I think this is a gray area, since the user doesn't have explicit control here. In any case, check out the docs for NSUserDefaults to find out how to do that.
Method 2: Write to a file whose existence indicates whether or not the tutorial has been viewed. You can easily create a file with an NSData object by calling its writeToFile:atomically: method. Later, you can use the NSFileManager class to check if that file exists or not.
Sample code:
- (NSString*) filename {
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:#"notFirstTime"];
}
- (void) setNotFirstTime {
NSData* data = [[[NSData alloc] init] autorelease];
[data writeToFile:[self filename] atomically:YES];
}
- (BOOL) isNotFirstTime {
return [[NSFileManager defaultManager] fileExistsAtPath:[self filename]];
}
You could store in your property store a boolean value saying whether it's the first time or not, then check that on application start.