gpt4 book ai didi

ios - 在 Core Data 中加载 csv 文件

转载 作者:行者123 更新时间:2023-11-29 10:54:27 25 4
gpt4 key购买 nike

当应用程序第一次运行时,我试图在核心数据中加载一个 csv 文件。在此处 ( What is the fastest way to load a large CSV file into core data ) 上找到的另一篇关于 stackoverflow 的帖子中,我找到了如何做到这一点。

我在我的 Controller 中使用与所提供函数相同的代码:populateDB,如果之前从未加载过数据(首次运行),我会调用该函数。然而,xcode 给我一个错误:

No visible @interface for ...Controller declares the selector persistentStoreCoordinator.

函数是:

-(void)populateDB{
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
NSManagedObjectContext *context;
if (coordinator != nil) {
context = [[NSManagedObjectContext alloc] init];
[context setPersistentStoreCoordinator:coordinator];
}

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"input" ofType:@"txt"];
if (filePath) {
NSString * myText = [[NSString alloc]
initWithContentsOfFile:filePath
encoding:NSUTF8StringEncoding
error:nil];
if (myText) {
__block int count = 0;


[myText enumerateLinesUsingBlock:^(NSString * line, BOOL * stop) {
line=[line stringByReplacingOccurrencesOfString:@"\t" withString:@" "];
NSArray *lineComponents=[line componentsSeparatedByString:@" "];
if(lineComponents){
if([lineComponents count]==3){
float f=[[lineComponents objectAtIndex:0] floatValue];
NSNumber *number=[NSNumber numberWithFloat:f];
NSString *string1=[lineComponents objectAtIndex:1];
NSString *string2=[lineComponents objectAtIndex:2];
NSManagedObject *object=[NSEntityDescription insertNewObjectForEntityForName:@"Bigram" inManagedObjectContext:context];
[object setValue:number forKey:@"number"];
[object setValue:string1 forKey:@"string1"];
[object setValue:string2 forKey:@"string2"];
NSError *error;
count++;
if(count>=1000){
if (![context save:&error]) {
NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
}
count=0;

}
}
}



}];
NSLog(@"done importing");
NSError *error;
if (![context save:&error]) {
NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
}

}
}
}

我在离开 3 年后再次拿起 iOS,之前我从未深入研究过 SDK 的这一部分。我将不胜感激对这个问题的任何帮助...

最佳答案

下面的代码向您展示了一个使用 Matt Gallagher 的类 CSVParser.h 并假设一个实体 MyEntity

在 Core Data 中加载 csv 文件的示例
    // CSV File input.csv and not input.txt separate by space @" "
CSVParser *csvParser = [[CSVParser alloc] initWithContentOfFile:[NSBundle mainBundle] pathForResource:@"input" ofType:@"csv" separator:@" "];

// Array with all your data from CSV
NSArray *data = [csvParser parseFile];

// Your entity from Core Data
MyEntity *myEntity = nil;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
for (NSDictionary *dic in data)
{
fetchRequest.entity = [NSEntityDescription entityForName:@"MyEntity" inManagedObjectContext:context];

if (!entity)
entity = [NSEntityDescription insertNewObjectForEntityForName:@"MyEntity"
inManagedObjectContext:context];

[entity setValue:number forKey:@"number"];
[entity setValue:string1 forKey:@"string1"];
[entity setValue:string2 forKey:@"string2"];
}

// Save the context
[managedObjectContext save:nil];

使用 ARC 的 CVSParser.h:

//
// CSVParser.h
// CSVImporter
//
// Created by Matt Gallagher on 2009/11/30.
// Copyright 2009 Matt Gallagher. All rights reserved.
//
// Permission is given to use this source code file, free of charge, in any
// project, commercial or otherwise, entirely at your risk, with the condition
// that any redistribution (in part or whole) of source code must retain
// this copyright and permission notice. Attribution in compiled projects is
// appreciated but not required.
//
// Source : http://cocoawithlove.com/2009/11/writing-parser-using-nsscanner-csv.html

@interface CSVParser : NSObject
{
NSString *csvString;
NSString *separator;
NSScanner *scanner;
BOOL hasHeader;
NSMutableArray *fieldNames;
id receiver;
SEL receiverSelector;
NSCharacterSet *endTextCharacterSet;
BOOL separatorIsSingleChar;
}

