![Page 1: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/1.jpg)
www.softwarehut.pl 1
Dependency Injection + iOSMichał Karpowicz
![Page 2: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/2.jpg)
www.softwarehut.pl 2
00WSTĘP
![Page 3: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/3.jpg)
www.softwarehut.pl 3
1.Dependency Injection2.TDD3.DYI4.Typhoon
![Page 4: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/4.jpg)
www.softwarehut.pl 4
Projekt
• Dwa View Controllery – DashboardViewController i CustomersViewController• CustomersDataSource• CustomerService• SessionManager
![Page 5: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/5.jpg)
www.softwarehut.pl 5
01Dependency Injection
![Page 6: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/6.jpg)
www.softwarehut.pl 6
Inversion of Control
![Page 7: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/7.jpg)
www.softwarehut.pl 7
Cele
•Podział na moduły•Rozszerzalność
![Page 8: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/8.jpg)
www.softwarehut.pl 8
Dependency Injection
class CustomersDataSource: NSObject { let service: CustomerService override init() { service = CustomerService(manager: SessionManager(baseUrl: "https://api.customer.com", configuration: NSURLSessionConfiguration(), timeout: 30)) } }
![Page 9: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/9.jpg)
www.softwarehut.pl 9
Dependency Injection
![Page 10: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/10.jpg)
www.softwarehut.pl 10
Rodzaje DI
•Extract and override•Method injection•Property injection•Constructor injection
![Page 11: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/11.jpg)
www.softwarehut.pl 11
DEPENDENCY INJECTION?
import UIKitimport Foundation
class UserCredentials { private let authorizationTokenKey = "AuthorizationTokenKey" func getAuthorizationToken() -> String { let value = NSUserDefaults.standardUserDefaults().stringForKey(authorizationTokenKey) guard let retVal = value else { return "" } return retVal }}
![Page 12: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/12.jpg)
www.softwarehut.pl 12
EXTRACT AND OVERRIDE
private let authorizationTokenKey = "AuthorizationTokenKey" func getAuthorizationToken() -> String { let value = userDefaults().stringForKey(authorizationTokenKey) guard let retVal = value else { return "" } return retVal } func userDefaults() -> NSUserDefaults { return NSUserDefaults.standardUserDefaults() }
![Page 13: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/13.jpg)
www.softwarehut.pl 13
METHOD INJECTION
private let authorizationTokenKey = "AuthorizationTokenKey" func getAuthorizationToken(userDefaults userDefaults: NSUserDefaults) -> String { let value = userDefaults.stringForKey(authorizationTokenKey) guard let retVal = value else { return "" } return retVal }
![Page 14: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/14.jpg)
www.softwarehut.pl 14
PROPERTY INJECTION
class UserCredentials { var userDefaults: NSUserDefaults! private let authorizationTokenKey = "AuthorizationTokenKey" func getAuthorizationToken() -> String { let value = userDefaults.stringForKey(authorizationTokenKey) guard let retVal = value else { return "" } return retVal }}
let credentials = UserCredentials()credentials.userDefaults = NSUserDefaults.standardUserDefaults()
![Page 15: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/15.jpg)
www.softwarehut.pl 15
CONSTRUCTOR INJECTION
private let userDefaults: NSUserDefaults private let authorizationTokenKey = "AuthorizationTokenKey" init(userDefaults: NSUserDefaults) { self.userDefaults = userDefaults } func getAuthorizationToken() -> String { let value = userDefaults.stringForKey(authorizationTokenKey) guard let retVal = value else { return "" } return retVal }
let credentials = UserCredentials(NSUserDefaults.standardUserDefaults())
![Page 16: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/16.jpg)
www.softwarehut.pl 16
Dependency Injection
class CustomersDataSource: NSObject { let service: CustomerService override init() { service = CustomerService(manager: SessionManager(baseUrl: "https://api.customer.com", configuration: NSURLSessionConfiguration(), timeout: 30)) } }
![Page 17: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/17.jpg)
www.softwarehut.pl 17
Dependency Injection
let service: CustomerService init(customerService: CustomerService) { service = customerService }
![Page 18: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/18.jpg)
www.softwarehut.pl 18
Dependency Injection
• Niezmienność obiektów• Klasy łatwe do testowania
![Page 19: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/19.jpg)
www.softwarehut.pl 19
02TDD
![Page 20: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/20.jpg)
www.softwarehut.pl 20
TDD
TDD + Dependency Injection = <3
![Page 21: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/21.jpg)
www.softwarehut.pl 21
TDD
Networking Tests
![Page 22: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/22.jpg)
www.softwarehut.pl 22
TDD
Response mock
class MockGETSessionManager: NSObject, SessionManagerProtocol { var success: ((AnyObject) -> ())! func GET(url: String, parameters: AnyObject?, success: (AnyObject) -> (), failure: () -> ()) { self.success = success } }
protocol SessionManagerProtocol { func GET(url: String, parameters: AnyObject?, success: (AnyObject) -> (), failure: () -> ())}
![Page 23: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/23.jpg)
www.softwarehut.pl 23
TDD
Testowanie mockafunc testMockGET() { let mockSessionManager = MockGETSessionManager() let customerService = CustomerService(sessionManager: mockSessionManager) let customerDataSource = CustomersDataSource(customerService: customerService) customerDataSource.fetchData() mockSessionManager.success(NSData()) XCTAssertNotNil(customerDataSource.customers) }
![Page 24: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/24.jpg)
www.softwarehut.pl 24
TDD
Frameworki• OCMockito (Objective-C) - https://github.com/jonreid/OCMockito• Mockingjay (Swift) - https://github.com/kylef/Mockingjay
![Page 25: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/25.jpg)
www.softwarehut.pl 25
03DYI
![Page 26: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/26.jpg)
www.softwarehut.pl 26
DIY
![Page 27: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/27.jpg)
www.softwarehut.pl 27
DIY
class Injector: NSObject { func dashboardViewController() -> DashboardViewController { let viewController = DashboardViewController() viewController.injector = self return viewController }}
![Page 28: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/28.jpg)
www.softwarehut.pl 28
DIY
class AppDelegate: UIResponder, UIApplicationDelegate {
/…/let injector = Injector()
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
window?.rootViewController = injector.dashboardViewController() return true }/.../}
![Page 29: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/29.jpg)
www.softwarehut.pl 29
DIY
func sessionManager() -> SessionManager { let sessionManager = SessionManager(baseUrl: "https://api.customer.com", configuration: NSURLSessionConfiguration(), timeout: 30) return sessionManager} func customerService() -> CustomerService { let customerService = CustomerService(sessionManager: sessionManager()) return customerService}func customerDataSource() -> CustomersDataSource { let dataSource = CustomersDataSource(customerService: customerService()) return dataSource }func customersViewController() -> CustomersViewController { let viewController = CustomersViewController() viewController.injector = self viewController.dataSource = customerDataSource() return viewController}
![Page 30: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/30.jpg)
www.softwarehut.pl 30
DIY
class DashboardViewController: UIViewController {
/.../
func showCustomersView() { let viewController = injector?.customersViewController() navigationController?.pushViewController(viewController!, animated: true) }}
![Page 31: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/31.jpg)
www.softwarehut.pl 31
04TYPHOON
![Page 32: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/32.jpg)
www.softwarehut.pl 32
Typhoon?
http://typhoonframework.org/
• Nie inwazyjny• Wsparcie constructor i property injection• Wstrzykiwanie view controllerów• Integracja ze storyboardami• Minimalne obciążenie CPU• Battle-tested• Aktywnie rozwijany• “Swift”!
![Page 33: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/33.jpg)
www.softwarehut.pl 33
Typhoon - Podstawy
1.Assembly – TyphoonAssembly2.Definition – TyphoonDefinition
![Page 34: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/34.jpg)
www.softwarehut.pl 34
Typhoon - Setup
1.Instalacja2.Stworzenie ApplicationAssembly – subclass TyphoonAssembly3.Dodanie listy TyphoonInitialAssembies do Info.plis
That’s it!
![Page 35: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/35.jpg)
www.softwarehut.pl 35
Typhoon - Instalacja
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!
target 'DI-Typhoon' do pod 'Typhoon'End
Podfile:
pod installTerminal:
![Page 36: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/36.jpg)
www.softwarehut.pl 36
Typhoon – ApplicationAssembly
import Typhoon
class ApplicationAssembly: TyphoonAssembly { dynamic func appDelegate() -> AnyObject { return TyphoonDefinition.withClass(AppDelegate.self) { definition in } }}
![Page 37: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/37.jpg)
www.softwarehut.pl 37
Typhoon
Real life scenario
![Page 38: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/38.jpg)
www.softwarehut.pl 38
Typhoon – Projekt startowy
Lista TyphoonAssemblies:• ApplicationAssembly• ViewControllerAssembly• DataSourceAssembly• CoreServicesAssembly
![Page 39: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/39.jpg)
www.softwarehut.pl 39
ApplicationAssembly
class ApplicationAssembly: TyphoonAssembly { var viewControllerAssembly: ViewControllerAssembly! dynamic func appDelegate() -> AnyObject { return TyphoonDefinition.withClass(AppDelegate.self) { definition in definition.injectProperty("viewControllerAssembly", with: self.viewControllerAssembly) } }}
![Page 40: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/40.jpg)
www.softwarehut.pl 40
ViewControllerAssembly
class ViewControllerAssembly: TyphoonAssembly { var dataSourceAssembly: DataSourceAssembly! dynamic func customersViewController() -> AnyObject { return TyphoonDefinition.withClass(CustomersViewController.self) { definition in definition.useInitializer("init") { initializer in } definition.injectProperty("dataSource", with: self.dataSourceAssembly.customerDataSource()) definition.injectProperty("viewControllerAssembly", with: self) } } /.../}
![Page 41: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/41.jpg)
www.softwarehut.pl 41
DataSourceAssembly
class DataSourceAssembly: TyphoonAssembly { var coreServicesAssembly: CoreServicesAssembly! dynamic func customerDataSource() -> AnyObject { return TyphoonDefinition.withClass(CustomersDataSource.self) { definition in definition.useInitializer("initWithCustomerService:") { initializer in initializer.injectParameterWith(self.coreServicesAssembly.customerService()) } } }}
![Page 42: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/42.jpg)
www.softwarehut.pl 42
CoreServicesAssembly
dynamic func sessionManager() -> AnyObject { return TyphoonDefinition.withClass(SessionManager.self) { definition in definition.useInitializer("initWithBaseUrl:configuration:timeout:") { initializer in initializer.injectParameterWith("https://api.customer.com") initializer.injectParameterWith(NSURLSessionConfiguration()) initializer.injectParameterWith(30) } } }dynamic func customerService() -> AnyObject { return TyphoonDefinition.withClass(CustomerService.self) { definition in definition.useInitializer("initWithSessionManager:") { initializer in initializer.injectParameterWith(self.sessionManager()) } } }
![Page 43: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/43.jpg)
www.softwarehut.pl 43
AppDelegate
class AppDelegate: UIResponder, UIApplicationDelegate {
/…/var viewControllerAssembly: ViewControllerAssembly!
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
window?.rootViewController = viewControllerAssembly.dashboardViewController() as! DashboardViewController return true }/.../}
![Page 44: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/44.jpg)
www.softwarehut.pl 44
Typhoon
Dlaczego “Swift”?
![Page 45: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/45.jpg)
www.softwarehut.pl 45
Typhoon
![Page 46: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/46.jpg)
www.softwarehut.pl 46
PYTANIA?
![Page 47: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/47.jpg)
www.softwarehut.pl 47
PYTANIA I CHABORY
![Page 48: Mobile Bialystok #5 Dependency Injection iOS @Michał Karpowicz](https://reader036.vdocuments.mx/reader036/viewer/2022062503/589b71821a28abdd258b6335/html5/thumbnails/48.jpg)
www.softwarehut.pl 48
DZIĘKUJĘ ZA UWAGĘ
Siedziba firmy:Sienkiewicza 11015-005 Białystok