Exporting from Core Data on iOS

exporting_from_core_dataimgSo, I’m working on the latest release of our scrapbooking app (Coolibah) and I needed to export some objects that are stored in SQLLite through Core Data to my server. After googling around for a while (and finding not much, it seems like search results have started to really suck lately) I had to strike out on my own and work something up. I got to use a very cool Objective C feature that I’ve only recently discovered: categories.

I was able to extend the NSManagedObject class and add a new xmlString property. By using the entity property to do some simple introspection, I was able to write a serialization function in about 50 lines of code. Enjoy!

NSManagedObject+XMLSync.h

//
//  Created by Scott Means on 1/5/11.
//  Released into the public domain without warranty.
#import <CoreData/CoreData.h>
#import <Foundation/Foundation.h>

@interface NSManagedObject (XMLSync)

@property (nonatomic, readonly) NSString *xmlString;

@end

NSManagedObject+XMLSync.m

//
//  Created by Scott Means on 1/5/11.
//  Released into the public domain without warranty.

#import "NSManagedObject+XMLSync.h"

@implementation NSManagedObject (XMLSync)

- (NSString *)xmlString
{
        NSEntityDescription *ed = self.entity;
        NSURL *uri = self.objectID.URIRepresentation;
        NSMutableString *x = [NSMutableString stringWithFormat:@"<%@ id=\"/%@%@\"",
                ed.name, uri.host, uri.path];

        for (NSString *a in ed.attributesByName.allKeys) {
                id value = [self valueForKey:a];

                if (value) {
                        if ([value isKindOfClass:[NSString class]]) {
                                [x appendFormat:@" %@=\"%@\"", a, value];
                        } else {
                                if (![value respondsToSelector:@selector(stringValue)]) {
                                        NSLog(@"no stringValue");
                                }
                                [x appendFormat:@" %@=\"%@\"", a, [value stringValue]];
                        }
                }
        }

        bool hasChildren = NO;

        for (NSString *r in ed.relationshipsByName) {
                if (!hasChildren) {
                        [x appendString:@"/>"];
                        hasChildren = YES;
                }

                NSRelationshipDescription *rd = [ed.relationshipsByName objectForKey:r];

                if (rd.isToMany) {
                        hasChildren = YES;
                        [x appendFormat:@"<%@>", r];

                        for (NSManagedObject *c in [self valueForKey:r]) {
                                [x appendString:c.xmlString];
                        }

                        [x appendFormat:@"", r];
                }
        }

        if (hasChildren) {
                [x appendFormat:@"", ed.name];
        }

        return x;
}

@end

Next project: figure out how to do better code formatting in WordPress!

Leave a Reply

Your email address will not be published. Required fields are marked *