Slide 1

Slide 1 text

Software Design & Eclecticism

Slide 2

Slide 2 text

• UITableView Wrangler • URL Request Slinger • JSON Serialization Expert • Getter/Setter Go-Getter • Documentation Force of Nature • NSManagedObject Whisperer

Slide 3

Slide 3 text

This is a talk about getting back to what 
 I love most about programming

Slide 4

Slide 4 text

French Republican Calendar

Slide 5

Slide 5 text

1793 – 1805

Slide 6

Slide 6 text

Design Goals

Slide 7

Slide 7 text

12 Months of 3 Weeks of 10 Days of 10 Hours of 100 Minutes of 100 Seconds

Slide 8

Slide 8 text

Vendémiaire Nivôse Germinal Messidor Brumaire Pluviôse Floréal Thermidor Frimaire Ventôse Prairial Fructidor -aire -ôse -al -dor

Slide 9

Slide 9 text

1.primidi 2.duodi 3.tridi 4.quartidi 5.quintidi
 6.sextidi 7.septidi 8.octidi 9.nonidi 10.décadi

Slide 10

Slide 10 text

Brumaire 1 Pomme Pluviôse 25 Lièvre

Slide 11

Slide 11 text

360 Days + 
 5 or 6 
 “Complementary Days”

Slide 12

Slide 12 text

Les Jours Complémentaires • Celebration of Virtue • Celebration of Talent • Celebration of Labor • Celebration of Convictions • Celebration of Honors • Celebration of the Revolution

Slide 13

Slide 13 text

NSCalendar

Slide 14

Slide 14 text

NSCalendar 
 -initWithCalendarIdentifier:

Slide 15

Slide 15 text

• Gregorian • Buddhist • Chinese • Hebrew • Islamic • Islamic Civil
 • Japanese • Republic of China • Persian • Indian • ISO 8601

Slide 16

Slide 16 text

_NSCopyOnWriteCalendarWrapper
 
 CFCalendarRef

Slide 17

Slide 17 text

@interface _FRARepublicanCalendar : 
 NSCalendar @end

Slide 18

Slide 18 text

NSString * const 
 NSCalendarIdentifierFrenchRepublican =
 @"calendrier-républicain-français"

Slide 19

Slide 19 text

- (id)fra_initWithCalendarIdentifier:(NSString *)ident 
 __attribute__((objc_method_family(init))) 
 { if ([ident isEqualToString: NSCalendarIdentifierFrenchRepublican]) { return [[_FRARepublicanCalendar alloc] init]; } ! return [self fra_initWithCalendarIdentifier:ident]; }

Slide 20

Slide 20 text

- (NSRange)maximumRangeOfUnit:(NSCalendarUnit)unit { switch (unit) { case NSYearCalendarUnit: return NSMakeRange(-NSUIntegerMax, NSUIntegerMax); case NSMonthCalendarUnit: return NSMakeRange(1, 13); case NSWeekCalendarUnit: return NSMakeRange(1, 3); case NSWeekdayCalendarUnit: return NSMakeRange(1, 10); case NSDayCalendarUnit: return NSMakeRange(1, 30); case NSHourCalendarUnit: return NSMakeRange(1, 10); case NSMinuteCalendarUnit: return NSMakeRange(1, 100); case NSSecondCalendarUnit: return NSMakeRange(1, 100); case NSEraCalendarUnit: default: return NSMakeRange(0, 0); } }

Slide 21

Slide 21 text

NSTimeInterval const FRAFrenchRevolutionaryEpoch = 2375839.5; // 22 September 1792

Slide 22

Slide 22 text

- components:
 fromDate: - dateByAddingComponents:
 toDate: - dateFromComponents:

Slide 23

Slide 23 text

Phone Numbers

Slide 24

Slide 24 text

+1 (555) 555 - 1234 United States

Slide 25

Slide 25 text

+44 20 1234 5678 United Kingdom

Slide 26

Slide 26 text

1 2 ABC 3 DEF 4 GHI 5 JKL 6 MNO 7 PQRS 8 TUV 9 WXYZ ˎ 0 + #

Slide 27

Slide 27 text

Whitby 
 01947 (WH)

Slide 28

Slide 28 text

1-800-HIPSTER Alphabetical Phone Number

Slide 29

Slide 29 text

+1 (555) 555 - 6789 x42 Extension

Slide 30

Slide 30 text

911 Emergency Number

Slide 31

Slide 31 text

55422 SMS Short Code

Slide 32

Slide 32 text

IP Addresses

Slide 33

Slide 33 text

E.164 Telephone Numbering Plan

Slide 34

Slide 34 text

