Skip to content

Commit 03d0886

Browse files
committed
Code formatting.
1 parent eb8c67b commit 03d0886

29 files changed

+177
-186
lines changed

KVC Validation Pattern/KVC Validation Pattern/CTCAppDelegate.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212

1313
@interface CTCAppDelegate : UIResponder <UIApplicationDelegate>
1414

15-
@property (strong, nonatomic) UIWindow *window;
16-
15+
@property (strong, nonatomic) UIWindow *window;
1716
@property (strong, nonatomic) CTCViewController *viewController;
1817

1918
@end

KVC Validation Pattern/KVC Validation Pattern/CTCAppDelegate.m

Lines changed: 5 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,46 +7,19 @@
77
//
88

99
#import "CTCAppDelegate.h"
10-
1110
#import "CTCViewController.h"
1211

1312
@implementation CTCAppDelegate
1413

15-
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
16-
{
14+
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
1715
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
18-
// Override point for customization after application launch.
16+
1917
self.viewController = [[CTCViewController alloc] initWithNibName:@"CTCViewController" bundle:nil];
18+
2019
self.window.rootViewController = self.viewController;
2120
[self.window makeKeyAndVisible];
21+
2222
return YES;
2323
}
2424

25-
- (void)applicationWillResignActive:(UIApplication *)application
26-
{
27-
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
28-
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
29-
}
30-
31-
- (void)applicationDidEnterBackground:(UIApplication *)application
32-
{
33-
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
34-
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
35-
}
36-
37-
- (void)applicationWillEnterForeground:(UIApplication *)application
38-
{
39-
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
40-
}
41-
42-
- (void)applicationDidBecomeActive:(UIApplication *)application
43-
{
44-
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
45-
}
46-
47-
- (void)applicationWillTerminate:(UIApplication *)application
48-
{
49-
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
50-
}
51-
52-
@end
25+
@end

KVC Validation Pattern/KVC Validation Pattern/CTCViewController.m

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,35 @@ - (void)displayInfoForStation:(CTCStation*)station {
4444
[self.tableView reloadData];
4545
}
4646

47+
- (NSString*)jsonStringForResponse:(NSUInteger)responseIndex {
48+
NSString *filename = nil;
49+
50+
switch (responseIndex) {
51+
case 0:
52+
default:
53+
filename = @"ResponseA";
54+
break;
55+
56+
case 1:
57+
filename = @"ResponseB";
58+
break;
59+
60+
case 2:
61+
filename = @"ResponseC";
62+
break;
63+
64+
case 3:
65+
filename = @"ResponseD";
66+
break;
67+
68+
case 4:
69+
filename = @"ResponseE";
70+
break;
71+
}
72+
73+
return [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:filename ofType:@"json"] encoding:NSUTF8StringEncoding error:nil];
74+
}
75+
4776

4877
#pragma mark - UI response
4978

@@ -187,38 +216,6 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
187216
}
188217

189218

190-
#pragma mark - JSON responses
191-
192-
- (NSString*)jsonStringForResponse:(NSUInteger)responseIndex {
193-
NSString *filename = nil;
194-
195-
switch (responseIndex) {
196-
case 0:
197-
default:
198-
filename = @"ResponseA";
199-
break;
200-
201-
case 1:
202-
filename = @"ResponseB";
203-
break;
204-
205-
case 2:
206-
filename = @"ResponseC";
207-
break;
208-
209-
case 3:
210-
filename = @"ResponseD";
211-
break;
212-
213-
case 4:
214-
filename = @"ResponseE";
215-
break;
216-
}
217-
218-
return [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:filename ofType:@"json"] encoding:NSUTF8StringEncoding error:nil];
219-
}
220-
221-
222219
#pragma mark - Formatting
223220

