简体   繁体   English

在xCode中解析嵌套的NSDictionary和NSArray数据

[英]Parsing Nested NSDictionary and NSArray Data in xCode

I have a complex JSON file that I need to parse into a CoreData table. 我有一个复杂的JSON文件,需要将其解析为CoreData表。 Currently, I capture the data into an NSArray with this format and the following 6 elements: 当前,我使用这种格式和以下6个元素将数据捕获到NSArray中:

 2013-08-29 10:54:04.930 iTrackTest[1542:c07] athleteRecords[0]: @SchoolID
 2013-08-29 10:54:04.930 iTrackTest[1542:c07] athleteRecords[1]: @LastName
 2013-08-29 10:54:04.930 iTrackTest[1542:c07] athleteRecords[2]: @Gender
 2013-08-29 10:54:04.931 iTrackTest[1542:c07] athleteRecords[3]: SchType
 2013-08-29 10:54:04.931 iTrackTest[1542:c07] athleteRecords[4]: @FirstName
 2013-08-29 10:54:04.931 iTrackTest[1542:c07] athleteRecords[5]: @IDAthlete

First question, it appears that SchType is a k-dimensional NSArray of NSDictionaries. 第一个问题,似乎SchType是NSDictionaries的k维NSArray。 Is that true? 真的吗?

I have been capturing simpler, single-tiered JSON files using code from Paul Hegarty of Stanford: 我一直在使用斯坦福大学的Paul Hegarty的代码捕获更简单的单层JSON文件:

 dispatch_async(fetchQ, ^{
    NSArray *athleteRecords;
    athleteRecords = [AthleticNetDataFetcher retrieveDataForAthleteWithID:athleteID];
    NSLog(@"In %@: athleteRecords has %d records",NSStringFromClass([self class]), [athleteRecords count]);
    NSLog(@"NSArray with athleteRecords: %@", athleteRecords);

    [document.managedObjectContext performBlock:^{ 
        int iCount=0;
        for (NSDictionary *athleteInfo in athleteRecords) {
            [self resultsWithAthleteInfoForAthleteWithID:athleteInfo inManagedObjectContext:document.managedObjectContext];
            NSLog(@"athleteRecords[%d]: %@", iCount, athleteInfo);
            iCount++;
        }
        [document saveToURL:document.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:NULL];

    }];
});

I need data elements from each node for every record in my CoreData table. 我需要CoreData表中每个记录的每个节点的数据元素。 For example, SchoolName from School node, IDSeason from Season node, and all elements from Results node would be written to a single CoreData table row (record). 例如,来自School节点的SchoolName,来自Season节点的IDSeason以及来自Results节点的所有元素都将被写入单个CoreData表行(记录)。

Do I need to resort to dot notation and abandon the iteration through the NSArray or do I need to capture multiple NSArrays each with data further down the nodes? 我是否需要求助于点符号并放弃通过NSArray进行的迭代,还是需要捕获多个NSArray,每个NSArray的数据都位于节点下方? Having a hard time getting my head around this. 很难解决这个问题。

Thanks! 谢谢!

Not sure why I had such a difficult time getting my head around this, but Hot Licks got me on the right track. 不知道为什么我很难解决这个问题,但是Hot Licks让我步入正轨。

Here is what I learned that might be helpful to others: 这是我了解到的可能对其他人有用的知识:

If you have multiple NSDictionaries embedded within an array, it is much simpler to parse these sub-dictionaries in other methods. 如果您在一个数组中嵌入了多个NSDictionaries,则使用其他方法解析这些子字典要简单得多。

+(void)parseDivisionBranches:(NSDictionary *)schTypeDictionary usingStudentInfoFrom:(NSDictionary *)myAthleteInfo
          intoManagedDoc: (UIManagedDocument *)document
{

NSArray* schoolDivisions = [self wrapDictionaryInArrayIfNecessary:[schTypeDictionary valueForKeyPath:@"School.SchoolDivision"]];

for (NSDictionary* schoolDivision in schoolDivisions) {

        [MarksFromMeets  parseDictionaryWithXcMarksForAthlete:(NSString*) [myAthleteInfo objectForKey:@"athlete_ID"]
                                     fromDictionary:(NSDictionary *)schoolDivision
                                     intoThisManagedDoc:(UIManagedDocument *)document];
    }
}

In instances where only a single NSDictionary is passed at a particular level of the tree, it is simpler to embed that NSDictionary inside an NSArray so that you can use the same code to extract data; 在树的特定级别仅传递一个NSDictionary的实例中,将NSDictionary嵌入到NSArray中比较容易,这样您就可以使用相同的代码来提取数据。 therefore, I always check to see if have an NSArray or NSDict. 因此,我总是检查是否有NSArray或NSDict。

+ (NSArray*) wrapDictionaryInArrayIfNecessary:(NSObject*)dictionaryMasquaradingAsAnArray

{ NSMutableArray* newArray = [[NSMutableArray alloc] init]; {NSMutableArray * newArray = [[NSMutableArray alloc] init];

if([dictionaryMasquaradingAsAnArray isKindOfClass:[NSArray class]]) {
        newArray = [dictionaryMasquaradingAsAnArray copy];
    }else if([dictionaryMasquaradingAsAnArray isKindOfClass:[NSDictionary class]]) {
        [newArray addObject:dictionaryMasquaradingAsAnArray];
    }else {
        NSString *className = NSStringFromClass([dictionaryMasquaradingAsAnArray class]);
        NSLog(@"ERROR - dictionaryMasquaradingAsAnArray of %@ class", className);
        newArray = nil;
    }
return newArray;
}

Then parse each sub-dictionary in turn by calling the method associated with the branch of the data tree, in this case: 然后通过调用与数据树的分支关联的方法依次解析每个子词典,在这种情况下:

+ (void)parseDictionaryWithXcMarksForAthlete:(NSString*)withAthleteID
                            fromDictionary:(NSDictionary *)dictionary
                        intoThisManagedDoc:(UIManagedDocument *)document
{

NSArray* seasons = [self wrapDictionaryInArrayIfNecessary:[dictionary valueForKeyPath:@"Season"]];

BOOL* parsedSeasonData;
    for (NSDictionary* season in seasons) {
    parsedSeasonData = [self parseDictionaryWithSeasonsListings:(NSString*)withAthleteID
                                                 fromDictionary:(NSDictionary *)season
                                             intoThisManagedDoc:(UIManagedDocument *)document];

    }

}

At some nodes, I had to capture data and pass it along down the chain for use later when I would ultimately write a record to CoreData. 在某些节点上,我必须捕获数据并将其沿链向下传递以供以后最终将记录写入CoreData时使用。 Again, thanks to Hot Licks and hope this helps others. 再次感谢Hot Licks,并希望这对其他人有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM