Slide 1

Slide 1 text

Building Fabric.app in Swift "Building Fabric.app in Swift" - Javier Soto. April 2016 1

Slide 2

Slide 2 text

Intro @Javi "Building Fabric.app in Swift" - Javier Soto. April 2016 2

Slide 3

Slide 3 text

"Building Fabric.app in Swift" - Javier Soto. April 2016 3

Slide 4

Slide 4 text

Outline 4 What is Fabric.app? 4 Tools used 4 Architecture 4 Better with Swift 4 Error reporting "Building Fabric.app in Swift" - Javier Soto. April 2016 4

Slide 5

Slide 5 text

What is Fabric.app? "Building Fabric.app in Swift" - Javier Soto. April 2016 5

Slide 6

Slide 6 text

What is Fabric.app? "Building Fabric.app in Swift" - Javier Soto. April 2016 6

Slide 7

Slide 7 text

What is Fabric.app? "Building Fabric.app in Swift" - Javier Soto. April 2016 7

Slide 8

Slide 8 text

Tools "Building Fabric.app in Swift" - Javier Soto. April 2016 8

Slide 9

Slide 9 text

Dependency management "Building Fabric.app in Swift" - Javier Soto. April 2016 9

Slide 10

Slide 10 text

Dependency management 4 SSL Pinning 4 Keychain 4 1Password integration 4 Graphs 4 Networking, caching "Building Fabric.app in Swift" - Javier Soto. April 2016 10

Slide 11

Slide 11 text

Dependency management 4 CocoaPods 4 Carthage "Building Fabric.app in Swift" - Javier Soto. April 2016 11

Slide 12

Slide 12 text

CocoaPods 4 More widely adopted 4 Less work to integrate frameworks 4 Easily link some frameworks only in Debug "Building Fabric.app in Swift" - Javier Soto. April 2016 12

Slide 13

Slide 13 text

Carthage 4 Precompilation == Speed "Building Fabric.app in Swift" - Javier Soto. April 2016 13

Slide 14

Slide 14 text

Swift Package Manager "Building Fabric.app in Swift" - Javier Soto. April 2016 14

Slide 15

Slide 15 text

Interface Builder "Building Fabric.app in Swift" - Javier Soto. April 2016 15

Slide 16

Slide 16 text

AutoLayout "Building Fabric.app in Swift" - Javier Soto. April 2016 16

Slide 17

Slide 17 text

AutoLayout "Building Fabric.app in Swift" - Javier Soto. April 2016 17

Slide 18

Slide 18 text

Storyboards "Building Fabric.app in Swift" - Javier Soto. April 2016 18

Slide 19

Slide 19 text

UIStoryboard class UIStoryboard { func instantiateViewControllerWithIdentifier(_ identifier: String) -> UIViewController } "Building Fabric.app in Swift" - Javier Soto. April 2016 19

Slide 20

Slide 20 text

UIStoryboard let vc = mainStoryboard.instantiateViewControllerWithIdentifier("ApplicationOverviewID") as! ApplicationOverviewVC vc.userSession = ... vc.applicationID = ... "Building Fabric.app in Swift" - Javier Soto. April 2016 20

Slide 21

Slide 21 text

