Slide 1

Slide 1 text

Building the Fabric iOS App @Javi 1 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 2

Slide 2 text

Outline → Fabric → GraphQL → Dependency Injection → Error Reporting → Fastlane 2 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 3

Slide 3 text

What's Fabric? 3 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 4

Slide 4 text

Fabric 4 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 5

Slide 5 text

Fabric 5 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 6

Slide 6 text

GraphQL1 1 http://graphql.org/ 6 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 7

Slide 7 text

GraphQL - Queries → GET /users/ 7 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 8

Slide 8 text

GraphQL - Queries → GET /users/ → GET /users//friends 8 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 9

Slide 9 text

GraphQL - Queries 9 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 10

Slide 10 text

GraphQL - Queries { user(id: 4802170) { name profilePicture(size: 50) { uri width } friends(first: 5) { id name } } } 10 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 11

Slide 11 text

GraphQL - Queries { "data": { "user": { "id": "4802170", "name": "Javi", "profilePicture": { "uri": "http://bit.ly/1E8lYDq", "width": 50 }, "friends": [ { "id": "305249", "name": "Jony Ive" }, { "id": "3108935", "name": "Elon Musk" } ] } } } 11 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 12

Slide 12 text

GraphQL - Features → Hierarchical, human-readable query language → Strongly-typed → Version free 12 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 13

Slide 13 text

GraphQL - GraphiQL 13 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 14

Slide 14 text

Dependency Injection 14 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 15

Slide 15 text

Dependency injection Software design pattern that implements inversion of control for resolving dependencies. An injection is the passing of a dependency to a dependent object that would use it. — https://en.wikipedia.org/wiki/ Dependency_injection 15 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 16

Slide 16 text

Dependencies → View Controller => Data Provider → Data Provider => API Client → Persistence Manager => Database Client 16 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 17

Slide 17 text

Dependency Resolution → Self-instantiation → Global access → Injection via setters → Injection via constructor 17 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 18

Slide 18 text

Dependency Resolution - Self-Instantiation class ViewController { private let dataProvider: DataProvider init() { self.dataProvider = DataProvider() } } 18 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 19

Slide 19 text

Dependency Resolution - Global Access class ViewController { private let dataProvider: DataProvider init() { self.dataProvider = DataProvider.shared } } 19 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 20

Slide 20 text

Dependency Resolution - Injection via Setters class ViewController { var dataProvider: DataProvider! init() { } } 20 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 21

Slide 21 text

Dependency Resolution - Injection via Constructor class ViewController { private let dataProvider: DataProvider init(dataProvider: DataProvider) { self.dataProvider = dataProvider } } 21 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 22

Slide 22 text

Easy vs Simple 22 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 23

Slide 23 text

Easy - Hard Simple - Complex 23 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 24

Slide 24 text

Dependency injection Implicit vs explicit 24 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 25

Slide 25 text

Dependency injection - UIStoryboard class UIStoryboard { func instantiateViewController(withIdentifier identifier: String) -> UIViewController } 25 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 26

Slide 26 text

Dependency injection - UIStoryboard let sb = UIStoryboard... let vc = sb.instantiateViewController(withIdentifier: "ID") as! ApplicationOverviewVC vc.userSession = ... vc.applicationID = ... 26 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 27

Slide 27 text

