NSUserDefaultsProblem - cocoa-touch

I have a simple problem:
I add an object to an NSArray, then I add an object to it then I use the NSUserDefaults way to save the array, but it doesn't work, I mean the array isn't saved and the console sends me this messange:
2011-03-21 23:09:53.994 Project[10490:207] * -[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value '(
""
)' of class '__NSArrayM'.
does anybody know how can I fix this.

NSUserDefaults only allows you to save basic lightweight objects; for example NSString, NSNumber and NSData. If you want to add another class, you'll have to shoehorn it into an NSData object beforehand. This is pretty simple, usually just a call to [NSKeyedArchiver archivedDataWithRootObject:array];. Note that the objects in the array must implement the NSCoding protocol, which you'll have to add to any of your own custom classes if that's what you want to save.
Also keep in mind NSUserDefaults is meant for lightweight preferences, not application data. If you have a large array of objects, you might be better served by archiving it to its own file or using Core Data (if you feel comfortable using something a little more advanced).

The only types you can save in NSUserDefaults are property list types: NSString, NSDate, NSArray, NSDictionary, NSNumber, NSData. You're probably trying to save an array of objects that aren't one of these types.

Related

Access raw NSData for a Transformable attribute in Core Data

In my model, I have an attribute transformingString that stores an NSString object as NSData, using the "Transformable" type. In my code, I have an NSString as an dynamic property in my NSManagedObject, and accessing that property automatically invokes the value transformer to convert from NSData to NSString.
In some cases, though, I want to access the raw NSData in my code, without invoking the NSValueTransformer, so I can handle the NSData in a different way for some edge case. How can I do this? I don't think there is any way to just turn off the Transformable type for my Core Data model. I'm hoping there is some way to access the raw NSData directly that is passed into the transformer.
I've tried [self primitiveValueForKey: #"transformingString"] but that also invoked the NSValueTransformer and returns the NSString type. Is there a way to do this?
If i resume you want access a value on a NSManagedObject that is not stored in persistent Store. I suggest you to add a category on your NSManagedObject. In this category declare a property in readonly (for be sure that not use for an other thing). In the implementation return the raw NSData.

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.

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.

How to add an NSEvent to a Property List?

I'd like to encode an NSEvent using NSPropertyListSerialization, but NSPropertyListSerialization only accepts NSData, NSString, NSArray, NSDictionary, NSDate, and NSNumber objects.
Is there a recommended way to convert an NSEvent to a NSPropertyListSerialization-capable NSDictionary (and to restore an NSEvent from such an NSDictionary)?
In this situation you need to handle saving and restoring the object yourself. Or rather, the pieces of the object you're interested in, either by putting each value in an NSDictionary or storing them separately and using the values to create a new object when your class is decoded.
This situation is a little weird since you usually don't create or store NSEvent objects. If you're doing something like storing the last touch coordinate, consider using an CGPoint instead. Not only will you reduce your memory footprint by a small amount, but you can then use an NSValue to serialize the point.

What is the best way to store data in an objective-c model?

I am writing an objective-c model to hold all of the data parsed from an XML connection. I am using an NSURLConnection to download the data asynchronously and it is then passed to the parser. I have done this before, but not with such a large xml file. I would like to garner some opinions on the best way to store the data. Here are some options:
Create a bunch of NSMutableDictionary's that represent the sections in the xml. Then add a key/value to these dictionaries with the child tags.
Create structs to hold the data as such:
`struct section_one {
NSString *string1;
NSString *string2;
} sectionOne;
The only thing I'm worried about is how to go about managing the memory of the strings inside the struct. Should I copy the strings when I am instantiating them and release each individual string in the dealloc of the Model class.
Overall, I would just like some suggestions as to how to store the data.
I'd suggest using NSDictionary instances nested inside another NSDictionary (whether these need to mutable or not depends on how you intend to use them, so I won't comment on that). The keys to the top-level dictionary could then be sectionOne, sectionTwo, etc., and their corresponding values would be the nested dictionary instances.