实现NSCoding协议以将对象发送到基于Java的服务器

时间:2014-03-23 22:38:38

标签: objective-c xml-serialization nskeyedarchiver nscoding

我几天前问了一个类似的问题...... 虽然我取得了一些进展,但我似乎仍然无法使其发挥作用。

这是我到现在为止所做的:

customWriteableObj.h:

@interface customWriteableObj : NSObject <NSCoding>
@property int integer;
@property NSString * string;
@property BOOL boo;
@end

customWriteableObj.m:

#import "customWriteableObj.h"

@implementation customWriteableObj
-(id)init
{
    _integer = 117;
    _string = @"aString";
    _boo = YES;
    return self;
}
-(id)initWithCoder:(NSCoder *)aDecoder
{
    _integer = [aDecoder decodeIntForKey:@"integer"];
    _boo = [aDecoder decodeBoolForKey:@"boo"];
    _string = [aDecoder decodeObjectForKey:@"string"];
    return self;
}

-(void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:self.string forKey:@"string"];
    [aCoder encodeBool:self.boo forKey:@"boo"];
    [aCoder encodeInteger:self.integer forKey:@"integer"];
}
@end

主:

customWriteableObj * x = [[customWriteableObj alloc]init];
    NSMutableData *dat = [[NSMutableData alloc] init];
    NSKeyedArchiver* arch1 = [[NSKeyedArchiver alloc]initForWritingWithMutableData:dat];
    arch1.outputFormat = NSPropertyListXMLFormat_v1_0;
    [arch1 encodeObject:x forKey:@"tester1"];
    [arch1 finishEncoding];

    [dat writeToFile:@"text.xml";
    customWriteableObj * y = [[customWriteableObj alloc]init];
    y = [NSKeyedUnarchiver unarchiveObjectWithFile:@"text.xml";

XML输出:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>$archiver</key>
    <string>NSKeyedArchiver</string>
    <key>$objects</key>
    <array>
        <string>$null</string>
        <dict>
            <key>$class</key>
            <dict>
                <key>CF$UID</key>
                <integer>3</integer>
            </dict>
            <key>boo</key>
            <true/>
            <key>integer</key>
            <integer>117</integer>
            <key>string</key>
            <dict>
                <key>CF$UID</key>
                <integer>2</integer>
            </dict>
        </dict>
        <string>aString</string>
        <dict>
            <key>$classes</key>
            <array>
                <string>customWriteableObj</string>
                <string>NSObject</string>
            </array>
            <key>$classname</key>
            <string>customWriteableObj</string>
        </dict>
    </array>
    <key>$top</key>
    <dict>
        <key>tester1</key>
        <dict>
            <key>CF$UID</key>
            <integer>1</integer>
        </dict>
    </dict>
    <key>$version</key>
    <integer>100000</integer>
</dict>
</plist>

这似乎不正确,因为我在这里看不到任何数据,而且,当我试着读回来时,我得到一个零! 我还需要将此对象持久保存到基于java的服务器上的数据库......

2 个答案:

答案 0 :(得分:1)

看起来很正确。在XML中,您可以看到117aString值。 XML是一种自定义格式,因此您通常不应该尝试将其用于存储和重新加载以外的任何其他内容。

当您尝试重新加载存档时,您的结果对象是nil,因为您的重新加载与归档不同(在结构方面)。如果您使用[arch1 encodeObject:x forKey:@"tester1"];进行存档,则需要使用initForReadingWithData:decodeObjectForKey:取消归档。

答案 1 :(得分:1)

一眼就看出你错过了init方法中的super次调用。这意味着您覆盖了这些初始化方法,并且从未实际初始化对象。因此,当您反序列化时,您最终会得到nil。这应该解决它:

-(id)init
{
   if(self = [super init])
   {
        _integer = 117;
        _string = @"aString";
        _boo = YES;
   }
   return self;
}

-(id)initWithCoder:(NSCoder *)aDecoder
{
    if(self = [self init])
    {
        _integer = [aDecoder decodeIntForKey:@"integer"];
        _boo = [aDecoder decodeBoolForKey:@"boo"];
        _string = [aDecoder decodeObjectForKey:@"string"];
    }
    return self;
}

使用JSON序列化示例进行编辑

在自定义对象类上创建一个方法,将对象转换为可序列化的字典。它可能看起来像:

- (NSDictionary *) jsonDictionary
{
    return @{@"integer": @(_integer), @"boo": @(_boo), @"string" : _string};
}

然后只要您准备好发送它们,就可以迭代地调用数组中的所有对象。这可能看起来像:

// Assuming you have an NSArray called customObjects

NSMutableArray *customObjectsJSON = [[NSMutableArray alloc] initWithCapacity:customObjects.count];
for(customWriteableObj *object in customObjects)
{
    [customObjectsJSON addObject:[object jsonDictionary]];
}

此时,customObjectsJSON已准备好设置为网络请求的参数。根据您使用的其他工具,您可能需要使用NSJSONSerialization

将其转换为JSON