Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Framework Oriented Programming (NSBudapest)

Framework Oriented Programming (NSBudapest)

Learn how to modularize your app and reuse your business logic across products, platforms, and projects.

B0a336761194918a853deeff1f22b537?s=128

Pedro Piñera Buendía

June 29, 2016
Tweet

More Decks by Pedro Piñera Buendía

Other Decks in Technology

Transcript

  1. FRAMEWORK ORIENTED PROGRAMMING Pedro Piñera @pepibumur - IOS DEVELOPER AT

    SOUNDCLOUD NSBUDAPEST ⌚"#$
  2. SZIASZTOK! ! Pedro IOS DEVELOPER AT SOUNDCLOUD @PEPIBUMUR TWITTER/FACEBOOK/YOUTUBE WWW.PPINERA.ES

  3. CONTEXT Before 2008 OSX - 1 TARGET !

  4. CONTEXT 2008 ! LAUNCHES IPHONE SOFTWARE DEVELOPMENT KIT " (Developers

    move to iOS. New platform, frameworks,... New exciting area)
  5. CONTEXT After 2008 ! - 1 TARGET " ! -

    1 TARGET"
  6. CONTEXT 2011 COCOAPODS RELEASED Dependency Resolving + Integration + Community

    !
  7. CONTEXT After 2011 ! - 1 TARGET " ! -

    1 TARGET " X TARGETS (EXTERNAL) !!
  8. CONTEXT 2015 ⌚ "

  9. None
  10. CONTEXT 2015 ! - 1 TARGET ! - 1 TARGET

    ! - 1 TARGET ⌚ - 1 TARGET
  11. HOW TO REUSE CODE? (ACROSS PLATFORMS) Frameworks !

  12. SWIFT ❤ DYNAMIC FRAMEWORKS

  13. EMBEDDED RESOURCES (IMAGES, FONTS, ...)

  14. DYNAMICALLY LINKED (NO DUPLICATED SYMBOLS)

  15. SWIFT CODE

  16. FRAMEWORK ORIENTED PROGRAMMING Reusable & platform independent code GITHUB

  17. BEST PRACTICES PRINCIPLES ADVICES EXAMPLES

  18. FRAMEWORKS STACK SoundCloud Approach

  19. PRINCIPLES Some theory !

  20. 1. SINGLE RESPONSIBILITY SOLID INSPIRED

  21. 1. SINGLE RESPONSIBILITY SOLID INSPIRED

  22. 1. SINGLE RESPONSIBILITY START FROM A HIGH LEVEL

  23. 1. SINGLE RESPONSIBILITY SLICE THEM PROGRESSIVELY

  24. 1. SINGLE RESPONSIBILITY SLICE THEM PROGRESSIVELY

  25. 2. VERTICAL DEPENDENCIES (OVER HORIZONTAL)

  26. 3. LOWER IN THE STACK FEWER EXTERNAL DEPENDENCIES

  27. 4. ONE STEP DEPENDENCIES

  28. 4. ONE STEP DEPENDENCIES

  29. 5. INTERNAL BY DEFAULT

  30. 6. FINAL SOLID INSPIRED (OPEN/CLOSED)

  31. 6. FINAL SOLID INSPIRED (OPEN/CLOSED)

  32. 6. FINAL SOLID INSPIRED (OPEN/CLOSED)

  33. 6. FINAL SOLID INSPIRED (OPEN/CLOSED) final class Person { let

    name: String } class Alien: Person { // Compiler complains }
  34. 7. FRAMEWORK MODELS DON'T SHARE FRAMEWORKS' MODELS UPWARDS

  35. 7. FRAMEWORK MODELS DON'T SHARE FRAMEWORKS' MODELS UPWARDS

  36. 7. FRAMEWORK MODELS DON'T SHARE FRAMEWORKS' MODELS UPWARDS // Persistence

    class Author: NSManagedObjectModel { let name: String } class Track: NSManagedObjectModel { let author: Author } // ListenersKit struct StreamTrackEntity { let name: String let authorName: String }
  37. 7. FRAMEWORK MODELS DON'T SHARE FRAMEWORKS' MODELS UPWARDS struct StreamTrackEntityAdapter

    { func adapt(track: Track) -> StreamTrackEntity { return StreamTrackEntity(name: track.name, authorName: track.author.name) } }
  38. 8. PLATFORM ABSTRACTION SOLID INSPIRED (DI)

  39. 9. PROTOCOL ORIENTED INTERFACES SOLID INSPIRED (DI)

  40. 9. PROTOCOL ORIENTED INTERFACES SOLID INSPIRED (DI)

  41. 9. PROTOCOL ORIENTED INTERFACES SOLID INSPIRED (DI)

  42. 9. PROTOCOL ORIENTED INTERFACES SOLID INSPIRED (DI)

  43. 9. PROTOCOL ORIENTED INTERFACES SOLID INSPIRED (DI)

  44. 10. CORE/TESTING (AKA YOUR PROJECT FOUNDATION FRAMEWORKS)

  45. 10. CORE/TESTING (AKA YOUR PROJECT FOUNDATION FRAMEWORKS) ▸ Extensions ▸

    Logging ▸ Analytics ▸ Architectural components (e.g. Reactive)
  46. ADVANTAGES

  47. MULTIPLATFORM APPS Only working on the UI ⌚"#$

  48. MULTIPLATFORM APPS Only working on the UI ⌚"#$

  49. EXPERIMENTATION ▸ Prototyping ▸ Playgrounds import MyAppKit requestFactory.request(path: "/myPath/").subscribeNext {

    response in // yai! }
  50. NEW PRODUCTS With similar core needs BECAUSE YOU WANT TO

    REUSE CODE, RIGHT?
  51. NEW PRODUCTS With similar core needs BECAUSE YOU WANT TO

    REUSE CODE, RIGHT?
  52. OPEN SOURCE And benefit from the community BUILD PIECES OF

    CODE THAT YOU'D BE PROUD OF OPEN SOURCING
  53. SPECIALIZED TEAMS From UI lovers to Core Data experts (CLEARLY

    DEFINED TEAM BOUNDARIES)
  54. SPECIALIZED TEAMS From UI lovers to Core Data experts (CLEARLY

    DEFINED TEAM BOUNDARIES)
  55. HOW TO? ! There are multiple options (I'LL SHOW YOU

    SOME)
  56. CocoaPods

  57. CocoaPods ▸ ✅ Easy setup (each Framework .podspec) ▸ ✅

    Same setup for local/external dependencies ▸ ❌ It sucks if you don't version ▸ ❌ Fully frameworks approach (load time)
  58. Manual ▸ ✅ More control over the workspace ▸ ✅

    Custom setup (you design it) ▸ ❌ Cumbersome setup (Build Settings) External dependencies can be checked out with Carthage/Git Submodules
  59. XCCONFIG AND MAKING YOUR FRAMEWORK MULTIPLATFORM

  60. SUPPORTED_PLATFORMS = iphoneos iphonesimulator appletvsimulator appletvos macosx watchsimulator watchos TARGETED_DEVICE_FAMILY[sdk=iphone*]

    = 1,2 TARGETED_DEVICE_FAMILY[sdk=watch*] = 4 TARGETED_DEVICE_FAMILY[sdk=appletv*] = 3 VALID_ARCHS[sdk=macosx*] = x86_64 LD_RUNPATH_SEARCH_PATHS[sdk=iphone*] = $(inherited) @executable_path/Frameworks @loader_path/Frameworks LD_RUNPATH_SEARCH_PATHS[sdk=macosx*] = $(inherited) @executable_path/../Frameworks @loader_path/../Frameworks LD_RUNPATH_SEARCH_PATHS[sdk=watch*] = $(inherited) @executable_path/Frameworks @loader_path/Frameworks LD_RUNPATH_SEARCH_PATHS[sdk=appletv*] = $(inherited) @executable_path/Frameworks @loader_path/Frameworks
  61. Hybrid

  62. Hybrid ▸ ✅ CocoaPods resolves/integrates app dependencies ▸ ✅ Carthage

    resolves frameworks dependencies ▸ ✅ Custom stack setup
  63. OPEN QUESTIONS

  64. VERSIONING? GIT REPO PER FRAMEWORK?

  65. 1. Keep it in the same repository (fast iterations) 2.

    Move it once it consolidates (sporadic changes) 3. Then version it! (snapshots in time)
  66. EXTERNAL DEPENDENCIES? HOW TO FETCH THEM?

  67. ▸ If CocoaPods for local: Use it also for external

    ▸ If manual setup: Use Carthage or Git Submodules
  68. STATIC OR DYNAMIC? !

  69. ▸ Objective-C & not shared - Static ▸ Objective-C &&

    shared - Dynamic ▸ Swift - Dynamic
  70. HOW MANY DYNAMIC FRAMEWORKS? THE MORE, THE WORSE LOADING TIME

    WILL ! IMPROVE IT? "
  71. ▸ No more than 6 - (WWDC2016:406) ▸ Group dependencies

    in Framework (Manual setup) Testing.framework Quick.{swift,h,m} Nimble.{swift,h,m} OHHTTPStubs.{swift,h,m} Core.framework RxSwift{.swift}
  72. DOWNSIDES !

  73. LACK OF DOCUMENTATION (TARGETS CONFIGURATION) Tip: Use CocoaPods and copy

    the configuration
  74. STORYBOARDS/XIBS IN FRAMEWORKS Sucks ! TIP: KEEP THEM IN THE

    APPLICATION TARGET
  75. FRAMEWORKS CODE RECOGNITION Sucks even more !

  76. SOME EXTERNAL DEPENDENCIES ARE DISTRIBUTED AS PLATFORM BINARIES

  77. ## XCConfig LD_RUNPATH_SEARCH_PATHS[sdk=macosx*] = $(inherited) Fabric/OSX LD_RUNPATH_SEARCH_PATHS[sdk=appletv*] = $(inherited) Fabric/tvOS

    LD_RUNPATH_SEARCH_PATHS[sdk=iphone*] = $(inherited) Fabric/iOS
  78. SOME EVEN DON'T PROVIDE BINARIES FOR ALL THE PLATFORMS

  79. PROXY THEM USING MACROS

  80. MACROS! #if !os(watchOS) import Fabric #end def log(message: String) {

    #if !os(watchOS) // Log using Fabric #end }
  81. APIS MIGHT DIFFER BETWEEN PLATFORMS

  82. ▸ NSFetchedResultsController not for macOS ▸ NSIndexPath for watchOS has

    no row/section
  83. PROXY THEM ALSO USING MACROS!

  84. CONCLUSIONS

  85. Very time-saver FOR MULTI-PLATFORM PROJECTS

  86. AIMS LESS COUPLED CODE (defined boundaries) !

  87. SETUP REQUIRES SOME Xcode Build Settings knowledge (UNLESS YOU USE

    COCOAPODS) !
  88. MINIMIZE DEPENDENCIES 6 DEPENDENCIES (KISS)

  89. USE YOUR COMMONSENSE WHEN DESIGNING YOUR STACK

  90. USE YOUR COMMONSENSE Don't be a Javascript developer !!!!!!!!!!!

  91. AND REMEMBER THE STACK DEPENDS ON YOUR NEEDS

  92. IS IT A COMPANY OR A FREELANCE PROJECT?

  93. IS IT A COMPANY OR A FREELANCE PROJECT? IS IT

    A NEW PROJECT?
  94. IS IT A COMPANY OR A FREELANCE PROJECT? IS IT

    A NEW PROJECT? AM I USING ANY DEPENDENCIES TOOL?
  95. IS IT A COMPANY OR A FREELANCE PROJECT? IS IT

    A NEW PROJECT? AM I USING ANY DEPENDENCIES TOOL? HOW MANY PEOPLE IN THE TEAM?
  96. REFERENCES ▸ Library Oriented Programming: Justin Spahr-Summers ▸ The Unofficial

    Guide to xcconfig files ▸ WWDC: Optimizing App Startup Time ▸ Static & Dynamic libraries ▸ pepibumur/framework-oriented-programming
  97. CREDITS ! FROM UNSPLASH

  98. None
  99. SZIMPLA Network Testing in Swift GITHUB.COM/PEPIBUMUR/SZIMPLA

  100. Köszönöm ! QUESTIONS? SLIDES (SPEAKERDECK) - HTTP://BIT.LY/29EKOCN pepibumur - pepibumur@gmail.com