International Access Code 011 Country Code +44 Area Code 555 Subscriber Number 555 1234 Extension x42

Slide 35

Slide 35 text

E164PhoneNumberComponents

Slide 36

Slide 36 text

• @property NSString *internationalAccessCode • @property NSString *countryCode • @property NSString *areaCode • @property NSString *subscriberNumber • @property NSString *extension • @property NSString *emergencyNumber • @property NSString *shortCode

Slide 37

Slide 37 text

E164PhoneNumberComponents

Slide 38

Slide 38 text

E164PhoneNumberFormatter • @property NSLocale *locale • @property NSString *countryCodePrefix • @property NSString *extensionPrefix

Slide 39

Slide 39 text

- phoneNumberWithComponents: - components:
 fromPhoneNumber:

Slide 40

Slide 40 text

NFPA 704 
 Hazard Identification System

Slide 41

Slide 41 text

3 2 0 Ethyl Alcohol CH3CH2OH

Slide 42

Slide 42 text

1 0 2 Sodium Hydride NaH W

Slide 43

Slide 43 text

4 3 2 W

Slide 44

Slide 44 text

4 3 2 W • @property flammabilityLabel • @property healthLabel • @property reactivityLabel • @property specialNoteLabel

Slide 45

Slide 45 text

4 3 2 W • @property flammabilityBackgroundColor • @property healthBackgroundColor • @property reactivityBackgroundColor • @property specialNoteBackgroundColor

Slide 46

Slide 46 text

typedef NS_ENUM(NSUInteger, NFPA704HazardLevel) { NFPA704MinimalHazard = 0, NFPA704SlightHazard = 1, NFPA704ModerateHazard = 2, NFPA704SeriousHazard = 3, NFPA704ExtremeHazard = 4, }; • @property NFPA704HazardLevel flammability • @property NFPA704HazardLevel health • @property NFPA704HazardLevel reactivity • @property NSString *specialNote

Slide 47

Slide 47 text

