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.
This commit is contained in:
@@ -190,7 +190,20 @@
|
||||
<view key="view" contentMode="scaleToFill" id="skY-EN-baw">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pZa-ia-7UT">
|
||||
<rect key="frame" x="8" y="96" width="398" height="14.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="12"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
||||
<constraints>
|
||||
<constraint firstItem="WIX-Yu-LXJ" firstAttribute="trailing" secondItem="pZa-ia-7UT" secondAttribute="trailing" constant="8" id="8F1-nO-xrO"/>
|
||||
<constraint firstItem="pZa-ia-7UT" firstAttribute="leading" secondItem="WIX-Yu-LXJ" secondAttribute="leading" constant="8" id="9Yo-N3-VeP"/>
|
||||
<constraint firstItem="pZa-ia-7UT" firstAttribute="top" secondItem="WIX-Yu-LXJ" secondAttribute="top" constant="8" id="GZ7-bL-EbS"/>
|
||||
</constraints>
|
||||
<viewLayoutGuide key="safeArea" id="WIX-Yu-LXJ"/>
|
||||
</view>
|
||||
<navigationItem key="navigationItem" id="U0U-wB-eVJ">
|
||||
@@ -200,6 +213,9 @@
|
||||
</connections>
|
||||
</barButtonItem>
|
||||
</navigationItem>
|
||||
<connections>
|
||||
<outlet property="monsterMeta" destination="pZa-ia-7UT" id="QEV-cs-IEk"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="lvO-c7-FKV" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
@@ -276,7 +292,7 @@
|
||||
</scene>
|
||||
</scenes>
|
||||
<inferredMetricsTieBreakers>
|
||||
<segue reference="Ob1-Gh-ZDQ"/>
|
||||
<segue reference="W6E-7q-Wzb"/>
|
||||
</inferredMetricsTieBreakers>
|
||||
<resources>
|
||||
<image name="book.fill" catalog="system" width="128" height="100"/>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<entity name="Monster" representedClassName="Monster" syncable="YES" codeGenerationType="category">
|
||||
<attribute name="alignment" optional="YES" attributeType="String"/>
|
||||
<attribute name="name" attributeType="String" defaultValueString=""/>
|
||||
<attribute name="size" optional="YES" attributeType="String"/>
|
||||
<attribute name="size" optional="YES" attributeType="String" defaultValueString=""/>
|
||||
<attribute name="subtype" optional="YES" attributeType="String"/>
|
||||
<attribute name="type" optional="YES" attributeType="String"/>
|
||||
</entity>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user