- (id)initWithString:(NSString *)aCSVString
separator:(NSString *)aSeparatorString;

- (id)initWithContentOfFile:(NSString *)aPath
separator:(NSString *)aSeparatorString;

- (id)initWithString:(NSString *)aCSVString
separator:(NSString *)aSeparatorString
hasHeader:(BOOL)header
fieldNames:(NSArray *)names;

- (id)initWithContentOfFile:(NSString *)aPath
separator:(NSString *)aSeparatorString
hasHeader:(BOOL)header
fieldNames:(NSArray *)names;

- (NSArray *)arrayOfParsedRows;
- (void)parseRowsForReceiver:(id)aReceiver selector:(SEL)aSelector;

- (NSArray *)parseFile;
- (NSMutableArray *)parseHeader;
- (NSDictionary *)parseRecord;
- (NSString *)parseName;
- (NSString *)parseField;
- (NSString *)parseEscaped;
- (NSString *)parseNonEscaped;
- (NSString *)parseDoubleQuote;
- (NSString *)parseSeparator;
- (NSString *)parseLineSeparator;
- (NSString *)parseTwoDoubleQuotes;
- (NSString *)parseTextData;

@end

使用 ARC 的 CVSParser.m:

//
// CSVParser.m
// CSVImporter
//
// Created by Matt Gallagher on 2009/11/30.
// Copyright 2009 Matt Gallagher. All rights reserved.
//
// Permission is given to use this source code file, free of charge, in any
// project, commercial or otherwise, entirely at your risk, with the condition
// that any redistribution (in part or whole) of source code must retain
// this copyright and permission notice. Attribution in compiled projects is
// appreciated but not required.
//

#import "CSVParser.h"


@implementation CSVParser

//
// initWithString:separator:hasHeader:fieldNames:
//
// Parameters:
// aCSVString - the string that will be parsed
// aSeparatorString - the separator (normally "," or "\t")
// header - if YES, treats the first row as a list of field names
// names - a list of field names (will have no effect if header is YES)
//
// returns the initialized object (nil on failure)
//
- (id)initWithString:(NSString *)aCSVString
separator:(NSString *)aSeparatorString
hasHeader:(BOOL)header
fieldNames:(NSArray *)names
{
self = [super init];
if (self)
{
csvString = [aCSVString retain];
separator = [aSeparatorString retain];

NSAssert([separator length] > 0 &&
[separator rangeOfString:@"\""].location == NSNotFound &&
[separator rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet]].location == NSNotFound,
@"CSV separator string must not be empty and must not contain the double quote character or newline characters.");

NSMutableCharacterSet *endTextMutableCharacterSet =
[[NSCharacterSet newlineCharacterSet] mutableCopy];
[endTextMutableCharacterSet addCharactersInString:@"\""];
[endTextMutableCharacterSet addCharactersInString:[separator substringToIndex:1]];
endTextCharacterSet = endTextMutableCharacterSet;

if ([separator length] == 1)
{
separatorIsSingleChar = YES;
}

hasHeader = header;
fieldNames = [names mutableCopy];
}

return self;
}

- (id)initWithString:(NSString *)aCSVString
separator:(NSString *)aSeparatorString
{
return [self initWithString:aCSVString
separator:aSeparatorString
hasHeader:YES
fieldNames:nil];
}

- (id)initWithContentOfFile:(NSString *)aPath
separator:(NSString *)aSeparatorString
{
return [self initWithString:[NSString stringWithContentsOfFile:aPath
encoding:NSUTF8StringEncoding
error:nil]
separator:aSeparatorString];
}

- (id)initWithContentOfFile:(NSString *)aPath
separator:(NSString *)aSeparatorString
hasHeader:(BOOL)header
fieldNames:(NSArray *)names
{
return [self initWithString:[NSString stringWithContentsOfFile:aPath
encoding:NSUTF8StringEncoding
error:nil]
separator:aSeparatorString
hasHeader:header
fieldNames:names];
}

//
// dealloc
//
// Releases instance memory.
//
- (void)dealloc
{
[csvString release];
[separator release];
[fieldNames release];
[endTextCharacterSet release];
[super dealloc];
}