CGContextSaveGState(ctx); { CGContextTranslateCTM(ctx,CGRectGetWidth(rect)/2.0f, 0.0f); CGContextRotateCTM(ctx, M_PI_4); CGContextScaleCTM(ctx, 1.0f / M_SQRT2, 1.0f / M_SQRT2); // … } CGContextRestoreGState(ctx);

Slide 48

Slide 48 text

Beer Measurement

Slide 49

Slide 49 text

@interface Beer @property NSString *name @property id brewery @property NSNumber *ABV @property NSNumber *IBU @property NSNumber *SRM

Slide 50

Slide 50 text

°L Example Color EBC 2 Pale lager, Witbier, Pilsener, Berliner Weisse 4 3 Maibock, Blonde Ale 6 4 Weissbier 8 6 American Pale Ale, India Pale Ale 12 8 Weissbier, Saison 16 10 English Bitter, ESB 20 13 Biere de Garde, Double IPA 26 17 Dark lager, Vienna lager, Marzen, Amber Ale 33 20 Brown Ale, Bock, Dunkel, Dunkelweizen 39 24 Irish Dry Stout, Doppelbock, Porter 47 29 Stout 57 35 Foreign Stout, Baltic Porter 69 40+ Imperial Stout 79

Slide 51

Slide 51 text

Morey Equation MCU = weight of grains (lbs) • color of grains (°L) volume (gallons) SRM = 1.4922 • MCU^0.6859

Slide 52

Slide 52 text

Morey Approximation UIColor * UIColorForDegreesLovibond(CGFloat lovibond) { CGFloat r, g, b; if (lovibond < 1.7f) { r = 226.6017f, g = 174.7456f, b = 101.7924; } else if (lovibond > 600.0f) { r = 76.52f, g = 58.344f, b = 47.936f; } else { r = (227.3 - 0.4112 * lovibond) + (0.0002665 * powf(lovibond, 2.0f)); g = (175.5 - 0.4445 * lovibond) + (0.0004154 * powf(lovibond, 2.0f)); b = (102.2 - 0.2402 * lovibond) + (0.0002496 * powf(lovibond, 2.0f)); } ! return [UIColor colorWithRed:(r / 255.0f) green:(g / 255.0f) blue:(b / 255.0f) alpha:1.0f]; }

Slide 53

Slide 53 text

@interface BeerView - setBeer:

Slide 54

Slide 54 text

Shoe Sizing

Slide 55

Slide 55 text

UK Barleycorn ⅓ inch France Paris Point ⅔ cm

Slide 56

Slide 56 text

• Europe • UK • Australia • USA / Canada • Mexico • Japan • Korea
 • Inches • Centimeters Regional Systems Measurements

Slide 57

Slide 57 text

ISO 9407 Mondopoint

Slide 58

Slide 58 text

200 205 210 215 220 225 230 235 240 245 250 255 260 265 270 275 280 285 290 295 300 305 310 315 320 7¾ 8 8¼ 8½ 8¾ 9 9¼ 9½ 9¾ 10 10¼ 10½ 10¾ 11 11¼ 11½ 11¾ 12 12¼ 12½ [mm] [in] foot 215 220 225 230 235 240 245 250 255 260 265 270 275 280 285 290 295 300 305 310 315 320 325 330 335 8¼ 8½ 8¾ 9 9¼ 9½ 9¾ 10 10¼ 10½ 10¾ 11 11¼ 11½ 11¾ 12 12¼ 12½ 12¾ 13 [mm] [in] shoe Mondopoint 200 205 210 215 220 225 230 235 240 245 250 255 260 265 270 275 280 285 290 295 300 305 310 315 320 EUR 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 UK 0 0½ 1 1½ 2 2½ 3 3½ 4 4½ 5 5½ 6 6½ 7 7½ 8 8½ 9 9½ 10 10½ 11 11½ 12 12½ 13 13½ 14 64ø. 1 1½ 2 2½ 3 3½ 4 4½ 5 5½ 6 6½ 7 7½ 8 8½ 9 9½ 10 10½ 11 11½ 12 12½ 13 13½ 14 14½ 15 64ø.ø "UIM 2 2½ 3 3½ 4 4½ 5 5½ 6 6½ 7 7½ 8 8½ 9 9½ 10 10½ 11 11½ 12 12½ 13 13½ 14 64ø8ø '*" 2 2½ 3 3½ 4 4½ 5 5½ 6 6½ 7 7½ 8 8½ 9 9½ 10 10½ 11 11½ 12 12½ 13 13½ 14 14½ 15 15½ 16 64ø8ø "UIM 3 3½ 4 4½ 5 5½ 6 6½ 7 7½ 8 8½ 9 9½ 10 10½ 11 11½ 12 12½ 13 13½ 14 14½ 15 JP/CN 20 20½ 21 21½ 22 22½ 23 23½ 24 24½ 25 25½ 26 26½ 27 27½ 28 28½ 29 29½ 30

Slide 59

Slide 59 text

Function or Lookup Table?

Slide 60

Slide 60 text

#import ! extern double USAWomensSizeToMondopoint(double size); ! - (void)testUSAWomensSizeToMondopointEquivalences { static NSDictionary *mondopointByWomensSize = @{@(2): @(203), ...}; ! [mondopointByWomensSize enumerateKeysAndObjectsUsingBlock: ^(NSNumber *womensSize, NSNumber *mondopoint, BOOL *stop) { XCTAssertEqual( USAWomensSizeToMondopoint([womensSize doubleValue]), [mondopoint doubleValue], @"sizes not equivalent” ); }]; }

Slide 61

Slide 61 text

Braille

Slide 62

Slide 62 text

a/1 b/2 c/3 d/4 e/5 f/6 g/7 h/8 i/9 j/0 k l m n o p q r s t u v x y z w

Slide 63

Slide 63 text

Comma Semicolon Apostrophe Colon Hyphen Decimal point Full stop! (Period) Exclamation! point Open quote,! question mark Close! quote Bracket! (Parentheses) Slash! (Fraction)

Slide 64

Slide 64 text

UISimpleTextPrintFormatter

Slide 65

Slide 65 text

NSMutableString *mutableText = [text mutableCopy]; ! CFStringTransform(mutableText, NULL, kCFStringTransformToLatin, NO); ! CFStringTransform(mutableText, NULL, kCFStringTransformStripCombiningMarks, NO); ! text = [NSString stringWithString:mutableText];

Slide 66

Slide 66 text

NSMutableString *mutableBrailleText = [NSMutableString string]; [text enumerateSubstringsInRange:NSMakeRange(0, [text length]) options:NSStringEnumerationByComposedCharacterSequences usingBlock: ^(NSString *substring, …) { [mutableBrailleText appendString: EnglishBrailleCharacterForCharacter([substring characterAtIndex:0])]; }]; ! [super setText:mutableBrailleText];

Slide 67

Slide 67 text

static NSString * EnglishBrailleCharacterForCharacter(unichar character) { switch (character) { case 'a': return @"⠁"; case 'b': return @"⠃"; // ... } ! return nil; }

Slide 68

Slide 68 text

Concepts • Swizzling & Private Class Clusters • Formatters vs. Value Transformers vs. Functions • View Composition & Transformations • Model-Driven Views • Unit Conversion Strategies & Unit Testing • String Enumeration & UIPrinterFormatter