Software Design & Eclecticism

Software Design & Eclecticism

What makes Foundation stand out among other standard libraries is how thoroughly it's designed. From its date and time calculations to its internationalization and URL loading system, Cocoa APIs demonstrate thoughtfulness and a deep appreciation for understanding a problem in its entirety.

In the service of cultivating a sense and appreciation of good software design, this session will explore a variety of topics, including beer taxonomy, international shoe sizes, NFPA 704 "fire diamonds", and the French Republican Calendar, applying patterns and conventions in Objective-C and Cocoa to model these obscure subjects.

In the service of cultivating a sense and appreciation of good software design, this session will explore a variety of topics, including beer taxonomy, SMPTE film timecodes, international shoe sizes, NFPA 704 "fire diamonds", and the French Republican Calendar, applying patterns and conventions in Objective-C and Cocoa to model these obscure subjects.

D29bb4d2d2f2ba2c2fb5a329e1e4651f?s=128

Mattt Thompson

March 24, 2014
Tweet

Transcript

  1. Software Design & Eclecticism

  2. • UITableView Wrangler • URL Request Slinger • JSON Serialization

    Expert • Getter/Setter Go-Getter • Documentation Force of Nature • NSManagedObject Whisperer
  3. This is a talk about getting back to what 


    I love most about programming
  4. French Republican Calendar

  5. 1793 – 1805

  6. Design Goals

  7. 12 Months of 3 Weeks of 10 Days of 10

    Hours of 100 Minutes of 100 Seconds
  8. Vendémiaire Nivôse Germinal Messidor Brumaire Pluviôse Floréal Thermidor Frimaire Ventôse

    Prairial Fructidor -aire -ôse -al -dor
  9. 1.primidi 2.duodi 3.tridi 4.quartidi 5.quintidi
 6.sextidi 7.septidi 8.octidi 9.nonidi 10.décadi

  10. Brumaire 1 Pomme Pluviôse 25 Lièvre

  11. 360 Days + 
 5 or 6 
 “Complementary Days”

  12. Les Jours Complémentaires • Celebration of Virtue • Celebration of

    Talent • Celebration of Labor • Celebration of Convictions • Celebration of Honors • Celebration of the Revolution
  13. NSCalendar

  14. NSCalendar 
 -initWithCalendarIdentifier:

  15. • Gregorian • Buddhist • Chinese • Hebrew • Islamic

    • Islamic Civil
 • Japanese • Republic of China • Persian • Indian • ISO 8601
  16. _NSCopyOnWriteCalendarWrapper
 
 CFCalendarRef

  17. @interface _FRARepublicanCalendar : 
 NSCalendar @end

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

  19. - (id)fra_initWithCalendarIdentifier:(NSString *)ident 
 __attribute__((objc_method_family(init))) 
 { if ([ident isEqualToString:

    NSCalendarIdentifierFrenchRepublican]) { return [[_FRARepublicanCalendar alloc] init]; } ! return [self fra_initWithCalendarIdentifier:ident]; }
  20. - (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); } }
  21. NSTimeInterval const FRAFrenchRevolutionaryEpoch = 2375839.5; // 22 September 1792

  22. - components:
 fromDate: - dateByAddingComponents:
 toDate: - dateFromComponents:

  23. Phone Numbers

  24. +1 (555) 555 - 1234 United States

  25. +44 20 1234 5678 United Kingdom

  26. 1 2 ABC 3 DEF 4 GHI 5 JKL 6

    MNO 7 PQRS 8 TUV 9 WXYZ ˎ 0 + #
  27. Whitby 
 01947 (WH)

  28. 1-800-HIPSTER Alphabetical Phone Number

  29. +1 (555) 555 - 6789 x42 Extension

  30. 911 Emergency Number

  31. 55422 SMS Short Code

  32. IP Addresses

  33. E.164 Telephone Numbering Plan

  34. International Access Code 011 Country Code +44 Area Code 555

    Subscriber Number 555 1234 Extension x42
  35. E164PhoneNumberComponents

  36. • @property NSString *internationalAccessCode • @property NSString *countryCode • @property

    NSString *areaCode • @property NSString *subscriberNumber • @property NSString *extension • @property NSString *emergencyNumber • @property NSString *shortCode
  37. E164PhoneNumberComponents

  38. E164PhoneNumberFormatter • @property NSLocale *locale • @property NSString *countryCodePrefix •

    @property NSString *extensionPrefix
  39. - phoneNumberWithComponents: - components:
 fromPhoneNumber:

  40. NFPA 704 
 Hazard Identification System

  41. 3 2 0 Ethyl Alcohol CH3CH2OH

  42. 1 0 2 Sodium Hydride NaH W

  43. 4 3 2 W

  44. 4 3 2 W • @property flammabilityLabel • @property healthLabel

    • @property reactivityLabel • @property specialNoteLabel
  45. 4 3 2 W • @property flammabilityBackgroundColor • @property healthBackgroundColor

    • @property reactivityBackgroundColor • @property specialNoteBackgroundColor
  46. 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
  47. 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);
  48. Beer Measurement

  49. @interface Beer @property NSString *name @property id brewery @property NSNumber

    *ABV @property NSNumber *IBU @property NSNumber *SRM
  50. °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
  51. Morey Equation MCU = weight of grains (lbs) • color

    of grains (°L) volume (gallons) SRM = 1.4922 • MCU^0.6859
  52. 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]; }
  53. @interface BeerView - setBeer:

  54. Shoe Sizing

  55. UK Barleycorn ⅓ inch France Paris Point ⅔ cm

  56. • Europe • UK • Australia • USA / Canada

    • Mexico • Japan • Korea
 • Inches • Centimeters Regional Systems Measurements
  57. ISO 9407 Mondopoint

  58. 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
  59. Function or Lookup Table?

  60. #import <XCTest/XCTest.h> ! 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” ); }]; }
  61. Braille

  62. 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
  63. Comma Semicolon Apostrophe Colon Hyphen Decimal point Full stop! (Period)

    Exclamation! point Open quote,! question mark Close! quote Bracket! (Parentheses) Slash! (Fraction)
  64. UISimpleTextPrintFormatter

  65. NSMutableString *mutableText = [text mutableCopy]; ! CFStringTransform(mutableText, NULL, kCFStringTransformToLatin, NO);

    ! CFStringTransform(mutableText, NULL, kCFStringTransformStripCombiningMarks, NO); ! text = [NSString stringWithString:mutableText];
  66. NSMutableString *mutableBrailleText = [NSMutableString string]; [text enumerateSubstringsInRange:NSMakeRange(0, [text length]) options:NSStringEnumerationByComposedCharacterSequences

    usingBlock: ^(NSString *substring, …) { [mutableBrailleText appendString: EnglishBrailleCharacterForCharacter([substring characterAtIndex:0])]; }]; ! [super setText:mutableBrailleText];
  67. static NSString * EnglishBrailleCharacterForCharacter(unichar character) { switch (character) { case

    'a': return @"⠁"; case 'b': return @"⠃"; // ... } ! return nil; }
  68. 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