UIStoryboard final class ApplicationOverviewVC { // I hope you like "!"s... var userSession: UserSession! var applicationID: String! func viewDidLoad() { super.viewDidLoad() self.userSession.foo() } } "Building Fabric.app in Swift" - Javier Soto. April 2016 21

Slide 22

Slide 22 text

Storyboards final class ApplicationOverviewVC { let userSession: UserSession let applicationID: String init(userSession: UserSession, applicationID: String) { self.userSession = userSession self.applicationID = applicationID super.init(nibName: ..., bundle: ...) } func viewDidLoad() { super.viewDidLoad() // Compile-time guarantee of object fully initialized self.userSession.foo() } } "Building Fabric.app in Swift" - Javier Soto. April 2016 22

Slide 23

Slide 23 text

Fastlane "Building Fabric.app in Swift" - Javier Soto. April 2016 23

Slide 24

Slide 24 text

Fastlane - https://github.com/fastlane/examples "Building Fabric.app in Swift" - Javier Soto. April 2016 24

Slide 25

Slide 25 text

ReactiveCocoa "Building Fabric.app in Swift" - Javier Soto. April 2016 25

Slide 26

Slide 26 text

ReactiveCocoa self.accountService.muteAllNotifications(untilTime: date) "Building Fabric.app in Swift" - Javier Soto. April 2016 26

Slide 27

Slide 27 text

ReactiveCocoa self.accountService.muteAllNotifications(untilTime: date) .continueWhenApplicationIsBackgrounded(taskName: "Muting notifications") "Building Fabric.app in Swift" - Javier Soto. April 2016 27

Slide 28

Slide 28 text

Tools "Building Fabric.app in Swift" - Javier Soto. April 2016 28

Slide 29

Slide 29 text

Architecture "Building Fabric.app in Swift" - Javier Soto. April 2016 29

Slide 30

Slide 30 text

Architecture FabricAPI.framework "Building Fabric.app in Swift" - Javier Soto. April 2016 30

Slide 31

Slide 31 text

Architecture 4 Massive View Controllers 4 View Models 4 Glue-code View Controllers 4 Table View Data sources "Building Fabric.app in Swift" - Javier Soto. April 2016 31

Slide 32

Slide 32 text

Architecture GenericTableViewDataSource "Building Fabric.app in Swift" - Javier Soto. April 2016 32

Slide 33

Slide 33 text

Architecture GenericTableViewDataSource protocol TableSectionType { associatedtype AssociatedTableRowType: TableRowType var rows: [AssociatedTableRowType] { get } var title: String? { get } } protocol TableRowType { } "Building Fabric.app in Swift" - Javier Soto. April 2016 33

Slide 34

Slide 34 text

Architecture GenericTableViewDataSource final class GenericTableViewDataSource : NSObject, UITableViewDataSource "Building Fabric.app in Swift" - Javier Soto. April 2016 34

Slide 35

Slide 35 text

Architecture GenericTableViewDataSource enum ProjectIssueRow: TableRowType, Equatable { case Loading case NoIssues case ErrorLoadingIssues case ProjectIssue(Issue) } return GenericTableViewDataSource( tableView: tableView, tableViewData: observableProperty, // Observable computeSections: { elements in ... }, /// Pure function from `Elements` to `[SectionType]` configureRow: { row, indexPath in ... } /// Function from `RowType` to `UITableViewCell` ) "Building Fabric.app in Swift" - Javier Soto. April 2016 35

Slide 36

Slide 36 text

Better with Swift "Building Fabric.app in Swift" - Javier Soto. April 2016 36

Slide 37

Slide 37 text

Better with Swift 4 Nullability 4 Type-safe JSON parsing 4 Code generation "Building Fabric.app in Swift" - Javier Soto. April 2016 37

Slide 38

Slide 38 text

Nullability "Building Fabric.app in Swift" - Javier Soto. April 2016 38

Slide 39

Slide 39 text

"Building Fabric.app in Swift" - Javier Soto. April 2016 39

Slide 40

Slide 40 text

Nullability final class ApplicationListViewController: BaseFabricTableViewController "Building Fabric.app in Swift" - Javier Soto. April 2016 40

Slide 41

Slide 41 text

Nullability final class ApplicationListViewController: BaseFabricTableViewController { override viewDidLoad() { super.viewDidLoad() let session = UserSession.currentUserSession if let session = session session { session.requestApplications()... } // or... session!.requestApplications()... } "Building Fabric.app in Swift" - Javier Soto. April 2016 41

Slide 42

Slide 42 text

Nullability final class ApplicationListViewController: BaseFabricTableViewController { init(viewModel: ApplicationListViewModel) } final class ApplicationListViewModel { init(fabricAPI: AuthenticatedFabricAPI) } public final class AuthenticatedFabricAPI { public init(authResponse: AuthResponse) } public final class AuthResponse { let accessToken: String } "Building Fabric.app in Swift" - Javier Soto. April 2016 42

Slide 43

Slide 43 text

"Building Fabric.app in Swift" - Javier Soto. April 2016 43

Slide 44

Slide 44 text

Nullability final class ApplicationListViewModel { var applications: [Application]? } "Building Fabric.app in Swift" - Javier Soto. April 2016 44

Slide 45

Slide 45 text

Nullability enum DataLoadState { case Loading case Failed case Loaded(T) } final class ApplicationListViewModel { var applications: DataLoadState<[Application]> = .Loading } "Building Fabric.app in Swift" - Javier Soto. April 2016 45

Slide 46

Slide 46 text

Type-safe JSON parsing "Building Fabric.app in Swift" - Javier Soto. April 2016 46

Slide 47

Slide 47 text

JSON Parsing Anti-Patterns public struct Application { public var ID: String? public var name: String? public var bundleIdentifier: String? public mutating func decode(j: [String: AnyObject]) { self.ID = j["id"] as? String self.name = j["name"] as? String self.bundleIdentifier = j["identifier"] as? String } } "Building Fabric.app in Swift" - Javier Soto. April 2016 47

Slide 48

Slide 48 text

JSON Parsing Anti-Patterns public struct Application { public let ID: String public let name: String public let bundleIdentifier: String public static func decode(j: [String: AnyObject]) -> Application? { guard let ID = j["id"] as? String, let name = j["name"] as? String, let bundleIdentifier = j["identifier"] as? String else { return nil } return Application( ID: ID, name: name, bundleIdentifier: bundleIdentifier ) } } "Building Fabric.app in Swift" - Javier Soto. April 2016 48

Slide 49

Slide 49 text

Type-safe JSON parsing import Decodable /// https://github.com/Anviking/Decodable public struct Application: Decodable { public let ID: String public let name: String public let bundleIdentifier: String public static func decode(j: AnyObject) throws -> Application { return try Application( ID: j => "id", name: j => "name", bundleIdentifier: j => "identifier" ) } } "Building Fabric.app in Swift" - Javier Soto. April 2016 49

Slide 50

Slide 50 text

Code Generation "Building Fabric.app in Swift" - Javier Soto. April 2016 50

Slide 51

Slide 51 text

Code Generation /// Swift < 2.2 UIBarButtonItem(barButtonSystemItem: .Done, target: self, action: Selector("buttonTapped")) // Swift 2.2 UIBarButtonItem(barButtonSystemItem: .Done, target: self, action: #selector(ViewController.buttonTapped)) "Building Fabric.app in Swift" - Javier Soto. April 2016 51

Slide 52

Slide 52 text

Code Generation super.init(nibName: "ViewControllerNibName", bundle: nil) let nib = UINib(nibName: "NibName", bundle: nil) tableView.registerNib(nib, forCellReuseIdentifier: "ReuseIdentifier") let cell = tableView.dequeueReusableCellWithIdentifier("ReuseIdentifier", forIndexPath: indexPath) as! MyTableViewCell let image = UIImage(named: "ImageName")! "Building Fabric.app in Swift" - Javier Soto. April 2016 52

Slide 53

Slide 53 text

Code Generation: R.swift https://github.com/mac-cain13/R.swift "Building Fabric.app in Swift" - Javier Soto. April 2016 53

Slide 54

Slide 54 text

Code Generation: R.swift https://github.com/mac-cain13/R.swift 4 Nibs 4 Reuse Identifiers 4 Image names in asset catalogs 4 Other file names in the bundle "Building Fabric.app in Swift" - Javier Soto. April 2016 54

Slide 55

Slide 55 text

Code Generation: R.swift https://github.com/mac-cain13/R.swift super.init(nibResource: R.nib.myViewController) class MyTableViewCell: UITableViewCell, ReusableNibTableViewCell { /// This will even fail to compile if it's not the right cell static let nibResource = R.nib.myTableViewCell } tableView.registerReusableNibCell(MyTableViewCell) let cell = MyTableViewCell.dequeueFromTableView(tableView, indexPath) let image = R.image.imageName "Building Fabric.app in Swift" - Javier Soto. April 2016 55

Slide 56

Slide 56 text

Error Reporting "Building Fabric.app in Swift" - Javier Soto. April 2016 56

Slide 57

Slide 57 text

Error Reporting do { try fileManager.createDirectoryAtPath(path, withIntermediateDirectories: true, attributes: nil) /// ... } catch { print("Error: \(error)") } "Building Fabric.app in Swift" - Javier Soto. April 2016 57

Slide 58

Slide 58 text

Error Reporting do { try fileManager.createDirectoryAtPath(path, withIntermediateDirectories: true, attributes: nil) /// ... } catch { Crashlytics.sharedInstance().recordError(error, withAdditionalUserInfo: userInfo) } "Building Fabric.app in Swift" - Javier Soto. April 2016 58

Slide 59

Slide 59 text

Error Reporting "Building Fabric.app in Swift" - Javier Soto. April 2016 59

Slide 60

Slide 60 text

Questions? 4 @Javi 4 javi@twitter.com 4 fabric-app-ios@twitter.com "Building Fabric.app in Swift" - Javier Soto. April 2016 60

Slide 61

Slide 61 text

Thanks ! "Building Fabric.app in Swift" - Javier Soto. April 2016 61