I'm in the midst of writing a data import routine for an iPad application. It seems to be working fine. However, because I'm an IOS noob and coming from an application development background in which such tasks are handled via calls to an SQL server, I'm feeling the need to double-check if I'm using the correct approach.
Here is the basic approach I'm using to import data into one of my master data entities:
// SET UP SOME VARIABLES/VALUES APPLICABLE TO ALL IMPORTS
NSStringEncoding encoding = 1;
NSNumberFormatter* numberFormatter = [[NSNumberFormatter alloc] init];
NSString* file = nil;
NSError* error = nil;
NSArray* records = nil;
NSArray* fields = nil;
NSPredicate* predicate = nil;
NSArray* filteredArray = nil;
// IMPORT GEO DATA
// ProvinceState
file = [[NSBundle bundleForClass:[self class]] pathForResource:@"ProvinceState" ofType:@"txt"];
error = nil;
records = [NSArray arrayWithContentsOfCSVFile:file usedEncoding:&encoding error:&error];
NSManagedObject* provinceState = nil;
NSMutableArray* provinceStateArray = [NSMutableArray arrayWithCapacity:[records count]];
for (int i = 0; i < [records count]; ++i)
{
fields = [records objectAtIndex:i];
if ([fields count] == 2)
{
provinceState = [NSEntityDescription insertNewObjectForEntityForName:@"ProvinceState" inManagedObjectContext:self.managedObjectContext];
[provinceState setValue: [nu开发者_开发知识库mberFormatter numberFromString:[fields objectAtIndex:0]] forKey:@"id"];
[provinceState setValue:[fields objectAtIndex:1] forKey:@"name"];
[provinceStateArray addObject:provinceState];
}
}
A couple of key points. This particular entity is very simple - just an integer id and a string name. Its source table is a simple csv file. The method arrayWithContentsOfCSVFile:usedEncoding:error:
is from Dave Delong's excellent CHCSV parser, which makes parsing a breeze. I have not yet applied any error handling because I'm trying to work out the basic techniques first.
Okay, so unless you spot anything wrong with this simple code, I'll now get on with my main questions. The provinceStateArray referenced in the last meaningful line of the above code is to save myself the hassle of having to query the master data entities later on, when I need to populate them into the relationships of my transactional data. I realize this a) increases my memory requirements and b) prevents me, by implication, from draining the associated autoreleasepool, but since the half-dozen or so master data entities contain only a few hundred small objects in total, I didn't think this was a concern. Anyone think differently?
Now the part that does concern me. In the following code, which populates a Locations entity, I'm using these same master data entity arrays as follows:
file = [[NSBundle bundleForClass:[self class]] pathForResource:@"Location" ofType:@"txt"];
error = nil;
records = [NSArray arrayWithContentsOfCSVFile:file usedEncoding:&encoding error:&error];
NSManagedObject* location = nil;
NSMutableArray* locationArray = [NSMutableArray arrayWithCapacity:[records count]];
for (int i = 0; i < [records count]; ++i)
{
NSArray* fields = [records objectAtIndex:i];
if ([fields count] == 5)
{
location = [NSEntityDescription insertNewObjectForEntityForName:@"Location" inManagedObjectContext:self.managedObjectContext];
[location setValue: [numberFormatter numberFromString:[fields objectAtIndex:0]] forKey:@"id"];
predicate = [NSPredicate predicateWithFormat:@"id = %@", [numberFormatter numberFromString:[fields objectAtIndex:1]]];
filteredArray = [provinceStateArray filteredArrayUsingPredicate:predicate];
if ([filteredArray count] > 0)
{
[location setValue:[filteredArray objectAtIndex:0] forKey:@"provinceState"];
}
...and so on down through the other relationship entities that must be set.
This is the part - having to construct large quantities of objects simply to set the relationships - that feels foreign to me, even though I don't see any alternative.
Also, because the source data is from an RDBMS, I'm populating the one side of one-to-many relationships instead of iterating through sets.
Anything smell bad in all of this, or can I carry on with some comfort that I understand?
I think it is better to create SQLite database, import it to your project and import data from a file to that database(it is hard drive memory), not to arrays in RAM. Then, when your database is ready for use, make queries to it to populate only needed data for your user to iPhone RAM.
精彩评论