Slide 1

Slide 1 text

Framework Oriented Programming Pedro Piñera @pepibumur ⌚"#$

Slide 2

Slide 2 text

Hello It's me (From the other side London)

Slide 3

Slide 3 text

iOS Developer at SoundCloud @pepibumur

Slide 4

Slide 4 text

Framework Oriented Programming • Started with GitDo • Applying principles to SoundClound • Ideas/Principles together in a repository (Reference) • Feedback is welcome !

Slide 5

Slide 5 text

Index • Context • Principles • Advantages • How to? • Open Questions • SoundCloud attempt • Downsides • Conclusions

Slide 6

Slide 6 text

Index • Context • Principles • Advantages • How to? • Open Questions • SoundCloud attempt • Downsides • Conclusions

Slide 7

Slide 7 text

Context Before 2008 OSX == 1 Bundle* *Xcode project target

Slide 8

Slide 8 text

Context 2008 Apple launches iPhone Software Development Kit ! (Developers move to iOS. New platform, frameworks,... New exciting area)

Slide 9

Slide 9 text

Context After 2008 iOS == 1 Bundle* OSX == 1 Bundle* *Xcode project target

Slide 10

Slide 10 text

2011

Slide 11

Slide 11 text

Context 2011 CocoaPods released Dependency Resolving + Integration + Community !

Slide 12

Slide 12 text

Context After 2011 iOS == 1 Bundle* OSX == 1 Bundle* X Bundles (External Dependencies) *Xcode project target

Slide 13

Slide 13 text

Context 2015 ⌚ "

Slide 14

Slide 14 text

OMG That's Awesome

Slide 15

Slide 15 text

Trying to reuse ! your code base

Slide 16

Slide 16 text

Context 2015 iOS == 1 Bundle* OSX == 1 Bundle* tvOS == 1 Bundle* watchOS == 1 Bundle*

Slide 17

Slide 17 text

How to reuse code? (across platforms) Frameworks

Slide 18

Slide 18 text

Swift ❤ Dynamic Frameworks (OSX, iOS, watchOS, tvOS) • Allow embedded resources (images, fonts, ...) • Dynamically linked (No duplicated symbols) • Swift code

Slide 19

Slide 19 text

Framework Oriented Programming Coding your apps organizing your code base in reusable & multiplatform code bundles Best Practices, Principles, Advices.. github.com/pepibumur/framework-oriented-programming

Slide 20

Slide 20 text

Index • Context • Principles • Advantages • How to? • Open Questions • SoundCloud attempt • Downsides • Conclusions

Slide 21

Slide 21 text

Frameworks Stack SoundCloud Approach

Slide 22

Slide 22 text

1. Single Responsibility SOLID inspired

Slide 23

Slide 23 text

1. Single Responsibility SOLID inspired

Slide 24

Slide 24 text

Responsibility? CoreData access layer?

Slide 25

Slide 25 text

Responsibility? CoreData access layer? Storage access layer?

Slide 26

Slide 26 text

Responsibility? CoreData access layer? Storage access layer? Keychain access layer?

Slide 27

Slide 27 text

Responsibility? CoreData access layer? Storage access layer? Keychain access layer? Models?

Slide 28

Slide 28 text

Responsibility? CoreData access layer? Storage access layer? Keychain access layer? Models? !

Slide 29

Slide 29 text

1. Single Responsibility Start from a high level

Slide 30

Slide 30 text

1. Single Responsibility Slice them progressively

Slide 31

Slide 31 text

1. Single Responsibility Slice them progressively

Slide 32

Slide 32 text

2. Vertical dependencies (Over Horizontal)

Slide 33

Slide 33 text

3. Lower in the stack Fewer external dependencies

Slide 34

Slide 34 text

4. One Step Dependencies

Slide 35

Slide 35 text

4. One Step Dependencies

Slide 36

Slide 36 text

5. Internal by default

Slide 37

