We want to import a huge XML-file (13MB) to Core Data. At the moment, the XML-File includes around 64000 entries, but this number will increase in future.
XML-Structure:
<entry name='...' doctype='' last-modified='...' [some more attributes] />
After a lot of research which included the XMLSchema Sample Project, Ray Wenderlich XML Tutorial and some stackoverflow entries, we didn't found a solution yet.
We first download the XML-File, and afterwards start parsing and insert the data to CoreData
Here is our implementation:
- (void)importXMLFile:(NSString*)fileName {
NSInputStream* theStream = [[NSInputStream alloc] initWithFileAtPath:fileName];
_theParser = [[NSXMLParser alloc] initWithStream:theStream];
_theParser.delegate = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
[_theParser parse];
});
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
if ([elementName isEqualToString:@"entry"]) {
Importer* __weak weakSelf = self;
NSManagedObjectContext* theContext = self.importContext;
[theContext performBlock:^{
CustomObject* mo;
// Create ManagedObject
// Read values from parsed XML element
dispatch_async(dispatch_get_main_queue(), ^{
// Call a handler, just for information "added object"
});
NSError *error = nil;
if ([theContext hasChanges] && ![theContext save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
} else {
DLOGError(error);
}
}];
}
}
Using this methods, memory usage explodes leading to a crash. The XML file seems to be parsed completely before even one block is being processed by Core Data
. So the question is:
Is it possible to process parts of the XML file (f.e. 30 entries a time), than save to CoreData
and after that continue parsing?
Or more commonly asked: How can memory usage be optimized?