简体   繁体   中英

Converting a NSObject into NSData

I am having an issue in converting a NSObject into NSData . I have a class which inherits NSObject .

When i tried to convert the object of that particular class into NSData as follows :

NSData *dataOnObject = [NSKeyedArchiver archivedDataWithRootObject:classObject];

but it gives out exception stating that -[classObject encodeWithCoder:]: unrecognized selector sent to instance ..

I have also added the object to a newly created array as

NSMutableArray *wrapperedData = [NSMutableArray arrayWithObject: classObject];
NSData *dataOnObject = [NSKeyedArchiver archivedDataWithRootObject:value];

But still , its giving out exception.

So I need to extract the bytes from the object classObject .

Any help would be greatly appreciated ...

awaiting for your reply ...

You must implement for your own object such as:

- (void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:self.name forKey:@"name"];
    [aCoder encodeInt:self.age forKey:@"age"];
    [aCoder encodeObject:self.email forKey:@"email"];
    [aCoder encodeObject:self.password forKey:@"password"];
}
BOOL success = [NSKeyedArchiver archiveRootObject:person toFile:archiveFilePath];

and:

- (id)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super init]) {
        self.name = [aDecoder decodeObjectForKey:@"name"];
        self.age = [aDecoder decodeIntForKey:@"age"];
        self.email = [aDecoder decodeObjectForKey:@"email"];
        self.password = [aDecoder decodeObjectForKey:@"password"];
    }
    return self;
}
Person *unarchivePerson = [NSKeyedUnarchiver unarchiveObjectWithFile:archiveFilePath];

You need to implement encodeWithCoder: on your custom class, serializing all of its attributes using the NSCoder passed into it. If its attributes include any more custom classes, they'll need encodeWithCoder: implementing too.

Instead of

NSData *dataOnObject = [NSKeyedArchiver archivedDataWithRootObject:classObject];

it should be

NSData *dataOnObject = [[NSUserDefaults standardUserDefaults] objectForKey:@"someKey"];

But that's just for reading data in that's already been saved. If you want to save an object as NSData then you have this:

[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:classObject] forKey:@"someKey"];

But that's not all. Your classObject has to implement the NSCoding protocol and have the two methods encodeWithCoder: and initWithCoder: since it's not an NS object in order for it to work.

您只能归档支持NSCoding协议的NSCoding

You can convert any object to NSData with the NSCoding protocol.

You can find sample code to do this here:
http://samsoff.es/posts/archiving-objective-c-objects-with-nscoding

This is a example of custom object converted to NSData (so it can be then saved into user defaults)

Create the following files:

Catalog.h

@interface Catalog : NSObject

@property (nonatomic, assign) int pk;
@property (nonatomic, copy) NSString *catalogName;
@property (nonatomic, copy) NSString *catalogDescription;
@property (nonatomic, assign) int catalogEdition;
@property (nonatomic, assign) int catalogTotalPages;

- (void)encodeWithCoder:(NSCoder *)aCoder;
- (id)initWithCoder:(NSCoder *)aDecoder;

@end

Catalog.m

#import <Foundation/Foundation.h>
#import "Catalog.h"

@implementation Catalog

- (void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:self.catalogName forKey:@"catalogName"];
    [aCoder encodeObject:self.catalogDescription forKey:@"catalogDescription"];
    [aCoder encodeInt:self.catalogEdition forKey:@"catalogEdition"];
    [aCoder encodeInt:self.catalogTotalPages forKey:@"catalogTotalPages"];
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super init]) {
        self.catalogName = [aDecoder decodeObjectForKey:@"catalogName"];
        self.catalogDescription = [aDecoder decodeObjectForKey:@"catalogDescription"];
        self.catalogEdition = [aDecoder decodeIntForKey:@"catalogEdition"];
        self.catalogTotalPages = [aDecoder decodeIntForKey:@"catalogTotalPages"];
    }
    return self;
}

@end

Finally in your controller include header files

#import "Catalog.h"

And add this code to use your object (in this case im saving into user defaults)

            Catalog *catalog = [[Catalog alloc] init];
            catalog.catalogName = @"catalogName";
            catalog.catalogDescription = @"catalogName";
            catalog.catalogEdition = 1;

NOTE: in this line of code is where the actual data passing is taking place

//archiving object to nsdata
NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:catalog];

[[NSUserDefaults standardUserDefaults] setObject:encodedObject forKey:@"keyName"];
[[NSUserDefaults standardUserDefaults] synchronize];

In case you want to get your object back from NSData

NSData *nsData = [[NSUserDefaults standardUserDefaults] objectForKey:@"keyName"];
//unarchiving object to nsdata
Catalog *selectedCatalog = [NSKeyedUnarchiver unarchiveObjectWithData: nsData];

Hope this helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM