Storing a Base 64 String in NSUserDefaults - objective-c

I am working on some code that I inherited from a programmer who is no longer with my company. In this code, a few images are encoded as base 64 string, then subsequently stored in NSUserDefaults inside a NSDictionary. The issue I am having is if the application has been killed (i.e. thorugh the mulitasking UI), the dictionary containing the data does not seem to load.
Are Base 64 strings considered a property list objects in Objective-C?
I realize this is NOT the ideal solution for storing data on disk, but this is what I have to work with for the immdeiate future.

Do they show up in the application's plist as string or data? If the latter, they're encoded NSData objects; try using objectForKey: and then -[NSImage initWithData:].

Related

How to have NSData in an object that will be converted with NSJSONSerialization?

I have a NSMutableArray with custom objects. The objects inside have a NSData field. I want to transport them to my web service using JSON format but I don't really know how to do it with NSJSONSerialization as it doesn't support NSData. Can you tell me if it's possible and provide me with some sample code or some other library that can handle this?
No. As the NSJSONSerialization documentation makes clear:
An object that may be converted to JSON must have the following properties:
The top level object is an NSArray or NSDictionary.
All objects are instances of NSString, NSNumber, NSArray, NSDictionary, or NSNull.
All dictionary keys are instances of NSString.
Numbers are not NaN or infinity.
NSData obviously doesn't have those properties.
So likely what you'll want to do is encode it as a Base64 string or some other form you consider acceptable (there are plenty of options other than Base64, but it's the one that immediately comes to mind). You might also be able to get by with just converting it to a string (depending on what the data is) that uses the appropriate escape codes and so on, though you should make sure that won't result in any encoding issues.
Anyway, the answer's no. Find a way to encode it as an NSString or something else NSJSONSerialization can work with.

is it good way to store custom data in UserDefaults?

i need to store some objects from table.
It will be no more than 100 objects.
Is it good way to store it like array in NSUserDefaults? Or there is any better way?
Although you can store this is NSUserDefaults using [[NSUserDefaults standardUserDefaults] arrayForKey:#"key"]; you probably shouldn't. Defaults was designed to store VERY small ammounts of data, like a users preferences (thus the name). If you wish to store more data than this, then you may want to look into .plists, NSDocumentDirectory, Core-Data, or SQLite databases.
The better way would be to serialize it as a binary blob on disk using NSArrays writeToFile:atomically: or writeToURL:atomically:. NSUserDefaults aren't stored as binary and thus need extra parsing time upon loading, and extra time to write out to disk. NSUserDefaults is also not designed to hold large amounts of data but for a small set of settings data.
Store all custom data in NSDictionary or NSArray.
Now save dictionary or array with custom data in document directory follow this link
no Storing data on NSUserDefaults is not good, because it can cause a serious hack.
instead of it you can use AppDelegate to store data globally.

Saving data encoded with NSCoder

I'm encoding some NSDictionary with NSCoder and I want to save it somehow inside the app. Could anyone please tell me how I could do it?
I want to give the user the ability to see what he's done previously when he opens the app.
You can write it to a file in your Application Support folder or, if it's small, you can put it into NSUserDefaults. For either of those, though, if the dictionary contains only property list types, you can write the dictionary directly. You don't have to encode it to an NSData first.

Is a plist or NSUserDefaults More Efficient for storing a small amount of data?

I can go either way on this for this project, but I'm curious if using a plist to store some data is going to be more or less efficient than just keeping a plist in the documents folder. The data is about 50 strings/dictionaries.
In both cases the data gets persisted using some file IO so disk access should be similar.
However, the plist seems like a little more work.
NSUserDefaults is a plist (that is why only plist types can be stored in it). So ultimately there isn't going to be much difference in efficiency (whatever you mean by that). Your consideration should rather be where it is appropriate to keep this data. Don't keep it in the Document folder unless it is appropriate for storage in iCloud, says Apple; it will be backed up when the user backs up the device, and will subtract from the user's quota, so you need to be sparing of what you keep there.
In one of my own apps, where I download a bunch of data from an RSS feed and present it to the user, I store the data in the user defaults, because it is part of the app's persistent state the next time it appears. My data isn't a document; it's the app's state. That's my reasoning, and I'd suggest you might reason along similar lines...
In my opinion, plist are much simpler to use than NSuserDefaults. Afterall, a dictionary can save itself as a plist. As for efficiency, they sould be the same as NSUserDefaults stores everything as a plist but provides more services such as comparing which key/values pair have changed compared to a provided set of key/values default pairs.
You may want to consider JSON using JSONKit. Some tests show it's faster than a binary plist, if speed is your primary concern. The API is dead simple because it creates a category on NSDictionary and NSArray. Calling -(NSData *)JSONData on either of those objects returns an NSData object ready to save.

Which method is better to save data nsdictionary or plist?

I want to save data locally but i do not know which method is better nsdictionary or plist?Can anyone tell which method is better and why?
Thanks in advance!
I think maybe what you meant to ask is which is better, plist or binary. If you save an NSDictionary to file using writeToFile: it will be stored as a plist. So in that sense there is zero difference between the two.
However, you also have the option of converting an NSDictionary instance into a serialized NSData representation, and then storing the serialized data as a binary file.
As for which is better and why, that depends upon what you want to do. The API for converting an NSDictionary to/from a plist file is more convenient to use than the API for serializing and reconstructing to/from NSData. However, storing an NSDictionary as a plist file only works if everything in the dictionary is a plist object (instances of NSData, NSDate, NSNumber, NSString, NSArray, or NSDictionary) and if all of your keys are of type NSString. Otherwise your writeToFile: call will fail with frustratingly little information being provided about why.
So if your data structure meets the requirements for being stored as a plist and you cannot foresee it ever being changed such that it would no longer meet the requirements then you may find it more convenient storing it as a plist. Otherwise your only option is to do a binary serialization and storage using NSData. You may prefer this latter option if you want to have code that cannot be accidentally broken by someone sticking a non-plist-object in your data structure.