Dependency injection - UIStoryboard final class ApplicationOverviewVC { // I hope you like "!"s... var userSession: UserSession! var applicationID: String! func viewDidLoad() { super.viewDidLoad() self.userSession.foo() // Or... if let userSession = self.userSession { userSession.foo() } else { /* Can't do anything useful here... */ } } } 27 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 28

Slide 28 text

28 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 29

Slide 29 text

Dependency injection in the Fabric app final class ApplicationListViewController: UIViewController { init(viewModel: ApplicationListViewModel) } final class ApplicationListViewModel { init(fabricAPI: AuthenticatedFabricAPI) } public final class AuthenticatedFabricAPI { public init(session: Session) } public struct Session { let accessToken: String } 29 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 30

Slide 30 text

DataLoadState final class ApplicationListViewModel { var applications: [Application]? } 30 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 31

Slide 31 text

DataLoadState enum DataLoadState { case loading case failed case loaded(T) } final class ApplicationListViewModel { var applications: DataLoadState<[Application]> = .loading } 31 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 32

Slide 32 text

Error Reporting 32 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 33

Slide 33 text

Error Reporting class Crashlytics { public func record(_ error: NSError, withAdditionalUserInfo: [AnyHashable : Any]?) } 33 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 34

Slide 34 text

Error Reporting 34 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 35

Slide 35 text

Error Reporting public protocol ReportableError: Swift.Error { var info: [String : Any] { get } var underlyingErrors: [ReportableError] { get } } 35 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 36

Slide 36 text

Error Reporting private enum URLHandlerError: ReportableError { case unknownURL(URL) case malformedURLMissingParameter /// This is useful because the `NSError` conversion will only give us a "code" integer. private var name: String { switch self { case .unknownURL: return "UnknownURL" case .malformedURLMissingParameter: return "MalformedURLMissingParameter" } } var info: [String : Any] { var info: [String : Any] = ["name": self.name] switch self { case let .unknownURL(url): info["url"] = url.path ?? "" case .malformedURLMissingParameter: () } return info } } 36 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 37

Slide 37 text

Error Reporting extension ReportableError { var errorCode: Int { return (self as Error).code } var errorDomain: String { return (self as Error).domain } var asNSError: NSError { return NSError( domain: self.errorDomain, code: self.errorCode, userInfo: self.info ) } } 37 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 38

Slide 38 text

Error Reporting var allErrors: [ReportableError] { return [ [self], self.underlyingErrors.flatMap { $0.allErrors } // Recur ] .flatMap { $0 } } 38 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 39

Slide 39 text

Error Reporting public final class ErrorReporting { // We get file and function names for free internal func report( error: ReportableError, filePath: StaticString = #file, functionName: StaticString = #function, lineNumber: Int = #line ) { error.allErrors.forEach { var userInfo = $0.info userInfo["file"] = "\((filePath as NSString).lastPathComponent):\(lineNumber)" userInfo["function"] = functionName Crashlytics.sharedInstance().recordError($0.asNSError, withAdditionalUserInfo: userInfo) } } } 39 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 40

Slide 40 text

40 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 41

Slide 41 text

Fastlane → Code signing → Deployment 41 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 42

Slide 42 text

Fastlane - Code Signing 42 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 43

Slide 43 text

Fastlane - Code Signing https://codesigning.guide/ 43 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 44

Slide 44 text

Fastlane - 44 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 45

Slide 45 text

Fastlane - Deployment 45 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 46

Slide 46 text

Fastlane - Deployment lane :appstore do snapshot # Generate screenshots for the App Store match # Ensure code signing is set-up gym # Build your app deliver # Upload the screenshots and the binary to iTunes slack # Let your team-mates know the new version is live end 46 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 47

Slide 47 text

Fastlane - Deployment lane :appstore do snapshot # Generate screenshots for the App Store match # Ensure code signing is set-up gym # Build your app deliver # Upload the screenshots and the binary to iTunes slack # Let your team-mates know the new version is live end $ fastlane appstore 47 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 48

Slide 48 text

Fastlane - Deployment lane :appstore do |options| ensure_git_branch(branch: "(master|release\\S+)") ensure_git_status_clean ensure_xcode_version(version: "8.0") increment_version_number(version_number: options[:version_number]) build_number = increment_build_number complete_version_number = "#{version_number} (#{build_number})" commit_version_bump(message: "Version bump to #{complete_version_number}") set_github_release(repository_name: "...", name: complete_version_number) ... end $ fastlane appstore version_number:1.6.0 48 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 49

Slide 49 text

Fastlane.tools 49 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 50

Slide 50 text

Questions? @Javi / [email protected] 50 — "Building the Fabric iOS App" - @Javi. NSSpain 2016

Slide 51

Slide 51 text

Thanks ! 51 — "Building the Fabric iOS App" - @Javi. NSSpain 2016