Slide 37 text

6. Final SOLID inspired (open/closed)

Slide 38

Slide 38 text

6. Final SOLID inspired (open/closed)

Slide 39

Slide 39 text

6. Final SOLID inspired (open/closed)

Slide 40

Slide 40 text

6. Final SOLID inspired (open/closed) final class Person { let name: String } class Alien: Person { // Compiler complains }

Slide 41

Slide 41 text

7. Framework models Don't share lower frameworks models upwards

Slide 42

Slide 42 text

7. Framework models Don't share lower frameworks models upwards

Slide 43

Slide 43 text

7. Framework models Don't share lower 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 }

Slide 44

Slide 44 text

7. Framework models Don't share lower frameworks models upwards struct StreamTrackEntityAdapter { func adapt(track: Track) -> StreamTrackEntity { return StreamTrackEntity(name: track.name, authorName: track.author.name) } }

Slide 45

Slide 45 text

8. Platform Abstraction SOLID inspired (DI)

Slide 46

Slide 46 text

But... There's platform specific logic Examples - No NSFetchedResultsController in macOS - NSIndexPath is slightly different for watchOS.

Slide 47

Slide 47 text

8. Platform Abstraction Macros! #if os(OSX) // OSX logic #else // Other platforms logic #endif

Slide 48

Slide 48 text

9. Protocol Oriented Interfaces SOLID inspired (DI)

Slide 49

Slide 49 text

9. Protocol Oriented Interfaces SOLID inspired (DI)

Slide 50

Slide 50 text

9. Protocol Oriented Interfaces SOLID inspired (DI)

Slide 51

Slide 51 text

9. Protocol Oriented Interfaces SOLID inspired (DI)

Slide 52

Slide 52 text

9. Protocol Oriented Interfaces SOLID inspired (DI)

Slide 53

Slide 53 text

10. Core/Testing (aka your project Foundation frameworks)

Slide 54

Slide 54 text

10. Core/Testing Accessible from all the Frameworks • Extensions • Logging • Analytics • Architectural components (e.g. Reactive)

Slide 55

Slide 55 text

Index • Context • Principles • Advantages ! • How to? • Open Questions • SoundCloud attempt • Downsides • Conclusions

Slide 56

Slide 56 text

Multiplatform apps Only working on the UI ⌚"#$

Slide 57

Slide 57 text

Multiplatform apps Only working on the UI ⌚"#$

Slide 58

Slide 58 text

Experimentation import MyAppKit • Prototyping • Playgrounds

Slide 59

Slide 59 text

New products With similar core needs Because you want to reuse code, right?

Slide 60

Slide 60 text

New products With similar core needs Because you want to reuse code, right?

Slide 61

Slide 61 text

Open Source And benefit from the community Build pieces of code that you'd be proud of open sourcing

Slide 62

Slide 62 text

Specialized teams From UI lovers to Core Data experts (clearly defined team boundaries)

Slide 63

Slide 63 text

Specialized teams From UI lovers to Core Data experts (clearly defined team boundaries)

Slide 64

Slide 64 text

Index • Context • Principles • Advantages • How to? • Open Questions • SoundCloud attempt • Downsides • Conclusions

Slide 65

Slide 65 text

How to? There are multiple options (I'll show you some)

Slide 66

Slide 66 text

How to? CocoaPods

Slide 67

Slide 67 text

How to? CocoaPods • ✅ Easy setup (each Framework .podspec) • ✅ You don't have to worry about Xcode Frameworks configuration • ✅ Same setup for local/external dependencies • ❌ .podspec cannot point to another local .podspecs • ❌ CocoaPods sucks if you don't version.

Slide 68

Slide 68 text

How to? Local podspec discovery # Networking ~> Core dependency not found pod 'Networking' pod 'Core' pod 'AppKit'

Slide 69

Slide 69 text

How to? Local podspec discovery pod 'Core' pod 'Networking' # Core has already been resolved pod 'AppKit'

Slide 70

Slide 70 text

How to? Manual • ✅ More control over the workspace • ❌ Cumbersome setup (Build Settings) • External dependencies can be checked out with Carthage/Git Submodules.

Slide 71

Slide 71 text

How to? Hybrid

Slide 72

Slide 72 text

Index • Context • Principles • Advantages • How to? • Open Questions • SoundCloud attempt • Downsides • Conclusions

Slide 73

Slide 73 text

Open Questions External Dependencies? RECOMMENDATION ⾠ • If CocoaPods for local: Use it also for external. • If manual setup: Use Carthage for checking out external dependencies carthage update • With the binary. • Adding the project to the workspace: --no-build

Slide 74

Slide 74 text

Open Questions Versioning? Git repo per framework? RECOMMENDATION ⾠ 1. Keep it in the same repository (fast iterations) 2. Move it once it consolidates. (sporadic changes) 3. Then version it! (snapshots in time)

Slide 75

Slide 75 text

Open Questions Static or Dynamic? RECOMMENDATION ⾠ - Objective-C & not shared ~> Static - Objective-C && shared ~> Dynamic - Swift && .* ~> Dynamic The more dynamic the worse load time

Slide 76

Slide 76 text

Open Questions Migrate existing project RECOMMENDATION ⾠ - Start with Core/Testing - Move Foundation components down. - Continue building layers progressively. You'll figure out how couple your code is !

Slide 77

Slide 77 text

Index • Context • Principles • Advantages • How to? • Open Questions • SoundCloud attempt • Downsides • Conclusions

Slide 78

Slide 78 text

We failed at our first try Why?

Slide 79

Slide 79 text

1. We didn't version with CocoaPods I'm not against CocoaPods! Local Pods + No versioning + Team = It Sucks

Slide 80

Slide 80 text

2. Too many frameworks • No clear responsibilities • Crossed dependencies • Messy dependency tree • Very small responsibilities

Slide 81

Slide 81 text

No content

Slide 82

Slide 82 text

No content

Slide 83

Slide 83 text

No content

Slide 84

Slide 84 text

Index • Context • Principles • Advantages • How to? • Open Questions • SoundCloud attempt • Downsides • Conclusions

Slide 85

Slide 85 text

Lack of documentation (Targets Configuration) Tip: Use CocoaPods and copy the configuration

Slide 86

Slide 86 text

Storyboards/Xibs in Frameworks Sucks ! Tip 1: Keep them in the application target Tip 2: Reuse UI only if it's in code

Slide 87

Slide 87 text

Frameworks code recognition Sucks even more !

Slide 88

Slide 88 text

Index • Context • Principles • Advantages • How to? • Open Questions • SoundCloud attempt • Downsides • Conclusions

Slide 89

Slide 89 text

Very time-saver for multi-platform projects

Slide 90

Slide 90 text

Helps with less coupled code (defined boundaries)

Slide 91

Slide 91 text

Setup requires some Xcode Build Settings knowledge Unless you use CocoaPods

Slide 92

Slide 92 text

Minimize external dependencies (KISS) (avoid more than 2 levels)

Slide 93

Slide 93 text

Use your commonsense When deciding the Frameworks you need (don't get inspired from Javascript) • Try to have only those that you really need.

Slide 94

Slide 94 text

Configuration depends on your project • New project? • Existing project to migrate? • Many external dependencies? • Not that many? • Already using CocoaPods? • How many people in your team?

Slide 95

Slide 95 text

References • Library Oriented Programming: Justin Spahr-Summers • The Unofficial Guide to xcconfig files • CocoaPods • Carthage • pepibumur/framework-oriented-programming • Static & Dynamic libraries • Creating your first iOS Framework

Slide 96

Slide 96 text

Thanks Questions? ! SpeakerDeck Slides: http:/ /bit.ly/22m4lwi