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!
