![Page 2: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/2.jpg)
A client comes…
![Page 3: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/3.jpg)
– Our Beloved Client
“I have a start-up, I need an app, previous team sucked so I’d like you to continue develop the
project”
![Page 4: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/4.jpg)
Great!Let’s look at the code.
![Page 5: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/5.jpg)
1Split code to independent single-purpose services.
(no tests without that, sorry)
![Page 6: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/6.jpg)
2Write couple of tests.
![Page 7: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/7.jpg)
Example service:
BeaconManager
![Page 8: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/8.jpg)
Public API
![Page 9: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/9.jpg)
Why should I make a wrapper around
CLLocationManager?
![Page 10: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/10.jpg)
• seamlessly manages permissions
• smoothens out beacon power fluctuations
• doesn’t require all listeners to duplicate single beacon filtering code and leaving beacon logic
• enable / disable listening
• saves energy (takes care of switching between monitoring/ranging automatically)
• takes care of background ranging (☠☠☠)
• it’s listeners actually don’t have to care about anything, only implement code on beacon events.
![Page 11: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/11.jpg)
BeaconManager uses another services/APIs
• CLLocationManager for permissions and background ranging (updating location)
• Logger (sends critical logs to back-end)
• Data
• SyncManager
• NSNotificationCenter
![Page 12: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/12.jpg)
![Page 13: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/13.jpg)
BeaconManager is critical service to test
![Page 14: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/14.jpg)
Singletons.Hard to test.
![Page 15: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/15.jpg)
Objective-C dynamic runtime allows us easily change implementation of classes /
methods.
OCMock!
![Page 16: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/16.jpg)
Can I do this in Swift?
Hmm…
![Page 17: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/17.jpg)
Let’s readhttp://ocmock.org/swift/
![Page 18: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/18.jpg)
There are smart people around who claim differently:
http://nshipster.com/swift-objc-runtime/
IMVHO, not the best option.
![Page 19: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/19.jpg)
Where is Swift going?
Will there ever be runtime access in Swift?
![Page 20: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/20.jpg)
I have no idea.
![Page 21: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/21.jpg)
But if Swift is about to be super-fast and super-safe,
I wouldn’t count on it.
![Page 22: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/22.jpg)
Why Obj-C runtime is so great in testing?
• Effortless and quick mocks/stubs
• No refactoring needed at all. Just jump into writing tests.
![Page 23: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/23.jpg)
Disadvantages of OCMock way of testing?
• No compile-time protection
• We can forget to stub some important things
• Encourages a bit to write ugly code (inline mocks / stubs) which could create problems with duplication later
• No explicit list of dependencies like in dependency injection
• Still have to write mocks / stubs :(
![Page 24: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/24.jpg)
Alternatives?
![Page 25: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/25.jpg)
Stubbing based on abstraction layer.
Service Locator or DI
![Page 26: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/26.jpg)
How does it work?
![Page 27: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/27.jpg)
Service Locator
![Page 28: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/28.jpg)
![Page 29: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/29.jpg)
![Page 30: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/30.jpg)
![Page 31: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/31.jpg)
Advantages of SL
• compile-time
• quite quick to implement (actually, sharedInstance properties could be overwritten so that they call Service Locator themselves).
• Service protocols are a beautiful way to investigate app architecture without going too deep into implementation details
![Page 32: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/32.jpg)
Disadvantages of SL
• We need to complicate architecture (is that really bad thing?)
• We can forget to stub some libs
• No explicit list of dependencies (like in DI)
• Still have to write our stubs :(
![Page 33: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/33.jpg)
Dependency injection
"Dependency Injection" is a 25-dollar term for a 5-cent concept.
James Shore
![Page 34: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/34.jpg)
"Dependency Injection" is a 25-dollar term for a 5-cent concept.
James Shore
![Page 35: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/35.jpg)
![Page 36: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/36.jpg)
![Page 37: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/37.jpg)
![Page 38: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/38.jpg)
We must initialise services and inject properties when
app starts.
![Page 39: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/39.jpg)
We could use some automation for initialising
services.
![Page 40: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/40.jpg)
Advantages of DI• compile-time
• explicit list of dependencies (nice app architecture guard)
• we won’t forget to stub anything
• service protocols are a beautiful way to investigate app architecture without going too deep into implementation details
![Page 41: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/41.jpg)
Disadvantages of DI
• Quite not-so-fast to implement
• Architecture gets more complicated (like in SL)
• We still need to write stubs
![Page 42: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/42.jpg)
SL vs. DI
• http://www.martinfowler.com/articles/injection.html
• http://bayou.io/draft/In_Defense_of_Service_Locator.html
• rest of the Internet
![Page 43: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/43.jpg)
Are there any libraries for Dependency Injection?
![Page 44: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/44.jpg)
Typhoon
Swinject
![Page 45: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/45.jpg)
Typhoon
December, 2012 1667StarsFirst github commit
![Page 46: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/46.jpg)
Swinject
July, 2015 454StarsFirst github commit
![Page 47: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/47.jpg)
There’s a single disadvantage of all testing
methods.
![Page 48: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/48.jpg)
No lib with stubs.
![Page 49: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/49.jpg)
I’d like to test like this
![Page 50: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/50.jpg)
Why do I have to write mocks/stubs for Apple or
3rd party libs?
![Page 51: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/51.jpg)
Let’s take a look at modern framework like
angular.js
![Page 52: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/52.jpg)
Which iOS frameworks could be easily stubbed not to duplicate code?
![Page 53: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/53.jpg)
Summary• method / class swizzling is probably not what you want
in Swift
• service locator is quickest way to get legacy code tested
• typhoon and swinject are 3rd party libs for Swift testing
• swinject seems to be nice
• unfortunately, there are no libraries which out of the box give developers stubs / mocks for Apple APIs.
![Page 54: [CocoaHeads Tricity] Andrzej Dąbrowski - Dependency injection and testable architecture in Swift apps](https://reader031.vdocuments.site/reader031/viewer/2022030214/588aa7b51a28ab4c308b5905/html5/thumbnails/54.jpg)
Thank you