//
// arrayOfParsedRows
//
// Performs a parsing of the csvString, returning the entire result.
//
// returns the array of all parsed row records
//
- (NSArray *)arrayOfParsedRows
{
scanner = [[NSScanner alloc] initWithString:csvString];
[scanner setCharactersToBeSkipped:[[[NSCharacterSet alloc] init] autorelease]];

NSArray *result = [self parseFile];
[scanner release];
scanner = nil;

return result;
}

//
// parseRowsForReceiver:selector:
//
// Performs a parsing of the csvString, sending the entries, 1 row at a time,
// to the receiver.
//
// Parameters:
// aReceiver - the target that will receive each row as it is parsed
// aSelector - the selector that will receive each row as it is parsed
// (should be a method that takes a single NSDictionary argument)
//
- (void)parseRowsForReceiver:(id)aReceiver selector:(SEL)aSelector
{
scanner = [[NSScanner alloc] initWithString:csvString];
[scanner setCharactersToBeSkipped:[[[NSCharacterSet alloc] init] autorelease]];
receiver = [aReceiver retain];
receiverSelector = aSelector;

[self parseFile];

[scanner release];
scanner = nil;
[receiver release];
receiver = nil;
}

//
// parseFile
//
// Attempts to parse a file from the current scan location.
//
// returns the parsed results if successful and receiver is nil, otherwise
// returns nil when done or on failure.
//
- (NSArray *)parseFile
{
scanner = [[NSScanner alloc] initWithString:csvString];
[scanner setCharactersToBeSkipped:[[[NSCharacterSet alloc] init] autorelease]];

if (hasHeader)
{
if (fieldNames)
{
[fieldNames release];
}

fieldNames = [[self parseHeader] retain];
if (!fieldNames || ![self parseLineSeparator])
{
return nil;
}
}

NSMutableArray *records = nil;
if (!receiver)
{
records = [NSMutableArray array];
}

NSDictionary *record = [[self parseRecord] retain];
if (!record)
{
return nil;
}

while (record)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

if (receiver)
{
[receiver performSelector:receiverSelector withObject:record];
}
else
{
[records addObject:record];
}
[record release];

if (![self parseLineSeparator])
{
break;
}

record = [[self parseRecord] retain];

[pool drain];
}

[scanner release];
scanner = nil;

return records;
}

//
// parseHeader
//
// Attempts to parse a header row from the current scan location.
//
// returns the array of parsed field names or nil on parse failure.
//
- (NSMutableArray *)parseHeader
{
NSString *name = [self parseName];
if (!name)
{
return nil;
}

NSMutableArray *names = [NSMutableArray array];
while (name)
{
[names addObject:name];

if (![self parseSeparator])
{
break;
}

name = [self parseName];
}
return names;
}

//
// parseRecord
//
// Attempts to parse a record from the current scan location. The record
// dictionary will use the fieldNames as keys, or FIELD_X for each column
// X-1 if no fieldName exists for a given column.
//
// returns the parsed record as a dictionary, or nil on failure.
//
- (NSDictionary *)parseRecord
{
//
// Special case: return nil if the line is blank. Without this special case,
// it would parse as a single blank field.
//
if ([self parseLineSeparator] || [scanner isAtEnd])
{
return nil;
}

NSString *field = [self parseField];
if (!field)
{
return nil;
}

NSInteger fieldNamesCount = [fieldNames count];
NSInteger fieldCount = 0;

NSMutableDictionary *record =
[NSMutableDictionary dictionaryWithCapacity:[fieldNames count]];
while (field)
{
NSString *fieldName;
if (fieldNamesCount > fieldCount)
{
fieldName = [fieldNames objectAtIndex:fieldCount];
}
else
{
fieldName = [NSString stringWithFormat:@"FIELD_%d", fieldCount + 1];
[fieldNames addObject:fieldName];
fieldNamesCount++;
}

[record setObject:field forKey:fieldName];
fieldCount++;

if (![self parseSeparator])
{
break;
}

field = [self parseField];
}

return record;
}

//
// parseName
//
// Attempts to parse a name from the current scan location.
//
// returns the name or nil.
//
- (NSString *)parseName
{
return [self parseField];
}

