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

Swift User Group - April 2016: Building Fabric.app in Swift

Swift User Group - April 2016: Building Fabric.app in Swift

Collection to tidbits about the things I learned while building the Fabric app.

C0eafab7106ab63b8db4025e57c1a8d2?s=128

Javier Soto

April 14, 2016
Tweet

More Decks by Javier Soto

Other Decks in Programming

Transcript

  1. Building Fabric.app in Swift "Building Fabric.app in Swift" - Javier

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

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

  4. 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
  5. What is Fabric.app? "Building Fabric.app in Swift" - Javier Soto.

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

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

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

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

    2016 9
  10. 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
  11. Dependency management 4 CocoaPods 4 Carthage "Building Fabric.app in Swift"

    - Javier Soto. April 2016 11
  12. 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
  13. Carthage 4 Precompilation == Speed "Building Fabric.app in Swift" -

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

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

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

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

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

    18
  19. UIStoryboard class UIStoryboard { func instantiateViewControllerWithIdentifier(_ identifier: String) -> UIViewController

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

    vc.applicationID = ... "Building Fabric.app in Swift" - Javier Soto. April 2016 20
  21. 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
  22. 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
  23. Fastlane "Building Fabric.app in Swift" - Javier Soto. April 2016

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

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

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

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

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

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

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

    2016 30
  31. 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
  32. Architecture GenericTableViewDataSource "Building Fabric.app in Swift" - Javier Soto. April

    2016 32
  33. 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
  34. Architecture GenericTableViewDataSource final class GenericTableViewDataSource <Elements, SectionType: TableSectionType, RowType: TableRowType

    where SectionType.AssociatedTableRowType == RowType, SectionType: Equatable, RowType: Equatable>: NSObject, UITableViewDataSource "Building Fabric.app in Swift" - Javier Soto. April 2016 34
  35. Architecture GenericTableViewDataSource enum ProjectIssueRow: TableRowType, Equatable { case Loading case

    NoIssues case ErrorLoadingIssues case ProjectIssue(Issue) } return GenericTableViewDataSource( tableView: tableView, tableViewData: observableProperty, // Observable<Elements> 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
  36. Better with Swift "Building Fabric.app in Swift" - Javier Soto.

    April 2016 36
  37. Better with Swift 4 Nullability 4 Type-safe JSON parsing 4

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

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

  40. Nullability final class ApplicationListViewController: BaseFabricTableViewController "Building Fabric.app in Swift" -

    Javier Soto. April 2016 40
  41. 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
  42. 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
  43. "Building Fabric.app in Swift" - Javier Soto. April 2016 43

  44. Nullability final class ApplicationListViewModel { var applications: [Application]? } "Building

    Fabric.app in Swift" - Javier Soto. April 2016 44
  45. Nullability enum DataLoadState<T> { 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
  46. Type-safe JSON parsing "Building Fabric.app in Swift" - Javier Soto.

    April 2016 46
  47. 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
  48. 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
  49. 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
  50. Code Generation "Building Fabric.app in Swift" - Javier Soto. April

    2016 50
  51. 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
  52. 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
  53. Code Generation: R.swift https://github.com/mac-cain13/R.swift "Building Fabric.app in Swift" - Javier

    Soto. April 2016 53
  54. 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
  55. 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
  56. Error Reporting "Building Fabric.app in Swift" - Javier Soto. April

    2016 56
  57. 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
  58. 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
  59. Error Reporting "Building Fabric.app in Swift" - Javier Soto. April

    2016 59
  60. Questions? 4 @Javi 4 javi@twitter.com 4 fabric-app-ios@twitter.com "Building Fabric.app in

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

    2016 61