views:

82

answers:

1

I am trying to save drafts using NSUserDefaults but I am not sure if it is the right place to save data not user's preferences in.

My application allows user to choose 1 or 2 images to upload and share. Users can save draft and come back to upload later. My current approach is to save the chosen UIImage to /Library directory and save the file path to NSUserDefaults.

The data structure is NSUserDefaults -> Draft NSDictionary -> key - NSArray. I have many drafts (just like email drafts). The Draft Dictionary contains a saved date string as a key and string file paths in NSArray. The saving process doesn't have any problems currently. But because in NSUserDefaults doc, they say:

The defaults system allows an application to customize its behavior to match a user’s preferences.to match a user’s preferences.

So, I don't know if my approach is good or not, any possible future problems with it?

Do you suggest me any simple solution that can do this well without having to code much. I know there is CoreData but I don't know much about it. Is it easy to learn and implement?

I don't know if this can affect some memory problem or not, but I expect that a user may save drafts less than 100.

+2  A: 

You don't want to save any actual data to NSUserDefaults, however, it acceptable to save the previous application state in the defaults such that the app can resume where it left off.

Your data structure seems overly complex. You can just save an array of file paths directly to the user defaults.

NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
NSArray *draftPaths=[NSArray arrayWithObjects:filePath1, filePath2,nil];
[defaults setObject:draftPaths forKey:@"DraftPaths_Key"];
// to retrieve
NSArray *previousDraftPaths=[defaults objectForKey:@"DraftPaths_Key"];

You don't want to save the files into the cache folders because the system can delete caches if space gets tight. Instead, save them to custom folder in the /Library directory. You can get the path to the library with:

NSArray *libraryPaths=NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *libPath=[libraryPaths objectAtIndex:0];
TechZen
Thanks for correcting me about the Cache folder, I actually save it in the /Library using the same code with you, but is it still called "Cache" folder there?
vodkhang
The problem is that I can have many drafts, not just previous draft. Like you are writing email, and sometimes, we have many email drafts. I will clarify this part in my question. Any difference if I store a lot of drafts in NSUserDefaults, will them be deleted?
vodkhang
"Caches" is a system name so I would use something else such as "Drafts" and just park that in the root level of the Library directory. You shouldn't the data itself into defaults but just the file paths. If you anticipate having more than a couple of dozen, then you should look at saving the file paths or the drafts themselves in a plist or Core Data. Defaults are really for application state/configuration data and not the end user's primary data e.g. the user's preferred font for word processing but not what he actually writes.
TechZen
Does plist have any performance issue? Do I have to load everything just to find out what I need or the Resource system will automatically load in need?
vodkhang
Plist have the limitation that they must be read into memory at once but that is not a concern unless you have large amounts of data(>1mb). Anything you contemplate sticking in defaults will fit easily into a plist. If you just have a list of file paths, a plist will work fine.
TechZen
Ok, thanks a lot. I think I will do plist now, much simpler to implement than core data in this case, I think so
vodkhang