How do I save a custom c++ class object to NSUserDefaults? - ios

I want to add a C++ Class object into NSUserDefaults. If I add it directly, it crashes.
How do I add c++ Class object to NSUserDefaults?

NSUserDefaults supports some NSObject-based classes to be encoded out of the box. Proper way to save custom NSObject classes into NSUserDefaults instance is to encode them into NSData and save it.
In your case, since you have a C++ class, you could either wrap it's data to an NSObject (NSDictionary maybe) or implement a class <-> string serialisation and deserialisation, saving a string object into the NSUserDefaults instance.

Related

How can I save a Swift dictionary structure?

I have a Swift dictionary structure ([String : CustomObject]) that I need to save once and then reload later whenever the application launches. How do I go about saving and reloading a dictionary using Swift?
you can convert the Dictionary to NSData link here and then save it to NSUserDefaults as it is here
If you have custom objects then you need to make them conform to the NSCoding protocol. This means implementing the methods encodeWithCoder and initWithCoder. It comes down to deconstructing the state values of your object to data types that are either "property list" types, or types that also conform to NSCoding. Your implementation of encodeWithCoder can, encode it's properties that are objects that conform to NSCoding by calling encodeObject:forKey:

Initialize a subclass of NSManagedObject

I have a question about CoreData and NSManagedObject.
I receive a NSDictionary in my ClientRESTClass (I use AFNetworking 2.0) so I have a Json data in this NSDictionary.
For this object type I use a my protocol with two methods that these objects must implement:
- encodeFromJson //(instance to JSON)
- decodeFromJson //(from json I create an instance)
Now I have a myObj as subclass of NSManageObject that implements this protocol.
1) In the decodeFromJson how can I to generate an instance of myObj? Is necessary to use in this point a context? Is possible to use a simple init?
2) At this level I receive data from server an I create instance of these object. I pass this instance to the caller and he will decide whether to save the object or if you do not save it in CoreData.
So, If I have to use a contex, how can I discard objects that I placed in the context?
You should not create an NSManagedObject directly, you should use the NSNSEntityDescription's insertNewObjectForEntityForName -- see: Apple Docs.

How to transmit NSObject data in Objective C MultipeerConnectivity framwork

I am new to Objective C and is working on a iOS mobile app based on MultipeerConnectivity network project framework. This framework provides me with send message and receive message methods between devices.
Here I want to send a MyMessage NSObject defined by myself as follows through this function to transmit different kinds of data. However, I want to include a NSMutableArray, which contains multiple objects of information in a single message object.
#interface MyMessage : NSObject
{
NSMutableArray playersInfo;
}
#end
I understand that in Objective C we cannot statically allocate interface type like this. Instead we should use a pointer. In this case, however, if I set playersInfo as a pointer NSMutableArray* playersInfo, then after the object is transmitted to another device, the other device cannot get the data pointed by the playersInfo. (I assume MyMessage object will be transmitted using only shallow copt so the data in NSMutableArray* playersInfo will not be transmitted) Here I am asking how can I achieve a message class that can contain the actually NSObject data.
Like any implementation, to send data you need to decompose your primitive, structure or object into a block of data that can be transported across the comms link. Sometimes this is called serialisation (typically when applied to objects)
In iOS, objects can be serialised by using NSKeyedArchive/Unarchive. So in your example, each of the objects you have stored in your array need to implement the Archive/Unarchive logic by conforming to NSCoding
Then to generate your serialised data (NSData object), you will invoke the archiver on the array object. NSArray conforms to the NSCoding protocol.
How deep/shallow you want to go depends on your implementation. You decide how many of your objects properties you want to encode/decode as part of implementing encodeWithCoder.
I use this pattern to exchange data withpeers, but I also extend it using inheritance - for example I define a class: myMessageBase then inherit that Base class into each of my various Message variants.
MultipeerConnectivity framework allows you to send NSData using MCSession API . convert your NSArray to NSData then send
[self.session sendData:messageData toPeers:self.session.connectedPeers withMode:MCSessionSendDataReliable error:&error];
convert NSData to NSArray
NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:data]
convert NSArray to NSData
NSString *error;
NSData *data = [NSPropertyListSerialization dataFromPropertyList:array format:NSPropertyListBinaryFormat_v1_0 errorDescription:&error];

How do I control what objects to encode using NSKeyedArchiver?

I have an array filled with two different types of custom classes. Lets call them ClassA and ClassB.
I want to enabled encoding/serialization for ClassA, but not for ClassB.
I am using [NSKeyedArchiver archiveRootObject:toFile] to serialize the list to disk.
I want NSKeyedArchiver to ignore all objects of type ClassB.
I dont want to iterate though the list and remove all ClassB objects, as I want to keep the original list in memory.
You can either subclass NSArray and override the -encodeWithCoder: method or copy and filter the original and then archive the copy rather than the original.

How to store custom object in User Defaults - IOS

I created one custom class & created object for that class. I want to store that object into NSUserDefault. I am getting error while set the object into userfaults. How can I set?
You have to implement the NSCoding protocol in your class & implement the protocols methods.
This is simply serialization. While storing the object you should serialize(NSKeyedArchiver) the class & same as retrieval you should unserialize(NSKeyedUnArchiver) that object.
the methods are
(void)encodeWithCoder:(NSCoder *)aCoder;
(id)initWithCoder:(NSCoder *)aDecoder;
As the documentation states:
A default object must be a property list, that is, an instance of (or
for collections a combination of instances of): NSData, NSString,
NSNumber, NSDate, NSArray, or NSDictionary. If you want to store any
other type of object, you should typically archive it to create an
instance of NSData.
The simplest way of creating an instance of NSData is by using an NSKeyedArchiver.
The most probably reason is that you have something hard to archive in your structure.
Here is a quote from the NSUserDefaults Class Reference that you might find useful:
The NSUserDefaults class provides convenience methods for accessing common types such as floats, doubles, integers, Booleans, and URLs. A default object must be a property list, that is, an instance of (or for collections a combination of instances of): NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary. If you want to store any other type of object, you should typically archive it to create an instance of NSData. For more details, see Preferences and Settings Programming Guide.
Edit.
Beaten to the punch by Stephen, give the man a prize :)

Resources