//
// parseField
//
// Attempts to parse a field from the current scan location.
//
// returns the field or nil
//
- (NSString *)parseField
{
NSString *escapedString = [self parseEscaped];
if (escapedString)
{
return escapedString;
}

NSString *nonEscapedString = [self parseNonEscaped];
if (nonEscapedString)
{
return nonEscapedString;
}

//
// Special case: if the current location is immediately
// followed by a separator, then the field is a valid, empty string.
//
NSInteger currentLocation = [scanner scanLocation];
if ([self parseSeparator] || [self parseLineSeparator] || [scanner isAtEnd])
{
[scanner setScanLocation:currentLocation];
return @"";
}

return nil;
}

//
// parseEscaped
//
// Attempts to parse an escaped field value from the current scan location.
//
// returns the field value or nil.
//
- (NSString *)parseEscaped
{
if (![self parseDoubleQuote])
{
return nil;
}

NSString *accumulatedData = [NSString string];
while (YES)
{
NSString *fragment = [self parseTextData];
if (!fragment)
{
fragment = [self parseSeparator];
if (!fragment)
{
fragment = [self parseLineSeparator];
if (!fragment)
{
if ([self parseTwoDoubleQuotes])
{
fragment = @"\"";
}
else
{
break;
}
}
}
}

accumulatedData = [accumulatedData stringByAppendingString:fragment];
}

if (![self parseDoubleQuote])
{
return nil;
}

return accumulatedData;
}

//
// parseNonEscaped
//
// Attempts to parse a non-escaped field value from the current scan location.
//
// returns the field value or nil.
//
- (NSString *)parseNonEscaped
{
return [self parseTextData];
}

//
// parseTwoDoubleQuotes
//
// Attempts to parse two double quotes from the current scan location.
//
// returns a string containing two double quotes or nil.
//
- (NSString *)parseTwoDoubleQuotes
{
if ([scanner scanString:@"\"\"" intoString:NULL])
{
return @"\"\"";
}
return nil;
}

//
// parseDoubleQuote
//
// Attempts to parse a double quote from the current scan location.
//
// returns @"\"" or nil.
//
- (NSString *)parseDoubleQuote
{
if ([scanner scanString:@"\"" intoString:NULL])
{
return @"\"";
}
return nil;
}

//
// parseSeparator
//
// Attempts to parse the separator string from the current scan location.
//
// returns the separator string or nil.
//
- (NSString *)parseSeparator
{
if ([scanner scanString:separator intoString:NULL])
{
return separator;
}
return nil;
}

//
// parseLineSeparator
//
// Attempts to parse newline characters from the current scan location.
//
// returns a string containing one or more newline characters or nil.
//
- (NSString *)parseLineSeparator
{
NSString *matchedNewlines = nil;
[scanner
scanCharactersFromSet:[NSCharacterSet newlineCharacterSet]
intoString:&matchedNewlines];
return matchedNewlines;
}

//
// parseTextData
//
// Attempts to parse text data from the current scan location.
//
// returns a non-zero length string or nil.
//
- (NSString *)parseTextData
{
NSString *accumulatedData = [NSString string];
while (YES)
{
NSString *fragment;
if ([scanner scanUpToCharactersFromSet:endTextCharacterSet intoString:&fragment])
{
accumulatedData = [accumulatedData stringByAppendingString:fragment];
}

//
// If the separator is just a single character (common case) then
// we know we've reached the end of parseable text
//
if (separatorIsSingleChar)
{
break;
}

//
// Otherwise, we need to consider the case where the first character
// of the separator is matched but we don't have the full separator.
//
NSUInteger location = [scanner scanLocation];
NSString *firstCharOfSeparator;
if ([scanner scanString:[separator substringToIndex:1] intoString:&firstCharOfSeparator])
{
if ([scanner scanString:[separator substringFromIndex:1] intoString:NULL])
{
[scanner setScanLocation:location];
break;
}

//
// We have the first char of the separator but not the whole
// separator, so just append the char and continue
//
accumulatedData = [accumulatedData stringByAppendingString:firstCharOfSeparator];
continue;
}
else
{
break;
}
}

if ([accumulatedData length] > 0)
{
return accumulatedData;
}

return nil;
}

@end

关于ios - 在 Core Data 中加载 csv 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19039361/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com