224221
- (NSString*)stringForPrice:(CGFloat)price {

KVC Validation Pattern/KVC Validation Pattern/Model/CTCBaseModel.m

Lines changed: 86 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,25 @@ typedef NS_ENUM(NSUInteger, CTCPropertyType){
2727
CTCPropertyTypeDouble // Property is a double
2828
};
2929

30+
3031
@interface CTCBaseModel ()
3132

3233
@property (nonatomic, readwrite, strong) NSString *dictionaryKey;
3334

3435
@end
3536

37+
3638
@implementation CTCBaseModel {
3739
dispatch_once_t keyToken;
3840
}
41+
3942
static NSMutableDictionary *modelProperties; // Dictionary used to convert json key's into classes proper-cased keys
4043
static dispatch_once_t onceToken;
4144
static NSArray *propertyTypesArray;
4245

46+
47+
#pragma mark - Class methods
48+
4349
+ (void)initialize {
4450
[super initialize];
4551

@@ -72,79 +78,6 @@ + (void)initialize {
7278
[modelProperties setObject:translateNameDict forKey:[self calculateClassName]];
7379
}
7480

75-
- (id)initWithDictionary:(NSDictionary *)dictionary {
76-
self = [self init];
77-
if (self){
78-
// This is where all the KVC magic begins. This method can be called on an object that has already been
79-
// created. This is just a convenience initializer. The same thing could be accomplished in the following manner:
80-
//
81-
// MySubClass *subClass = [MySubClass new];
82-
// [subClass setValuesForKeysWithDictionary:dictionary];
83-
[self setValuesForKeysWithDictionary:dictionary];
84-
}
85-
return self;
86-
}
87-
88-
- (NSString *)dictionaryKey {
89-
// This will cause this key to be generated once, on a per-class/per-instance basis. This is done
90-
// because the logic in calculateClassName can be rather expensive when called repeatedly on
91-
// every property, for every class.
92-
dispatch_once(&keyToken, ^{
93-
_dictionaryKey = [[self class] calculateClassName];
94-
});
95-
return _dictionaryKey;
96-
}
97-
98-
#pragma mark - KVC methods
99-
100-
- (void)setValue:(id)value forKey:(NSString *)key {
101-
// We can assume at this point, the key is not in proper case. We will call the set value method
102-
// with proper casing NO and it will figure out the proper casing for the key (if it can)
103-
[self setValue:value forKey:key properCase:NO];
104-
}
105-
106-
- (void)setValue:(id)value forUndefinedKey:(NSString *)key {
107-
// We will look in the undefinedKeys Dictionary (should be defined in the subclass), and look for
108-
// this undefined key to see if the class maps the key to a know key. This method is called automatically
109-
// by KVC if setValue:forKey: cannot find a property to match the key. Also, we wanted to implement
110-
// this method in the base class, because the default implementation of this on NSObject throws
111-
// an exception.
112-
NSString *newKey = self.undefinedKeys[[key lowercaseString]];
113-
if (newKey){
114-
// If we have found the key, we will call our set value for key with proper case set to YES because
115-
// the key should be put into the dictionary in proper case. If it is not, this will not work, and our value
116-
// will never be set.
117-
[self setValue:value forKey:newKey properCase:YES];
118-
}
119-
}
120-
121-
- (void)setValue:(id)value forKey:(NSString *)key properCase:(BOOL)properCase {
122-
// We first check to see if the key is already in proper case. If not, we'll make it proper case. This is done
123-
// because calling lowerCaseString on a string value can get expensive when called repeatedly. That is what
124-
// will happen when setting a classes values from a dictionary as it will iteratively call setValue:forKey: on every
125-
// key it finds in the dictionary.
126-
if (!properCase) {
127-
NSString *lowerCaseKey = [key lowercaseString];
128-
// We do the lookup in the modelProperties dictionary for the proper cased key. If we find it, we change
129-
// the key to be that value.
130-
NSString *properKey = modelProperties[self.dictionaryKey][lowerCaseKey];
131-
if (properKey){
132-
key = properKey;
133-
}
134-
}
135-
136-
NSError *error = nil;
137-
// Here we call the validation logic. Calling validateValue:forKey:error: will cause validate<key>:error: to be called
138-
// so all the validation methods we added dynamically to this class in initialize will no be utilised.
139-
BOOL isValid = [self validateValue:&value forKey:key error:&error];
140-
141-
// We only want to set the value if the value is valid.
142-
if (isValid) {
143-
[super setValue:value forKey:key];
144-
}
145-
}
146-
147-
14881
+ (NSString *)calculateClassName {
14982
// This method is here because sometimes NSStringFromClass will return the class name with a - and some characters
15083
// after the class name.
@@ -163,7 +96,7 @@ + (void)hydrateModelProperties:(Class)class translateDictionary:(NSMutableDictio
16396
if (!class || class == [NSObject class]){
16497
return;
16598
}
166-
99+
167100
unsigned int outCount, i;
168101
// Get the class property list.
169102
objc_property_t *properties = class_copyPropertyList(class, &outCount);
@@ -207,7 +140,7 @@ + (NSString *)getPropertyType:(objc_property_t)property {
207140
propertyType = (const char *)[[NSData dataWithBytes:(attribute + 3) length:strlen(attribute) - 4] bytes];
208141
}
209142
}
210-
143+
211144
return [[NSString alloc] initWithCString:propertyType encoding:NSUTF8StringEncoding];
212145
}
213146

@@ -217,13 +150,13 @@ + (void)addValidatorForProperty:(NSString *)propertyName type:(NSString *)proper
217150

218151
// Look up the string property type in the propertyTypes array
219152
NSUInteger n = [propertyTypesArray indexOfObject:propertyType];
220-
153+
221154
if (n == NSNotFound){
222155
type = CTCPropertyUnknown;
223156
} else {
224157
type = (CTCPropertyType)n;
225158
}
226-
159+
227160
switch (type){
228161
case CTCPropertyTypeString:
229162
implementation = (IMP)validateStringProperty;
@@ -273,4 +206,80 @@ +(NSString *)generateValidationMethodName:(NSString *)key{
273206
return [NSString stringWithFormat:@"validate%@:error:", [NSString capitalizeFirstCharacter:key]];
274207
}
275208

209+
210+
#pragma mark - Life cycle
211+
212+
- (id)initWithDictionary:(NSDictionary *)dictionary {
213+
self = [self init];
214+
if (self){
215+
// This is where all the KVC magic begins. This method can be called on an object that has already been
216+
// created. This is just a convenience initializer. The same thing could be accomplished in the following manner:
217+
//
218+
// MySubClass *subClass = [MySubClass new];
219+
// [subClass setValuesForKeysWithDictionary:dictionary];
220+
[self setValuesForKeysWithDictionary:dictionary];
221+
}
222+
return self;
223+
}
224+
225+
- (NSString *)dictionaryKey {
226+
// This will cause this key to be generated once, on a per-class/per-instance basis. This is done
227+
// because the logic in calculateClassName can be rather expensive when called repeatedly on
228+
// every property, for every class.
229+
dispatch_once(&keyToken, ^{
230+
_dictionaryKey = [[self class] calculateClassName];
231+
});
232+
return _dictionaryKey;
233+
}
234+
235+
236+
#pragma mark - KVC methods
237+
238+
- (void)setValue:(id)value forKey:(NSString *)key {
239+
// We can assume at this point, the key is not in proper case. We will call the set value method
240+
// with proper casing NO and it will figure out the proper casing for the key (if it can)
241+
[self setValue:value forKey:key properCase:NO];
242+
}
243+
244+
- (void)setValue:(id)value forUndefinedKey:(NSString *)key {
245+
// We will look in the undefinedKeys Dictionary (should be defined in the subclass), and look for
246+
// this undefined key to see if the class maps the key to a know key. This method is called automatically
247+
// by KVC if setValue:forKey: cannot find a property to match the key. Also, we wanted to implement
248+
// this method in the base class, because the default implementation of this on NSObject throws
249+
// an exception.
250+
NSString *newKey = self.undefinedKeys[[key lowercaseString]];
251+
if (newKey){
252+
// If we have found the key, we will call our set value for key with proper case set to YES because
253+
// the key should be put into the dictionary in proper case. If it is not, this will not work, and our value
254+
// will never be set.
255+
[self setValue:value forKey:newKey properCase:YES];
256+
}
257+
}
258+
259+
- (void)setValue:(id)value forKey:(NSString *)key properCase:(BOOL)properCase {
260+
// We first check to see if the key is already in proper case. If not, we'll make it proper case. This is done
261+
// because calling lowerCaseString on a string value can get expensive when called repeatedly. That is what
262+
// will happen when setting a classes values from a dictionary as it will iteratively call setValue:forKey: on every
263+
// key it finds in the dictionary.
264+
if (!properCase) {
265+
NSString *lowerCaseKey = [key lowercaseString];
266+
// We do the lookup in the modelProperties dictionary for the proper cased key. If we find it, we change
267+
// the key to be that value.
268+
NSString *properKey = modelProperties[self.dictionaryKey][lowerCaseKey];
269+
if (properKey){
270+
key = properKey;
271+
}
272+
}
273+
274+
NSError *error = nil;
275+
// Here we call the validation logic. Calling validateValue:forKey:error: will cause validate<key>:error: to be called
276+
// so all the validation methods we added dynamically to this class in initialize will no be utilised.
277+
BOOL isValid = [self validateValue:&value forKey:key error:&error];
278+
279+
// We only want to set the value if the value is valid.
280+
if (isValid) {
281+
[super setValue:value forKey:key];
282+
}
283+
}
284+
276285
@end

KVC Validation Pattern/KVC Validation Pattern/Model/NSString+Utilities.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@
1212
@interface NSString (Utilities)
1313

1414
+ (NSString *)capitalizeFirstCharacter:(NSString *)string;
15-
1615
+ (NSString *)stripNonNumericCharacters:(NSString *)string;
17-
1816
+ (NSString *)leftPadString:(NSString *)string length:(NSUInteger)length padCharacter:(NSString *)padCharacter;
1917

2018
@end

KVC Validation Pattern/KVC Validation Pattern/Model/NSString+Utilities.m

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,4 @@ + (NSString *)leftPadString:(NSString *)string length:(NSUInteger)length padChar
4242
return string;
4343
}
4444

45-
4645
@end

KVC Validation Pattern/KVC Validation Pattern/Model/Validation/CTCArrayTypeValidator.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@
1212

1313

1414
@interface CTCArrayTypeValidator : CTCBaseValidator
15+
1516
@end

0 commit comments

Comments
 (0)