Slide 1

Slide 1 text

building Swift libraries with @ythecombinator & @macabeus

Slide 2

Slide 2 text

intro ↪modularization matters ↪package managers

Slide 3

Slide 3 text

intro> Modularization Matters

Slide 4

Slide 4 text

Write programs that: ↪do one thing ↪do it well ↪work together Ken Thompson, Doug McIlroy, Rob Pike et al.

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

+ Libraries - Coupling

Slide 7

Slide 7 text

+ Libraries - Coupling × understanding one 㱺 understanding the other × testing one 㱺 testing the other × lack of reusability Coupling

Slide 8

Slide 8 text

+ Libraries - Coupling Libraries ✔ force an abstraction boundary on you ✔ introduce good friction × understanding one 㱺 understanding the other × testing one 㱺 testing the other × lack of reusability

Slide 9

Slide 9 text

intermission: Namespacing, Modules and others

Slide 10

Slide 10 text

Modules Packages Products Namespaces A namespace is something that holds a mapping from a particular name to a particular meaning. MyClass.hello() !" hello from app MyFramework.MyClass.hello() !" hello from framework

Slide 11

Slide 11 text

Modules Packages Products Namespaces Each module specifies a namespace and enforces access controls on which parts of that code can be used outside of the module. A program may have all of its code in a single module, or it may import other modules as dependencies.

Slide 12

Slide 12 text

Modules Packages Products Namespaces A package consists of Swift source files + a manifest file. A package has one or more targets. Each target specifies a product and may declare one or more dependencies.

Slide 13

Slide 13 text

Modules Packages Products Namespaces A target may build either a library or an executable as its product. A library contains a module that can be imported by other Swift code. An executable is a program that can be run by the operating system.

Slide 14

Slide 14 text

intermission: Namespacing, Modules and others ✔

Slide 15

Slide 15 text

intro> Dependencies Managers

Slide 16

Slide 16 text

A B C D E F

Slide 17

Slide 17 text

$ git submodule add $ git submodule update --init --recursive

Slide 18

Slide 18 text

$ git submodule add $ git submodule update --init --recursive ✔ total control over dependencies ✔ easy to include local dependencies

Slide 19

Slide 19 text

× a lot of manual steps × error prone × maintaining dependencies updates $ git submodule add $ git submodule update --init --recursive ✔ total control over dependencies ✔ easy to include local dependencies

Slide 20

Slide 20 text

Dependency managers… ↪ simplify/standardize fetching third party code and incorporating it into your project ↪ pick out appropriate and compatible versions of each dependency you use

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

✔ static frameworks support out of the box ✔ co"#unity support ✔ easy to setup and use × high abstraction over project configuration × libraries must create, update and host Podspec files × we have to manage Ruby dependencies

Slide 23

Slide 23 text

✔ non-invasive by default ✔ decentralized by default ✔ plain Swift × workarounds required when dealing with static frameworks × more manual work × slow/unstable (reports)

Slide 24

Slide 24 text

✔ non-invasive by default ✔ decentralized by default ✔ plain Swift ✔ cross-platform ✔ automated testing × Swift only × host-side only × lack of documentation

Slide 25

Slide 25 text

hands -on ↪scaffolding ↪doing manually

Slide 26

Slide 26 text

extra ↪testing/ coverage ↪quality ↪docs ↪CI

Slide 27

Slide 27 text

extra> Testing

Slide 28

Slide 28 text

focus on what the feature provides for the end user, not implementation

Slide 29

Slide 29 text

https://github.com/Quick/Quick

Slide 30

Slide 30 text

describe(".load()") { context("JSON is fetched successfully") { it("loads JSON from NSUserDefaults") { expect(StatsJSON.load()) .to(beTrue()) } } }

Slide 31

Slide 31 text

context("JSON is fetched successfully") { it("loads JSON from NSUserDefaults") { expect(StatsJSON.load()) .to(beTrue()) } } } wrap method tests in a describe block describe(".load()") {

Slide 32

Slide 32 text

it("loads JSON from NSUserDefaults") { expect(StatsJSON.load()) .to(beTrue()) } } } context("JSON is fetched successfully") { wrap scenarios into a context block describe(".load()") {

Slide 33

Slide 33 text

wrap side-effects in multiple it blocks expect(StatsJSON.load()) .to(beTrue()) } } } it("loads JSON from NSUserDefaults") { describe(".load()") { context("JSON is fetched successfully") {

Slide 34

Slide 34 text

extra> Tests Coverage

Slide 35

Slide 35 text

https://codecov.io/

Slide 36

Slide 36 text

extra> Code Complexity

Slide 37

Slide 37 text

intermission: Cyclomatic Complexity

Slide 38

Slide 38 text

E - N + 2*P E = number of edges in the flow graph N = number of nodes in the flow graph P = number of nodes that have exit points

Slide 39

Slide 39 text

func containsOnlyLetters(input: String) %→ Bool { for chr in input.characters { if (!(chr '( "a" )* chr +, "z") )* !(chr '( "A" )* chr +, "Z") ) { return false } } return true } 1 point for the function declaration 1 point for every if, while, for and case

Slide 40

Slide 40 text

intermission: Cyclomatic Complexity ✔

Slide 41

Slide 41 text

intermission: NPath Complexity

Slide 42

Slide 42 text

the number of acyclic execution paths through that function

Slide 43

Slide 43 text

if (x) { if (y) { !" Do something } else { !" Do something else } } else { !" Do something even more else } As you nest control structures more deeply, the number of possible paths increases exponentially.

Slide 44

Slide 44 text

intermission: NPath Complexity ✔

Slide 45

Slide 45 text

https://github.com/yopeso/Taylor

Slide 46

Slide 46 text

https://codebeat.co/

Slide 47

Slide 47 text

extra> Documentation

Slide 48

Slide 48 text

https://github.com/realm/jazzy

Slide 49

Slide 49 text

https://github.com/noffle/art-of-readme

Slide 50

Slide 50 text

https://robots.thoughtbot.com/how-to-write-a- great-readme

Slide 51

Slide 51 text

extra> Styleguide

Slide 52

Slide 52 text

https://github.com/realm/swiftlint

Slide 53

Slide 53 text

extra> Continuous Integration

Slide 54

Slide 54 text

No content

Slide 55

Slide 55 text

No content

Slide 56

Slide 56 text

https://macalogs.com.br/ desenvolvendo-pacotes-em-swift

Slide 57

Slide 57 text

NSLog(@"Thanks!");