patternMinor
Parsing NSDictionary from NSJSONSerialization
Viewed 0 times
fromnsdictionaryparsingnsjsonserialization
Problem
playerObject is an NSDictionary from JSONObjectWithData:options:error.I'm trying to update a
CoreData entity.if ([results count] > 0)
{
newPlayer = (Player *)[results objectAtIndex:0];
} else {
//Add a new player
newPlayer = [NSEntityDescription insertNewObjectForEntityForName:@"Player" inManagedObjectContext:temporaryContext];
}
//Assume these exist and are not null
newPlayer.email = [playerObject objectForKey:@"email"];
newPlayer.username = [playerObject objectForKey:@"username"];
newPlayer.continent = [playerObject objectForKey:@"continent"];
//Dates
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:@"yyyy-MM-dd hh:mm:ss"];
newPlayer.created = [df dateFromString: [playerObject objectForKey:@"created"]];
//Optional properties
if ([[playerObject objectForKey:@"title"] isKindOfClass:[NSNull class]])
{
newPlayer.title = nil;
} else {
newPlayer.title = [[playerObject objectForKey:@"title"] stringValue];
}Is there any way to make it less verbose? Have I left myself open to any issues?
Solution
if ([results count] > 0)
{
newPlayer = (Player *)[results objectAtIndex:0];
} else {
//Add a new player
newPlayer = [NSEntityDescription insertNewObjectForEntityForName:@"Player" inManagedObjectContext:temporaryContext];
}This chunk of code could be replaced with:
newPlayer = (Player *)([results firstObject] ?: [NSEntityDescription insertNewObjectForEntityForName:@"Player" inManagedObjectContext:temporaryContext]);if ([[playerObject objectForKey:@"title"] isKindOfClass:[NSNull class]])
{
newPlayer.title = nil;
} else {
newPlayer.title = [[playerObject objectForKey:@"title"] stringValue];
}This chunk of code could also be slightly better.
NSString *newTitle = playerObject[@"title"];
newPlayer.title = [newTitle isEqual:[NSNull null]] ? nil : [newTitle stringValue];The last comment that I'll make is a strong recommendation that you use constants for your keys rather than literal strings. Defined constants will auto-complete for you, which is nice, but more importantly, it will eliminate misspellings entirely.
static NSString * const kKey_Player = @"Player";
static NSString * const kKey_Title = @"title";
// etc.Then use it as such:
NSString *newTitle = playerObject[kKey_Title];Under the covers, this actually doesn't change in the slightest what the code does. Even when you use string literals, a memory location is still allocated for them. The advantage here is that you eliminate programmer mistakes.
Code Snippets
if ([results count] > 0)
{
newPlayer = (Player *)[results objectAtIndex:0];
} else {
//Add a new player
newPlayer = [NSEntityDescription insertNewObjectForEntityForName:@"Player" inManagedObjectContext:temporaryContext];
}newPlayer = (Player *)([results firstObject] ?: [NSEntityDescription insertNewObjectForEntityForName:@"Player" inManagedObjectContext:temporaryContext]);if ([[playerObject objectForKey:@"title"] isKindOfClass:[NSNull class]])
{
newPlayer.title = nil;
} else {
newPlayer.title = [[playerObject objectForKey:@"title"] stringValue];
}NSString *newTitle = playerObject[@"title"];
newPlayer.title = [newTitle isEqual:[NSNull null]] ? nil : [newTitle stringValue];static NSString * const kKey_Player = @"Player";
static NSString * const kKey_Title = @"title";
// etc.Context
StackExchange Code Review Q#15059, answer score: 2
Revisions (0)
No revisions yet.