From ee9994c2c851470af4cf1fdda94b4cf67afd0d2a Mon Sep 17 00:00:00 2001 From: Tom Hicks Date: Sat, 12 Sep 2020 03:08:10 -0700 Subject: [PATCH] Adds meta string to monster cards. Implements meta method in Monster to return a formatted meta string. Adds size to edit monster. Moves monster copy logic to copyFromMonster in the Monster class. Fixes JSON parsing to set strings to an empty string if they're missing from the json blob. Makes Monster.size default to an empty string instead of null. Cleans up some raw strings to use NSLocalizedString instead. --- MonsterCards/Base.lproj/Main.storyboard | 18 ++++++++++- MonsterCards/Models/Monster.h | 2 ++ MonsterCards/Models/Monster.m | 31 +++++++++++++++++-- .../MonsterCards.xcdatamodel/contents | 2 +- .../Views/EditMonsterViewController.m | 21 ++++++++++--- MonsterCards/Views/LibraryViewController.m | 2 +- MonsterCards/Views/MonsterViewController.h | 1 + MonsterCards/Views/MonsterViewController.m | 6 ++++ MonsterCardsTests/Models/MonsterTests.m | 18 ++++++++++- 9 files changed, 91 insertions(+), 10 deletions(-) diff --git a/MonsterCards/Base.lproj/Main.storyboard b/MonsterCards/Base.lproj/Main.storyboard index b0017d5..795f07a 100644 --- a/MonsterCards/Base.lproj/Main.storyboard +++ b/MonsterCards/Base.lproj/Main.storyboard @@ -190,7 +190,20 @@ + + + + + + + + @@ -200,6 +213,9 @@ + + + @@ -276,7 +292,7 @@ - + diff --git a/MonsterCards/Models/Monster.h b/MonsterCards/Models/Monster.h index 290f5e2..b4bbcf6 100644 --- a/MonsterCards/Models/Monster.h +++ b/MonsterCards/Models/Monster.h @@ -63,6 +63,8 @@ NS_ASSUME_NONNULL_BEGIN -(id)initWithJSONString:(NSString*)jsonString andContext:(NSManagedObjectContext*)context; -(id)initWithJSONData:(NSData*)jsonData andContext:(NSManagedObjectContext*)context; -(id)initWithMonster:(Monster*)monster; +-(void)copyFromMonster:(Monster*)monster; + -(NSString*)meta; -(int)abilityScoreForAbilityScoreName: (NSString*)abilityScoreName; -(int)abilityModifierForAbilityScoreName: (NSString*)abilityScoreName; diff --git a/MonsterCards/Models/Monster.m b/MonsterCards/Models/Monster.m index d8bcf55..258e266 100644 --- a/MonsterCards/Models/Monster.m +++ b/MonsterCards/Models/Monster.m @@ -7,6 +7,7 @@ // #import "Monster.h" +#import "StringHelper.h" @implementation Monster @@ -54,6 +55,7 @@ self = [super init]; self.name = @""; + self.size = @""; return self; } @@ -69,7 +71,8 @@ NSDictionary *jsonRoot = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil]; - self.name = [jsonRoot objectForKey:@"name"]; + self.name = [jsonRoot objectForKey:@"name"] ?: @""; + self.size = [jsonRoot objectForKey:@"size"] ?: @""; return self; } @@ -83,7 +86,26 @@ } -(NSString*)meta { - @throw [[NSException alloc] initWithName:@"unimplemented" reason:@"Method not implemented." userInfo:nil]; + //"${size} ${type} (${subtype}) ${alignment}" + + NSMutableArray *parts = [NSMutableArray arrayWithCapacity:4]; + if (![StringHelper isStringNilOrEmpty:self.size]) { + [parts addObject:self.size]; + } + + if (![StringHelper isStringNilOrEmpty:self.type]) { + [parts addObject:self.type]; + } + + if (![StringHelper isStringNilOrEmpty:self.subtype]) { + [parts addObject:[NSString stringWithFormat:@"(%@)", self.subtype]]; + } + + if (![StringHelper isStringNilOrEmpty:self.alignment]) { + [parts addObject:self.alignment]; + } + + return [parts componentsJoinedByString:@" "]; } -(int)abilityScoreForAbilityScoreName: (NSString*)abilityScoreName { @@ -309,4 +331,9 @@ @throw [[NSException alloc] initWithName:@"unimplemented" reason:@"Method not implemented." userInfo:nil]; } +-(void)copyFromMonster:(Monster*)monster { + self.name = monster.name; + self.size = monster.size; +} + @end diff --git a/MonsterCards/MonsterCards.xcdatamodeld/MonsterCards.xcdatamodel/contents b/MonsterCards/MonsterCards.xcdatamodeld/MonsterCards.xcdatamodel/contents index f130f0b..f9229af 100644 --- a/MonsterCards/MonsterCards.xcdatamodeld/MonsterCards.xcdatamodel/contents +++ b/MonsterCards/MonsterCards.xcdatamodeld/MonsterCards.xcdatamodel/contents @@ -3,7 +3,7 @@ - + diff --git a/MonsterCards/Views/EditMonsterViewController.m b/MonsterCards/Views/EditMonsterViewController.m index fa6f4ad..4c0c276 100644 --- a/MonsterCards/Views/EditMonsterViewController.m +++ b/MonsterCards/Views/EditMonsterViewController.m @@ -41,7 +41,7 @@ [_context rollback]; } else if ([@"SaveChanges" isEqualToString:segue.identifier]) { // TODO: this should use a method on originalMonster to copy values from editingMonster or pass the new monster back some way. Core Data would save and probably trigger a refresh in the receiving view. - self.originalMonster.name = self.editingMonster.name; + [self.originalMonster copyFromMonster:self.editingMonster]; [_context refreshObject:self.editingMonster mergeChanges:NO]; [_context save:nil]; } else { @@ -59,7 +59,7 @@ // * Subtype // * Alignment - return 1; + return 2; } - (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath { @@ -76,9 +76,20 @@ } shortStringCell.delegate = self; shortStringCell.identifier = @"monster.name"; - // TODO: make these setters on EditableShortStringTableViewCell + // TODO: make these use setters on EditableShortStringTableViewCell shortStringCell.textField.text = self.editingMonster.name; - shortStringCell.textField.placeholder = @"Name"; + shortStringCell.textField.placeholder = NSLocalizedString(@"Name", @"Placeholder text for the name of a monster or NPC."); + return shortStringCell; + case 1: + shortStringCell = [self.monsterTableView dequeueReusableCellWithIdentifier:@"EditableShortString"]; + if (shortStringCell == nil) { + shortStringCell = [[EditableShortStringTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"EditableShortString"]; + } + shortStringCell.delegate = self; + shortStringCell.identifier = @"monster.size"; + // TODO: make these use setters on EditableShortStringTableViewCell + shortStringCell.textField.text = self.editingMonster.size; + shortStringCell.textField.placeholder = NSLocalizedString(@"Size", @"Placehodler text for the size of a monster or NPC."); return shortStringCell; } break; @@ -93,6 +104,8 @@ if ([@"String" isEqualToString:type]) { if ([@"monster.name" isEqualToString:identifier]) { self.editingMonster.name = (NSString*)value; + } else if ([@"monster.size" isEqualToString:identifier]) { + self.editingMonster.size = (NSString*)value; } } } diff --git a/MonsterCards/Views/LibraryViewController.m b/MonsterCards/Views/LibraryViewController.m index b80f958..69b781b 100644 --- a/MonsterCards/Views/LibraryViewController.m +++ b/MonsterCards/Views/LibraryViewController.m @@ -34,7 +34,7 @@ - (IBAction)addNewMonster:(id)sender { Monster *monster = [[Monster alloc] initWithContext:_context]; - monster.name = @"Unnamed Monster"; + monster.name = NSLocalizedString(@"Unnamed Monster", @"The default name of a new monster."); self.allMonsters = [self.allMonsters arrayByAddingObject:monster]; //DispatchQueue.main.async{"code here"} [_context save:nil]; diff --git a/MonsterCards/Views/MonsterViewController.h b/MonsterCards/Views/MonsterViewController.h index 33d6ca3..305ad8e 100644 --- a/MonsterCards/Views/MonsterViewController.h +++ b/MonsterCards/Views/MonsterViewController.h @@ -14,6 +14,7 @@ NS_ASSUME_NONNULL_BEGIN @interface MonsterViewController : UIViewController @property (weak, nonatomic) IBOutlet UILabel *monsterName; +@property (weak, nonatomic) IBOutlet UILabel *monsterMeta; @property Monster* monster; diff --git a/MonsterCards/Views/MonsterViewController.m b/MonsterCards/Views/MonsterViewController.m index 7e2a19c..33a0b66 100644 --- a/MonsterCards/Views/MonsterViewController.m +++ b/MonsterCards/Views/MonsterViewController.m @@ -35,6 +35,12 @@ self.navigationItem.title = self.monster.name; } } + NSString *metaText = self.monster.meta; + if (metaText == nil) { + self.monsterMeta.text = @""; + } else { + self.monsterMeta.text = metaText; + } } - (IBAction)unwindWithSegue:(UIStoryboardSegue *)unwindSegue { diff --git a/MonsterCardsTests/Models/MonsterTests.m b/MonsterCardsTests/Models/MonsterTests.m index f262cb2..58cd575 100644 --- a/MonsterCardsTests/Models/MonsterTests.m +++ b/MonsterCardsTests/Models/MonsterTests.m @@ -25,7 +25,7 @@ - (void)setUp { _context = nil; _monster = [[Monster alloc] initWithContext:_context]; - _jsonString = @"{\"name\":\"Acolyte\"}"; + _jsonString = @"{\"name\":\"Acolyte\",\"size\":\"large\"}"; _jsonData = [_jsonString dataUsingEncoding:NSUTF8StringEncoding]; } @@ -36,6 +36,7 @@ - (void)testDefaultInitializer { XCTAssertNotNil(_monster); XCTAssertEqualObjects(@"", _monster.name); + XCTAssertEqualObjects(@"", _monster.size); } - (void)testInitWithJSONString { @@ -43,13 +44,22 @@ XCTAssertNotNil(_monster); XCTAssertEqualObjects(@"Acolyte", _monster.name); + XCTAssertEqualObjects(@"large", _monster.size); } +- (void)testInitWithEmptyJSONString { + _monster = [[Monster alloc] initWithJSONString:@"{}" andContext:_context]; + + XCTAssertNotNil(_monster); + XCTAssertEqualObjects(@"", _monster.name); + XCTAssertEqualObjects(@"", _monster.size); +} - (void)testInitWithJSONData { _monster = [[Monster alloc] initWithJSONData:_jsonData andContext:_context]; XCTAssertNotNil(_monster); XCTAssertEqualObjects(@"Acolyte", _monster.name); + XCTAssertEqualObjects(@"large", _monster.size); } - (void)testNameGetterAndSetter { @@ -58,4 +68,10 @@ XCTAssertEqualObjects(name, _monster.name); } +- (void)testSizeGetterAndSetter { + NSString *size = @"huge"; + _monster.size = size; + XCTAssertEqualObjects(size, _monster.size); +} + @end