-1

I have two UITextField

  1. email
  2. password

These two field values are stored in a NSMutableDictionary call userData. Now i want to save these two field values in a file, so that the records keep there and i can restore this record to check user login correctly. Here i want to accomplish that, but not working.

My code :

-(void) saveRegistrationData
{
    userData = [[NSMutableDictionary alloc]
                initWithObjects:[[NSMutableArray alloc] initWithObjects:@"123456", nil]
                forKeys:[[NSMutableArray alloc] initWithObjects:@"admin@gmail.com", nil]];

    [userData setObject:passwordTextField.text forKey:emailTextField.text];

    NSString   *savePath = [@"/MediaFiles/Documents/" stringByExpandingTildeInPath];
    [userData writeToFile: savePath atomically: YES];

    //[userData writeToFile:@"MediaFiles/Documents/" atomically:YES];

    for (id key in userData)
    {
        NSLog(@"%@ is for %@", key, [userData objectForKey:key]);
    }
}

I think the path is not setting correctly. If any one similar with the solution, please share with me. Thanks in advanced. Have a good day.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Tulon
  • 4,011
  • 6
  • 36
  • 56

2 Answers2

4

It's not working for a few reasons.

1) You're writing to a folder in the root of the device's filesystem. Apple uses sandboxing to prevent this from happening as you could overwrite and modify any system files.

2) You're writing to a folder rather than a file. To write to a file, you need to specify a filename (and extension). i.e. "/MediaFiles/Documents/dnt_lk_at_dis.plist"

In order to fix these issues, you need to be firstly getting the path to the sandbox (documents directory) and then append the filepath.

NSString *docsPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filename = @"secret.plist";
NSString *filePath = [docsPath stringByAppendingPathComponent:filename];

Furthermore, I strongly suggest that you instead use the keychain for storing sensitive user information. Anybody with a jailbroken device, or anybody that has access to the file system will be able to extract the user's information if it is stored in plain-text. At the very least, please encrypt the password before writing it to disk.

max_
  • 24,076
  • 39
  • 122
  • 211
  • Thanks for the nice explanations. Actually i tried with other many options as you said, like `/MediaFiles/Documents/dnt_lk_at_dis.txt`, but neither of them working. Besides i see a couple of tutorials about it. How to use plist to store data in it. But, it looks like little bit complicated to me. If i use the `NSSearchPathForDirectoriesInDomains`, then after go to library where suppose i find the `secret.txt` file, to check that the data are actually saving there? Thanks for sharing the security issue, i will work on it. – Tulon Mar 25 '14 at 20:03
  • @Tulon that path won't work because of the first issue I mentioned, the code I posted will work for certain. You can check to see if it's writing to disk by `NSLog(@"%@", filePath)` and going to the containing folder in Finder (having run the app on iOS Simulator) – max_ Mar 25 '14 at 20:20
  • Yes, you are great. it is working & i find the `secret.txt` tracking the `NSLog` directory. But here now i realize one thing that, In `NSMutableDictionary` the previous data are not saved like database. When ever i give input, my previous record is gone from the `secret.txt` and it replace with the latest one. That mean i can't use `NSMutableDictionary` as Database, isn't it? – Tulon Mar 25 '14 at 20:57
  • @Tulon Thanks! I don't really understand what you mean? As soon as you write to the same filepath, the old data will of course be overridden. What are you aiming to achieve instead? – max_ Mar 25 '14 at 22:30
  • i was thinking, all entry value will save in the directory file one after another and i can pick up those data at the time of user login. But i think i have to stay with `sqlite` to do that. NSMUtableDictionary can't use like database. :( – Tulon Mar 26 '14 at 09:36
  • @Tulon you want an array of `NSDictionary`s. – max_ Mar 27 '14 at 21:09
1
-(void) saveRegistrationData
{
    userData = [[NSMutableDictionary alloc] init];


    [userData setObject:passwordTextField.text forKey:@"password"];
    [userData setObject:emailTextField.text forKey:@"email"];


    // Alternative to the above:
       userData = [[NSMutableDictionary alloc]
                initWithObjects:[[NSMutableArray alloc] initWithObjects:passwordTextField.text, emailTextField.text, nil]
                forKeys:[[NSMutableArray alloc] initWithObjects:@"password", @"email" nil]];


    NSString   *savePath = [@"/MediaFiles/Documents/myDict.plist" stringByExpandingTildeInPath]; // write to a file, not a dictionary
    [userData writeToFile: savePath atomically: YES];

    for (id key in userData)
    {
        NSLog(@"%@ is for %@", key, [userData objectForKey:key]); // now you should see the result that you want to. 
    }

    // Alternative for the above - the lazy way of doing it: 
    NSLog (@"theDictionary: %@", userData);
}

Please forgive me any typos or so. I did not compile it for you :-)

Hermann Klecker
  • 14,039
  • 5
  • 48
  • 71