Exporting from Core Data on iOS.

So, 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!

About smeans
I'm trying to be a Renaissance man in an age of specialization. I'm a father, a writer, a programmer, a lover, and a fighter. I'm trying real hard to be the shepard, but sometimes I'm afraid that I am the tyranny of evil men. You get a cookie if you recognize the movie reference :-)

Comments are closed.