Compare commits
385 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a1ece4b0ab | |||
| 0b00e13e00 | |||
| 4aec626a1f | |||
| d477392deb | |||
| 3b23dc1a6f | |||
| 1d7d0052bf | |||
| b1fee5c1db | |||
| e19b65d9c2 | |||
| 86bb28da14 | |||
| e4545e3ed3 | |||
| 52455e663c | |||
| 7a10d1e46e | |||
| e95df85503 | |||
| a028c05271 | |||
| e18a4b131f | |||
| e2799279ab | |||
| ffb61be63c | |||
| 0070522341 | |||
| 6842a016bf | |||
| 6a6c4a358e | |||
| 734e67f124 | |||
| aa46ef79b9 | |||
| 2d177b7aea | |||
| 3ada18d756 | |||
| 2441f096d6 | |||
| f9f2777474 | |||
| 1dca889730 | |||
| 86b23d7260 | |||
| 85897e562d | |||
| cdb5f1b901 | |||
| 03903931f2 | |||
| 5016ce860c | |||
| 8da6be8cad | |||
| 873347aed0 | |||
| 637ff1f916 | |||
| c8ddfad188 | |||
| 22d73210d0 | |||
| feeb7b424a | |||
| a6d2a1b1ab | |||
| fa400b9a50 | |||
| 771c993d78 | |||
| 10d2560b57 | |||
| 2887b78944 | |||
| ed6d45e372 | |||
| 7654737a34 | |||
| f1d35a6a96 | |||
| 0b355e0fbe | |||
| 9a8e189ce7 | |||
| 53ff00f00d | |||
| 1c18eab371 | |||
| cd47d888aa | |||
| 499b0c1e38 | |||
| 6536a2182d | |||
| e2ae164d3e | |||
| 092afd8a8b | |||
| a7985f949a | |||
| 967e1a43cb | |||
| 73225ddd10 | |||
| 2d238265ca | |||
| cdfbf3dbfe | |||
| 21a3b43d9b | |||
| 8f0f49e790 | |||
| 7c5966ab61 | |||
| c41696cd23 | |||
| 6e7a168fb7 | |||
| a2efe0abff | |||
| d876389c19 | |||
| 5c54e07219 | |||
| 0e32a79d8c | |||
| 37c8b3d03d | |||
| 21ea965607 | |||
| 80d8b1ba99 | |||
| 975041933e | |||
| 404b65b633 | |||
| 73a78ed5a0 | |||
| 2371338e9b | |||
| 65f4b0a4ab | |||
| 2c7444fef8 | |||
| daad001e17 | |||
| 11ed3c975a | |||
| 02e0877fcb | |||
| 54844f8459 | |||
| fe006c4f13 | |||
| 8e0e165aa4 | |||
| 0319bcff97 | |||
| ffdfdb0826 | |||
| c0884deddd | |||
| 23318bbb7b | |||
| 2800c84553 | |||
| 18087d67c9 | |||
| ab235c23e9 | |||
| c82dfb3dbe | |||
| 2865a07e5a | |||
| ac5999011d | |||
| cd92deeccd | |||
| 4f1dbd1e48 | |||
| 51e95fe73c | |||
| aaab404d45 | |||
| 55da6f3707 | |||
| e24d4cb577 | |||
| b733c74e34 | |||
| 5927ab9471 | |||
| 86a7289d2c | |||
| 2c85a01f0d | |||
| bb85e27db8 | |||
| eadd87a5bb | |||
| 4c4b9ef57a | |||
| ee99cf4fdc | |||
| 40dfd6419f | |||
| 88fa94ed30 | |||
| 58d1813681 | |||
| 7277b940ca | |||
| 581c241fd1 | |||
| 3c9d2a6db8 | |||
| 10309c1d5d | |||
| 2a27152fa1 | |||
| e04a741479 | |||
| dbaba50c88 | |||
| 032db2d2b1 | |||
| b2456e0430 | |||
| fd17075a8a | |||
| 2d9be9acc0 | |||
| efd279b26b | |||
| b5cb796f5f | |||
| e1fd904842 | |||
| c65ae6cedd | |||
| 21aedcb655 | |||
| 37d0e4750f | |||
| 95157a99f6 | |||
| 1ad3aa2c18 | |||
| 1c916cbafc | |||
| 86b6afe5d9 | |||
| a1e7a1f958 | |||
| c414882c6a | |||
| f8cd1c4dc3 | |||
| 3e68acd37b | |||
| 9b047e4145 | |||
| f31236688d | |||
| af61fea49e | |||
| 8c9172aac9 | |||
| 5495bd2b97 | |||
| b3e6c3c61a | |||
| be86b30da3 | |||
| 26ba11dcbf | |||
| 1356a8056f | |||
| 0ddb37bea3 | |||
| 537cad5923 | |||
| 0c4ce2213b | |||
| a91dacb29c | |||
| 895a6f2583 | |||
| 73f71a99b2 | |||
| 41664914f4 | |||
| 53bc97ba63 | |||
| c321189b66 | |||
| 317d67ca90 | |||
| cbcef835f7 | |||
| 47a1870de1 | |||
| da2197c909 | |||
| 3ee8b04118 | |||
| 29c1a3805f | |||
| 4dc11a6e2d | |||
| 7a4d9c554c | |||
| cf4bb0352a | |||
| 8c6a822eca | |||
| 4c6718efb3 | |||
| 1306f12804 | |||
| 764cb98a59 | |||
| 130d71ce3c | |||
| 490c2a4d56 | |||
| 6e98f270bf | |||
| b3d090c3fd | |||
| 4e5cf238c9 | |||
| f4f660d81d | |||
| 211b2fce97 | |||
| 3aa79d1c69 | |||
| 4d085d1329 | |||
| 84845c9b17 | |||
| f4c38f281e | |||
| 99315e32eb | |||
| b48fe9840a | |||
| 6a6fbf906b | |||
| 7e5a0c8ada | |||
| 1f7ce50035 | |||
| 6656116e12 | |||
| 3700f687a2 | |||
| 92499c9561 | |||
| 7c5ea83dc4 | |||
| 4793232d8c | |||
| 2c09b4d6d1 | |||
| 34e920a348 | |||
| 3357630deb | |||
| f23492ee40 | |||
| c817980dd8 | |||
| 328d1b98a5 | |||
| 9f77677014 | |||
| b13a38cf9e | |||
| edb0d3e576 | |||
| bd8a503085 | |||
| 6af8f18a63 | |||
| bcf2329312 | |||
| b01b7fb055 | |||
| 0515e7358d | |||
| 463f9a37a3 | |||
| 6c802d2c39 | |||
| 967a2342b4 | |||
| d7b3db1476 | |||
| f65949bafc | |||
| ba420c27a1 | |||
| ef66212ba3 | |||
| 1d71eb08ca | |||
| 689ff2ed29 | |||
| 126c5d3191 | |||
| 3b4dab4c97 | |||
| 7de69e1fa0 | |||
| a44d11b72f | |||
| 7352769a47 | |||
| 5be2995ef1 | |||
| 306a52f9d5 | |||
| 764024700f | |||
| ee6c9b6115 | |||
| da5cc8f1a7 | |||
| b7b586cba1 | |||
| b50691205a | |||
| d3d1f3cbf9 | |||
| 8d4c71fe5a | |||
| 591c1bfefc | |||
| 786b56b5ea | |||
| 4938023a60 | |||
| 0db1d2433d | |||
| fbb1bcc94f | |||
| f41d28382d | |||
| 7a242a7656 | |||
| 1c7e8419c7 | |||
| 03cf8f7b32 | |||
| a36efc1c5e | |||
| 19d1d38d63 | |||
| 2bae6bce60 | |||
| 66bca3d5b6 | |||
| 4dcdabc8ae | |||
| d8859fb44a | |||
| fef5eb10ac | |||
| fc337f0fe3 | |||
| d3759baff6 | |||
| bd45b97400 | |||
| 4479b58ace | |||
| 47043a213e | |||
| cc399031e7 | |||
| d50ca57d49 | |||
| 6f5ab994a0 | |||
| 33601418f3 | |||
| 691762242f | |||
| 345b6e164a | |||
| 4b0554b539 | |||
| d786eb17dd | |||
| d4d275cda6 | |||
| cdf9f43c9b | |||
| f8a4b40281 | |||
| 3803a72548 | |||
| 8f3fad759e | |||
| c6bf18181f | |||
| d6908e1feb | |||
| 288673ecb3 | |||
| 14c13d7f35 | |||
| 11a9c7fb70 | |||
| c670a220d5 | |||
| 049737dd2f | |||
| 79adaed6d3 | |||
| c7f9c82f81 | |||
| ad9c095041 | |||
| 409f0f1990 | |||
| 685809e6ec | |||
| dcea032624 | |||
| ace73a2672 | |||
| ff6645d012 | |||
| e3448d9148 | |||
| b14c4aeb10 | |||
| 0adc671bd1 | |||
| 1d7533a516 | |||
| 6ad4b82ec0 | |||
| 6bc96bc8af | |||
| 8b9879a9a2 | |||
| 406e47206a | |||
| 69e8eef0f1 | |||
| 78e789cbce | |||
| ebbe9a1513 | |||
| bc0511261f | |||
| 6a0fa295cb | |||
| 73d8990afa | |||
| d7d8f28a36 | |||
| e97883efb0 | |||
| 342fdf9c92 | |||
| feb5064b93 | |||
| 9778236416 | |||
| 184e1f4543 | |||
| b50046c071 | |||
| 8be1139114 | |||
| afc8e49b18 | |||
| 333fa96b62 | |||
| d611ea240e | |||
| ee16baacfc | |||
| b4221e25a1 | |||
| 0edd3747e8 | |||
| 0c93e868f0 | |||
| ada995590f | |||
| c0e5df3443 | |||
| 37d42281c1 | |||
| 6c56e12eeb | |||
| 948b3cd780 | |||
| adde50a3d0 | |||
| 450a2f8a72 | |||
| 59719a0c37 | |||
| f6afdfd08e | |||
| abf2202eeb | |||
| 938108f2ab | |||
| 9d619d6a25 | |||
| 58efc586db | |||
| 3a2aecbe48 | |||
| 2708f7e434 | |||
| 378432e376 | |||
| 62b99edb59 | |||
| 4166afa387 | |||
| b15fc47935 | |||
| 5623ff9d13 | |||
| 79ef7e72f5 | |||
| aacf2adbd3 | |||
| bc516a3cc3 | |||
| 66ef3f7697 | |||
| 794dec0d95 | |||
| 3f0d66bbd9 | |||
| 24e5c002ed | |||
| 3317a9d994 | |||
| 53c770c7fc | |||
| 04a6230dd8 | |||
| 5adb520a69 | |||
| 69da1b0e1f | |||
| 4e101cab4d | |||
| a985ccb407 | |||
| 42ea4b155b | |||
| 3ccbff4780 | |||
| 72663deec7 | |||
| b9bf2da0d4 | |||
| 89acac24c5 | |||
| 2ea5e17a51 | |||
| f1c7c52f14 | |||
| ae04c11ae8 | |||
| b5fca0a306 | |||
| 04aa2e190e | |||
| e97e3974d2 | |||
| 6faf08096a | |||
| 23924ce4a4 | |||
| 85807fea9c | |||
| ecac5ce29f | |||
| fbd4cb8321 | |||
| 9e528da256 | |||
| ec3d979391 | |||
| 25ef719be0 | |||
| a37a8f2dbb | |||
| 1de582a2a5 | |||
| 7952c0850a | |||
| 156347d5c2 | |||
| dbc8900270 | |||
| 6162c26963 | |||
| 7f9c54e484 | |||
| ec177fba78 | |||
| 6b6f85ba4c | |||
| 5f845e6701 | |||
| 0028083289 | |||
| 10dd5a51a5 | |||
| 4e3a53997e | |||
| ae8d56e5d8 | |||
| bc303da493 | |||
| 0db3155835 | |||
| 74112c6051 | |||
| a98a9eed56 | |||
| a4f6db4f8d | |||
| a74b527324 | |||
| 225fb70bd4 | |||
| 368d4f920f | |||
| 61042efb53 | |||
| 4ba6e48fd2 | |||
| 2303aee66f | |||
| 7dd3fc3c5c | |||
| c920c4f425 | |||
| c0833fd92f | |||
| 31673bbf21 |
@@ -32,3 +32,7 @@ Carthage
|
||||
# `pod install` in .travis.yml
|
||||
#
|
||||
# Pods/
|
||||
|
||||
# SPM
|
||||
.build/
|
||||
Packages
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
3.0
|
||||
@@ -1,15 +1,34 @@
|
||||
language: objective-c
|
||||
osx_image: xcode7
|
||||
matrix:
|
||||
allow_failures:
|
||||
- os: linux
|
||||
include:
|
||||
- script:
|
||||
- set -o pipefail && xcodebuild test -workspace Dip.xcworkspace -scheme Dip -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6,OS=latest' ONLY_ACTIVE_ARCH=NO | xcpretty -c
|
||||
- set -o pipefail && xcodebuild test -workspace Dip.xcworkspace -scheme Dip -sdk macosx -destination 'platform=macOS,arch=x86_64' ONLY_ACTIVE_ARCH=NO | xcpretty -c
|
||||
- set -o pipefail && xcodebuild test -workspace Dip.xcworkspace -scheme Dip -sdk appletvsimulator -destination 'platform=tvOS Simulator,name=Apple TV 1080p,OS=latest' ONLY_ACTIVE_ARCH=NO | xcpretty -c
|
||||
- set -o pipefail && xcodebuild -workspace Dip.xcworkspace -scheme Dip -sdk watchsimulator -destination 'platform=watchOS Simulator,name=Apple Watch - 38mm,OS=latest' ONLY_ACTIVE_ARCH=NO | xcpretty - c
|
||||
- set -o pipefail && xcodebuild test -workspace Dip.xcworkspace -scheme DipSampleApp -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6,OS=latest' ONLY_ACTIVE_ARCH=NO | xcpretty -c
|
||||
- pod spec lint
|
||||
- carthage build --no-skip-current
|
||||
os: osx
|
||||
osx_image: xcode8
|
||||
language: objective-c
|
||||
before_install:
|
||||
- gem install cocoapods --version 1.1.0.rc.2 --no-document
|
||||
- script:
|
||||
- swift build --clean && swift build && swift test
|
||||
os: linux
|
||||
dist: trusty
|
||||
sudo: required
|
||||
language: generic
|
||||
before_install:
|
||||
- wget -q -O - https://swift.org/keys/all-keys.asc | gpg --import -
|
||||
- cd ..
|
||||
- export SWIFT_VERSION=swift-3.0-RELEASE
|
||||
- wget https://swift.org/builds/swift-3.0-release/ubuntu1404/$SWIFT_VERSION/$SWIFT_VERSION-ubuntu14.04.tar.gz
|
||||
- tar xzf $SWIFT_VERSION-ubuntu14.04.tar.gz
|
||||
- export PATH="${PWD}/${SWIFT_VERSION}-ubuntu14.04/usr/bin:${PATH}"
|
||||
- cd Dip
|
||||
|
||||
# cache: cocoapods
|
||||
# podfile: Example/Podfile
|
||||
# before_install:
|
||||
# - gem install cocoapods # Since Travis is not always on latest version
|
||||
# - pod install --project-directory=Example
|
||||
|
||||
install:
|
||||
- gem install xcpretty --no-rdoc --no-ri --no-document --quiet
|
||||
|
||||
script:
|
||||
- set -o pipefail && xcodebuild test -workspace Example/Dip.xcworkspace -scheme DipSampleApp -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6,OS=latest' ONLY_ACTIVE_ARCH=NO | xcpretty -c
|
||||
- pod lib lint --quick
|
||||
notifications:
|
||||
email: false
|
||||
|
||||
@@ -1,7 +1,272 @@
|
||||
# CHANGELOG
|
||||
|
||||
## 5.0.2
|
||||
|
||||
#### Fixed
|
||||
|
||||
* Fixed Swift 3 issues related to reflection and IUO
|
||||
[#125](https://github.com/AliSoftware/Dip/issues/125), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
|
||||
## 5.0.1
|
||||
|
||||
This release is the same as 5.0.0 and only fixes CocoaPods speck pushed to trunk without macOS, tvOS and watchOS deployment targets. Please use this release instead of 5.0.0 if you integrate Dip via Cocoapods.
|
||||
|
||||
## 5.0.0
|
||||
|
||||
* Migrated to Swift 3.0
|
||||
[#120](https://github.com/AliSoftware/Dip/issues/120), [@patrick-lind](https://github.com/patrick-lind), [@mark-urbanthings](https://github.com/mark-urbanthings), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Renamed `DefinitionOf` to `Definition` and some other source-breaking refactoring.
|
||||
[#113](https://github.com/AliSoftware/Dip/issues/113), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Added `invalidType` error when resolved instance does not implement requested type.
|
||||
[#118](https://github.com/AliSoftware/Dip/issues/118), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Added optional `type` parameter in register methods to be able to specify type when registering using method literal instead of closure.
|
||||
[#115](https://github.com/AliSoftware/Dip/issues/115), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Added `implements` family of methods in to `Definition` to register type-forwarding definitions.
|
||||
[#114](https://github.com/AliSoftware/Dip/issues/114), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Shared scope is now the default scope.
|
||||
[#112](https://github.com/AliSoftware/Dip/issues/112), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Single target project setup.
|
||||
[#121](https://github.com/AliSoftware/Dip/issues/121), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Simplified implementation of auto-wiring.
|
||||
[#117](https://github.com/AliSoftware/Dip/issues/117), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
|
||||
|
||||
#### Fixed
|
||||
* Auto-injected properties inherited from super class are now properly injected when resolving subclass.
|
||||
Added `resolveDependencies(_:DependencyContainer)` method to `Resolvable` protocol to handle inheritance when resolving.
|
||||
[#116](https://github.com/AliSoftware/Dip/issues/116), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
|
||||
|
||||
## 4.6.1
|
||||
|
||||
#### Fixed
|
||||
|
||||
* Fixed sharing singletons between collaborating containers.
|
||||
[#103](https://github.com/AliSoftware/Dip/issues/103), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Renamed some public API's (see release notes for more info).
|
||||
[#105](https://github.com/AliSoftware/Dip/issues/105), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
|
||||
## 4.6.0
|
||||
|
||||
* Containers collaboration. Break your definitions in modules and link them together.
|
||||
[#95](https://github.com/AliSoftware/Dip/pull/95), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Added WeakSingleton scope.
|
||||
[#96](https://github.com/AliSoftware/Dip/pull/96), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Properties Auto-injection now is performed before calling `resolveDependencies` block
|
||||
[#97](https://github.com/AliSoftware/Dip/pull/97), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Fixed updating container's context when resolving properties with auto-injection.
|
||||
[#98](https://github.com/AliSoftware/Dip/pull/98), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Improved logging.
|
||||
[#94](https://github.com/AliSoftware/Dip/pull/94), [#99](https://github.com/AliSoftware/Dip/pull/99), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Fixed warning about using only extensions api.
|
||||
[#92](https://github.com/AliSoftware/Dip/pull/92), [@mwoollard](https://github.com/mwoollard)
|
||||
|
||||
## 4.5.0
|
||||
|
||||
* Added weakly-typed API to resolve components when exact type is unknown during compile time.
|
||||
[#79](https://github.com/AliSoftware/Dip/pull/79), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Added type forwarding feature. You can register the same factory to resolve different types.
|
||||
[#89](https://github.com/AliSoftware/Dip/pull/89), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Container now can resolve optional types :tada:
|
||||
[#84](https://github.com/AliSoftware/Dip/pull/84), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Added container context that provides contextual information during graph resolution process.
|
||||
[#83](https://github.com/AliSoftware/Dip/pull/83), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Added method to validate container configuration.
|
||||
[#87](https://github.com/AliSoftware/Dip/pull/87), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Added method to manually set value wrapped by auto-injection wrappers.
|
||||
[#81](https://github.com/AliSoftware/Dip/pull/81), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Added separate error type for failures during auto-wiring.
|
||||
[#85](https://github.com/AliSoftware/Dip/pull/85), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
|
||||
|
||||
## 4.4.0
|
||||
|
||||
* Added `.EagerSingleton` scope for objectes requiring early instantiation and `bootstrap()` method on `DepenencyContainer`.
|
||||
[#65](https://github.com/AliSoftware/Dip/pull/65), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Reverted order of `Resolvable` callbacks.
|
||||
[#67](https://github.com/AliSoftware/Dip/pull/67), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
|
||||
## 4.3.1
|
||||
|
||||
* Fix Swift 2.2 compile errors in tests.
|
||||
[#62](https://github.com/AliSoftware/Dip/pull/62), [@mwoollard](https://github.com/mwoollard)
|
||||
|
||||
## 4.3.0
|
||||
|
||||
* Added `DependencyTagConvertible` protocol for better typed tags.
|
||||
[#50](https://github.com/AliSoftware/Dip/pull/50), [@gavrix](https://github.com/gavrix)
|
||||
* Auto-wiring. `DependencyContainer` resolves constructor arguments automatically.
|
||||
[#55](https://github.com/AliSoftware/Dip/pull/55), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Added `Resolvable` protocol to get a callback when dependencies graph is complete.
|
||||
[#57](https://github.com/AliSoftware/Dip/pull/57), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Removed `DipError.ResolutionFailed` error for better consistency.
|
||||
[#58](https://github.com/AliSoftware/Dip/pull/58), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
|
||||
|
||||
## 4.2.0
|
||||
|
||||
* Added support for Swift Package Manager.
|
||||
[#41](https://github.com/AliSoftware/Dip/pull/41), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Added Linux support.
|
||||
[#42](https://github.com/AliSoftware/Dip/pull/42), [#46](https://github.com/AliSoftware/Dip/pull/46), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Fixed the issue that could cause singleton instances to be reused between different containers.
|
||||
[#43](https://github.com/AliSoftware/Dip/pull/43), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Added public `AutoInjectedPropertyBox` protocol for user-defined auto-injected property wrappers.
|
||||
[#49](https://github.com/AliSoftware/Dip/pull/49), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
|
||||
|
||||
## 4.1.0
|
||||
|
||||
#### New features
|
||||
|
||||
* Added auto-injection feature.
|
||||
[#13](https://github.com/AliSoftware/Dip/pull/13), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Factories and `resolveDependencies` blocks of `DefinitionOf` are now allowed to `throw`. Improved errors handling.
|
||||
[#32](https://github.com/AliSoftware/Dip/pull/32), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Thread safety reimplemented with support for recursive methods calls.
|
||||
[#31](https://github.com/AliSoftware/Dip/pull/31), [@mwoollard](https://github.com/mwoollard)
|
||||
|
||||
|
||||
## 4.0.0
|
||||
|
||||
#### New Features
|
||||
|
||||
* Added support for circular dependencies:
|
||||
* Added `ObjectGraph` scope to reuse resolved instances
|
||||
* Added `resolveDependencies` method on `DefinitionOf` class to resolve dependencies of resolved instance.
|
||||
[#11](https://github.com/AliSoftware/Dip/pull/11), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Added methods to register/remove individual definitions.
|
||||
[#11](https://github.com/AliSoftware/Dip/pull/11), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* All `resolve` methods now can throw error if type can not be resolved.
|
||||
[#15](https://github.com/AliSoftware/Dip/issues/15), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* `DependencyContainer` is marked as `final`.
|
||||
* Added support for OSX, tvOS and watchOS2.
|
||||
[#26](https://github.com/AliSoftware/Dip/pull/26), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
|
||||
|
||||
#### Breaking Changes
|
||||
|
||||
* Removed container thread-safety to enable recursion calls to `resolve`.
|
||||
**Access to container from multiple threads should be handled by clients** from now on.
|
||||
* All `resolve` methods now can throw.
|
||||
|
||||
### Note on migration from 3.x to 4.0.0:
|
||||
* Errors
|
||||
|
||||
In 4.0.0 each `resolve` method can throw `DefinitionNotFound(DefinitionKey)` error, so you need to call it using `try!` or `try?`, or catch the error if it's appropriate for your case. See [#15](https://github.com/AliSoftware/Dip/issues/15) for rationale of this change.
|
||||
|
||||
* Thread safety
|
||||
|
||||
In 4.0.0 `DependencyContainer` drops any guarantee of thread safety. From now on code that uses Dip must ensure that it's methods are called from a single thread. For example if you have registered type as a singleton and later two threads try to resolve it at the same time you can have two different instances of type instead of one as expected. This change was required to enable recursive calls of `resolve` method to resolve circular dependencies.
|
||||
|
||||
* Removed methods
|
||||
|
||||
Methods deprecated in 3.1.0 are now removed.
|
||||
|
||||
|
||||
## 3.1.0
|
||||
|
||||
#### New
|
||||
|
||||
* Added name for the first runtime argument in `resolve(tag:withArguments: … )` methods to make more clear separation between tag and factory runtime arguments.
|
||||
|
||||
#### Depreciations
|
||||
|
||||
* `resolve(tag:_: … )` methods are deprecated in favor of those new `resolve(tag:withArguments: … )` methods.
|
||||
* Deprecated `register(tag:instance:)` method in favor of `register(.Singleton) { … }`.
|
||||
|
||||
## 3.0.0
|
||||
|
||||
* Added support for factories with up to six runtime arguments.
|
||||
[#8](https://github.com/AliSoftware/Dip/pull/8), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
* Parameter `tag` is now named in all register/resolve methods.
|
||||
* Playground added to project.
|
||||
[#10](https://github.com/AliSoftware/Dip/pull/10), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
|
||||
### Note on migration from 2.0.0 to 3.0.0:
|
||||
|
||||
If you used tags to register and resolve your components you have to add `tag` name for tag parameter. Don't forget to add it both in `register` and `resolve` methods. If you forget to add it in `resolve` call then tag value will be treated as first runtime argument for a factory, but there is no such factory registerd, so resolve will fail.
|
||||
|
||||
**Example**:
|
||||
|
||||
This code:
|
||||
|
||||
```swift
|
||||
container.register(tag: "some tag") { SomeClass() as SomeProtocol }
|
||||
container.resolve("some tag") as SomeProtocol
|
||||
```
|
||||
|
||||
becomes this:
|
||||
|
||||
```swift
|
||||
container.register(tag: "some tag") { SomeClass() as SomeProtocol }
|
||||
container.resolve(tag: "some tag") as SomeProtocol
|
||||
```
|
||||
|
||||
|
||||
## 2.0.0
|
||||
|
||||
* Moved from generic _tag_ parameter on container to `Tag` enum with `String` and `Int` cases
|
||||
[#3](https://github.com/AliSoftware/Dip/pull/3), [@ilyapuchka](https://github.com/ilyapuchka)
|
||||
|
||||
> This API change allows easier use of `DependencyContainer` and avoid some constraints. For a complete rationale on that change, see [PR #3](https://github.com/AliSoftware/Dip/pull/3).
|
||||
|
||||
## 1.0.1
|
||||
|
||||
* Improved README
|
||||
* Imrpoved discoverability using keywords in `podspec`
|
||||
|
||||
## 1.0.0
|
||||
|
||||
#### Dip
|
||||
|
||||
* Added Unit Tests for `SWAPIPersonProvider` and `SWAPIStarshipProvider`
|
||||
|
||||
_All work in progress is now done. I consider `Dip` to be ready for production and with a stable API, hence the `1.0.0` version bump._
|
||||
|
||||
#### Example Project
|
||||
|
||||
* Using `func fetchIDs` and `func fetchOne` instead of `lazy var` for readability
|
||||
|
||||
## 0.1.0
|
||||
|
||||
#### Dip
|
||||
|
||||
* Dip is now Thread-Safe
|
||||
* Added a configuration block so we can easily create the container and register the dependencies all in one expression:
|
||||
|
||||
```swift
|
||||
let deps = DependencyContainer() {
|
||||
$0.register() { x as Foo }
|
||||
$0.register() { y as Bar }
|
||||
$0.register() { z as Baz }
|
||||
}
|
||||
```
|
||||
|
||||
* Source Documentation
|
||||
|
||||
#### Example Project
|
||||
|
||||
* Code Cleanup
|
||||
* Added more values to `HardCodedStarshipProvider` so it works when the `PersonProviderAPI` uses real pilots from swapi.co (`SWAPIPersonProvider`)
|
||||
|
||||
## 0.0.4
|
||||
|
||||
#### Example Project
|
||||
|
||||
* Added `SWAPIPersonProvider` & `SWAPIStarshipProvider` that use http://swapi.co
|
||||
|
||||
## 0.0.3
|
||||
|
||||
#### Example Project
|
||||
|
||||
* Revamped the Sample project to a more complete example (using StarWars API!)
|
||||
* Using Mixins & Traits in the Sample App for `FetchableTrait` and `FillableCell`
|
||||
|
||||
## 0.0.2
|
||||
|
||||
#### Dip
|
||||
|
||||
* Switched from class methods to instance methods ([#1](https://github.com/AliSoftware/Dip/issues/1)). This allows you to have multiple `DependencyContainers`
|
||||
* Renamed the class from `Dependency` to `DependencyContainer`
|
||||
* Renamed the `instanceFactory:` parameter to `factory:`
|
||||
|
||||
@@ -1,32 +1,26 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "Dip"
|
||||
s.version = "0.0.1"
|
||||
s.summary = "A simple Dependency Resolver (Simplified Dependency Injection-like resolution)."
|
||||
s.version = "5.0.2"
|
||||
s.summary = "Dependency Injection for Swift made easy."
|
||||
|
||||
s.description = <<-DESC
|
||||
Dip is a Swift framework to manage your Dependencies between your classes
|
||||
in your app.
|
||||
|
||||
It's aimed to be very simple to use while improving testability
|
||||
of your app by allowing you to get rid of those sharedInstances and instead
|
||||
inject values based on protocol resolution.
|
||||
|
||||
Define your API using a protocol, then ask Dip to resolve this protocol into
|
||||
an instance dynamically in your classes. Then your App and your Tests can be
|
||||
configured to resolve the protocol using a different instance or class so this
|
||||
improve testability by decoupling the API and the concrete class used to implement it.
|
||||
|
||||
It's not real Dependency Injection _per se_, but it's close.
|
||||
DESC
|
||||
Dip is a Swift Dependency Injection Container.
|
||||
It provides reusable functionality for managing dependencies of your types
|
||||
and will help you to wire up different parts of your app.
|
||||
DESC
|
||||
|
||||
s.homepage = "https://github.com/AliSoftware/Dip"
|
||||
s.license = 'MIT'
|
||||
s.author = { "Olivier Halligon" => "olivier@halligon.net" }
|
||||
s.authors = { "Olivier Halligon" => "olivier@halligon.net", "Ilya Puchka" => "ilya@puchka.me" }
|
||||
s.source = { :git => "https://github.com/AliSoftware/Dip.git", :tag => s.version.to_s }
|
||||
s.social_media_url = 'https://twitter.com/aligatr'
|
||||
|
||||
s.platform = :ios, '8.0'
|
||||
s.ios.deployment_target = '8.0'
|
||||
s.osx.deployment_target = '10.9'
|
||||
s.tvos.deployment_target = '9.0'
|
||||
s.watchos.deployment_target = '2.0'
|
||||
|
||||
s.requires_arc = true
|
||||
|
||||
s.source_files = 'Sources/**/*'
|
||||
s.source_files = 'Sources/**/*.swift'
|
||||
end
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:DipPlayground.playground">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Dip/Dip.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:SampleApp/DipSampleApp.xcodeproj">
|
||||
</FileRef>
|
||||
<Group
|
||||
location = "container:"
|
||||
name = "Podspec Metadata">
|
||||
<FileRef
|
||||
location = "group:Dip.podspec">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:README.md">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:LICENSE">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:CHANGELOG.md">
|
||||
</FileRef>
|
||||
</Group>
|
||||
</Workspace>
|
||||
@@ -0,0 +1,498 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
0903B3621C161544002241C1 /* Dip.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0903B3581C161543002241C1 /* Dip.framework */; };
|
||||
0919F4D31C16417B00DC3B10 /* Dip.h in Headers */ = {isa = PBXBuildFile; fileRef = 0919F4C91C16417000DC3B10 /* Dip.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
0919F4D41C16417B00DC3B10 /* Dip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0919F4CA1C16417000DC3B10 /* Dip.swift */; };
|
||||
0919F4D51C16417B00DC3B10 /* Definition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0919F4C81C16417000DC3B10 /* Definition.swift */; };
|
||||
0919F4D61C16417B00DC3B10 /* RuntimeArguments.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0919F4CC1C16417000DC3B10 /* RuntimeArguments.swift */; };
|
||||
095F829C1D043B41008CD706 /* TypeForwarding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 095F829B1D043B41008CD706 /* TypeForwarding.swift */; };
|
||||
0982AF0C1C5183A000B62463 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0982AF0B1C5183A000B62463 /* Utils.swift */; };
|
||||
09873F561C1E0237000C02F6 /* AutoInjection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09873F551C1E0237000C02F6 /* AutoInjection.swift */; };
|
||||
09B036001C5D2B83001EA5B7 /* AutoWiring.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09B035FF1C5D2B83001EA5B7 /* AutoWiring.swift */; };
|
||||
09BD350E1D84E30D00B33E53 /* AutoInjectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09BD35041D84E30D00B33E53 /* AutoInjectionTests.swift */; };
|
||||
09BD350F1D84E30D00B33E53 /* AutoWiringTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09BD35051D84E30D00B33E53 /* AutoWiringTests.swift */; };
|
||||
09BD35101D84E30D00B33E53 /* ComponentScopeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09BD35061D84E30D00B33E53 /* ComponentScopeTests.swift */; };
|
||||
09BD35111D84E30D00B33E53 /* ContextTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09BD35071D84E30D00B33E53 /* ContextTests.swift */; };
|
||||
09BD35121D84E30D00B33E53 /* DefinitionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09BD35081D84E30D00B33E53 /* DefinitionTests.swift */; };
|
||||
09BD35131D84E30D00B33E53 /* DipTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09BD35091D84E30D00B33E53 /* DipTests.swift */; };
|
||||
09BD35141D84E30D00B33E53 /* RuntimeArgumentsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09BD350A1D84E30D00B33E53 /* RuntimeArgumentsTests.swift */; };
|
||||
09BD35151D84E30D00B33E53 /* ThreadSafetyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09BD350B1D84E30D00B33E53 /* ThreadSafetyTests.swift */; };
|
||||
09BD35161D84E30D00B33E53 /* TypeForwardingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09BD350C1D84E30D00B33E53 /* TypeForwardingTests.swift */; };
|
||||
09BD35171D84E30D00B33E53 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09BD350D1D84E30D00B33E53 /* Utils.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
0903B3631C161544002241C1 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 094526881BEA1CFF0034E72A /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 0903B3571C161543002241C1;
|
||||
remoteInfo = "Dip-OSX";
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
0903B3581C161543002241C1 /* Dip.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Dip.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
0903B3611C161543002241C1 /* DipTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DipTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
0919F4C81C16417000DC3B10 /* Definition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Definition.swift; path = ../../Sources/Definition.swift; sourceTree = "<group>"; };
|
||||
0919F4C91C16417000DC3B10 /* Dip.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Dip.h; sourceTree = "<group>"; };
|
||||
0919F4CA1C16417000DC3B10 /* Dip.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Dip.swift; path = ../../Sources/Dip.swift; sourceTree = "<group>"; };
|
||||
0919F4CB1C16417000DC3B10 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
0919F4CC1C16417000DC3B10 /* RuntimeArguments.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = RuntimeArguments.swift; path = ../../Sources/RuntimeArguments.swift; sourceTree = "<group>"; };
|
||||
0919F4D11C16417000DC3B10 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
095F829B1D043B41008CD706 /* TypeForwarding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TypeForwarding.swift; path = ../../Sources/TypeForwarding.swift; sourceTree = "<group>"; };
|
||||
0982AF0B1C5183A000B62463 /* Utils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Utils.swift; path = ../../Sources/Utils.swift; sourceTree = "<group>"; };
|
||||
09873F551C1E0237000C02F6 /* AutoInjection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AutoInjection.swift; path = ../../Sources/AutoInjection.swift; sourceTree = "<group>"; };
|
||||
09B035FF1C5D2B83001EA5B7 /* AutoWiring.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AutoWiring.swift; path = ../../Sources/AutoWiring.swift; sourceTree = "<group>"; };
|
||||
09BD35041D84E30D00B33E53 /* AutoInjectionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AutoInjectionTests.swift; path = ../../Tests/DipTests/AutoInjectionTests.swift; sourceTree = "<group>"; };
|
||||
09BD35051D84E30D00B33E53 /* AutoWiringTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AutoWiringTests.swift; path = ../../Tests/DipTests/AutoWiringTests.swift; sourceTree = "<group>"; };
|
||||
09BD35061D84E30D00B33E53 /* ComponentScopeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ComponentScopeTests.swift; path = ../../Tests/DipTests/ComponentScopeTests.swift; sourceTree = "<group>"; };
|
||||
09BD35071D84E30D00B33E53 /* ContextTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ContextTests.swift; path = ../../Tests/DipTests/ContextTests.swift; sourceTree = "<group>"; };
|
||||
09BD35081D84E30D00B33E53 /* DefinitionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = DefinitionTests.swift; path = ../../Tests/DipTests/DefinitionTests.swift; sourceTree = "<group>"; };
|
||||
09BD35091D84E30D00B33E53 /* DipTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = DipTests.swift; path = ../../Tests/DipTests/DipTests.swift; sourceTree = "<group>"; };
|
||||
09BD350A1D84E30D00B33E53 /* RuntimeArgumentsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RuntimeArgumentsTests.swift; path = ../../Tests/DipTests/RuntimeArgumentsTests.swift; sourceTree = "<group>"; };
|
||||
09BD350B1D84E30D00B33E53 /* ThreadSafetyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ThreadSafetyTests.swift; path = ../../Tests/DipTests/ThreadSafetyTests.swift; sourceTree = "<group>"; };
|
||||
09BD350C1D84E30D00B33E53 /* TypeForwardingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TypeForwardingTests.swift; path = ../../Tests/DipTests/TypeForwardingTests.swift; sourceTree = "<group>"; };
|
||||
09BD350D1D84E30D00B33E53 /* Utils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Utils.swift; path = ../../Tests/DipTests/Utils.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
0903B3541C161543002241C1 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
0903B35E1C161543002241C1 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0903B3621C161544002241C1 /* Dip.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
0919F4C71C16417000DC3B10 /* Dip */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0919F4C91C16417000DC3B10 /* Dip.h */,
|
||||
0919F4CA1C16417000DC3B10 /* Dip.swift */,
|
||||
0919F4C81C16417000DC3B10 /* Definition.swift */,
|
||||
0919F4CC1C16417000DC3B10 /* RuntimeArguments.swift */,
|
||||
09873F551C1E0237000C02F6 /* AutoInjection.swift */,
|
||||
09B035FF1C5D2B83001EA5B7 /* AutoWiring.swift */,
|
||||
095F829B1D043B41008CD706 /* TypeForwarding.swift */,
|
||||
0982AF0B1C5183A000B62463 /* Utils.swift */,
|
||||
0919F4CB1C16417000DC3B10 /* Info.plist */,
|
||||
);
|
||||
path = Dip;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0919F4CD1C16417000DC3B10 /* DipTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
09BD35041D84E30D00B33E53 /* AutoInjectionTests.swift */,
|
||||
09BD35051D84E30D00B33E53 /* AutoWiringTests.swift */,
|
||||
09BD35061D84E30D00B33E53 /* ComponentScopeTests.swift */,
|
||||
09BD35071D84E30D00B33E53 /* ContextTests.swift */,
|
||||
09BD35081D84E30D00B33E53 /* DefinitionTests.swift */,
|
||||
09BD35091D84E30D00B33E53 /* DipTests.swift */,
|
||||
09BD350A1D84E30D00B33E53 /* RuntimeArgumentsTests.swift */,
|
||||
09BD350B1D84E30D00B33E53 /* ThreadSafetyTests.swift */,
|
||||
09BD350C1D84E30D00B33E53 /* TypeForwardingTests.swift */,
|
||||
09BD350D1D84E30D00B33E53 /* Utils.swift */,
|
||||
0919F4D11C16417000DC3B10 /* Info.plist */,
|
||||
);
|
||||
path = DipTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
094526871BEA1CFF0034E72A = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0919F4C71C16417000DC3B10 /* Dip */,
|
||||
0919F4CD1C16417000DC3B10 /* DipTests */,
|
||||
094526921BEA1CFF0034E72A /* Products */,
|
||||
);
|
||||
indentWidth = 2;
|
||||
sourceTree = "<group>";
|
||||
tabWidth = 2;
|
||||
};
|
||||
094526921BEA1CFF0034E72A /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0903B3581C161543002241C1 /* Dip.framework */,
|
||||
0903B3611C161543002241C1 /* DipTests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
0903B3551C161543002241C1 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0919F4D31C16417B00DC3B10 /* Dip.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
0903B3571C161543002241C1 /* Dip */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 0903B36D1C161544002241C1 /* Build configuration list for PBXNativeTarget "Dip" */;
|
||||
buildPhases = (
|
||||
0903B3531C161543002241C1 /* Sources */,
|
||||
0903B3541C161543002241C1 /* Frameworks */,
|
||||
0903B3551C161543002241C1 /* Headers */,
|
||||
0903B3561C161543002241C1 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = Dip;
|
||||
productName = "Dip-OSX";
|
||||
productReference = 0903B3581C161543002241C1 /* Dip.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
0903B3601C161543002241C1 /* DipTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 0903B36E1C161544002241C1 /* Build configuration list for PBXNativeTarget "DipTests" */;
|
||||
buildPhases = (
|
||||
0903B35D1C161543002241C1 /* Sources */,
|
||||
0903B35E1C161543002241C1 /* Frameworks */,
|
||||
0903B35F1C161543002241C1 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
0903B3641C161544002241C1 /* PBXTargetDependency */,
|
||||
);
|
||||
name = DipTests;
|
||||
productName = "Dip-OSXTests";
|
||||
productReference = 0903B3611C161543002241C1 /* DipTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
094526881BEA1CFF0034E72A /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0730;
|
||||
LastUpgradeCheck = 0800;
|
||||
ORGANIZATIONNAME = AliSoftware;
|
||||
TargetAttributes = {
|
||||
0903B3571C161543002241C1 = {
|
||||
CreatedOnToolsVersion = 7.1.1;
|
||||
LastSwiftMigration = 0800;
|
||||
};
|
||||
0903B3601C161543002241C1 = {
|
||||
CreatedOnToolsVersion = 7.1.1;
|
||||
LastSwiftMigration = 0800;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 0945268B1BEA1CFF0034E72A /* Build configuration list for PBXProject "Dip" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = 094526871BEA1CFF0034E72A;
|
||||
productRefGroup = 094526921BEA1CFF0034E72A /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
0903B3571C161543002241C1 /* Dip */,
|
||||
0903B3601C161543002241C1 /* DipTests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
0903B3561C161543002241C1 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
0903B35F1C161543002241C1 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
0903B3531C161543002241C1 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0982AF0C1C5183A000B62463 /* Utils.swift in Sources */,
|
||||
0919F4D51C16417B00DC3B10 /* Definition.swift in Sources */,
|
||||
09B036001C5D2B83001EA5B7 /* AutoWiring.swift in Sources */,
|
||||
0919F4D41C16417B00DC3B10 /* Dip.swift in Sources */,
|
||||
095F829C1D043B41008CD706 /* TypeForwarding.swift in Sources */,
|
||||
09873F561C1E0237000C02F6 /* AutoInjection.swift in Sources */,
|
||||
0919F4D61C16417B00DC3B10 /* RuntimeArguments.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
0903B35D1C161543002241C1 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
09BD35141D84E30D00B33E53 /* RuntimeArgumentsTests.swift in Sources */,
|
||||
09BD35151D84E30D00B33E53 /* ThreadSafetyTests.swift in Sources */,
|
||||
09BD35121D84E30D00B33E53 /* DefinitionTests.swift in Sources */,
|
||||
09BD350F1D84E30D00B33E53 /* AutoWiringTests.swift in Sources */,
|
||||
09BD35111D84E30D00B33E53 /* ContextTests.swift in Sources */,
|
||||
09BD35171D84E30D00B33E53 /* Utils.swift in Sources */,
|
||||
09BD35131D84E30D00B33E53 /* DipTests.swift in Sources */,
|
||||
09BD35101D84E30D00B33E53 /* ComponentScopeTests.swift in Sources */,
|
||||
09BD350E1D84E30D00B33E53 /* AutoInjectionTests.swift in Sources */,
|
||||
09BD35161D84E30D00B33E53 /* TypeForwardingTests.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
0903B3641C161544002241C1 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 0903B3571C161543002241C1 /* Dip */;
|
||||
targetProxy = 0903B3631C161544002241C1 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
0903B3691C161544002241C1 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=*]" = "";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
FRAMEWORK_VERSION = A;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
"iOS=1",
|
||||
);
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.alisoftware.Dip;
|
||||
PRODUCT_NAME = Dip;
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
0903B36A1C161544002241C1 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=*]" = "";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
FRAMEWORK_VERSION = A;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.alisoftware.Dip;
|
||||
PRODUCT_NAME = Dip;
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
0903B36B1C161544002241C1 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=*]" = "";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
INFOPLIST_FILE = DipTests/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks @loader_path/../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.alisoftware.DipTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
0903B36C1C161544002241C1 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=*]" = "";
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
INFOPLIST_FILE = DipTests/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks @loader_path/../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.alisoftware.DipTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
094526A31BEA1CFF0034E72A /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 5.0.2;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
INFOPLIST_FILE = Dip/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SUPPORTED_PLATFORMS = "macosx watchsimulator iphonesimulator appletvsimulator watchos appletvos iphoneos";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 3.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2,3,4";
|
||||
TVOS_DEPLOYMENT_TARGET = 9.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
WATCHOS_DEPLOYMENT_TARGET = 2.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
094526A41BEA1CFF0034E72A /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 5.0.2;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
INFOPLIST_FILE = Dip/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SUPPORTED_PLATFORMS = "macosx watchsimulator iphonesimulator appletvsimulator watchos appletvos iphoneos";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
SWIFT_VERSION = 3.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2,3,4";
|
||||
TVOS_DEPLOYMENT_TARGET = 9.0;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
WATCHOS_DEPLOYMENT_TARGET = 2.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
0903B36D1C161544002241C1 /* Build configuration list for PBXNativeTarget "Dip" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
0903B3691C161544002241C1 /* Debug */,
|
||||
0903B36A1C161544002241C1 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
0903B36E1C161544002241C1 /* Build configuration list for PBXNativeTarget "DipTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
0903B36B1C161544002241C1 /* Debug */,
|
||||
0903B36C1C161544002241C1 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
0945268B1BEA1CFF0034E72A /* Build configuration list for PBXProject "Dip" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
094526A31BEA1CFF0034E72A /* Debug */,
|
||||
094526A41BEA1CFF0034E72A /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 094526881BEA1CFF0034E72A /* Project object */;
|
||||
}
|
||||
@@ -2,9 +2,9 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Dip.xcodeproj">
|
||||
location = "group:../DipPlayground.playground">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0700"
|
||||
LastUpgradeVersion = "0800"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@@ -14,10 +14,24 @@
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "61B2C099D2823B76EB65B5ECC8B08934"
|
||||
BlueprintIdentifier = "0903B3571C161543002241C1"
|
||||
BuildableName = "Dip.framework"
|
||||
BlueprintName = "Dip"
|
||||
ReferencedContainer = "container:Pods.xcodeproj">
|
||||
ReferencedContainer = "container:Dip.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "NO"
|
||||
buildForProfiling = "NO"
|
||||
buildForArchiving = "NO"
|
||||
buildForAnalyzing = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "0903B3601C161543002241C1"
|
||||
BuildableName = "DipTests.xctest"
|
||||
BlueprintName = "DipTests"
|
||||
ReferencedContainer = "container:Dip.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
@@ -26,9 +40,29 @@
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
codeCoverageEnabled = "YES">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "0903B3601C161543002241C1"
|
||||
BuildableName = "DipTests.xctest"
|
||||
BlueprintName = "DipTests"
|
||||
ReferencedContainer = "container:Dip.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "0903B3571C161543002241C1"
|
||||
BuildableName = "Dip.framework"
|
||||
BlueprintName = "Dip"
|
||||
ReferencedContainer = "container:Dip.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
@@ -45,10 +79,10 @@
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "61B2C099D2823B76EB65B5ECC8B08934"
|
||||
BlueprintIdentifier = "0903B3571C161543002241C1"
|
||||
BuildableName = "Dip.framework"
|
||||
BlueprintName = "Dip"
|
||||
ReferencedContainer = "container:Pods.xcodeproj">
|
||||
ReferencedContainer = "container:Dip.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
@@ -60,6 +94,15 @@
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "0903B3571C161543002241C1"
|
||||
BuildableName = "Dip.framework"
|
||||
BlueprintName = "Dip"
|
||||
ReferencedContainer = "container:Dip.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// Dip
|
||||
//
|
||||
// Copyright (c) 2015 Olivier Halligon <olivier@halligon.net>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
//! Project version number for Dip.
|
||||
FOUNDATION_EXPORT double DipVersionNumber;
|
||||
|
||||
//! Project version string for Dip.
|
||||
FOUNDATION_EXPORT const unsigned char DipVersionString[];
|
||||
|
||||
// In this header, you should import all the public headers of your framework using statements like #import <Dip/PublicHeader.h>
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,176 @@
|
||||
[
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 54,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 111,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 168,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 228,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 269,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 332,
|
||||
"remove": 3,
|
||||
"text": " ",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 472,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 508,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 613,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 649,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 754,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 808,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 879,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 924,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 1092,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 1149,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 1208,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 1265,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 1473,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 1516,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 1569,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 1643,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 1687,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 1762,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 1806,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 1848,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 2146,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 2315,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
},
|
||||
{
|
||||
"file": "/Users/ilya/Documents/Developer/iPhoneProjects/Dip/DipPlayground.playground/Sources/Models.swift",
|
||||
"offset": 2357,
|
||||
"remove": 6,
|
||||
"text": "open",
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,211 @@
|
||||
//: [Previous: Auto-wiring](@previous)
|
||||
|
||||
import UIKit
|
||||
import Dip
|
||||
|
||||
let container = DependencyContainer()
|
||||
/*:
|
||||
|
||||
### Auto-Injection
|
||||
|
||||
On the previous page you saw how auto-wiring helps us to get rid of boilerplate code when registering and resolving components with consturctor injection. Auto-injection solves the same problem for property injection.
|
||||
|
||||
Let's say you have following related components:
|
||||
*/
|
||||
|
||||
protocol Service: class {
|
||||
var logger: Logger? { get }
|
||||
var tracker: Tracker? { get }
|
||||
}
|
||||
|
||||
class ServiceImp: Service {
|
||||
var logger: Logger?
|
||||
var tracker: Tracker?
|
||||
}
|
||||
|
||||
/*:
|
||||
When you register them in a container you will end up with something like this:
|
||||
*/
|
||||
|
||||
container.register() { TrackerImp() as Tracker }
|
||||
container.register() { LoggerImp() as Logger }
|
||||
|
||||
container.register() { ServiceImp() as Service }
|
||||
.resolvingProperties { container, service in
|
||||
let service = service as! ServiceImp
|
||||
service.logger = try container.resolve() as Logger
|
||||
service.tracker = try container.resolve() as Tracker
|
||||
}
|
||||
|
||||
let service = try! container.resolve() as Service
|
||||
service.logger
|
||||
service.tracker
|
||||
|
||||
/*:
|
||||
Notice that the same boilerplate code that we saw in constructor injection now moved to `resolveDepedencies` block.
|
||||
With auto-injection your code transforms to this:
|
||||
*/
|
||||
|
||||
class AutoInjectedServiceImp: Service {
|
||||
private let injectedLogger = Injected<Logger>()
|
||||
var logger: Logger? { return injectedLogger.value }
|
||||
|
||||
private let injectedTracker = Injected<Tracker>()
|
||||
var tracker: Tracker? { return injectedTracker.value }
|
||||
}
|
||||
|
||||
container.register() { AutoInjectedServiceImp() as Service }
|
||||
|
||||
let autoInjectedService = try! container.resolve() as Service
|
||||
autoInjectedService.logger
|
||||
autoInjectedService.tracker
|
||||
|
||||
/*:
|
||||
As you can see we added two private properties to our implementation of `Service` - `injectedLogger` and `injectedTracker`. Their types are `Injeceted<Logger>` and `Injected<Tracker>` respectively. Note that we've not just defined them as properties of those types, but defined them with some initial value. `Injected<T>` is a simple _wrapper class_ that wraps value of generic type and provides read-write access to it with `value` property. This property is defined as optional, so that when we create instance of `Injected<T>` it will have `nil` in its value. There is also another wrapper - `InjectedWeak<T>` - which in contrast to `Injected<T>` holds a week reference to its wrapped object, thus requiring it to be a _reference type_ (or `AnyObject`), when `Injected<T>` can also wrap value types (or `Any`).
|
||||
|
||||
What is happening under the hood is that after concrete instance of resolved type is created (`Service` in that case), container will iterate through its properties using `Mirror`. For each of the properties wrapped with `Injected<T>` or `InjectedWeak<T>` it will search a definition that can be used to create an instance of wrapped type and use it to create and inject a concrete instance in a `value` property of a wrapper. The fact that wrappers are _classes_ or _reference types_ makes it possible at runtime to inject dependency in instance of resolved type.
|
||||
|
||||
The requirement for auto-injection is that types injected types should be registered in a container and should use factories with no runtime arguments.
|
||||
|
||||
Auto-injected properties can be marked with tag. Then container will search for definition tagged by the same tag to resolve this property.
|
||||
|
||||
You can provide closure that will be called when the dependency will be injected in the property. It is similar to `didSet` property observer.
|
||||
|
||||
Auto-injected properties are required by default. That means that if container fails to resolve any of auto-injected properties of the instance (or any of its dependencies) it will fail resolution of the object graph in whole.
|
||||
*/
|
||||
|
||||
class ServerWithRequiredClient {
|
||||
var client = Injected<Client>()
|
||||
}
|
||||
|
||||
container.register { ServerWithRequiredClient() }
|
||||
|
||||
do {
|
||||
let serverWithClient = try container.resolve() as ServerWithRequiredClient
|
||||
}
|
||||
catch {}
|
||||
|
||||
/*:
|
||||
You can make auto-injected property optional by passing `false` to `required` parameter of `Injected<T>`/`InjectedWeak<T>` constructor. For such properties container will ignore any errors when it resolves this property (or any of its dependencies).
|
||||
*/
|
||||
|
||||
class ServerWithOptionalClient {
|
||||
var optionalClient = Injected<Client>(required: false)
|
||||
}
|
||||
|
||||
container.register { ServerWithOptionalClient() }
|
||||
let serverWithNoClient = try! container.resolve() as ServerWithOptionalClient
|
||||
serverWithNoClient.optionalClient.value
|
||||
|
||||
/*:
|
||||
Another example of using auto-injection is circular dependencies. Let's say you have a `Server` and a `ServerClient` both referencing each other.
|
||||
*/
|
||||
|
||||
protocol Server: class {
|
||||
weak var client: ServerClient? { get }
|
||||
}
|
||||
|
||||
protocol ServerClient: class {
|
||||
var server: Server? { get }
|
||||
}
|
||||
|
||||
class ServerImp: Server {
|
||||
weak var client: ServerClient?
|
||||
}
|
||||
|
||||
class ServerClientImp: ServerClient {
|
||||
var server: Server?
|
||||
|
||||
init(server: Server) {
|
||||
self.server = server
|
||||
}
|
||||
}
|
||||
|
||||
/*:
|
||||
The standard way to register such components in `DependencyContainer` will lead to such code:
|
||||
*/
|
||||
|
||||
container.register {
|
||||
ServerClientImp(server: try container.resolve()) as ServerClient
|
||||
}
|
||||
|
||||
container.register { ServerImp() as Server }
|
||||
.resolvingProperties { (container: DependencyContainer, server: Server) in
|
||||
(server as! ServerImp).client = try container.resolve() as ServerClient
|
||||
}
|
||||
|
||||
let client = try! container.resolve() as ServerClient
|
||||
client.server
|
||||
|
||||
/*:
|
||||
With auto-injection you will have the following code:
|
||||
*/
|
||||
|
||||
class InjectedServerImp: Server {
|
||||
private var injectedClient = InjectedWeak<ServerClient>()
|
||||
var client: ServerClient? { return injectedClient.value }
|
||||
}
|
||||
|
||||
class InjectedClientImp: ServerClient {
|
||||
private var injectedServer = Injected<Server>()
|
||||
var server: Server? { get { return injectedServer.value } }
|
||||
}
|
||||
|
||||
container.register { InjectedServerImp() as Server }
|
||||
container.register { InjectedClientImp() as ServerClient }
|
||||
|
||||
let injectedClient = try! container.resolve() as ServerClient
|
||||
injectedClient.server
|
||||
injectedClient.server?.client === injectedClient //circular dependencies were resolved correctly
|
||||
|
||||
/*:
|
||||
You can see that component registration looks much simpler now. But on the other side it requires some boilerplate code in implementations, and also tightly coupls your code with Dip.
|
||||
|
||||
Here is an example with higher number of dependencies.
|
||||
*/
|
||||
container.register() { RouterImp() as Router }
|
||||
container.register() { DataProviderImp() as DataProvider }
|
||||
|
||||
class ViewController: UIViewController {
|
||||
var logger: Logger?
|
||||
var tracker: Tracker?
|
||||
var dataProvider: DataProvider?
|
||||
var router: Router?
|
||||
}
|
||||
|
||||
container.register { ViewController() }
|
||||
.resolvingProperties { container, controller in
|
||||
controller.logger = try container.resolve() as Logger
|
||||
controller.tracker = try container.resolve() as Tracker
|
||||
controller.dataProvider = try container.resolve() as DataProvider
|
||||
controller.router = try container.resolve() as Router
|
||||
}
|
||||
|
||||
let viewController = try! container.resolve() as ViewController
|
||||
viewController.router
|
||||
|
||||
/*:
|
||||
With auto-injection you can replace that with something like this:
|
||||
*/
|
||||
|
||||
class AutoInjectedViewController: UIViewController {
|
||||
let logger = Injected<Logger>()
|
||||
let tracker = Injected<Tracker>()
|
||||
let dataProvider = Injected<DataProvider>()
|
||||
let router = Injected<Router>()
|
||||
}
|
||||
|
||||
container.register { AutoInjectedViewController() }
|
||||
|
||||
let autoViewController = try! container.resolve() as AutoInjectedViewController
|
||||
autoViewController.router.value
|
||||
|
||||
/*:
|
||||
In such scenario when view controller is created by storyboard you will need to use property injection anyway, so the overhead of adding additional properties for auto-injection is smaller. Also all the boilerplate code of unwrapping injected properties (if you need that) can be moved to extension, cleaning implementation a bit.
|
||||
|
||||
> **Note**: For such cases concider using [DipUI](https://github.com/AliSoftware/Dip-UI). It is a small extension for Dip that allows you to do exactly what we need in this example - inject dependencies in instances created by storyboards. It does not require to use auto-injection feature but plays nice with it.
|
||||
|
||||
So as you can see there are certain advantages and disadvatages of using auto-injection. It makes your definitions simpler, especially if there are circular dependencies involved or the number of dependencies is high, removing boilerplate calls to `resolve` method in `resolveDependencies` block of your definitions. But it requires additional properties and some boilerplate code in your implementations, makes your implementatios tightly coupled with Dip. You can avoid tight coupoling by using your own boxing classes instead of `Injected<T>` and `InjectedWeak<T>` (see `AutoInjectedPropertyBox`).
|
||||
*/
|
||||
|
||||
//: [Next: Type Forwarding](@next)
|
||||
@@ -0,0 +1,117 @@
|
||||
//: [Previous: Shared Instances](@previous)
|
||||
|
||||
import Dip
|
||||
import UIKit
|
||||
|
||||
/*:
|
||||
|
||||
### Auto-wiring
|
||||
|
||||
Among three main DI patterns - _constructor_, _property_ and _method_ injection - constructor injection should be your choise by default. Dip makes using this pattern very simple.
|
||||
|
||||
Let's say you have some VIPER module with following components:
|
||||
*/
|
||||
protocol Service {}
|
||||
protocol Interactor {
|
||||
var service: Service { get }
|
||||
}
|
||||
protocol Router {}
|
||||
protocol ViewOutput {}
|
||||
protocol Presenter {
|
||||
var router: Router { get }
|
||||
var interactor: Interactor { get }
|
||||
var view: ViewOutput { get }
|
||||
}
|
||||
|
||||
class RouterImp: Router {}
|
||||
class View: UIView, ViewOutput {}
|
||||
class ServiceImp: Service {}
|
||||
|
||||
/*:
|
||||
VIPER module by its nature consists of a lot of components, wired up using protocols. Using constructor injection you can end up with following constructors for presenter and interactor:
|
||||
*/
|
||||
|
||||
class InteractorImp: Interactor {
|
||||
var service: Service
|
||||
|
||||
init(service: Service) {
|
||||
self.service = service
|
||||
}
|
||||
}
|
||||
|
||||
class PresenterImp: Presenter {
|
||||
let router: Router
|
||||
let interactor: Interactor
|
||||
let view: ViewOutput
|
||||
|
||||
init(view: ViewOutput, interactor: Interactor, router: Router) {
|
||||
self.view = view
|
||||
self.interactor = interactor
|
||||
self.router = router
|
||||
}
|
||||
}
|
||||
|
||||
/*:
|
||||
If you register these components in a container you will end up with rather boilerplate code:
|
||||
*/
|
||||
|
||||
let container = DependencyContainer()
|
||||
container.register { ServiceImp() as Service }
|
||||
container.register { RouterImp() as Router }
|
||||
container.register { View() as ViewOutput }
|
||||
|
||||
container.register { try InteractorImp(service: container.resolve()) as Interactor }
|
||||
container.register {
|
||||
try PresenterImp(
|
||||
view: container.resolve(),
|
||||
interactor: container.resolve(),
|
||||
router: container.resolve()) as Presenter
|
||||
}
|
||||
|
||||
|
||||
var presenter = try! container.resolve() as Presenter
|
||||
presenter.interactor.service
|
||||
|
||||
/*:
|
||||
While definition for `Interactor` looks fine, `Presenter`'s definition is overloaded with the same `resolve` calls to container.
|
||||
|
||||
The other option you have is to register factory with runtime arguments:
|
||||
*/
|
||||
|
||||
container.register { InteractorImp(service: $0) as Interactor }
|
||||
container.register { PresenterImp(view: $0, interactor: $1, router: $2) as Presenter }
|
||||
|
||||
/*:
|
||||
But then to resolve presenter or interactor you will first need to resolve their dependencies and pass them as arguments to `resolve` method:
|
||||
*/
|
||||
|
||||
let service = try! container.resolve() as Service
|
||||
let interactor = try! container.resolve(arguments: service) as Interactor
|
||||
let view = try! container.resolve() as ViewOutput
|
||||
let router = try! container.resolve() as Router
|
||||
presenter = try! container.resolve(arguments: view, interactor, router) as Presenter
|
||||
presenter.interactor.service
|
||||
|
||||
/*:
|
||||
Again to much of boilerplate code. Also it's easy to make a mistake in the order of arguments.
|
||||
|
||||
Auto-wiring solves this problem by combining these two approaches - you register factories with runtime arguments, but resolve components with just a call to `resolve()`. Container will resolve all consturctor arguments for you.
|
||||
*/
|
||||
|
||||
container.register { InteractorImp(service: $0) as Interactor }
|
||||
container.register { PresenterImp(view: $0, interactor: $1, router: $2) as Presenter }
|
||||
|
||||
presenter = try! container.resolve() as Presenter
|
||||
presenter.interactor.service
|
||||
|
||||
/*:
|
||||
You don't need to call `resolve` in a factory and care about order of arguments any more.
|
||||
|
||||
The only requirement is that all constructor arguments should be registered in the container and there should be no several factories with the same _number_ of arguments registered for the same components.
|
||||
|
||||
In very rare cases when you have several factories for the same component with different set of runtime arguments, when you try to resolve it container will try to use factory registered for the same type and tag (if provided, otherwise registered without tag) and with the maximum number of runtime arguments. If it finds two factories registered for the same type and tag and with the same number but different types of arguments it will throw an error.
|
||||
|
||||
You can use auto-wiring with tags. The tag that you pass to `resolve` method will be used to resolve each of the constructor arguments.
|
||||
*/
|
||||
|
||||
//: [Next: Auto-injection](@next)
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Timeline
|
||||
version = "3.0">
|
||||
<TimelineItems>
|
||||
</TimelineItems>
|
||||
</Timeline>
|
||||
@@ -0,0 +1,107 @@
|
||||
//: [Previous: Scopes](@previous)
|
||||
|
||||
import Dip
|
||||
import Foundation
|
||||
|
||||
let container = DependencyContainer()
|
||||
|
||||
/*:
|
||||
### Circular Dependencies
|
||||
|
||||
Very often we encounter situations when we have circular dependencies between components. The most obvious example is delegation pattern. Dip can resolve such dependencies easily.
|
||||
|
||||
Let's say you have some network client and it's delegate defined like this:
|
||||
*/
|
||||
|
||||
protocol NetworkClientDelegate: class {
|
||||
var networkClient: NetworkClient { get }
|
||||
}
|
||||
|
||||
protocol NetworkClient: class {
|
||||
weak var delegate: NetworkClientDelegate? { get set }
|
||||
}
|
||||
|
||||
class NetworkClientImp: NetworkClient {
|
||||
weak var delegate: NetworkClientDelegate?
|
||||
init() {}
|
||||
}
|
||||
|
||||
class Interactor: NSObject, NetworkClientDelegate {
|
||||
let networkClient: NetworkClient
|
||||
init(networkClient: NetworkClient) {
|
||||
self.networkClient = networkClient
|
||||
}
|
||||
}
|
||||
|
||||
/*:
|
||||
Note that:
|
||||
|
||||
- one of this classes uses _property injection_ (`NetworkClientImp`) — you'll give the `delegate` value via its property directly, _after_ initialization
|
||||
- and another uses _constructor injection_ (`Interactor`) — you'll need to give the `networkclient` value via the constructor, _during_ initialization.
|
||||
|
||||
It's very important that _at least one_ of them uses property injection, because if you try to use constructor injection for both of them then you will enter infinite loop when you will call `resolve`.
|
||||
|
||||
Now you can register those classes in container:
|
||||
*/
|
||||
|
||||
container.register {
|
||||
Interactor(networkClient: try container.resolve()) as NetworkClientDelegate
|
||||
}
|
||||
|
||||
container.register { NetworkClientImp() as NetworkClient }
|
||||
.resolvingProperties { (container, client) -> () in
|
||||
client.delegate = try container.resolve() as NetworkClientDelegate
|
||||
}
|
||||
|
||||
/*:
|
||||
Here you can spot the difference in the way we register classes.
|
||||
|
||||
- `Interactor` class uses constructor injection, so to register it we use the block factory where we call `resolve` to obtain instance of `NetworkClient` and pass it to constructor.
|
||||
- `NetworkClientImp` uses property injection for it's delegate property. Again we use block factory to create instance, but to inject the delegate property we use the special `resolveDependencies` method. Block passed to this method will be called right _after_ the block factory. So you can use this block to perform additional setup or, like in this example, to resolve circular dependencies.
|
||||
|
||||
This way `DependencyContainer` breaks infinite recursion that would happen if we used constructor injection for both of our components.
|
||||
|
||||
*Note*: You can use container reference inside instance factory without using capture list, there will be [no retain cycle](https://github.com/AliSoftware/Dip/issues/23)
|
||||
|
||||
|
||||
Now when you resolve `NetworkClientDelegate` you will get an instance of `Interactor` that will have client with delegate referencing the same `Interactor` instance:
|
||||
*/
|
||||
|
||||
let interactor = try! container.resolve() as NetworkClientDelegate
|
||||
interactor.networkClient.delegate === interactor // true: they are the same instances
|
||||
|
||||
/*:
|
||||
**Warning**: Note that one of the properties (`delegate`) is defined as _weak_. That's crucial to avoid retain cycle. But now if you try to resolve `NetworkClient` first it's delegate will be released before `resolve` returns, bcause no one holds a reference to it except the container.
|
||||
*/
|
||||
|
||||
let networkClient = try! container.resolve() as NetworkClient
|
||||
networkClient.delegate // delegate was alread released =(
|
||||
|
||||
/*:
|
||||
Note also that we used `.shared` scope to register implementations. This is also very important to preserve consistency of objects relationships.
|
||||
|
||||
If we would have used `.unique` scope for both components then container would not reuse instances and we would have an infinite loop:
|
||||
|
||||
- Each attempt to resolve `NetworkClientDelegate` will create new instance of `Interactor`.
|
||||
- It will resolve `NetworkClient` which will create new instance of `NetworkClientImp`.
|
||||
- It will try to resolve it's delegate property and that will create new instance of `Interactor`
|
||||
- … And so on and so on.
|
||||
|
||||
If we would have used `.unique` for one of the components it will lead to the same infinite loop or one of the relationships will be invalid:
|
||||
*/
|
||||
|
||||
container.reset()
|
||||
|
||||
container.register(.unique) {
|
||||
Interactor(networkClient: try container.resolve()) as NetworkClientDelegate
|
||||
}
|
||||
|
||||
container.register { NetworkClientImp() as NetworkClient }
|
||||
.resolvingProperties { (container, client) -> () in
|
||||
client.delegate = try container.resolve() as NetworkClientDelegate
|
||||
}
|
||||
|
||||
let invalidInteractor = try! container.resolve() as NetworkClientDelegate
|
||||
invalidInteractor.networkClient.delegate // that is not valid
|
||||
|
||||
//: [Next: Shared Instances](@next)
|
||||
@@ -0,0 +1,71 @@
|
||||
//: [Previous: Type Forwarding](@previous)
|
||||
|
||||
import Dip
|
||||
|
||||
/*:
|
||||
### Containers collaboration
|
||||
|
||||
Sometimes it makes sence to break your configuration in separate modules. For that you can use containers collaboration. You can link containers with each other and when you try to resolve a type using container where it was not registered, this container will forward request to its collaborating container. This way you can share core configurations or break them in separate modules, for example matching user stories, and still be able to link components from different modules.
|
||||
*/
|
||||
|
||||
protocol DataStore {}
|
||||
class CoreDataStore: DataStore {}
|
||||
class AddEventWireframe {
|
||||
var eventsListWireframe: EventsListWireframe?
|
||||
}
|
||||
class EventsListWireframe {
|
||||
var addEventWireframe: AddEventWireframe?
|
||||
let dataStore: DataStore
|
||||
init(dataStore: DataStore) {
|
||||
self.dataStore = dataStore
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let rootContainer = DependencyContainer()
|
||||
rootContainer.register(.singleton) { CoreDataStore() as DataStore }
|
||||
|
||||
let eventsListModule = DependencyContainer()
|
||||
eventsListModule.register { EventsListWireframe(dataStore: $0) }
|
||||
.resolvingProperties { container, wireframe in
|
||||
wireframe.addEventWireframe = try container.resolve()
|
||||
}
|
||||
|
||||
let addEventModule = DependencyContainer()
|
||||
addEventModule.register { AddEventWireframe() }
|
||||
|
||||
eventsListModule.collaborate(with: addEventModule, rootContainer)
|
||||
|
||||
var eventsListWireframe = try eventsListModule.resolve() as EventsListWireframe
|
||||
eventsListWireframe.dataStore
|
||||
eventsListWireframe.addEventWireframe
|
||||
|
||||
/*:
|
||||
As you can see dependencies were resolved even though not all components were registered in the same container.
|
||||
It is even safe to make circular references between containers. This way you can resolve circular dependencies between components registered in different containers.
|
||||
*/
|
||||
|
||||
eventsListModule.reset()
|
||||
addEventModule.reset()
|
||||
|
||||
eventsListModule.register { EventsListWireframe(dataStore: $0) }
|
||||
.resolvingProperties { container, wireframe in
|
||||
wireframe.addEventWireframe = try container.resolve()
|
||||
}
|
||||
|
||||
addEventModule.register { AddEventWireframe() }
|
||||
.resolvingProperties { container, wireframe in
|
||||
wireframe.eventsListWireframe = try container.resolve()
|
||||
}
|
||||
|
||||
addEventModule.collaborate(with: eventsListModule)
|
||||
|
||||
eventsListWireframe = try eventsListModule.resolve() as EventsListWireframe
|
||||
eventsListWireframe.addEventWireframe
|
||||
eventsListWireframe.addEventWireframe?.eventsListWireframe === eventsListWireframe
|
||||
|
||||
/*:
|
||||
If you try to link container with itself it will be silently ignored. When forwarding request collaborating containers will be iterated in the same order that they were added.
|
||||
*/
|
||||
|
||||
//: [Next: Testing](@next)
|
||||
@@ -0,0 +1,38 @@
|
||||
//: [Previous: What is Dip?](@previous)
|
||||
|
||||
import Dip
|
||||
|
||||
/*:
|
||||
Dip has two base components: a _DependencyContainer_ and its _Definitions_.
|
||||
|
||||
- _DependencyContainer_ is used to register _Definitions_ and to resolve them.
|
||||
- _Definitions_ describe how component should be created by the _DependencyContainer_.
|
||||
|
||||
### Creating the container
|
||||
|
||||
You can create a container using a simple `init()`:
|
||||
*/
|
||||
|
||||
var container = DependencyContainer()
|
||||
//register components here
|
||||
|
||||
/*:
|
||||
or using a configuration block:
|
||||
*/
|
||||
|
||||
container = DependencyContainer { container in
|
||||
//do not forget to use unowned reference if you will need
|
||||
//to reference container inside definition's factory
|
||||
unowned let container = container
|
||||
//register components here
|
||||
}
|
||||
|
||||
/*:
|
||||
Both syntaxes are equivalent. The one using the configuration block is simply a convenience way to scope your components registrations in a nice looking way.
|
||||
|
||||
### When/where to create container?
|
||||
|
||||
While there is an option to use container as a global variable we advise instead to create and configure container in your app delegate and pass it between your objects (see [Shared Instances](Shared%20Instances)).
|
||||
|
||||
*/
|
||||
//: [Next: Registering Components](@next)
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Timeline
|
||||
version = "3.0">
|
||||
<TimelineItems>
|
||||
</TimelineItems>
|
||||
</Timeline>
|
||||
@@ -0,0 +1,58 @@
|
||||
//: [Previous: Creating a DependencyContainer](@previous)
|
||||
|
||||
import Dip
|
||||
|
||||
/*:
|
||||
|
||||
### Registering components
|
||||
|
||||
You register a definition in a container using the `register` method:
|
||||
*/
|
||||
let container = DependencyContainer()
|
||||
container.register { ServiceImp1() as Service }
|
||||
|
||||
/*:
|
||||
That code means that when you need a `Service`, you want to use instances of `ServiceImp1` class created with it's `init()` initializer.
|
||||
|
||||
You can also register factories that accept runtime arguments:
|
||||
*/
|
||||
|
||||
container.register { service in ClientImp1(service: service) as Client }
|
||||
|
||||
/*:
|
||||
Dip supports up to six runtime arguments, but you can use as many as you want. For more details see ["Runtime arguments"](Runtime%20arguments).
|
||||
|
||||
You can also use factory methods in definitions. This can be useful if you already have some factories but want to migrate to Dip.
|
||||
*/
|
||||
|
||||
let factory = ServiceFactory()
|
||||
// factory.someService is a method with signature `() -> Service`, Cmd-Click to see definition
|
||||
container.register(factory: factory.someService)
|
||||
|
||||
/*:
|
||||
Optionally you can associate definitions with Integer or String tags. This way you can register different implementations for the same protocol.
|
||||
You can use `DependencyContainer.Tag` enum, String or Integer literals, or instances of types that conform to `DependencyTagConvertible` protocol.
|
||||
*/
|
||||
|
||||
container.register(tag: "tag") { ServiceImp1() as Service }
|
||||
container.register(tag: 0) { ServiceImp1() as Service }
|
||||
|
||||
enum MyCustomTag: String, DependencyTagConvertible {
|
||||
case SomeTag
|
||||
}
|
||||
|
||||
container.register(tag: MyCustomTag.SomeTag) { ServiceImp1() as Service }
|
||||
|
||||
/*:
|
||||
We recommand you to use constants for the tags, to make the intent clear and avoid magic numbers and typos.
|
||||
|
||||
You can remove all registered definitions or register and remove them one by one:
|
||||
*/
|
||||
|
||||
let serviceDefinition = container.register { ServiceImp1() as Service }
|
||||
container
|
||||
container.remove(serviceDefinition)
|
||||
|
||||
container.reset()
|
||||
|
||||
//: [Next: Resolving Components](@next)
|
||||
@@ -0,0 +1,46 @@
|
||||
//: [Previous: Registering Components](@previous)
|
||||
|
||||
import Dip
|
||||
let container = DependencyContainer()
|
||||
container.register { ServiceImp1() as Service }
|
||||
|
||||
/*:
|
||||
|
||||
### Resolving components
|
||||
|
||||
You resolve previously registered definition using `resolve` method:
|
||||
*/
|
||||
|
||||
var service = try! container.resolve() as Service
|
||||
|
||||
/*:
|
||||
That code says that you want your `container` to give you an instance that was registered as implementation of `Service` protocol.
|
||||
|
||||
It's important to specify the same type that you used for registration. You can use either `as` syntax, or specify type of you variable when you define it:
|
||||
*/
|
||||
|
||||
let otherService: Service = try! container.resolve()
|
||||
|
||||
/*:
|
||||
Both ways will let the `container` detect the type that you want to resolve as. We prefer the `as` syntax because it reads more naturally in Swift.
|
||||
|
||||
If you used a tag to register your component, you can use the same tag to resolve it. If there is no definition with such tag, the `container` will try to find a definition for the same type with no tag (`nil` tag), and resolve it instead, allowing you to provide default components in such cases.
|
||||
*/
|
||||
|
||||
container.register(tag: "production") { ServiceImp1() as Service }
|
||||
container.register(tag: "test") { ServiceImp2() as Service }
|
||||
|
||||
// Will give you a ServiceImp1 instance
|
||||
let productionService = try! container.resolve(tag: "production") as Service
|
||||
// Will give you a ServiceImp2 instance
|
||||
let testService = try! container.resolve(tag: "test") as Service
|
||||
// Will give you a ServiceImp1 because one was registered without a tag on line 4
|
||||
let defaultService = try! container.resolve() as Service
|
||||
|
||||
/*:
|
||||
You can use runtime arguments to resolve components. Dip supports up to six arguments. For more details see ["Runtime arguments"](Runtime%20arguments).
|
||||
*/
|
||||
container.register { service in ClientImp1(service: service) as Client }
|
||||
let client = try! container.resolve(arguments: service) as Client
|
||||
|
||||
//: [Next: Runtime Arguments](@next)
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Timeline
|
||||
version = "3.0">
|
||||
<TimelineItems>
|
||||
</TimelineItems>
|
||||
</Timeline>
|
||||
@@ -0,0 +1,52 @@
|
||||
//: [Previous: Resolving Components](@previous)
|
||||
|
||||
import Dip
|
||||
|
||||
let container = DependencyContainer()
|
||||
|
||||
/*:
|
||||
|
||||
### Runtime arguments
|
||||
|
||||
Dip lets you use runtime arguments to register and resolve your components.
|
||||
Note that __types__, __number__ and __order__ of arguments matters and you can register different factories with different set of runtime arguments for the same protocol. To resolve using one of this factory you will need to pass runtime arguments of the same types, number and in the same order to `resolve` as you used in `register` method.
|
||||
*/
|
||||
|
||||
container.register { (url: NSURL, port: Int) in ServiceImp4(name: "1", baseURL: url, port: port) as Service }
|
||||
container.register { (port: Int, url: NSURL) in ServiceImp4(name: "2", baseURL: url, port: port) as Service }
|
||||
container.register { (port: Int, url: NSURL?) in ServiceImp4(name: "3", baseURL: url!, port: port) as Service }
|
||||
|
||||
let url: NSURL = NSURL(string: "http://example.com")!
|
||||
let service1 = try! container.resolve(arguments: url, 80) as Service
|
||||
let service2 = try! container.resolve(arguments: 80, url) as Service
|
||||
let service3 = try! container.resolve(arguments: 80, NSURL(string: "http://example.com")) as Service
|
||||
|
||||
(service1 as! ServiceImp4).name
|
||||
(service2 as! ServiceImp4).name
|
||||
(service3 as! ServiceImp4).name
|
||||
|
||||
/*:
|
||||
Note that all of the services were resolved using different factories.
|
||||
|
||||
_Dip_ supports up to six runtime arguments. If that is not enougth you can extend `DependencyContainer` to accept more arguments. For example, here is how you can extend it to serve seven arguments.
|
||||
*/
|
||||
|
||||
extension DependencyContainer {
|
||||
|
||||
@discardableResult
|
||||
public func register<T, A, B, C, D, E, F, G>(_ scope: ComponentScope = .shared, type: T.Type = T.self, tag: DependencyTagConvertible? = nil, factory: @escaping (A, B, C, D, E, F, G) throws -> T) -> Definition<T, (A, B, C, D, E, F, G)> {
|
||||
return register(scope: scope, type: type, tag: tag, factory: factory, numberOfArguments: 7) { container, tag in
|
||||
try factory(container.resolve(tag: tag), container.resolve(tag: tag), container.resolve(tag: tag), container.resolve(tag: tag), container.resolve(tag: tag), container.resolve(tag: tag), container.resolve(tag: tag))
|
||||
}
|
||||
}
|
||||
|
||||
public func resolve<T, A, B, C, D, E, F, G>(tag: DependencyTagConvertible? = nil, _ arg1: A, _ arg2: B, _ arg3: C, _ arg4: D, _ arg5: E, _ arg6: F, _ arg7: G) throws -> T {
|
||||
return try resolve(tag: tag) { factory in try factory(arg1, arg2, arg3, arg4, arg5, arg6, arg7) }
|
||||
}
|
||||
}
|
||||
|
||||
/*:
|
||||
However, if you find yourself thinking about adding more runtime arguments, stop and think about your design instead. Having too many dependencies could be a sign of some problem in your architecture, so we strongly suggest that you refrain from doing so; six runtime arguments is already a lot.
|
||||
*/
|
||||
|
||||
//: [Next: Scopes](@next)
|
||||
@@ -0,0 +1,67 @@
|
||||
//: [Previous: Runtime Arguments](@previous)
|
||||
|
||||
import Dip
|
||||
|
||||
let container = DependencyContainer()
|
||||
|
||||
/*:
|
||||
|
||||
### Scopes
|
||||
|
||||
Dip supports three different scopes of objects: _Unique_, _Shared_ and _Singleton_.
|
||||
|
||||
* The `Unique` scope will make the `DependencyContainer` resolve your type as __a new instance every time__ you call `resolve`. This is the default scope.
|
||||
* The `Shared` scope is like `Unique` scope, but it will make the `DependencyContainer` to reuse resolved instances during one (recursive) call to `resolve` method. When this call returns, all resolved instances will be discarded and next call to `resolve` will produce new instances. This scope should be used to resolve [circular dependencies](Circular%20dependencies).
|
||||
* The `Singleton` scope will make the `DependencyContainer` retain the instance once resolved the first time, and reuse it in the next calls to `resolve` during the container lifetime.
|
||||
* The `EagerSingleton` scope is the same as `Singleton` scope but instances with this cope will be created when you call `bootstrap()` method on the container.
|
||||
* The `WeakSingleton` scope is the same as `Singleton` scope but instances are stored in container as weak references. This scope can be usefull when you need to recreate object graph without reseting container.
|
||||
|
||||
The `Unique` scope is the default. To set a scope you pass it as an argument to `register` method.
|
||||
*/
|
||||
|
||||
container.register { ServiceImp1() as Service }
|
||||
container.register(.unique, tag: "prototype") { ServiceImp1() as Service }
|
||||
container.register(.shared, tag: "object graph") { ServiceImp2() as Service }
|
||||
container.register(.singleton, tag: "shared instance") { ServiceImp3() as Service }
|
||||
|
||||
let service = try! container.resolve() as Service
|
||||
let anotherService = try! container.resolve() as Service
|
||||
// They are different instances as the scope defaults to .unique
|
||||
service as! ServiceImp1 === anotherService as! ServiceImp1 // false
|
||||
|
||||
let prototypeService = try! container.resolve(tag: "prototype") as Service
|
||||
let anotherUniqueService = try! container.resolve(tag: "prototype") as Service
|
||||
// They are different instances:
|
||||
prototypeService === anotherUniqueService // false
|
||||
|
||||
let graphService = try! container.resolve(tag: "object graph") as Service
|
||||
let anotherGraphService = try! container.resolve(tag: "object graph") as Service
|
||||
// still different instances — the Shared scope only keep instances during one (recursive) resolution call,
|
||||
// so the two calls on the two lines above are different calls and use different instances
|
||||
graphService === anotherGraphService // false
|
||||
|
||||
let sharedService = try! container.resolve(tag: "shared instance") as Service
|
||||
let sameSharedService = try! container.resolve(tag: "shared instance") as Service
|
||||
// same instances, the singleton scope keep and reuse instances during the lifetime of the container
|
||||
sharedService as! ServiceImp3 === sameSharedService as! ServiceImp3
|
||||
|
||||
/*:
|
||||
### Bootstrapping
|
||||
|
||||
You can use `bootstrap()` method to fix your container setup and initialise components registered with `EagerSingleton` scope.
|
||||
After bootstrapping if you try to add or remove any definition it will cause runtime exception. Call `boostrap` when you registered all the components, for example at the end of initialization block if you use `init(configBlock:)`.
|
||||
*/
|
||||
|
||||
var resolvedEagerSingleton = false
|
||||
let definition = container.register(.eagerSingleton, tag: "eager shared instance") { ServiceImp1() as Service }
|
||||
.resolvingProperties { _ in resolvedEagerSingleton = true }
|
||||
|
||||
try! container.bootstrap()
|
||||
resolvedEagerSingleton
|
||||
|
||||
let eagerSharedService = try! container.resolve(tag: "eager shared instance") as Service
|
||||
|
||||
container.remove(definition)
|
||||
|
||||
//: [Next: Circular Dependencies](@next)
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
//: [Previous: Circular Dependencies](@previous)
|
||||
|
||||
import Dip
|
||||
import UIKit
|
||||
|
||||
/*:
|
||||
### Shared Instances
|
||||
|
||||
The Singleton pattern is probably the most debatable and abused pattern in Cocoa development (and probably in programming in general). It's probably the first thing that you will hear from a candidate developer on interview when you ask about Cocoa patterns (the other one will be a delegate).
|
||||
|
||||
The problem with singleton is not that it's a worst pattern. The problem is that developers use it to solve problems that do not require it at all. Another problem is that it's very easy to be tempted by this pattern cause it's very easy to implement and use - import file and call `sharedInstance`. But that leads to all kinds of problems:
|
||||
|
||||
- First - singleton is a shared mutable state. And the worst thing is that it's a _mutable_ state.
|
||||
- Second - singleton tigthly couple components of your system.
|
||||
- Third - it limits your code flexibility.
|
||||
|
||||
Dip supports singletons, but it reduces cost of using them. Their singleton nature is managed by the _Container_ and defined only by the _Definitions_ that you register, not by concrete implementations of your classes.
|
||||
|
||||
- No need for calls to `sharedInstance` in your code anymore. Instead you get the instance from the _Container_ by resolving a protocol.
|
||||
- You can easyly change concrete implementations without the rest of your system even notice that something changed.
|
||||
- Also it's easy to test - you just register another object in your tests. Even if you still want to use a singleton in your system.
|
||||
|
||||
Those features you got when using Dip limits tight coupling in your code and gives you back your code flexibility.
|
||||
|
||||
Probably the most common example is using a singleton in the network layer or "API client".
|
||||
*/
|
||||
|
||||
class ApiClientSingleton {
|
||||
static let sharedInstance = ApiClientSingleton()
|
||||
private init() {}
|
||||
// Typically a method that makes a GET request on your API
|
||||
func get(path: String, completion:()->()) {}
|
||||
}
|
||||
|
||||
class MyViewControllerWithSingleton: UIViewController {
|
||||
override func viewDidAppear(_ amimated: Bool) {
|
||||
super.viewDidAppear(amimated)
|
||||
ApiClientSingleton.sharedInstance.get("/users") { /* refresh your UI */ }
|
||||
}
|
||||
}
|
||||
|
||||
/*:
|
||||
Sure, this is very easy to code indeed. And nothing bad so far.
|
||||
|
||||
But probably if you wrote a unit test or integration test for that code first, you would have noticed a problem earilier. How you test that code? And how you ensure that your tests are idenpendent of the API client's state from the previous test?
|
||||
Of cource you can work around all of the problems and the fact that `ApiClient` is a singleton, reset it's state somehow, or mock a class so that it will not return a singleton instance. But look - a moment before the singleton was your best friend and now you are fighting against it.
|
||||
|
||||
Think - why do you want API client to be a singleton in a first place? To queue or throttle requests? Then do your queue or throttler a singleton, not an API client. Or is there any other reason. Most likely API client itself does not have a requirement to have one and only one instance during the lifecycle of your application. Imagine that in the future we need two API Clients, because you now have to address two different servers & plaforms? Imposing that singleton restricts now your flexibility a lot.
|
||||
|
||||
Instead, inject API client in view controller with property injection or constructor injection.
|
||||
*/
|
||||
|
||||
protocol ApiClientProtocol {
|
||||
func get(path: String, completion:()->())
|
||||
}
|
||||
|
||||
class ApiClient: ApiClientProtocol {
|
||||
|
||||
private struct ApiScheduler {
|
||||
/* … */
|
||||
}
|
||||
|
||||
private let scheduler = ApiScheduler()
|
||||
|
||||
init(){}
|
||||
|
||||
func get(path: String, completion:()->()) {}
|
||||
}
|
||||
|
||||
class MyViewController: UIViewController {
|
||||
var apiClient: ApiClientProtocol!
|
||||
|
||||
override func viewDidAppear(amimated: Bool) {
|
||||
super.viewDidAppear(_ amimated)
|
||||
apiClient.get("path") {}
|
||||
}
|
||||
|
||||
convenience init(apiClient: ApiClientProtocol) {
|
||||
self.apiClient = apiClient
|
||||
self.init()
|
||||
}
|
||||
|
||||
init() {
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
}
|
||||
|
||||
//inject with constructor
|
||||
var viewController = MyViewController(apiClient: ApiClient())
|
||||
//or with property
|
||||
viewController.apiClient = ApiClient()
|
||||
|
||||
/*:
|
||||
With Dip this code can look like this:
|
||||
*/
|
||||
|
||||
let container = DependencyContainer()
|
||||
container.register { ApiClient() as ApiClientProtocol }
|
||||
|
||||
//inject with constructor
|
||||
viewController = try MyViewController(apiClient: container.resolve())
|
||||
//or with property
|
||||
viewController.apiClient = try container.resolve()
|
||||
|
||||
/*:
|
||||
Of cource `DependencyContainer` should not be a singleton too. There is just no need for that because you never should call `DependencyContainer` from inside of your components. That will make it a [service locator antipatter]((http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/)). You may only call `DependencyContainer` from the _Composition root_ - the place where all the components are configured and wired together.
|
||||
|
||||
Dependency Injection is a pattern (more precisely - a set of patterns) as well as a singleton. And any pattern can be abused. DI can be used in a [wrong way]((http://www.loosecouplings.com/2011/01/dependency-injection-using-di-container.html)), container can easily become a service locator. You should carefully decide when to use DI, you should not inject everything and everywhere and define a protocol for every single class you use. For every tool there is a right time and the same way as singleton can harm you the same way DI and protocols abuse can make your code unnececerry complex.
|
||||
|
||||
If you want to know more about Dependency Injection in general we recomend you to read ["Dependency Injection in .Net" by Mark Seemann](https://www.manning.com/books/dependency-injection-in-dot-net). Dip was inspired by implementations of IoC container for .Net platform and shares core principles described in that book.
|
||||
|
||||
*/
|
||||
|
||||
//: [Next: Auto-wiring](@next)
|
||||
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
//: [Previous: Containers Collaboration](@previous)
|
||||
|
||||
//import XCTest
|
||||
import Dip
|
||||
|
||||
let container = DependencyContainer()
|
||||
|
||||
/*:
|
||||
|
||||
### Testing
|
||||
|
||||
If you use Dependency Injection patterns like contructor and property injection it will be much easier
|
||||
to unit test your components. When it comes to integration tests you may want to mock some real services.
|
||||
In these tests you can register mock implementation in the container and it will be injected instead of the real implementation.
|
||||
|
||||
Dip is convenient to use for testing. Here is s simple example of how you can write tests with Dip.
|
||||
|
||||
> That's a very simple example just to demonstrate use of Dip in tests, not how you should or should not test your code in general.
|
||||
You can learn more about testing based on state verification vs behavior verification [here](http://martinfowler.com/articles/mocksArentStubs.html).
|
||||
|
||||
> XCTest is not supported by playgrounds so to be able to compile this page we commented out XCTest specific code.
|
||||
*/
|
||||
|
||||
protocol ServiceType {
|
||||
func doSomething()
|
||||
}
|
||||
|
||||
class RealService: ServiceType {
|
||||
func doSomething() {
|
||||
//do something real
|
||||
}
|
||||
}
|
||||
|
||||
class Client {
|
||||
var service: ServiceType!
|
||||
|
||||
func callService() {
|
||||
service.doSomething()
|
||||
}
|
||||
}
|
||||
|
||||
/*:
|
||||
Instead of the real `Service` implementation, provide a _fake_ implementation with test hooks that you need:
|
||||
*/
|
||||
|
||||
class FakeService: ServiceType {
|
||||
var doSomethingCalled = false
|
||||
|
||||
func doSomething() {
|
||||
doSomethingCalled = true
|
||||
}
|
||||
|
||||
init() {}
|
||||
}
|
||||
|
||||
/*:
|
||||
Somewhere in your production code you register real implementations:
|
||||
*/
|
||||
func configure(container: DependencyContainer) {
|
||||
container.register { RealService() as ServiceType }
|
||||
container.register { Client() }
|
||||
.resolvingProperties { container, client in
|
||||
client.service = try container.resolve()
|
||||
}
|
||||
}
|
||||
|
||||
class MyTests/*: XCTestCase*/ {
|
||||
|
||||
/*override*/ func setUp() {
|
||||
//super.setUp()
|
||||
|
||||
/*:
|
||||
Reset container configuration to normal state:
|
||||
*/
|
||||
container.reset()
|
||||
configure(container: container)
|
||||
}
|
||||
|
||||
func testThatDoSomethingIsCalled() {
|
||||
/*:
|
||||
Register fake implementation as `Service`:
|
||||
*/
|
||||
container.register { FakeService() as ServiceType }
|
||||
|
||||
let sut = try! container.resolve() as Client
|
||||
sut.callService()
|
||||
|
||||
/*:
|
||||
And finally you test it was called:
|
||||
*/
|
||||
let service = sut.service as! FakeService
|
||||
//XCTAssertTrue(service.doSomethingCalled)
|
||||
}
|
||||
}
|
||||
|
||||
/*:
|
||||
You can also validate your container configuration. You can do that either in a separate test suit or when runnging application in `DEBUG` mode.
|
||||
|
||||
During validation container will try to resolve all the definitions registered in it. If some of definitions requires runtime arguments you can provide them as arguments to `validate` method. They should exactly match types of arguments required by factories. Multiple arguments for the single factory should be grouped in a tuple. If you don't provide arguments validation will fail.
|
||||
*/
|
||||
container.register { (url: NSURL, port: Int) in ServiceImp4(name: "1", baseURL: url, port: port) as Service }
|
||||
try! container.validate((NSURL(string: "https://github.com/AliSoftware/Dip")!, 80))
|
||||
|
||||
do {
|
||||
try container.validate()
|
||||
}
|
||||
catch {
|
||||
print(error)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
//: [Previous: Auto-injection](@previous)
|
||||
|
||||
import Foundation
|
||||
import Dip
|
||||
|
||||
let container = DependencyContainer()
|
||||
|
||||
/*:
|
||||
### Type Forwarding
|
||||
|
||||
Very often we end up with single class that implements several protocols. This is normal even in [VIPER architecture](https://github.com/mutualmobile/VIPER-SWIFT/blob/master/VIPER-SWIFT/Classes/Modules/List/User%20Interface/Presenter/ListPresenter.swift#L12) that constantly strives for Single Responsibility Principle.
|
||||
|
||||
Let's look at example of VIPER architecture:
|
||||
*/
|
||||
|
||||
extension ListPresenter: ListInteractorOutput, ListModuleInterface, AddModuleDelegate {}
|
||||
extension ListInteractor: ListInteractorInput {}
|
||||
extension AddPresenter: AddModuleInterface {}
|
||||
|
||||
/*:
|
||||
In VIPER we need to create several objects (presenters, wireframes, interactors) which should be accessed thorugh different interfaces. We need to wire them all together so that we have the same instances in place for different types.
|
||||
|
||||
- `ListInteractor` referenced by `ListPresenter` in its `listInteractor` property (via `ListInteractorInput` protocol) should hold a backward reference to the same presenter in its `output` property
|
||||
- `ListWireframe` referenced by `ListPresenter` should also hold a backward reference to the same presenter in its `listPresenter` property
|
||||
- `AddWireframe` should hold a reference to `AddPresenter` that should hold reference to the same `ListPresenter` in its `addModuleDelegate` property (via `AddModuleDelegate` protocol).
|
||||
|
||||
We can achieve this result by explicitly rosolving concrete types:
|
||||
*/
|
||||
|
||||
container.register { ListWireframe(addWireFrame: $0, listPresenter: $1) }
|
||||
container.register { AddWireframe(addPresenter: $0) }
|
||||
|
||||
var listInteractorDefinition = container.register { ListInteractor() }
|
||||
.resolvingProperties { container, interactor in
|
||||
interactor.output = try container.resolve() as ListPresenter
|
||||
}
|
||||
|
||||
var listPresenterDefinition = container.register { ListPresenter() }
|
||||
.resolvingProperties { container, presenter in
|
||||
presenter.listInteractor = try container.resolve() as ListInteractor
|
||||
presenter.listWireframe = try container.resolve()
|
||||
}
|
||||
|
||||
var addPresenterDefinition = container.register { AddPresenter() }
|
||||
.resolvingProperties { container, presenter in
|
||||
presenter.addModuleDelegate = try container.resolve() as ListPresenter
|
||||
}
|
||||
|
||||
var addPresenter = try! container.resolve() as AddPresenter
|
||||
var listPresenter = addPresenter.addModuleDelegate as! ListPresenter
|
||||
var listInteractor = listPresenter.listInteractor as! ListInteractor
|
||||
listInteractor.output === listPresenter
|
||||
var listWireframe = listPresenter.listWireframe
|
||||
listWireframe?.listPresenter === listPresenter
|
||||
|
||||
/*:
|
||||
Alternatively we can use type-forwarding. With type-forwarding we register definition for one (source) type and also for another (forwarded) type. When container will try to resolve forwarded type it will use the same definition as for source type, and (if registered in `Shared` scope or as a singleton) will reuse the same instance. With that you don't need to resolve concrete types in definitions:
|
||||
*/
|
||||
|
||||
listInteractorDefinition = container.register { ListInteractor() }
|
||||
.resolvingProperties { container, interactor in
|
||||
interactor.output = try container.resolve()
|
||||
}
|
||||
|
||||
listPresenterDefinition = container.register { ListPresenter() }
|
||||
.resolvingProperties { container, presenter in
|
||||
presenter.listInteractor = try container.resolve()
|
||||
presenter.listWireframe = try container.resolve()
|
||||
}
|
||||
|
||||
addPresenterDefinition = container.register { AddPresenter() }
|
||||
.resolvingProperties { container, presenter in
|
||||
presenter.addModuleDelegate = try container.resolve()
|
||||
}
|
||||
|
||||
/*:
|
||||
And now we register definitions for type-forwarding:
|
||||
*/
|
||||
listInteractorDefinition
|
||||
.implements(ListInteractorInput.self)
|
||||
listPresenterDefinition
|
||||
.implements(ListInteractorOutput.self)
|
||||
.implements(ListModuleInterface.self)
|
||||
.implements(AddModuleDelegate.self)
|
||||
|
||||
addPresenter = try! container.resolve() as AddPresenter
|
||||
listPresenter = addPresenter.addModuleDelegate as! ListPresenter
|
||||
listInteractor = listPresenter.listInteractor as! ListInteractor
|
||||
listInteractor.output === listPresenter
|
||||
listWireframe = listPresenter.listWireframe
|
||||
listWireframe?.listPresenter === listPresenter
|
||||
|
||||
/*:
|
||||
Type forwarding will work the same way whenever your resolve dependencies with property injection using `resolveDependencies` block, or with auto-injected properties, or with constructor injection and auto-wiring.
|
||||
|
||||
Registering definition for type forwarding will effectively register another definition in the container, linked with original one. So the same overriding rool will be applied for such registrations - last wins. If you need to register different definitions for the same type you should register them with different tags.
|
||||
|
||||
You can also provide `resolveDependencies` block for forwarded definition. First container will call `resolveDependencies` block of the source definition, and then of forwarded definition:
|
||||
*/
|
||||
listInteractorDefinition
|
||||
.resolvingProperties { container, interactor in
|
||||
print("resolved ListInteractor")
|
||||
}
|
||||
let _ = container.register(listInteractorDefinition, type: ListInteractorInput.self)
|
||||
.resolvingProperties { container, interactor in
|
||||
print("resolved ListInteractorInput")
|
||||
}
|
||||
addPresenter = try! container.resolve() as AddPresenter
|
||||
|
||||
//: [Next: Containers Collaboration](@next)
|
||||
@@ -0,0 +1,24 @@
|
||||
/*:
|
||||
__Note__: _This playground needs to be open as part of the `Dip.xcworkspace` so it can import the Dip framework / module and demonstrate its usage. (The playground won't work properly if you open it on its own)._
|
||||
|
||||
_You might also need to ask Xcode to build the Dip framework first (Command-B) before it can find and import it in this playground._
|
||||
*/
|
||||
|
||||
/*:
|
||||
## What is Dip?
|
||||
|
||||
_Dip_ is a lightweight Swift implementation of [IoC container](https://en.wikipedia.org/wiki/Inversion_of_control).
|
||||
|
||||
If you follow [Protocol-Oriented programming](https://developer.apple.com/videos/play/wwdc2015-408/) or [SOLID principles](http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod) then instead of concrete classes you should use protocols to define dependencies between components of your system. I.e. if you need to access some network API, you should use instances of an `APIClient` protocol instead of instances of a concrete class `APIClientImp`.
|
||||
|
||||
[Dependency Injection](https://en.wikipedia.org/wiki/Dependency_injection) is a good tool to leverage Protocol-Oriented or SOLID design. Using this principle, you move the point where you create concrete instances _from inside objects_ that use them, _to higher levels_ of your system. **Now your objects do not depend on concrete implementations of their dependencies**, they depend **only on their public interfaces**, defined by protocols that they implement. That gives you all sorts of advantages from **easier testability** to **greater flexibility** of your system.
|
||||
|
||||
But still there should be some point in your program where concrete instances are created. The thing is that it's better to have one well defined point for that than to scatter setup logic all over the place with different factories and lazy properties. IoC containers like _Dip_ play the role of that point.
|
||||
|
||||
The following pages in this Playground demonstrates how to use _Dip_ to adopt all those concepts in practice.
|
||||
|
||||
If you want to know more about Dependency Injection in general we recomend you to read ["Dependency Injection in .Net" by Mark Seemann](https://www.manning.com/books/dependency-injection-in-dot-net). Dip was inspired by implementations of IoC container for .Net platform and shares core principles described in that book.
|
||||
|
||||
*/
|
||||
//: [Next: Creating a DependencyContainer](@next)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Timeline
|
||||
version = "3.0">
|
||||
<TimelineItems>
|
||||
</TimelineItems>
|
||||
</Timeline>
|
||||
@@ -0,0 +1,110 @@
|
||||
import Foundation
|
||||
|
||||
public protocol Service: class {}
|
||||
|
||||
public class ServiceImp1: Service {
|
||||
public init() {}
|
||||
}
|
||||
public class ServiceImp2: Service {
|
||||
public init() {}
|
||||
}
|
||||
public class ServiceImp3: Service {
|
||||
public init() {}
|
||||
}
|
||||
|
||||
public class ServiceImp4: Service {
|
||||
|
||||
public let name: String
|
||||
|
||||
public init(name: String, baseURL: NSURL, port: Int) {
|
||||
self.name = name
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public protocol Client: class {
|
||||
var service: Service {get}
|
||||
init(service: Service)
|
||||
}
|
||||
public class ClientImp1: Client {
|
||||
public var service: Service
|
||||
public required init(service: Service) {
|
||||
self.service = service
|
||||
}
|
||||
}
|
||||
|
||||
public class ClientImp2: Client {
|
||||
public var service: Service
|
||||
public required init(service: Service) {
|
||||
self.service = service
|
||||
}
|
||||
}
|
||||
|
||||
public class ServiceFactory {
|
||||
public init() {}
|
||||
|
||||
public func someService() -> Service {
|
||||
return ServiceImp1()
|
||||
}
|
||||
}
|
||||
|
||||
public class ClientServiceImp: Service {
|
||||
public weak var client: Client?
|
||||
public init() {}
|
||||
}
|
||||
|
||||
public protocol Logger {}
|
||||
public protocol Tracker {}
|
||||
public protocol DataProvider {}
|
||||
public protocol Router {}
|
||||
|
||||
public class LoggerImp: Logger {
|
||||
public init() {}
|
||||
}
|
||||
|
||||
public class TrackerImp: Tracker {
|
||||
public init() {}
|
||||
}
|
||||
|
||||
public class RouterImp: Router {
|
||||
public init() {}
|
||||
}
|
||||
|
||||
public class DataProviderImp: DataProvider {
|
||||
public init() {}
|
||||
}
|
||||
|
||||
public protocol ListInteractorOutput: class {}
|
||||
public protocol ListModuleInterface: class {}
|
||||
public protocol ListInteractorInput: class {}
|
||||
public class ListPresenter: NSObject {
|
||||
public var listInteractor : ListInteractorInput?
|
||||
public var listWireframe : ListWireframe?
|
||||
public override init() {}
|
||||
}
|
||||
public class ListInteractor: NSObject {
|
||||
public var output : ListInteractorOutput?
|
||||
public override init() {}
|
||||
}
|
||||
|
||||
public class ListWireframe : NSObject {
|
||||
public let addWireframe: AddWireframe
|
||||
public let listPresenter: ListPresenter
|
||||
public init(addWireFrame: AddWireframe, listPresenter: ListPresenter) {
|
||||
self.addWireframe = addWireFrame
|
||||
self.listPresenter = listPresenter
|
||||
}
|
||||
}
|
||||
|
||||
public protocol AddModuleDelegate: class {}
|
||||
public protocol AddModuleInterface: class {}
|
||||
public class AddWireframe: NSObject {
|
||||
let addPresenter : AddPresenter
|
||||
public init(addPresenter: AddPresenter) {
|
||||
self.addPresenter = addPresenter
|
||||
}
|
||||
}
|
||||
public class AddPresenter: NSObject {
|
||||
public var addModuleDelegate : AddModuleDelegate?
|
||||
public override init() {}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<playground version='6.0' target-platform='ios' display-mode='rendered'>
|
||||
<pages>
|
||||
<page name='What is Dip?'/>
|
||||
<page name='Creating container'/>
|
||||
<page name='Registering components'/>
|
||||
<page name='Resolving components'/>
|
||||
<page name='Runtime arguments'/>
|
||||
<page name='Scopes'/>
|
||||
<page name='Circular dependencies'/>
|
||||
<page name='Shared Instances'/>
|
||||
<page name='Auto-wiring'/>
|
||||
<page name='Auto-injection'/>
|
||||
<page name='Type Forwarding'/>
|
||||
<page name='Containers Collaboration'/>
|
||||
<page name='Testing'/>
|
||||
</pages>
|
||||
</playground>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
</Workspace>
|
||||
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,31 +0,0 @@
|
||||
//
|
||||
// AppDelegate.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 04/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
@UIApplicationMain
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
var window: UIWindow?
|
||||
|
||||
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
|
||||
// Override point for customization after application launch.
|
||||
|
||||
if let tabBarVC = self.window?.rootViewController as? UITabBarController,
|
||||
let vcs = tabBarVC.viewControllers as? [UINavigationController] {
|
||||
if let personListVC = vcs[0].topViewController as? PersonListViewController {
|
||||
personListVC.fetchAllObjects()
|
||||
}
|
||||
if let starshipListVC = vcs[1].topViewController as? StarshipListViewController {
|
||||
starshipListVC.fetchAllObjects()
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
//
|
||||
// DependencyContainers.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 10/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Dip
|
||||
|
||||
|
||||
enum WebService {
|
||||
case PersonWS
|
||||
case StarshipWS
|
||||
}
|
||||
|
||||
// Dependency Container for WebServices & NetworkLayer
|
||||
let wsDependencies: DependencyContainer<WebService> = {
|
||||
let dip = DependencyContainer<WebService>()
|
||||
|
||||
// Register the NetworkLayer, same for everyone here (but we have the ability to register a different one for a specific WebService if we wanted to)
|
||||
dip.register(instance: URLSessionNetworkLayer(baseURL: "http://swapi.co/api/")! as NetworkLayer)
|
||||
|
||||
return dip
|
||||
}()
|
||||
|
||||
|
||||
|
||||
/* Change this to toggle between real and fake data */
|
||||
let FAKE_PERSONS = false
|
||||
let FAKE_STARSHIPS = false
|
||||
|
||||
|
||||
// Dependency Container for Providers
|
||||
let providerDependencies: DependencyContainer<Int> = {
|
||||
let dip = DependencyContainer<Int>()
|
||||
|
||||
if FAKE_PERSONS {
|
||||
|
||||
// 1) Register the PersonProviderAPI singleton, one generic and one specific for a specific personID
|
||||
dip.register(instance: DummyPilotProvider() as PersonProviderAPI)
|
||||
dip.register(0, instance: PlistPersonProvider(plist: "mainPilot") as PersonProviderAPI)
|
||||
|
||||
} else {
|
||||
|
||||
// 1) Register the SWAPIPersonProvider (that hits the real swapi.co WebService)
|
||||
dip.register(instance: SWAPIPersonProvider() as PersonProviderAPI)
|
||||
|
||||
}
|
||||
|
||||
if FAKE_STARSHIPS {
|
||||
|
||||
// 2) Register the StarshipProviderAPI factories, one generic and one specific for a specific starshipID
|
||||
dip.register() { HardCodedStarshipProvider() as StarshipProviderAPI }
|
||||
dip.register(0) { DummyStarshipProvider(pilotName: "Main Pilot") as StarshipProviderAPI }
|
||||
|
||||
} else {
|
||||
|
||||
// 2) Register the SWAPIStarshipProvider (that hits the real swapi.co WebService)
|
||||
dip.register(instance: SWAPIStarshipProvider() as StarshipProviderAPI)
|
||||
|
||||
}
|
||||
|
||||
return dip
|
||||
}()
|
||||
@@ -1,34 +0,0 @@
|
||||
//
|
||||
// DummyPilotProvider.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 12/09/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct DummyPilotProvider : PersonProviderAPI {
|
||||
|
||||
func fetchIDs(completion: [Int] -> Void) {
|
||||
completion(Array(0..<5))
|
||||
}
|
||||
|
||||
func fetch(id: Int, completion: Person? -> Void) {
|
||||
completion(dummyPerson(id))
|
||||
}
|
||||
|
||||
private func dummyPerson(idx: Int) -> Person {
|
||||
let colors = ["blue", "brown", "yellow", "orange", "red", "dark"]
|
||||
let genders: [Gender?] = [Gender.Male, Gender.Female, nil]
|
||||
return Person(
|
||||
name: "John Dummy Doe #\(idx)",
|
||||
height: 150 + (idx*27%40),
|
||||
mass: 50 + (idx*7%30),
|
||||
hairColor: colors[idx*3%colors.count],
|
||||
eyeColor: colors[idx*2%colors.count],
|
||||
gender: genders[idx%3],
|
||||
starshipIDs: [idx % 3, 2*idx % 4]
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
//
|
||||
// DummyStarshipProvider.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 08/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct DummyStarshipProvider : StarshipProviderAPI {
|
||||
var pilotName: String
|
||||
|
||||
func fetchIDs(completion: [Int] -> Void) {
|
||||
let nbShips = pilotName.characters.count
|
||||
completion(Array(0..<nbShips))
|
||||
}
|
||||
|
||||
func fetch(id: Int, completion: Starship? -> Void) {
|
||||
completion(dummyStarship(id))
|
||||
}
|
||||
|
||||
private func dummyStarship(idx: Int) -> Starship {
|
||||
return Starship(
|
||||
name: "\(pilotName)'s awesome starship #\(idx)",
|
||||
model: "\(pilotName)Ship",
|
||||
manufacturer: "Dummy Industries",
|
||||
crew: 1 + (idx%3),
|
||||
passengers: 10 + (idx*7 % 40),
|
||||
pilotIDs: [idx]
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
//
|
||||
// HardCodedStarshipProvider.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 11/09/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class HardCodedStarshipProvider : StarshipProviderAPI {
|
||||
|
||||
let starships = [
|
||||
Starship(name: "First Ship", model: "AwesomeShip", manufacturer: "HardCoded Inc.", crew: 3, passengers: 20, pilotIDs: [1,2]),
|
||||
Starship(name: "Second Ship", model: "AwesomeShip Express", manufacturer: "HardCoded Inc.", crew: 4, passengers: 10, pilotIDs: [1]),
|
||||
Starship(name: "Third Ship", model: "AwesomeShip Cargo", manufacturer: "HardCoded Inc.", crew: 12, passengers: 150, pilotIDs: [2]),
|
||||
]
|
||||
|
||||
func fetchIDs(completion: [Int] -> Void) {
|
||||
completion(Array(0..<starships.count))
|
||||
}
|
||||
|
||||
func fetch(id: Int, completion: Starship? -> Void) {
|
||||
guard id < starships.count else {
|
||||
completion(nil)
|
||||
return
|
||||
}
|
||||
completion(starships[id])
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
//
|
||||
// NetworkLayer.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 10/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum NetworkResponse {
|
||||
case Success(NSData, NSHTTPURLResponse)
|
||||
case Error(NSError)
|
||||
|
||||
func unwrap() throws -> (NSData, NSHTTPURLResponse) {
|
||||
switch self {
|
||||
case Success(let data, let response):
|
||||
return (data, response)
|
||||
case Error(let error):
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
func json() throws -> AnyObject {
|
||||
let (data, _) = try self.unwrap()
|
||||
return try NSJSONSerialization.JSONObjectWithData(data, options: [])
|
||||
}
|
||||
}
|
||||
|
||||
protocol NetworkLayer {
|
||||
func request(path: String, completion: NetworkResponse -> Void)
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
//
|
||||
// PlistPersonProvider.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 12/09/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class PlistPersonProvider : PersonProviderAPI {
|
||||
let people: [Person]
|
||||
|
||||
init(plist basename: String) {
|
||||
guard let path = NSBundle.mainBundle().pathForResource(basename, ofType: "plist"),
|
||||
let list = NSArray(contentsOfFile: path),
|
||||
peopleDict = list as? [[String:AnyObject]]
|
||||
else { fatalError("PLIST for \(basename) not found") }
|
||||
|
||||
self.people = peopleDict.map(PlistPersonProvider.personFromDict)
|
||||
}
|
||||
|
||||
func fetchIDs(completion: [Int] -> Void) {
|
||||
completion(Array(0..<people.count))
|
||||
}
|
||||
|
||||
func fetch(id: Int, completion: Person? -> Void) {
|
||||
guard id < people.count else {
|
||||
completion(nil)
|
||||
return
|
||||
}
|
||||
completion(people[id])
|
||||
}
|
||||
|
||||
private static func personFromDict(dict: [String:AnyObject]) -> Person {
|
||||
guard
|
||||
let name = dict["name"] as? String,
|
||||
height = dict["height"] as? Int,
|
||||
mass = dict["mass"] as? Int,
|
||||
hairColor = dict["hairColor"] as? String,
|
||||
eyeColor = dict["eyeColor"] as? String,
|
||||
genderStr = dict["gender"] as? String,
|
||||
starshipsIDs = dict["starships"] as? [Int]
|
||||
else { fatalError("Invalid Plist")
|
||||
}
|
||||
|
||||
return Person(
|
||||
name: name,
|
||||
height: height,
|
||||
mass: mass,
|
||||
hairColor: hairColor,
|
||||
eyeColor: eyeColor,
|
||||
gender: Gender(rawValue: genderStr),
|
||||
starshipIDs: starshipsIDs
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
//
|
||||
// URLSessionNetworkLayer.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 10/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct URLSessionNetworkLayer : NetworkLayer {
|
||||
let baseURL: NSURL
|
||||
let session: NSURLSession
|
||||
let responseQueue: dispatch_queue_t
|
||||
|
||||
init?(baseURL: String, session: NSURLSession = .sharedSession(), responseQueue: dispatch_queue_t = dispatch_get_main_queue()) {
|
||||
guard let url = NSURL(string: baseURL) else { return nil }
|
||||
self.init(baseURL: url, session: session)
|
||||
}
|
||||
|
||||
init(baseURL: NSURL, session: NSURLSession = .sharedSession(), responseQueue: dispatch_queue_t = dispatch_get_main_queue()) {
|
||||
self.baseURL = baseURL
|
||||
self.session = session
|
||||
self.responseQueue = responseQueue
|
||||
}
|
||||
|
||||
func request(path: String, completion: NetworkResponse -> Void) {
|
||||
let url = self.baseURL.URLByAppendingPathComponent(path)
|
||||
let task = session.dataTaskWithURL(url) { data, response, error in
|
||||
if let data = data, let response = response as? NSHTTPURLResponse {
|
||||
dispatch_async(self.responseQueue) {
|
||||
completion(NetworkResponse.Success(data, response))
|
||||
}
|
||||
}
|
||||
else {
|
||||
let err = error ?? NSError(domain: NSURLErrorDomain, code: NSURLError.Unknown.rawValue, userInfo: nil)
|
||||
dispatch_async(self.responseQueue) {
|
||||
completion(NetworkResponse.Error(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
task.resume()
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
//
|
||||
// PersonListViewController.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 09/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class PersonListViewController: UITableViewController, FetchableTrait {
|
||||
var objects: [Person]?
|
||||
var batchRequestID = 0
|
||||
|
||||
lazy var fetchIDs: ([Int] -> Void) -> Void = (providerDependencies.resolve() as PersonProviderAPI).fetchIDs
|
||||
lazy var fetchOne: (Int, Person? -> Void) -> Void = { personID, completion in
|
||||
let provider = providerDependencies.resolve(personID) as PersonProviderAPI
|
||||
return provider.fetch(personID, completion: completion)
|
||||
}
|
||||
|
||||
var fetchProgress: (current: Int, total: Int?) = (0, nil) {
|
||||
didSet {
|
||||
displayProgressInNavBar(self.navigationItem)
|
||||
}
|
||||
}
|
||||
|
||||
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
|
||||
guard
|
||||
let id = segue.identifier, segueID = UIStoryboard.Segue.Main(rawValue: id)
|
||||
where segueID == .StarshipsSegue,
|
||||
let indexPath = self.tableView.indexPathForSelectedRow,
|
||||
let destVC = segue.destinationViewController as? StarshipListViewController,
|
||||
let person = self.objects?[indexPath.row]
|
||||
else {
|
||||
fatalError()
|
||||
}
|
||||
|
||||
destVC.fetchObjects(person.starshipIDs)
|
||||
}
|
||||
}
|
||||
|
||||
extension PersonListViewController {
|
||||
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return objects?.count ?? 0
|
||||
}
|
||||
|
||||
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
|
||||
guard let object = self.objects?[indexPath.row] else { fatalError() }
|
||||
let cell = PersonCell.dequeueFromTableView(tableView, forIndexPath: indexPath)
|
||||
cell.fillWithObject(object)
|
||||
return cell
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
//
|
||||
// StarshipListViewController.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 09/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class StarshipListViewController : UITableViewController, FetchableTrait {
|
||||
var objects: [Starship]?
|
||||
var batchRequestID = 0
|
||||
|
||||
var provider: (Int? -> StarshipProviderAPI) = { providerDependencies.resolve($0) }
|
||||
|
||||
lazy var fetchIDs: ([Int] -> Void) -> Void = self.provider(nil).fetchIDs
|
||||
lazy var fetchOne: (Int, Starship? -> Void) -> Void = { shipID, completion in
|
||||
self.provider(shipID).fetch(shipID, completion: completion)
|
||||
}
|
||||
|
||||
var fetchProgress: (current: Int, total: Int?) = (0, nil) {
|
||||
didSet {
|
||||
displayProgressInNavBar(self.navigationItem)
|
||||
}
|
||||
}
|
||||
|
||||
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
|
||||
guard
|
||||
let id = segue.identifier, segueID = UIStoryboard.Segue.Main(rawValue: id)
|
||||
where segueID == .PilotsSegue,
|
||||
let indexPath = self.tableView.indexPathForSelectedRow,
|
||||
let destVC = segue.destinationViewController as? PersonListViewController,
|
||||
let starship = self.objects?[indexPath.row]
|
||||
else {
|
||||
fatalError()
|
||||
}
|
||||
|
||||
destVC.fetchObjects(starship.pilotIDs)
|
||||
}
|
||||
}
|
||||
|
||||
extension StarshipListViewController {
|
||||
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return objects?.count ?? 0
|
||||
}
|
||||
|
||||
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
|
||||
guard let object = self.objects?[indexPath.row] else { fatalError() }
|
||||
let cell = StarshipCell.dequeueFromTableView(tableView, forIndexPath: indexPath)
|
||||
cell.fillWithObject(object)
|
||||
return cell
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
source 'https://github.com/CocoaPods/Specs.git'
|
||||
|
||||
use_frameworks!
|
||||
platform :ios, '8.0'
|
||||
|
||||
target 'DipSampleApp' do
|
||||
pod 'Dip', :path => '../'
|
||||
end
|
||||
|
||||
target 'DipTests' do
|
||||
pod "Dip", :path => '../'
|
||||
end
|
||||
@@ -1,14 +0,0 @@
|
||||
PODS:
|
||||
- Dip (0.1.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
- Dip (from `../`)
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
Dip:
|
||||
:path: ../
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Dip: c6d545af478b84d3708bf02d986fe687cb3322cc
|
||||
|
||||
COCOAPODS: 0.38.2
|
||||
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"name": "Dip",
|
||||
"version": "0.1.0",
|
||||
"summary": "A simple Dependency Resolver (Simplified Dependency Injection-like resolution).",
|
||||
"description": "Dip is a Swift framework to manage your Dependencies between your classes\nin your app.\n\nIt's aimed to be very simple to use while improving testability\nof your app by allowing you to get rid of those sharedInstances and instead\ninject values based on protocol resolution.\n\nDefine your API using a protocol, then ask Dip to resolve this protocol into\nan instance dynamically in your classes. Then your App and your Tests can be\nconfigured to resolve the protocol using a different instance or class so this\nimprove testability by decoupling the API and the concrete class used to implement it.\n\nIt's not real Dependency Injection _per se_, but it's close.",
|
||||
"homepage": "https://github.com/AliSoftware/Dip",
|
||||
"license": "MIT",
|
||||
"authors": {
|
||||
"Olivier Halligon": "olivier@halligon.net"
|
||||
},
|
||||
"source": {
|
||||
"git": "https://github.com/AliSoftware/Dip.git",
|
||||
"tag": "0.1.0"
|
||||
},
|
||||
"social_media_url": "https://twitter.com/aligatr",
|
||||
"platforms": {
|
||||
"ios": "8.0"
|
||||
},
|
||||
"requires_arc": true,
|
||||
"source_files": "Sources/**/*"
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
PODS:
|
||||
- Dip (0.1.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
- Dip (from `../`)
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
Dip:
|
||||
:path: ../
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Dip: c6d545af478b84d3708bf02d986fe687cb3322cc
|
||||
|
||||
COCOAPODS: 0.38.2
|
||||
@@ -1,669 +0,0 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
4281B9E4626ED37910E70A6053051095 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2913DD9CC28CEF3EB44C812C80C5C242 /* Foundation.framework */; };
|
||||
760ED030B3F9BF2B88E1F61BB696AF52 /* Pods-DipTests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = E6C6D62EFF728EC883AC33E16BEB08DA /* Pods-DipTests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
848961CC560A7BF0C4CCEC7F49AD9D93 /* Dip-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 3B7737BE94231569FDA05F39555BABA9 /* Dip-dummy.m */; };
|
||||
A56D11EEC8601D29B20437637A398FBE /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2913DD9CC28CEF3EB44C812C80C5C242 /* Foundation.framework */; };
|
||||
B43CB9F263659669B07655407B2663BD /* Pods-DipSampleApp-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 75D51085C4F230C1CC04D5C97D5CD181 /* Pods-DipSampleApp-dummy.m */; };
|
||||
B7AF29D7DFAADCE1D059AB81388DC3A9 /* Dip.swift in Sources */ = {isa = PBXBuildFile; fileRef = E85D8C26DBEA227876D2B6BE49C060A3 /* Dip.swift */; };
|
||||
B89AA8E9CD649EA8710AC177891DADF5 /* Pods-DipTests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = B538A5AA13D8CC5A2FB02B8C7E82ACB7 /* Pods-DipTests-dummy.m */; };
|
||||
CBC622391FBCC36E48C7E3D295582D5A /* Dip-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 8042B4793ED34FF6BB085F959C62C902 /* Dip-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
F71A77F6FC1D19954985C78BC04FFBCE /* Pods-DipSampleApp-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = BB9324BB13F4127B03E00DAB78DF3D75 /* Pods-DipSampleApp-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
F8BB3BC94ED3830270E0447B6BA4D12D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2913DD9CC28CEF3EB44C812C80C5C242 /* Foundation.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
717E8357C15C9EC952989F1892DAADD9 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 61B2C099D2823B76EB65B5ECC8B08934;
|
||||
remoteInfo = Dip;
|
||||
};
|
||||
E1543D580D5FE849EA4540C35848C670 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 61B2C099D2823B76EB65B5ECC8B08934;
|
||||
remoteInfo = Dip;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
040E6767354650F6353098E4EB50B3F7 /* Pods-DipSampleApp.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-DipSampleApp.modulemap"; sourceTree = "<group>"; };
|
||||
093DB70F67DB4E609AB442CBB509D4E7 /* Pods-DipTests-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-DipTests-resources.sh"; sourceTree = "<group>"; };
|
||||
17BD92E9BBD2033629156ED61085C674 /* Dip.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Dip.xcconfig; sourceTree = "<group>"; };
|
||||
2913DD9CC28CEF3EB44C812C80C5C242 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.3.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
|
||||
2DA289A9786072EC94A069BF0205D4D6 /* Dip-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Dip-prefix.pch"; sourceTree = "<group>"; };
|
||||
3B7737BE94231569FDA05F39555BABA9 /* Dip-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Dip-dummy.m"; sourceTree = "<group>"; };
|
||||
3BFEC463C4346DFBB40CFD331E7B8C8C /* Pods-DipSampleApp-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-DipSampleApp-acknowledgements.plist"; sourceTree = "<group>"; };
|
||||
4D03528B91AE7D78A28CE55BADFA6159 /* Pods-DipTests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-DipTests-acknowledgements.plist"; sourceTree = "<group>"; };
|
||||
53E603F956BC0848C3DC16E858DAA805 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
56CC73CE7812C91DDB29DC2C84CE562F /* Dip-Private.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Dip-Private.xcconfig"; sourceTree = "<group>"; };
|
||||
6177EEC55F08DE3EBAB9A7AFFB99FA26 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
649D66F1DA814B5F17F49CA0D5948332 /* Pods_DipTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_DipTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
65517CECF14CA488E474611D4E6C8A28 /* Pods_DipSampleApp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_DipSampleApp.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
6571AF80F9340C8BBB03E41828B56DAE /* Pods-DipSampleApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-DipSampleApp.release.xcconfig"; sourceTree = "<group>"; };
|
||||
75D51085C4F230C1CC04D5C97D5CD181 /* Pods-DipSampleApp-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-DipSampleApp-dummy.m"; sourceTree = "<group>"; };
|
||||
7C0F27E74B4689101CF66C46839222CA /* Pods-DipSampleApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-DipSampleApp.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
8042B4793ED34FF6BB085F959C62C902 /* Dip-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Dip-umbrella.h"; sourceTree = "<group>"; };
|
||||
865E74B4F963E602B5B976F7D5FFAA0A /* Dip.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = Dip.modulemap; sourceTree = "<group>"; };
|
||||
9B1020199AD13F9A6B345D4DA93D8FF0 /* Pods-DipTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-DipTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
A37235974396D8B3A4A2163B9FAF0328 /* Pods-DipSampleApp-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-DipSampleApp-resources.sh"; sourceTree = "<group>"; };
|
||||
AF0EA8CE3EB9D052ABA91BBDF5935932 /* Pods-DipSampleApp-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-DipSampleApp-frameworks.sh"; sourceTree = "<group>"; };
|
||||
B13AB9998F2CB1AA813B9AB7A6851FBA /* Pods-DipTests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-DipTests-frameworks.sh"; sourceTree = "<group>"; };
|
||||
B538A5AA13D8CC5A2FB02B8C7E82ACB7 /* Pods-DipTests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-DipTests-dummy.m"; sourceTree = "<group>"; };
|
||||
BA6428E9F66FD5A23C0A2E06ED26CD2F /* Podfile */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
|
||||
BB9324BB13F4127B03E00DAB78DF3D75 /* Pods-DipSampleApp-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-DipSampleApp-umbrella.h"; sourceTree = "<group>"; };
|
||||
CFFD5CBC2BC2688B5A6735AF757D7A13 /* Pods-DipTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-DipTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
D5CB81F4D94CD0DC953C46A26FA193D9 /* Dip.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Dip.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
DD7CF98DF0A99296E41AF2D9C3B473F9 /* Pods-DipTests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-DipTests-acknowledgements.markdown"; sourceTree = "<group>"; };
|
||||
DDDDDD06DF5540C55DA4B0C74E1EC511 /* Pods-DipTests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-DipTests.modulemap"; sourceTree = "<group>"; };
|
||||
E2C25F36DD7F27E8BA0BDFFF808541A7 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
E6C6D62EFF728EC883AC33E16BEB08DA /* Pods-DipTests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-DipTests-umbrella.h"; sourceTree = "<group>"; };
|
||||
E85D8C26DBEA227876D2B6BE49C060A3 /* Dip.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = Dip.swift; sourceTree = "<group>"; };
|
||||
F5067212B9AFB98F7CCBC7151A60A220 /* Pods-DipSampleApp-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-DipSampleApp-acknowledgements.markdown"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
139BA28D38AF67B41F2223A714A1DE43 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A56D11EEC8601D29B20437637A398FBE /* Foundation.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
7A84D2955EF7C71F5E6AF48E447815A1 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
4281B9E4626ED37910E70A6053051095 /* Foundation.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
FC3CB05065376B8016B026FD865ABAC0 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F8BB3BC94ED3830270E0447B6BA4D12D /* Foundation.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
02DBDCD39FB1D88711D499C4EE8EE355 /* Pods-DipTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
53E603F956BC0848C3DC16E858DAA805 /* Info.plist */,
|
||||
DDDDDD06DF5540C55DA4B0C74E1EC511 /* Pods-DipTests.modulemap */,
|
||||
DD7CF98DF0A99296E41AF2D9C3B473F9 /* Pods-DipTests-acknowledgements.markdown */,
|
||||
4D03528B91AE7D78A28CE55BADFA6159 /* Pods-DipTests-acknowledgements.plist */,
|
||||
B538A5AA13D8CC5A2FB02B8C7E82ACB7 /* Pods-DipTests-dummy.m */,
|
||||
B13AB9998F2CB1AA813B9AB7A6851FBA /* Pods-DipTests-frameworks.sh */,
|
||||
093DB70F67DB4E609AB442CBB509D4E7 /* Pods-DipTests-resources.sh */,
|
||||
E6C6D62EFF728EC883AC33E16BEB08DA /* Pods-DipTests-umbrella.h */,
|
||||
CFFD5CBC2BC2688B5A6735AF757D7A13 /* Pods-DipTests.debug.xcconfig */,
|
||||
9B1020199AD13F9A6B345D4DA93D8FF0 /* Pods-DipTests.release.xcconfig */,
|
||||
);
|
||||
name = "Pods-DipTests";
|
||||
path = "Target Support Files/Pods-DipTests";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
331BF982C22B5DA66B25F742D01C5F7D /* Dip */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FAEF7893A179133A40296BA56F7E8846 /* Sources */,
|
||||
7BF12AE4821DF0409A5DD1E494A23CB0 /* Support Files */,
|
||||
);
|
||||
name = Dip;
|
||||
path = ../..;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
46E7572EB1611944AB13E50F656187E9 /* Development Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
331BF982C22B5DA66B25F742D01C5F7D /* Dip */,
|
||||
);
|
||||
name = "Development Pods";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
53F661C0CA7190D2CF05023FB33D61E4 /* iOS */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2913DD9CC28CEF3EB44C812C80C5C242 /* Foundation.framework */,
|
||||
);
|
||||
name = iOS;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7BF12AE4821DF0409A5DD1E494A23CB0 /* Support Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
865E74B4F963E602B5B976F7D5FFAA0A /* Dip.modulemap */,
|
||||
17BD92E9BBD2033629156ED61085C674 /* Dip.xcconfig */,
|
||||
56CC73CE7812C91DDB29DC2C84CE562F /* Dip-Private.xcconfig */,
|
||||
3B7737BE94231569FDA05F39555BABA9 /* Dip-dummy.m */,
|
||||
2DA289A9786072EC94A069BF0205D4D6 /* Dip-prefix.pch */,
|
||||
8042B4793ED34FF6BB085F959C62C902 /* Dip-umbrella.h */,
|
||||
6177EEC55F08DE3EBAB9A7AFFB99FA26 /* Info.plist */,
|
||||
);
|
||||
name = "Support Files";
|
||||
path = "Example/Pods/Target Support Files/Dip";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
7DB346D0F39D3F0E887471402A8071AB = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BA6428E9F66FD5A23C0A2E06ED26CD2F /* Podfile */,
|
||||
46E7572EB1611944AB13E50F656187E9 /* Development Pods */,
|
||||
BC3CA7F9E30CC8F7E2DD044DD34432FC /* Frameworks */,
|
||||
CCA510CFBEA2D207524CDA0D73C3B561 /* Products */,
|
||||
A9D31FC7B7A14D2E4651A6C66A1A86EC /* Targets Support Files */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A9D31FC7B7A14D2E4651A6C66A1A86EC /* Targets Support Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E6EDC7112547C1E567413310A74E6AB2 /* Pods-DipSampleApp */,
|
||||
02DBDCD39FB1D88711D499C4EE8EE355 /* Pods-DipTests */,
|
||||
);
|
||||
name = "Targets Support Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BC3CA7F9E30CC8F7E2DD044DD34432FC /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
53F661C0CA7190D2CF05023FB33D61E4 /* iOS */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
CCA510CFBEA2D207524CDA0D73C3B561 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D5CB81F4D94CD0DC953C46A26FA193D9 /* Dip.framework */,
|
||||
65517CECF14CA488E474611D4E6C8A28 /* Pods_DipSampleApp.framework */,
|
||||
649D66F1DA814B5F17F49CA0D5948332 /* Pods_DipTests.framework */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E6EDC7112547C1E567413310A74E6AB2 /* Pods-DipSampleApp */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E2C25F36DD7F27E8BA0BDFFF808541A7 /* Info.plist */,
|
||||
040E6767354650F6353098E4EB50B3F7 /* Pods-DipSampleApp.modulemap */,
|
||||
F5067212B9AFB98F7CCBC7151A60A220 /* Pods-DipSampleApp-acknowledgements.markdown */,
|
||||
3BFEC463C4346DFBB40CFD331E7B8C8C /* Pods-DipSampleApp-acknowledgements.plist */,
|
||||
75D51085C4F230C1CC04D5C97D5CD181 /* Pods-DipSampleApp-dummy.m */,
|
||||
AF0EA8CE3EB9D052ABA91BBDF5935932 /* Pods-DipSampleApp-frameworks.sh */,
|
||||
A37235974396D8B3A4A2163B9FAF0328 /* Pods-DipSampleApp-resources.sh */,
|
||||
BB9324BB13F4127B03E00DAB78DF3D75 /* Pods-DipSampleApp-umbrella.h */,
|
||||
7C0F27E74B4689101CF66C46839222CA /* Pods-DipSampleApp.debug.xcconfig */,
|
||||
6571AF80F9340C8BBB03E41828B56DAE /* Pods-DipSampleApp.release.xcconfig */,
|
||||
);
|
||||
name = "Pods-DipSampleApp";
|
||||
path = "Target Support Files/Pods-DipSampleApp";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
FAEF7893A179133A40296BA56F7E8846 /* Sources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E85D8C26DBEA227876D2B6BE49C060A3 /* Dip.swift */,
|
||||
);
|
||||
path = Sources;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
20D2FAD8897F05F0F21B6E88F602A8B1 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
CBC622391FBCC36E48C7E3D295582D5A /* Dip-umbrella.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
757551662869B25EE206B19D53CC8F29 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
760ED030B3F9BF2B88E1F61BB696AF52 /* Pods-DipTests-umbrella.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
8F49CC8E1874111D7EF4D173435D7A24 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F71A77F6FC1D19954985C78BC04FFBCE /* Pods-DipSampleApp-umbrella.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
12D3E41651D0F284852A4D526F3256AB /* Pods-DipTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = D7E091A3E6CE5EC7EA78C29D8A21CA70 /* Build configuration list for PBXNativeTarget "Pods-DipTests" */;
|
||||
buildPhases = (
|
||||
AAA3A1408B53FD669A84EBE81D8355D0 /* Sources */,
|
||||
7A84D2955EF7C71F5E6AF48E447815A1 /* Frameworks */,
|
||||
757551662869B25EE206B19D53CC8F29 /* Headers */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
59D193CC66DB380EE84635F4E2991CAF /* PBXTargetDependency */,
|
||||
);
|
||||
name = "Pods-DipTests";
|
||||
productName = "Pods-DipTests";
|
||||
productReference = 649D66F1DA814B5F17F49CA0D5948332 /* Pods_DipTests.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
61B2C099D2823B76EB65B5ECC8B08934 /* Dip */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = CA02FBD0A4DFAC6631999B9E5DEAA891 /* Build configuration list for PBXNativeTarget "Dip" */;
|
||||
buildPhases = (
|
||||
27301CA68EAB0531B3E302342BE6B391 /* Sources */,
|
||||
139BA28D38AF67B41F2223A714A1DE43 /* Frameworks */,
|
||||
20D2FAD8897F05F0F21B6E88F602A8B1 /* Headers */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = Dip;
|
||||
productName = Dip;
|
||||
productReference = D5CB81F4D94CD0DC953C46A26FA193D9 /* Dip.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
F588C5114410BDD4CA3AF7BF16AF6FC8 /* Pods-DipSampleApp */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 9ECD5CC6E806AF1E5D7F66D29B6DDADD /* Build configuration list for PBXNativeTarget "Pods-DipSampleApp" */;
|
||||
buildPhases = (
|
||||
811AA0482F2A12B79AFCB6A2C9AFA4A1 /* Sources */,
|
||||
FC3CB05065376B8016B026FD865ABAC0 /* Frameworks */,
|
||||
8F49CC8E1874111D7EF4D173435D7A24 /* Headers */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
E87C16215529DC10230F8D3773193425 /* PBXTargetDependency */,
|
||||
);
|
||||
name = "Pods-DipSampleApp";
|
||||
productName = "Pods-DipSampleApp";
|
||||
productReference = 65517CECF14CA488E474611D4E6C8A28 /* Pods_DipSampleApp.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
D41D8CD98F00B204E9800998ECF8427E /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0700;
|
||||
LastUpgradeCheck = 0700;
|
||||
};
|
||||
buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = 7DB346D0F39D3F0E887471402A8071AB;
|
||||
productRefGroup = CCA510CFBEA2D207524CDA0D73C3B561 /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
61B2C099D2823B76EB65B5ECC8B08934 /* Dip */,
|
||||
F588C5114410BDD4CA3AF7BF16AF6FC8 /* Pods-DipSampleApp */,
|
||||
12D3E41651D0F284852A4D526F3256AB /* Pods-DipTests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
27301CA68EAB0531B3E302342BE6B391 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
848961CC560A7BF0C4CCEC7F49AD9D93 /* Dip-dummy.m in Sources */,
|
||||
B7AF29D7DFAADCE1D059AB81388DC3A9 /* Dip.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
811AA0482F2A12B79AFCB6A2C9AFA4A1 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B43CB9F263659669B07655407B2663BD /* Pods-DipSampleApp-dummy.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
AAA3A1408B53FD669A84EBE81D8355D0 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B89AA8E9CD649EA8710AC177891DADF5 /* Pods-DipTests-dummy.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
59D193CC66DB380EE84635F4E2991CAF /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
name = Dip;
|
||||
target = 61B2C099D2823B76EB65B5ECC8B08934 /* Dip */;
|
||||
targetProxy = 717E8357C15C9EC952989F1892DAADD9 /* PBXContainerItemProxy */;
|
||||
};
|
||||
E87C16215529DC10230F8D3773193425 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
name = Dip;
|
||||
target = 61B2C099D2823B76EB65B5ECC8B08934 /* Dip */;
|
||||
targetProxy = E1543D580D5FE849EA4540C35848C670 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
179C38BF617A5FDB3138E3FBBCFBCF96 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 56CC73CE7812C91DDB29DC2C84CE562F /* Dip-Private.xcconfig */;
|
||||
buildSettings = {
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 0.1.0;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 0.1.0;
|
||||
DYLIB_CURRENT_VERSION = "$(CURRENT_PROJECT_VERSION)";
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_PREFIX_HEADER = "Target Support Files/Dip/Dip-prefix.pch";
|
||||
INFOPLIST_FILE = "Target Support Files/Dip/Info.plist";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MODULEMAP_FILE = "Target Support Files/Dip/Dip.modulemap";
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
PRODUCT_NAME = Dip;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
1858E18D65A8B61BEAE72BD61ED409B9 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 7C0F27E74B4689101CF66C46839222CA /* Pods-DipSampleApp.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
INFOPLIST_FILE = "Target Support Files/Pods-DipSampleApp/Info.plist";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MODULEMAP_FILE = "Target Support Files/Pods-DipSampleApp/Pods-DipSampleApp.modulemap";
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
OTHER_LDFLAGS = "";
|
||||
OTHER_LIBTOOLFLAGS = "";
|
||||
PODS_ROOT = "$(SRCROOT)";
|
||||
PRODUCT_NAME = Pods_DipSampleApp;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
530E51D69A65177A0CB8BA9337627948 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 9B1020199AD13F9A6B345D4DA93D8FF0 /* Pods-DipTests.release.xcconfig */;
|
||||
buildSettings = {
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
INFOPLIST_FILE = "Target Support Files/Pods-DipTests/Info.plist";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MODULEMAP_FILE = "Target Support Files/Pods-DipTests/Pods-DipTests.modulemap";
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
OTHER_LDFLAGS = "";
|
||||
OTHER_LIBTOOLFLAGS = "";
|
||||
PODS_ROOT = "$(SRCROOT)";
|
||||
PRODUCT_NAME = Pods_DipTests;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
956BB501D5CF8EBD179183A55861D46E /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 6571AF80F9340C8BBB03E41828B56DAE /* Pods-DipSampleApp.release.xcconfig */;
|
||||
buildSettings = {
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
INFOPLIST_FILE = "Target Support Files/Pods-DipSampleApp/Info.plist";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MODULEMAP_FILE = "Target Support Files/Pods-DipSampleApp/Pods-DipSampleApp.modulemap";
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
OTHER_LDFLAGS = "";
|
||||
OTHER_LIBTOOLFLAGS = "";
|
||||
PODS_ROOT = "$(SRCROOT)";
|
||||
PRODUCT_NAME = Pods_DipSampleApp;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
9867AC43F4246CE452AFD55B859928CC /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 56CC73CE7812C91DDB29DC2C84CE562F /* Dip-Private.xcconfig */;
|
||||
buildSettings = {
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 0.1.0;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 0.1.0;
|
||||
DYLIB_CURRENT_VERSION = "$(CURRENT_PROJECT_VERSION)";
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_PREFIX_HEADER = "Target Support Files/Dip/Dip-prefix.pch";
|
||||
INFOPLIST_FILE = "Target Support Files/Dip/Info.plist";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MODULEMAP_FILE = "Target Support Files/Dip/Dip.modulemap";
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
PRODUCT_NAME = Dip;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
A70CDAD61F90AC503C7D04CC22DA2923 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
STRIP_INSTALLED_PRODUCT = NO;
|
||||
SYMROOT = "${SRCROOT}/../build";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
A72E6B5B0A3D3E28381E5C0A7A93C0A5 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = CFFD5CBC2BC2688B5A6735AF757D7A13 /* Pods-DipTests.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEFINES_MODULE = YES;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
INFOPLIST_FILE = "Target Support Files/Pods-DipTests/Info.plist";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MODULEMAP_FILE = "Target Support Files/Pods-DipTests/Pods-DipTests.modulemap";
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
OTHER_LDFLAGS = "";
|
||||
OTHER_LIBTOOLFLAGS = "";
|
||||
PODS_ROOT = "$(SRCROOT)";
|
||||
PRODUCT_NAME = Pods_DipTests;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
FB45FFD90572718D82AB9092B750F0CA /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "RELEASE=1";
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
STRIP_INSTALLED_PRODUCT = NO;
|
||||
SYMROOT = "${SRCROOT}/../build";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
A70CDAD61F90AC503C7D04CC22DA2923 /* Debug */,
|
||||
FB45FFD90572718D82AB9092B750F0CA /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
9ECD5CC6E806AF1E5D7F66D29B6DDADD /* Build configuration list for PBXNativeTarget "Pods-DipSampleApp" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
1858E18D65A8B61BEAE72BD61ED409B9 /* Debug */,
|
||||
956BB501D5CF8EBD179183A55861D46E /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
CA02FBD0A4DFAC6631999B9E5DEAA891 /* Build configuration list for PBXNativeTarget "Dip" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
179C38BF617A5FDB3138E3FBBCFBCF96 /* Debug */,
|
||||
9867AC43F4246CE452AFD55B859928CC /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
D7E091A3E6CE5EC7EA78C29D8A21CA70 /* Build configuration list for PBXNativeTarget "Pods-DipTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
A72E6B5B0A3D3E28381E5C0A7A93C0A5 /* Debug */,
|
||||
530E51D69A65177A0CB8BA9337627948 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = D41D8CD98F00B204E9800998ECF8427E /* Project object */;
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
#include "Dip.xcconfig"
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/Dip" "${PODS_ROOT}/Headers/Public"
|
||||
OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
|
||||
PODS_ROOT = ${SRCROOT}
|
||||
SKIP_INSTALL = YES
|
||||
@@ -1,5 +0,0 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
@interface PodsDummy_Dip : NSObject
|
||||
@end
|
||||
@implementation PodsDummy_Dip
|
||||
@end
|
||||
@@ -1,4 +0,0 @@
|
||||
#ifdef __OBJC__
|
||||
#import <UIKit/UIKit.h>
|
||||
#endif
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
|
||||
FOUNDATION_EXPORT double DipVersionNumber;
|
||||
FOUNDATION_EXPORT const unsigned char DipVersionString[];
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
framework module Dip {
|
||||
umbrella header "Dip-umbrella.h"
|
||||
|
||||
export *
|
||||
module * { export * }
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.cocoapods.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${CURRENT_PROJECT_VERSION}</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,26 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.cocoapods.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${CURRENT_PROJECT_VERSION}</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,26 +0,0 @@
|
||||
# Acknowledgements
|
||||
This application makes use of the following third party libraries:
|
||||
|
||||
## Dip
|
||||
|
||||
Copyright (c) 2015 Olivier Halligon <olivier@halligon.net>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
Generated by CocoaPods - http://cocoapods.org
|
||||
@@ -1,56 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>PreferenceSpecifiers</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>This application makes use of the following third party libraries:</string>
|
||||
<key>Title</key>
|
||||
<string>Acknowledgements</string>
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>Copyright (c) 2015 Olivier Halligon <olivier@halligon.net>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
</string>
|
||||
<key>Title</key>
|
||||
<string>Dip</string>
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>Generated by CocoaPods - http://cocoapods.org</string>
|
||||
<key>Title</key>
|
||||
<string></string>
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>StringsTable</key>
|
||||
<string>Acknowledgements</string>
|
||||
<key>Title</key>
|
||||
<string>Acknowledgements</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,5 +0,0 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
@interface PodsDummy_Pods_DipSampleApp : NSObject
|
||||
@end
|
||||
@implementation PodsDummy_Pods_DipSampleApp
|
||||
@end
|
||||
@@ -1,59 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
|
||||
SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
|
||||
|
||||
install_framework()
|
||||
{
|
||||
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
|
||||
local source="${BUILT_PRODUCTS_DIR}/$1"
|
||||
else
|
||||
local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
|
||||
fi
|
||||
|
||||
local destination="${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
|
||||
if [ -L "${source}" ]; then
|
||||
echo "Symlinked..."
|
||||
source="$(readlink "${source}")"
|
||||
fi
|
||||
|
||||
# use filter instead of exclude so missing patterns dont' throw errors
|
||||
echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
|
||||
rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
|
||||
|
||||
# Resign the code if required by the build settings to avoid unstable apps
|
||||
code_sign_if_enabled "${destination}/$(basename "$1")"
|
||||
|
||||
# Embed linked Swift runtime libraries
|
||||
local basename
|
||||
basename="$(basename "$1" | sed -E s/\\..+// && exit ${PIPESTATUS[0]})"
|
||||
local swift_runtime_libs
|
||||
swift_runtime_libs=$(xcrun otool -LX "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/${basename}.framework/${basename}" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]})
|
||||
for lib in $swift_runtime_libs; do
|
||||
echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
|
||||
rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
|
||||
code_sign_if_enabled "${destination}/${lib}"
|
||||
done
|
||||
}
|
||||
|
||||
# Signs a framework with the provided identity
|
||||
code_sign_if_enabled() {
|
||||
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
|
||||
# Use the current code_sign_identitiy
|
||||
echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
|
||||
echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements \"$1\""
|
||||
/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
if [[ "$CONFIGURATION" == "Debug" ]]; then
|
||||
install_framework 'Pods-DipSampleApp/Dip.framework'
|
||||
fi
|
||||
if [[ "$CONFIGURATION" == "Release" ]]; then
|
||||
install_framework 'Pods-DipSampleApp/Dip.framework'
|
||||
fi
|
||||
@@ -1,95 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
|
||||
RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
|
||||
> "$RESOURCES_TO_COPY"
|
||||
|
||||
XCASSET_FILES=()
|
||||
|
||||
realpath() {
|
||||
DIRECTORY="$(cd "${1%/*}" && pwd)"
|
||||
FILENAME="${1##*/}"
|
||||
echo "$DIRECTORY/$FILENAME"
|
||||
}
|
||||
|
||||
install_resource()
|
||||
{
|
||||
case $1 in
|
||||
*.storyboard)
|
||||
echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc ${PODS_ROOT}/$1 --sdk ${SDKROOT}"
|
||||
ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc" "${PODS_ROOT}/$1" --sdk "${SDKROOT}"
|
||||
;;
|
||||
*.xib)
|
||||
echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib ${PODS_ROOT}/$1 --sdk ${SDKROOT}"
|
||||
ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib" "${PODS_ROOT}/$1" --sdk "${SDKROOT}"
|
||||
;;
|
||||
*.framework)
|
||||
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
echo "rsync -av ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
rsync -av "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
;;
|
||||
*.xcdatamodel)
|
||||
echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1"`.mom\""
|
||||
xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodel`.mom"
|
||||
;;
|
||||
*.xcdatamodeld)
|
||||
echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd\""
|
||||
xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd"
|
||||
;;
|
||||
*.xcmappingmodel)
|
||||
echo "xcrun mapc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm\""
|
||||
xcrun mapc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm"
|
||||
;;
|
||||
*.xcassets)
|
||||
ABSOLUTE_XCASSET_FILE=$(realpath "${PODS_ROOT}/$1")
|
||||
XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
|
||||
;;
|
||||
/*)
|
||||
echo "$1"
|
||||
echo "$1" >> "$RESOURCES_TO_COPY"
|
||||
;;
|
||||
*)
|
||||
echo "${PODS_ROOT}/$1"
|
||||
echo "${PODS_ROOT}/$1" >> "$RESOURCES_TO_COPY"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
if [[ "${ACTION}" == "install" ]]; then
|
||||
mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
fi
|
||||
rm -f "$RESOURCES_TO_COPY"
|
||||
|
||||
if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ]
|
||||
then
|
||||
case "${TARGETED_DEVICE_FAMILY}" in
|
||||
1,2)
|
||||
TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone"
|
||||
;;
|
||||
1)
|
||||
TARGET_DEVICE_ARGS="--target-device iphone"
|
||||
;;
|
||||
2)
|
||||
TARGET_DEVICE_ARGS="--target-device ipad"
|
||||
;;
|
||||
*)
|
||||
TARGET_DEVICE_ARGS="--target-device mac"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Find all other xcassets (this unfortunately includes those of path pods and other targets).
|
||||
OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d)
|
||||
while read line; do
|
||||
if [[ $line != "`realpath $PODS_ROOT`*" ]]; then
|
||||
XCASSET_FILES+=("$line")
|
||||
fi
|
||||
done <<<"$OTHER_XCASSETS"
|
||||
|
||||
printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
fi
|
||||
@@ -1,6 +0,0 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
|
||||
FOUNDATION_EXPORT double Pods_DipSampleAppVersionNumber;
|
||||
FOUNDATION_EXPORT const unsigned char Pods_DipSampleAppVersionString[];
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
|
||||
OTHER_CFLAGS = $(inherited) -iquote "$CONFIGURATION_BUILD_DIR/Dip.framework/Headers"
|
||||
OTHER_LDFLAGS = $(inherited) -framework "Dip"
|
||||
OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
|
||||
PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-DipSampleApp
|
||||
PODS_ROOT = ${SRCROOT}/Pods
|
||||
@@ -1,6 +0,0 @@
|
||||
framework module Pods_DipSampleApp {
|
||||
umbrella header "Pods-DipSampleApp-umbrella.h"
|
||||
|
||||
export *
|
||||
module * { export * }
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
|
||||
OTHER_CFLAGS = $(inherited) -iquote "$CONFIGURATION_BUILD_DIR/Dip.framework/Headers"
|
||||
OTHER_LDFLAGS = $(inherited) -framework "Dip"
|
||||
OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
|
||||
PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-DipSampleApp
|
||||
PODS_ROOT = ${SRCROOT}/Pods
|
||||
@@ -1,26 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.cocoapods.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${CURRENT_PROJECT_VERSION}</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,26 +0,0 @@
|
||||
# Acknowledgements
|
||||
This application makes use of the following third party libraries:
|
||||
|
||||
## Dip
|
||||
|
||||
Copyright (c) 2015 Olivier Halligon <olivier@halligon.net>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
Generated by CocoaPods - http://cocoapods.org
|
||||
@@ -1,56 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>PreferenceSpecifiers</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>This application makes use of the following third party libraries:</string>
|
||||
<key>Title</key>
|
||||
<string>Acknowledgements</string>
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>Copyright (c) 2015 Olivier Halligon <olivier@halligon.net>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
</string>
|
||||
<key>Title</key>
|
||||
<string>Dip</string>
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>FooterText</key>
|
||||
<string>Generated by CocoaPods - http://cocoapods.org</string>
|
||||
<key>Title</key>
|
||||
<string></string>
|
||||
<key>Type</key>
|
||||
<string>PSGroupSpecifier</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>StringsTable</key>
|
||||
<string>Acknowledgements</string>
|
||||
<key>Title</key>
|
||||
<string>Acknowledgements</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,5 +0,0 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
@interface PodsDummy_Pods_DipTests : NSObject
|
||||
@end
|
||||
@implementation PodsDummy_Pods_DipTests
|
||||
@end
|
||||
@@ -1,59 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
|
||||
SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
|
||||
|
||||
install_framework()
|
||||
{
|
||||
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
|
||||
local source="${BUILT_PRODUCTS_DIR}/$1"
|
||||
else
|
||||
local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
|
||||
fi
|
||||
|
||||
local destination="${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
|
||||
if [ -L "${source}" ]; then
|
||||
echo "Symlinked..."
|
||||
source="$(readlink "${source}")"
|
||||
fi
|
||||
|
||||
# use filter instead of exclude so missing patterns dont' throw errors
|
||||
echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
|
||||
rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
|
||||
|
||||
# Resign the code if required by the build settings to avoid unstable apps
|
||||
code_sign_if_enabled "${destination}/$(basename "$1")"
|
||||
|
||||
# Embed linked Swift runtime libraries
|
||||
local basename
|
||||
basename="$(basename "$1" | sed -E s/\\..+// && exit ${PIPESTATUS[0]})"
|
||||
local swift_runtime_libs
|
||||
swift_runtime_libs=$(xcrun otool -LX "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/${basename}.framework/${basename}" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]})
|
||||
for lib in $swift_runtime_libs; do
|
||||
echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
|
||||
rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
|
||||
code_sign_if_enabled "${destination}/${lib}"
|
||||
done
|
||||
}
|
||||
|
||||
# Signs a framework with the provided identity
|
||||
code_sign_if_enabled() {
|
||||
if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
|
||||
# Use the current code_sign_identitiy
|
||||
echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
|
||||
echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements \"$1\""
|
||||
/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
if [[ "$CONFIGURATION" == "Debug" ]]; then
|
||||
install_framework 'Pods-DipTests/Dip.framework'
|
||||
fi
|
||||
if [[ "$CONFIGURATION" == "Release" ]]; then
|
||||
install_framework 'Pods-DipTests/Dip.framework'
|
||||
fi
|
||||
@@ -1,95 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
|
||||
RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
|
||||
> "$RESOURCES_TO_COPY"
|
||||
|
||||
XCASSET_FILES=()
|
||||
|
||||
realpath() {
|
||||
DIRECTORY="$(cd "${1%/*}" && pwd)"
|
||||
FILENAME="${1##*/}"
|
||||
echo "$DIRECTORY/$FILENAME"
|
||||
}
|
||||
|
||||
install_resource()
|
||||
{
|
||||
case $1 in
|
||||
*.storyboard)
|
||||
echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc ${PODS_ROOT}/$1 --sdk ${SDKROOT}"
|
||||
ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc" "${PODS_ROOT}/$1" --sdk "${SDKROOT}"
|
||||
;;
|
||||
*.xib)
|
||||
echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib ${PODS_ROOT}/$1 --sdk ${SDKROOT}"
|
||||
ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib" "${PODS_ROOT}/$1" --sdk "${SDKROOT}"
|
||||
;;
|
||||
*.framework)
|
||||
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
echo "rsync -av ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
rsync -av "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
;;
|
||||
*.xcdatamodel)
|
||||
echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1"`.mom\""
|
||||
xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodel`.mom"
|
||||
;;
|
||||
*.xcdatamodeld)
|
||||
echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd\""
|
||||
xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd"
|
||||
;;
|
||||
*.xcmappingmodel)
|
||||
echo "xcrun mapc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm\""
|
||||
xcrun mapc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm"
|
||||
;;
|
||||
*.xcassets)
|
||||
ABSOLUTE_XCASSET_FILE=$(realpath "${PODS_ROOT}/$1")
|
||||
XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
|
||||
;;
|
||||
/*)
|
||||
echo "$1"
|
||||
echo "$1" >> "$RESOURCES_TO_COPY"
|
||||
;;
|
||||
*)
|
||||
echo "${PODS_ROOT}/$1"
|
||||
echo "${PODS_ROOT}/$1" >> "$RESOURCES_TO_COPY"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
if [[ "${ACTION}" == "install" ]]; then
|
||||
mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
fi
|
||||
rm -f "$RESOURCES_TO_COPY"
|
||||
|
||||
if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ]
|
||||
then
|
||||
case "${TARGETED_DEVICE_FAMILY}" in
|
||||
1,2)
|
||||
TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone"
|
||||
;;
|
||||
1)
|
||||
TARGET_DEVICE_ARGS="--target-device iphone"
|
||||
;;
|
||||
2)
|
||||
TARGET_DEVICE_ARGS="--target-device ipad"
|
||||
;;
|
||||
*)
|
||||
TARGET_DEVICE_ARGS="--target-device mac"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Find all other xcassets (this unfortunately includes those of path pods and other targets).
|
||||
OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d)
|
||||
while read line; do
|
||||
if [[ $line != "`realpath $PODS_ROOT`*" ]]; then
|
||||
XCASSET_FILES+=("$line")
|
||||
fi
|
||||
done <<<"$OTHER_XCASSETS"
|
||||
|
||||
printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||
fi
|
||||
@@ -1,6 +0,0 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
|
||||
FOUNDATION_EXPORT double Pods_DipTestsVersionNumber;
|
||||
FOUNDATION_EXPORT const unsigned char Pods_DipTestsVersionString[];
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
|
||||
OTHER_CFLAGS = $(inherited) -iquote "$CONFIGURATION_BUILD_DIR/Dip.framework/Headers"
|
||||
OTHER_LDFLAGS = $(inherited) -framework "Dip"
|
||||
OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
|
||||
PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-DipTests
|
||||
PODS_ROOT = ${SRCROOT}/Pods
|
||||
@@ -1,6 +0,0 @@
|
||||
framework module Pods_DipTests {
|
||||
umbrella header "Pods-DipTests-umbrella.h"
|
||||
|
||||
export *
|
||||
module * { export * }
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
|
||||
OTHER_CFLAGS = $(inherited) -iquote "$CONFIGURATION_BUILD_DIR/Dip.framework/Headers"
|
||||
OTHER_LDFLAGS = $(inherited) -framework "Dip"
|
||||
OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
|
||||
PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-DipTests
|
||||
PODS_ROOT = ${SRCROOT}/Pods
|
||||
@@ -1,89 +0,0 @@
|
||||
import UIKit
|
||||
import XCTest
|
||||
import Dip
|
||||
|
||||
|
||||
var dip = DependencyContainer<String>()
|
||||
|
||||
//let p1 = ["name": "John Doe", "mass": "72", "height": "172", "eye_color": "brown", "hair_color": "black"]
|
||||
//let p2 = ["name": "Jane Doe", "mass": "63", "height": "167", "eye_color": "blue", "hair_color": "red"]
|
||||
//
|
||||
//class SWAPIWebServiceTests: XCTestCase {
|
||||
//
|
||||
// // MARK: - Mock object used for tests
|
||||
//
|
||||
// struct NetworkMock : NetworkLayer {
|
||||
// let fakeData: NSData?
|
||||
//
|
||||
// init(json: AnyObject) {
|
||||
// do {
|
||||
// fakeData = try NSJSONSerialization.dataWithJSONObject(json, options: [])
|
||||
// } catch {
|
||||
// fakeData = nil
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// func fetchURL(url: NSURL, completion: NSData? -> Void) {
|
||||
// completion(fakeData)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // MARK: - Test Suite
|
||||
//
|
||||
// override func setUp() {
|
||||
// super.setUp()
|
||||
//
|
||||
// dip.reset()
|
||||
// dip.register(instance: SWAPIPersonFactory() as PersonFactoryAPI)
|
||||
// dip.register(instance: JSONSerializer() as SerializerAPI)
|
||||
// }
|
||||
//
|
||||
// func testFetchPersons() {
|
||||
// let mock = NetworkMock(json: ["results":[p1,p2]])
|
||||
// dip.register(instance: mock as NetworkLayer)
|
||||
//
|
||||
// let ws = SWAPIWebService()
|
||||
// ws.fetch { persons in
|
||||
// XCTAssertNotNil(persons)
|
||||
// XCTAssertEqual(persons?.count, 2)
|
||||
//
|
||||
// XCTAssertEqual(persons?[0].name, "John Doe")
|
||||
// XCTAssertEqual(persons?[0].mass, 72)
|
||||
// XCTAssertEqual(persons?[0].height, 172)
|
||||
// XCTAssertEqual(persons?[0].eyesColor, "brown")
|
||||
// XCTAssertEqual(persons?[0].hairColor, "black")
|
||||
//
|
||||
// XCTAssertEqual(persons?[1].name, "Jane Doe")
|
||||
// XCTAssertEqual(persons?[1].mass, 63)
|
||||
// XCTAssertEqual(persons?[1].height, 167)
|
||||
// XCTAssertEqual(persons?[1].eyesColor, "blue")
|
||||
// XCTAssertEqual(persons?[1].hairColor, "red")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// func testFetchOnePerson() {
|
||||
// let mock = NetworkMock(json: p1)
|
||||
// dip.register(instance: mock as NetworkLayer)
|
||||
//
|
||||
// let ws = SWAPIWebService()
|
||||
// ws.fetch(1) { person in
|
||||
// XCTAssertNotNil(person)
|
||||
// XCTAssertEqual(person?.name, "John Doe")
|
||||
// XCTAssertEqual(person?.mass, 72)
|
||||
// XCTAssertEqual(person?.height, 172)
|
||||
// XCTAssertEqual(person?.eyesColor, "brown")
|
||||
// XCTAssertEqual(person?.hairColor, "black")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// func testFetchInvalidPerson() {
|
||||
// let json = ["error":"whoops"]
|
||||
// let mock = NetworkMock(json: json)
|
||||
// dip.register(instance: mock as NetworkLayer)
|
||||
//
|
||||
// let ws = SWAPIWebService()
|
||||
// ws.fetch(12) { person in
|
||||
// XCTAssertNil(person)
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// Dip
|
||||
//
|
||||
// Copyright (c) 2015 Olivier Halligon <olivier@halligon.net>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "Dip"
|
||||
)
|
||||
|
||||
@@ -1,130 +1,195 @@
|
||||
# Dip
|
||||
|
||||
[](https://travis-ci.org/AliSoftware/Dip)
|
||||
[](https://travis-ci.org/AliSoftware/Dip)
|
||||
[](http://cocoapods.org/pods/Dip)
|
||||
[](https://github.com/Carthage/Carthage)
|
||||
[](http://cocoapods.org/pods/Dip)
|
||||
[](http://cocoapods.org/pods/Dip)
|
||||
[](https://developer.apple.com/swift)
|
||||
[](https://developer.apple.com/swift)
|
||||
|
||||

|
||||
_Photo by [Matthew Hine](https://commons.wikimedia.org/wiki/File:Chocolate_con_churros_-_San_Ginés,_Madrid.jpg), cc-by-2.0_
|
||||

|
||||
_Photo courtesy of [www.kevinandamanda.com](http://www.kevinandamanda.com/recipes/appetizer/homemade-soft-cinnamon-sugar-pretzel-bites-with-salted-caramel-dipping-sauce.html)_
|
||||
|
||||
## Introduction
|
||||
|
||||
`Dip` is a simple **Dependency Injection Container**.
|
||||
|
||||
It's not true Dependency Injection, but it's damn close, and aimed to be as simple as possible.
|
||||
It's inspired by `.NET`'s [Unity Container](https://msdn.microsoft.com/library/ff647202.aspx).
|
||||
It's aimed to be as simple as possible yet provide rich functionality usual for DI containers on other platforms. It's inspired by `.NET`'s [Unity Container](https://msdn.microsoft.com/library/ff647202.aspx) and other DI containers.
|
||||
|
||||
* You start by creating `let dc = DependencyContainer()` and **register all your dependencies, by associating a `protocol` to an `instance` or a `factory`**.
|
||||
* Then anywhere in your application, you can call `dc.resolve()` to **resolve a `protocol` into an instance of a concrete type** using that `DependencyContainer`.
|
||||
* You start by creating `let container = DependencyContainer()` and **registering your dependencies, by associating a _protocol_ or _type_ to a `factory`** using `container.register { MyService() as Service }`.
|
||||
* Then you can call `container.resolve() as Service` to **resolve an instance of _protocol_ or _type_** using that `DependencyContainer`.
|
||||
* You can easily use Dip along with **Storyboards and Nibs** - checkout **[Dip-UI](https://github.com/AliSoftware/Dip-UI)** extensions. There is also a **[code generator](https://github.com/ilyapuchka/dipgen)** that can help to simplify registering new components.
|
||||
|
||||
This allows you to define the real, concrete types only in one place ([typically at the top of your `AppDelegate` for your app](https://github.com/AliSoftware/Dip/blob/master/Example/DipSampleApp/AppDelegate.swift#L12-L21), and [in your `setUp` for your Unit Tests](https://github.com/AliSoftware/Dip/blob/master/Example/Tests/SWAPIWebServiceTests.swift#L36-L38)) and then [only work with `protocols` in your code](https://github.com/AliSoftware/Dip/blob/master/Example/DipSampleApp/ViewController.swift#L15) (which only define an API contract), without worrying about the real implementation.
|
||||
<details>
|
||||
<summary>Basic usage</summary>
|
||||
|
||||
## Advantages of DI and loose coupling
|
||||
```swift
|
||||
import Dip
|
||||
|
||||
@UIApplicationMain
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
// Create the container
|
||||
private let container = DependencyContainer { container in
|
||||
|
||||
// Register some factory. ServiceImp here implements protocol Service
|
||||
container.register { ServiceImp() as Service }
|
||||
}
|
||||
|
||||
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
|
||||
|
||||
// Resolve a concrete instance. Container will instantiate new instance of ServiceImp
|
||||
let service = try! container.resolve() as Service
|
||||
|
||||
...
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>More sophisticated example</summary>
|
||||
|
||||
```swift
|
||||
import Dip
|
||||
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
private let container = DependencyContainer.configure()
|
||||
...
|
||||
}
|
||||
|
||||
//CompositionRoot.swift
|
||||
import Dip
|
||||
import DipUI
|
||||
|
||||
extension DependencyContainer {
|
||||
|
||||
static func configure() -> DependencyContainer {
|
||||
return DependencyContainer { container in
|
||||
unowned let container = container
|
||||
DependencyContainer.uiContainers = [container]
|
||||
|
||||
container.register(tag: "ViewController") { ViewController() }
|
||||
.resolvingProperties { container, controller in
|
||||
controller.animationsFactory = try container.resolve() as AnimatonsFactory
|
||||
}
|
||||
|
||||
container.register { AuthFormBehaviourImp(apiClient: $0) as AuthFormBehaviour }
|
||||
container.register { container as AnimationsFactory }
|
||||
container.register { view in ShakeAnimationImp(view: view) as ShakeAnimation }
|
||||
container.register { APIClient(baseURL: NSURL(string: "http://localhost:2368")!) as ApiClient }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension DependencyContainer: AnimationsFactory {
|
||||
func shakeAnimation(view: UIView) -> ShakeAnimation {
|
||||
return try! self.resolve(withArguments: view)
|
||||
}
|
||||
}
|
||||
|
||||
extension ViewController: StoryboardInstantiatable {}
|
||||
|
||||
//ViewController.swift
|
||||
|
||||
class ViewController {
|
||||
var animationsFactory: AnimationsFactory?
|
||||
|
||||
private let _formBehaviour = Injected<AuthFormBehaviour>()
|
||||
|
||||
var formBehaviour: AuthFormBehaviour? {
|
||||
return _formBehaviour.value
|
||||
}
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Documentation & Usage Examples
|
||||
|
||||
Dip is completely [documented](http://cocoadocs.org/docsets/Dip/5.0.0/) and comes with a Playground that lets you try all its features and become familiar with API. You can find it in `Dip.xcworkspace`.
|
||||
|
||||
> Note: it may happen that you will need to build Dip framework before playground will be able to use it. For that select `Dip` scheme and build for iPhone Simulator.
|
||||
|
||||
You can find bunch of usage examples and usfull tips in a [wiki](../../wiki).
|
||||
|
||||
If your are using [VIPER](https://www.objc.io/issues/13-architecture/viper/) architecture - [here](https://github.com/ilyapuchka/VIPER-SWIFT) is VIPER demo app that uses Dip instead of manual dependency injection.
|
||||
|
||||
There are also several blog posts that describe how to use Dip and some of its implementation details:
|
||||
|
||||
- [IoC container in Swift](http://ilya.puchka.me/ioc-container-in-swift/)
|
||||
- [IoC container in Swift. Circular dependencies and auto-injection](http://ilya.puchka.me/ioc-container-in-swift-circular-dependencies-and-auto-injection/)
|
||||
- [Dependency injection with Dip](http://ilya.puchka.me/dependency-injecinjection-with-dip/)
|
||||
|
||||
File an issue if you have any question. Pull requests are warmly welcome too.
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **[Scopes](../../wiki/scopes)**. Dip supports 5 different scopes (or life cycle strategies): _Unique_, _Shared_, _Singleton_, _EagerSingleton_, _WeakSingleton_;
|
||||
- **[Auto-wiring](../../wiki/auto-wiring)** & **[Auto-injection](../../wiki/auto-injection)**. Dip can infer your components' dependencies injected in constructor and automatically resolve them as well as dependencies injected with properties.
|
||||
- **[Resolving optionals](../../wiki/resolving-optionals)**. Dip is able to resolve constructor or property dependencies defined as optionals.
|
||||
- **[Type forwarding](../../wiki/type-forwarding)**. You can register the same factory to resolve different types implemeted by a single class.
|
||||
- **[Circular dependencies](../../wiki/circular-dependencies)**. Dip will be able to resolve circular dependencies if you will follow some simple rules;
|
||||
- **[Storyboards integration](../../wiki/storyboards-integration)**. You can easily use Dip along with storyboards and Xibs without ever referencing container in your view controller's code;
|
||||
- **[Named definitions](../../wiki/named-definitions)**. You can register different factories for the same protocol or type by registering them with [tags]();
|
||||
- **[Runtime arguments](../../wiki/runtime-arguments)**. You can register factories that accept up to 6 runtime arguments (and extend it if you need);
|
||||
- **[Easy configuration](../../wiki/containers-collaboration)** & **Code generation**. No complex containers hierarchy, no unneeded functionality. Tired of writing all registrations by hand? There is a [cool code generator](https://github.com/ilyapuchka/dipgen) that will create them for you. The only thing you need is to annotate your code with some comments.
|
||||
- **Weakly typed components**. Dip can resolve "weak" types when they are unknown at compile time.
|
||||
- **Thread safety**. Registering and resolving components is thread safe;
|
||||
- **Helpful error messages and configuration validation**. You can validate your container configuration. If something can not be resolved at runtime Dip throws an error that completely describes the issue;
|
||||
|
||||
* Define clear API contracts before even thinking about implementation, and make your code loosly coupled with the real implementation.
|
||||
* Easily switch between implementations — as long as they respect the same API contact (the `protocol`
|
||||
* Greatly improve testability, as you can register a real instance in your app but a fake instance in your tests dedicated for testing / mocking the fonctionnality
|
||||
* Get rid of those `sharedInstances` and avoid the singleton pattern at all costs
|
||||
|
||||
## Installation
|
||||
|
||||
Dip is available through [CocoaPods](http://cocoapods.org). To install
|
||||
it, simply add the following line to your Podfile:
|
||||
Since version 5.0.0 Dip is built with Swift 3.0. For Swift 2.2-2.3 compatible version use "swift2.3" branch.
|
||||
|
||||
You can install Dip using your favorite dependency manager:
|
||||
|
||||
<details>
|
||||
<summary>CocoaPods</summary>
|
||||
|
||||
```ruby
|
||||
pod "Dip"
|
||||
```
|
||||
> You need at least 1.1.0.rc.2 version of CocoaPods.
|
||||
|
||||
## Usage
|
||||
</details>
|
||||
|
||||
### Register instances and instance factories
|
||||
<details>
|
||||
<summary>Carthage</summary>
|
||||
|
||||
First, create a `DependencyContainer` and use it to register instances and factories with protocols, using those methods:
|
||||
|
||||
* `register(instance: _)` will register a singleton instance with a given protocol.
|
||||
* `register(factory: _)` will register an instance factory — which generates a new instance each time you `resolve()`.
|
||||
* You need **cast the instance to the protocol type** you want to register it with (e.g. `register(instance: PlistUsersProvider() as UsersListProviderType)`).
|
||||
|
||||
Typically, to register your dependencies as early as possible in your app life-cycle, you will declare a `let dip: DependencyContainer = { … }()` somewhere (for example [at the top of your `AppDelegate.swift`](https://github.com/AliSoftware/Dip/blob/master/Example/DipSampleApp/AppDelegate.swift#L12-L21)).
|
||||
In your (non-hosted, standalone) unit tests, you'll probably [declare them in your `func setUp()`](https://github.com/AliSoftware/Dip/blob/master/Example/Tests/SWAPIWebServiceTests.swift#L36-L38) instead.
|
||||
|
||||
### Resolve dependencies
|
||||
|
||||
* `resolve()` will return a new instance matching the requested protocol.
|
||||
* Explicitly specify the return type of `resolve` so that Swift's type inference knows which protocol you're trying to resolve.
|
||||
* If that protocol was registered as a singleton instance (using `register(instance: …)`, the same instance will be returned each time you call `resolve()` for this protocol type. Otherwise, the instance factory will generate a new instance each time.
|
||||
|
||||
### Using tags to associate various factories to one protocol
|
||||
|
||||
* If you give a `tag` in the parameter to `register()`, it will associate that instance or factory with this tag, which can be used later during `resolve` (see below).
|
||||
* `resolve(tag)` will try to find an instance (or instance factory) that match both the requested protocol _and_ the tag. If it doesn't find any, it will fallback to an instance (or instance factory) that only match the requested protocol.
|
||||
* The tags can be anything, as long as it's of a type conforming to `Equatable`. `DependencyContainer` is a generic class which takes that type as generic parameter (so one `DependencyContainer` will be tied with a given tag type)
|
||||
|
||||
|
||||
### Example
|
||||
|
||||
Somewhere in your App target, register the dependencies:
|
||||
|
||||
```swift
|
||||
let dip: DependencyContainer<String> = {
|
||||
let dip = DependencyContainer<String>()
|
||||
let env = ProductionEnvironment(analytics: true)
|
||||
dip.register(instance: env as EnvironmentType)
|
||||
dip.register(instance: WebService() as WebServiceType)
|
||||
dip.register() { DummyFriendsProvider(user: $0 ?? "Jane Doe") as FriendsProviderType }
|
||||
dip.register("me") { PlistFriendsProvider(plist: "myfriends") as FriendsProviderType }
|
||||
return dip
|
||||
}
|
||||
```
|
||||
github "AliSoftware/Dip"
|
||||
```
|
||||
|
||||
> Do the same in your Unit Tests target & test cases, but obviously with different Dependencies registered, depending on what you want to test and what instances you need to inject to provide dummy implementations for your tests.
|
||||
</details>
|
||||
|
||||
|
||||
Then to use dependencies throughout your app, use `dip.resolve()`, like this:
|
||||
<details>
|
||||
<summary>Swift Package Manager</summary>
|
||||
|
||||
```swift
|
||||
struct WebService {
|
||||
let env: EnvironmentType = dip.resolve()
|
||||
func sendRequest(path: String, …) {
|
||||
// ... use stuff like env.baseURL here
|
||||
}
|
||||
}
|
||||
|
||||
struct SomeViewModel {
|
||||
let ws: WebServiceType = dip.resolve()
|
||||
var friendsProvider: FriendsProviderType
|
||||
init(userName: String) {
|
||||
friendsProvider = dip.resolve(userName)
|
||||
}
|
||||
func foo() {
|
||||
ws.someMethodDeclaredOnWebServiceType()
|
||||
let friends = friendsProvider.someFriendsProviderTypeMethod()
|
||||
print("friends: \(friends)")
|
||||
}
|
||||
.Package(url: "https://github.com/AliSoftware/Dip", majorVersion: 5, minor: 0)
|
||||
```
|
||||
|
||||
This way, when running your app target:
|
||||
</details>
|
||||
|
||||
* `ws` will be resolved as your singleton instance `WebService` registered before.
|
||||
* `friendsProvider` will be resolved as a new instance each time, which will be an instance created via `PlistFriendsProvider(plist: "myfriends")` if `userName` is `me` and created via `DummyFriendsProvider(userName)` for any other `userName` value (because `resolve(userName)` will fallback to `resolve(nil)` in that case, using the instance factory which was registered without a tag).
|
||||
## Running tests
|
||||
|
||||
But when running your Unit tests target, it will probably resolve to other instances, depending on how you registered your dependencies in your Test Case.
|
||||
On OSX you can run tests from Xcode. On Linux you need to have Swift Package Manager installed and use it to build and run tests using this command: `swift build --clean && swift build && swift test`
|
||||
|
||||
## Credits
|
||||
|
||||
## Work In Progress
|
||||
This library has been created by [**Olivier Halligon**](olivier@halligon.net) and is maintained by [**Ilya Puchka**](https://twitter.com/ilyapuchka).
|
||||
|
||||
* [x] Example project
|
||||
* [ ] Unit Tests
|
||||
* [x] README
|
||||
* [ ] Source Documentation
|
||||
* [ ] Thread-Safety
|
||||
**Dip** is available under the **MIT license**. See the `LICENSE` file for more info.
|
||||
|
||||
The animated GIF at the top of this `README.md` is from [this recipe](http://www.kevinandamanda.com/recipes/appetizer/homemade-soft-cinnamon-sugar-pretzel-bites-with-salted-caramel-dipping-sauce.html) on the yummy blog of [Kevin & Amanda](http://www.kevinandamanda.com/recipes/). Go try the recipe!
|
||||
|
||||
## Author
|
||||
|
||||
Olivier Halligon, olivier@halligon.net
|
||||
|
||||
## License
|
||||
|
||||
Dip is available under the MIT license. See the LICENSE file for more info.
|
||||
The image used as the SampleApp LaunchScreen and Icon is from [Matthew Hine](https://commons.wikimedia.org/wiki/File:Chocolate_con_churros_-_San_Ginés,_Madrid.jpg) and is under _CC-by-2.0_.
|
||||
|
||||
@@ -7,55 +7,61 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
090012291BC6FECA0079C600 /* BaseCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 090012161BC6FECA0079C600 /* BaseCell.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
0900122A1BC6FECA0079C600 /* PersonCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 090012171BC6FECA0079C600 /* PersonCell.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
0900122C1BC6FECA0079C600 /* PersonProviderAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0900121B1BC6FECA0079C600 /* PersonProviderAPI.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
0900122D1BC6FECA0079C600 /* DummyPilotProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0900121C1BC6FECA0079C600 /* DummyPilotProvider.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
0900122E1BC6FECA0079C600 /* HardCodedStarshipProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0900121D1BC6FECA0079C600 /* HardCodedStarshipProvider.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
0900122F1BC6FECA0079C600 /* PlistPersonProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0900121E1BC6FECA0079C600 /* PlistPersonProvider.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
0900123B1BC6FF4D0079C600 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0900123A1BC6FF4D0079C600 /* Main.storyboard */; settings = {ASSET_TAGS = (); }; };
|
||||
0900123D1BC7012A0079C600 /* StarshipProviderAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0900123C1BC7012A0079C600 /* StarshipProviderAPI.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
090012401BC704C60079C600 /* Person.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0900123F1BC704C60079C600 /* Person.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
090012421BC7059E0079C600 /* Starship.swift in Sources */ = {isa = PBXBuildFile; fileRef = 090012411BC7059E0079C600 /* Starship.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
090012441BC708A00079C600 /* DummyStarshipProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 090012431BC708A00079C600 /* DummyStarshipProvider.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
090012291BC6FECA0079C600 /* BaseCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 090012161BC6FECA0079C600 /* BaseCell.swift */; };
|
||||
0900122A1BC6FECA0079C600 /* PersonCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 090012171BC6FECA0079C600 /* PersonCell.swift */; };
|
||||
0900122C1BC6FECA0079C600 /* PersonProviderAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0900121B1BC6FECA0079C600 /* PersonProviderAPI.swift */; };
|
||||
0900123B1BC6FF4D0079C600 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0900123A1BC6FF4D0079C600 /* Main.storyboard */; };
|
||||
0900123D1BC7012A0079C600 /* StarshipProviderAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0900123C1BC7012A0079C600 /* StarshipProviderAPI.swift */; };
|
||||
090012401BC704C60079C600 /* Person.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0900123F1BC704C60079C600 /* Person.swift */; };
|
||||
090012421BC7059E0079C600 /* Starship.swift in Sources */ = {isa = PBXBuildFile; fileRef = 090012411BC7059E0079C600 /* Starship.swift */; };
|
||||
0982AF081C503EEE00B62463 /* FakePersonsProviders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0982AF071C503EEE00B62463 /* FakePersonsProviders.swift */; };
|
||||
0982AF0A1C50401800B62463 /* FakeStarshipProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0982AF091C50401800B62463 /* FakeStarshipProvider.swift */; };
|
||||
099022621BC123C000E76F43 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 099022611BC123C000E76F43 /* AppDelegate.swift */; };
|
||||
099022691BC123C000E76F43 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 099022681BC123C000E76F43 /* Assets.xcassets */; };
|
||||
0990226C1BC123C000E76F43 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0990226A1BC123C000E76F43 /* LaunchScreen.storyboard */; };
|
||||
09D795FF1BC71F5A003C68EB /* PersonListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D795FE1BC71F5A003C68EB /* PersonListViewController.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
09D796011BC722C0003C68EB /* StarshipListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D796001BC722C0003C68EB /* StarshipListViewController.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
09D796031BC72691003C68EB /* StarshipCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D796021BC72691003C68EB /* StarshipCell.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
09D796071BC73E8B003C68EB /* StoryboardConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D796061BC73E8B003C68EB /* StoryboardConstants.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
09D7960D1BC7431C003C68EB /* FetchableTrait.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D7960C1BC7431C003C68EB /* FetchableTrait.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
09D796111BC97809003C68EB /* mainPilot.plist in Resources */ = {isa = PBXBuildFile; fileRef = 09D796101BC97809003C68EB /* mainPilot.plist */; settings = {ASSET_TAGS = (); }; };
|
||||
09D796131BC9A5BC003C68EB /* SWAPIPersonProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D796121BC9A5BC003C68EB /* SWAPIPersonProvider.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
09D796151BC9A5FC003C68EB /* NetworkLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D796141BC9A5FC003C68EB /* NetworkLayer.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
09D796171BC9B53D003C68EB /* URLSessionNetworkLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D796161BC9B53D003C68EB /* URLSessionNetworkLayer.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
09D796191BC9BA49003C68EB /* DependencyContainers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D796181BC9BA49003C68EB /* DependencyContainers.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
09D7961B1BC9BE65003C68EB /* SWAPIStarshipProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D7961A1BC9BE65003C68EB /* SWAPIStarshipProvider.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
09D7961D1BC9C62E003C68EB /* SWAPICommon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D7961C1BC9C62E003C68EB /* SWAPICommon.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
607FACEC1AFB9204008FA782 /* SWAPIWebServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* SWAPIWebServiceTests.swift */; };
|
||||
7BBD849465D99D9D1987AE6D /* Pods_DipTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 304AD039660A2C58EB08D985 /* Pods_DipTests.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
|
||||
84D8EBE5B2D583BEFB17C45A /* Pods_DipSampleApp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2FE9C70E965FF88C3F20AC76 /* Pods_DipSampleApp.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
|
||||
09B041B71C01F8CB000D383F /* Dip.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 09B041B61C01F8CB000D383F /* Dip.framework */; };
|
||||
09B041B81C01F8D1000D383F /* Dip.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 09B041B61C01F8CB000D383F /* Dip.framework */; };
|
||||
09D795FF1BC71F5A003C68EB /* PersonListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D795FE1BC71F5A003C68EB /* PersonListViewController.swift */; };
|
||||
09D796011BC722C0003C68EB /* StarshipListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D796001BC722C0003C68EB /* StarshipListViewController.swift */; };
|
||||
09D796031BC72691003C68EB /* StarshipCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D796021BC72691003C68EB /* StarshipCell.swift */; };
|
||||
09D796071BC73E8B003C68EB /* StoryboardConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D796061BC73E8B003C68EB /* StoryboardConstants.swift */; };
|
||||
09D7960D1BC7431C003C68EB /* FetchableTrait.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D7960C1BC7431C003C68EB /* FetchableTrait.swift */; };
|
||||
09D796111BC97809003C68EB /* mainPilot.plist in Resources */ = {isa = PBXBuildFile; fileRef = 09D796101BC97809003C68EB /* mainPilot.plist */; };
|
||||
09D796131BC9A5BC003C68EB /* SWAPIPersonProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D796121BC9A5BC003C68EB /* SWAPIPersonProvider.swift */; };
|
||||
09D796151BC9A5FC003C68EB /* NetworkLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D796141BC9A5FC003C68EB /* NetworkLayer.swift */; };
|
||||
09D796171BC9B53D003C68EB /* URLSessionNetworkLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D796161BC9B53D003C68EB /* URLSessionNetworkLayer.swift */; };
|
||||
09D796191BC9BA49003C68EB /* DependencyContainers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D796181BC9BA49003C68EB /* DependencyContainers.swift */; };
|
||||
09D7961B1BC9BE65003C68EB /* SWAPIStarshipProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D7961A1BC9BE65003C68EB /* SWAPIStarshipProvider.swift */; };
|
||||
09D7961D1BC9C62E003C68EB /* SWAPICommon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D7961C1BC9C62E003C68EB /* SWAPICommon.swift */; };
|
||||
09D796221BCA8305003C68EB /* NetworkLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D796141BC9A5FC003C68EB /* NetworkLayer.swift */; };
|
||||
09D796231BCA833E003C68EB /* SWAPIPersonProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D796121BC9A5BC003C68EB /* SWAPIPersonProvider.swift */; };
|
||||
09D796241BCA8345003C68EB /* PersonProviderAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0900121B1BC6FECA0079C600 /* PersonProviderAPI.swift */; };
|
||||
09D796251BCA8345003C68EB /* StarshipProviderAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0900123C1BC7012A0079C600 /* StarshipProviderAPI.swift */; };
|
||||
09D796261BCA8348003C68EB /* SWAPIStarshipProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D7961A1BC9BE65003C68EB /* SWAPIStarshipProvider.swift */; };
|
||||
09D796271BCA8550003C68EB /* Person.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0900123F1BC704C60079C600 /* Person.swift */; };
|
||||
09D796281BCA8550003C68EB /* Starship.swift in Sources */ = {isa = PBXBuildFile; fileRef = 090012411BC7059E0079C600 /* Starship.swift */; };
|
||||
09D796291BCA86D4003C68EB /* SWAPICommon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D7961C1BC9C62E003C68EB /* SWAPICommon.swift */; };
|
||||
09D7962C1BCA8AD4003C68EB /* NetworkMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D7962A1BCA8AB3003C68EB /* NetworkMock.swift */; };
|
||||
09D7962F1BCA922E003C68EB /* SWAPIStarshipProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D7962D1BCA91D3003C68EB /* SWAPIStarshipProviderTests.swift */; };
|
||||
607FACEC1AFB9204008FA782 /* SWAPIPersonProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* SWAPIPersonProviderTests.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
090012161BC6FECA0079C600 /* BaseCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseCell.swift; sourceTree = "<group>"; };
|
||||
090012171BC6FECA0079C600 /* PersonCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PersonCell.swift; sourceTree = "<group>"; };
|
||||
0900121B1BC6FECA0079C600 /* PersonProviderAPI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PersonProviderAPI.swift; sourceTree = "<group>"; };
|
||||
0900121C1BC6FECA0079C600 /* DummyPilotProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DummyPilotProvider.swift; sourceTree = "<group>"; };
|
||||
0900121D1BC6FECA0079C600 /* HardCodedStarshipProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HardCodedStarshipProvider.swift; sourceTree = "<group>"; };
|
||||
0900121E1BC6FECA0079C600 /* PlistPersonProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlistPersonProvider.swift; sourceTree = "<group>"; };
|
||||
0900123A1BC6FF4D0079C600 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; };
|
||||
0900123C1BC7012A0079C600 /* StarshipProviderAPI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StarshipProviderAPI.swift; sourceTree = "<group>"; };
|
||||
0900123F1BC704C60079C600 /* Person.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Person.swift; sourceTree = "<group>"; };
|
||||
090012411BC7059E0079C600 /* Starship.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Starship.swift; sourceTree = "<group>"; };
|
||||
090012431BC708A00079C600 /* DummyStarshipProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DummyStarshipProvider.swift; sourceTree = "<group>"; };
|
||||
097D52FE1BC18A09006C893C /* CHANGELOG.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; name = CHANGELOG.md; path = ../CHANGELOG.md; sourceTree = "<group>"; };
|
||||
0982AF071C503EEE00B62463 /* FakePersonsProviders.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FakePersonsProviders.swift; sourceTree = "<group>"; };
|
||||
0982AF091C50401800B62463 /* FakeStarshipProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FakeStarshipProvider.swift; sourceTree = "<group>"; };
|
||||
0990225F1BC123C000E76F43 /* DipSampleApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DipSampleApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
099022611BC123C000E76F43 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
099022681BC123C000E76F43 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
0990226B1BC123C000E76F43 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
0990226D1BC123C000E76F43 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
09B041B61C01F8CB000D383F /* Dip.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Dip.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
09D795FE1BC71F5A003C68EB /* PersonListViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PersonListViewController.swift; sourceTree = "<group>"; };
|
||||
09D796001BC722C0003C68EB /* StarshipListViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StarshipListViewController.swift; sourceTree = "<group>"; };
|
||||
09D796021BC72691003C68EB /* StarshipCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StarshipCell.swift; sourceTree = "<group>"; };
|
||||
@@ -68,18 +74,11 @@
|
||||
09D796181BC9BA49003C68EB /* DependencyContainers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DependencyContainers.swift; sourceTree = "<group>"; };
|
||||
09D7961A1BC9BE65003C68EB /* SWAPIStarshipProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SWAPIStarshipProvider.swift; sourceTree = "<group>"; };
|
||||
09D7961C1BC9C62E003C68EB /* SWAPICommon.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SWAPICommon.swift; sourceTree = "<group>"; };
|
||||
2FE9C70E965FF88C3F20AC76 /* Pods_DipSampleApp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_DipSampleApp.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
304AD039660A2C58EB08D985 /* Pods_DipTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_DipTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
607FACE51AFB9204008FA782 /* DipTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DipTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
09D7962A1BCA8AB3003C68EB /* NetworkMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkMock.swift; sourceTree = "<group>"; };
|
||||
09D7962D1BCA91D3003C68EB /* SWAPIStarshipProviderTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SWAPIStarshipProviderTests.swift; sourceTree = "<group>"; };
|
||||
607FACE51AFB9204008FA782 /* DipSampleAppTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DipSampleAppTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
607FACEB1AFB9204008FA782 /* SWAPIWebServiceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SWAPIWebServiceTests.swift; sourceTree = "<group>"; };
|
||||
64B6CB26CB93DFD18565BB72 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = "<group>"; };
|
||||
6AB71DAFECF410F2FB12A44C /* Pods-DipSampleApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DipSampleApp.debug.xcconfig"; path = "Pods/Target Support Files/Pods-DipSampleApp/Pods-DipSampleApp.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
7E5EDFB4A9194B50CAED7E1A /* Pods-DipTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DipTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-DipTests/Pods-DipTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
9B78063878AFC700C876DEE9 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = "<group>"; };
|
||||
B16085421B606723B72DE694 /* Pods-DipSampleApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DipSampleApp.release.xcconfig"; path = "Pods/Target Support Files/Pods-DipSampleApp/Pods-DipSampleApp.release.xcconfig"; sourceTree = "<group>"; };
|
||||
D9BBF14E74848332935F75C4 /* Pods-DipTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DipTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-DipTests/Pods-DipTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
FDB7C1D2EFEC1BA700762782 /* Dip.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = Dip.podspec; path = ../Dip.podspec; sourceTree = "<group>"; };
|
||||
607FACEB1AFB9204008FA782 /* SWAPIPersonProviderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SWAPIPersonProviderTests.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -87,7 +86,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
84D8EBE5B2D583BEFB17C45A /* Pods_DipSampleApp.framework in Frameworks */,
|
||||
09B041B71C01F8CB000D383F /* Dip.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -95,7 +94,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
7BBD849465D99D9D1987AE6D /* Pods_DipTests.framework in Frameworks */,
|
||||
09B041B81C01F8D1000D383F /* Dip.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -147,8 +146,7 @@
|
||||
090012381BC6FEFD0079C600 /* PersonProviders */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0900121C1BC6FECA0079C600 /* DummyPilotProvider.swift */,
|
||||
0900121E1BC6FECA0079C600 /* PlistPersonProvider.swift */,
|
||||
0982AF071C503EEE00B62463 /* FakePersonsProviders.swift */,
|
||||
09D796121BC9A5BC003C68EB /* SWAPIPersonProvider.swift */,
|
||||
);
|
||||
name = PersonProviders;
|
||||
@@ -157,8 +155,7 @@
|
||||
090012391BC6FF080079C600 /* StarshipProviders */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
090012431BC708A00079C600 /* DummyStarshipProvider.swift */,
|
||||
0900121D1BC6FECA0079C600 /* HardCodedStarshipProvider.swift */,
|
||||
0982AF091C50401800B62463 /* FakeStarshipProvider.swift */,
|
||||
09D7961A1BC9BE65003C68EB /* SWAPIStarshipProvider.swift */,
|
||||
);
|
||||
name = StarshipProviders;
|
||||
@@ -195,8 +192,7 @@
|
||||
1A92CB92072DE61786F63E4C /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2FE9C70E965FF88C3F20AC76 /* Pods_DipSampleApp.framework */,
|
||||
304AD039660A2C58EB08D985 /* Pods_DipTests.framework */,
|
||||
09B041B61C01F8CB000D383F /* Dip.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
@@ -204,19 +200,17 @@
|
||||
607FACC71AFB9204008FA782 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
607FACF51AFB993E008FA782 /* Podspec Metadata */,
|
||||
099022601BC123C000E76F43 /* DipSampleApp */,
|
||||
607FACE81AFB9204008FA782 /* Tests */,
|
||||
607FACD11AFB9204008FA782 /* Products */,
|
||||
1A92CB92072DE61786F63E4C /* Frameworks */,
|
||||
B10E0DA4AD9E022CCA0B272F /* Pods */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
607FACD11AFB9204008FA782 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
607FACE51AFB9204008FA782 /* DipTests.xctest */,
|
||||
607FACE51AFB9204008FA782 /* DipSampleAppTests.xctest */,
|
||||
0990225F1BC123C000E76F43 /* DipSampleApp.app */,
|
||||
);
|
||||
name = Products;
|
||||
@@ -225,7 +219,9 @@
|
||||
607FACE81AFB9204008FA782 /* Tests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
607FACEB1AFB9204008FA782 /* SWAPIWebServiceTests.swift */,
|
||||
09D7962A1BCA8AB3003C68EB /* NetworkMock.swift */,
|
||||
607FACEB1AFB9204008FA782 /* SWAPIPersonProviderTests.swift */,
|
||||
09D7962D1BCA91D3003C68EB /* SWAPIStarshipProviderTests.swift */,
|
||||
607FACE91AFB9204008FA782 /* Supporting Files */,
|
||||
);
|
||||
path = Tests;
|
||||
@@ -239,28 +235,6 @@
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
607FACF51AFB993E008FA782 /* Podspec Metadata */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FDB7C1D2EFEC1BA700762782 /* Dip.podspec */,
|
||||
64B6CB26CB93DFD18565BB72 /* README.md */,
|
||||
097D52FE1BC18A09006C893C /* CHANGELOG.md */,
|
||||
9B78063878AFC700C876DEE9 /* LICENSE */,
|
||||
);
|
||||
name = "Podspec Metadata";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B10E0DA4AD9E022CCA0B272F /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6AB71DAFECF410F2FB12A44C /* Pods-DipSampleApp.debug.xcconfig */,
|
||||
B16085421B606723B72DE694 /* Pods-DipSampleApp.release.xcconfig */,
|
||||
7E5EDFB4A9194B50CAED7E1A /* Pods-DipTests.debug.xcconfig */,
|
||||
D9BBF14E74848332935F75C4 /* Pods-DipTests.release.xcconfig */,
|
||||
);
|
||||
name = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
@@ -268,12 +242,9 @@
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 0990226E1BC123C000E76F43 /* Build configuration list for PBXNativeTarget "DipSampleApp" */;
|
||||
buildPhases = (
|
||||
52BA3DF5A38A73C99738362E /* Check Pods Manifest.lock */,
|
||||
0990225B1BC123C000E76F43 /* Sources */,
|
||||
0990225C1BC123C000E76F43 /* Frameworks */,
|
||||
0990225D1BC123C000E76F43 /* Resources */,
|
||||
586A7844323215ADA94020FD /* Embed Pods Frameworks */,
|
||||
8665FFA2238FD898C8846391 /* Copy Pods Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@@ -284,24 +255,21 @@
|
||||
productReference = 0990225F1BC123C000E76F43 /* DipSampleApp.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
607FACE41AFB9204008FA782 /* DipTests */ = {
|
||||
607FACE41AFB9204008FA782 /* DipSampleAppTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "DipTests" */;
|
||||
buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "DipSampleAppTests" */;
|
||||
buildPhases = (
|
||||
5CA726E6162DF780766DC6CA /* Check Pods Manifest.lock */,
|
||||
607FACE11AFB9204008FA782 /* Sources */,
|
||||
607FACE21AFB9204008FA782 /* Frameworks */,
|
||||
607FACE31AFB9204008FA782 /* Resources */,
|
||||
7982A68D936539C16CA74E2D /* Embed Pods Frameworks */,
|
||||
B0AB134AABD1E8CE42E5A2EC /* Copy Pods Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = DipTests;
|
||||
name = DipSampleAppTests;
|
||||
productName = Tests;
|
||||
productReference = 607FACE51AFB9204008FA782 /* DipTests.xctest */;
|
||||
productReference = 607FACE51AFB9204008FA782 /* DipSampleAppTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
@@ -311,7 +279,7 @@
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0700;
|
||||
LastUpgradeCheck = 0700;
|
||||
LastUpgradeCheck = 0800;
|
||||
ORGANIZATIONNAME = AliSoftware;
|
||||
TargetAttributes = {
|
||||
0990225E1BC123C000E76F43 = {
|
||||
@@ -322,7 +290,7 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "Dip" */;
|
||||
buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "DipSampleApp" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
@@ -336,7 +304,7 @@
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
0990225E1BC123C000E76F43 /* DipSampleApp */,
|
||||
607FACE41AFB9204008FA782 /* DipTests */,
|
||||
607FACE41AFB9204008FA782 /* DipSampleAppTests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
@@ -362,124 +330,29 @@
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
52BA3DF5A38A73C99738362E /* Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Check Pods Manifest.lock";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
586A7844323215ADA94020FD /* Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Embed Pods Frameworks";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-DipSampleApp/Pods-DipSampleApp-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
5CA726E6162DF780766DC6CA /* Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Check Pods Manifest.lock";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
7982A68D936539C16CA74E2D /* Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Embed Pods Frameworks";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-DipTests/Pods-DipTests-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
8665FFA2238FD898C8846391 /* Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Copy Pods Resources";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-DipSampleApp/Pods-DipSampleApp-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
B0AB134AABD1E8CE42E5A2EC /* Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Copy Pods Resources";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-DipTests/Pods-DipTests-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
0990225B1BC123C000E76F43 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
09D796151BC9A5FC003C68EB /* NetworkLayer.swift in Sources */,
|
||||
0982AF081C503EEE00B62463 /* FakePersonsProviders.swift in Sources */,
|
||||
09D795FF1BC71F5A003C68EB /* PersonListViewController.swift in Sources */,
|
||||
0900122A1BC6FECA0079C600 /* PersonCell.swift in Sources */,
|
||||
09D796011BC722C0003C68EB /* StarshipListViewController.swift in Sources */,
|
||||
0900122C1BC6FECA0079C600 /* PersonProviderAPI.swift in Sources */,
|
||||
09D7961D1BC9C62E003C68EB /* SWAPICommon.swift in Sources */,
|
||||
090012291BC6FECA0079C600 /* BaseCell.swift in Sources */,
|
||||
0900122D1BC6FECA0079C600 /* DummyPilotProvider.swift in Sources */,
|
||||
099022621BC123C000E76F43 /* AppDelegate.swift in Sources */,
|
||||
09D796131BC9A5BC003C68EB /* SWAPIPersonProvider.swift in Sources */,
|
||||
090012421BC7059E0079C600 /* Starship.swift in Sources */,
|
||||
0900123D1BC7012A0079C600 /* StarshipProviderAPI.swift in Sources */,
|
||||
0982AF0A1C50401800B62463 /* FakeStarshipProvider.swift in Sources */,
|
||||
09D7961B1BC9BE65003C68EB /* SWAPIStarshipProvider.swift in Sources */,
|
||||
0900122E1BC6FECA0079C600 /* HardCodedStarshipProvider.swift in Sources */,
|
||||
09D796071BC73E8B003C68EB /* StoryboardConstants.swift in Sources */,
|
||||
09D796031BC72691003C68EB /* StarshipCell.swift in Sources */,
|
||||
090012401BC704C60079C600 /* Person.swift in Sources */,
|
||||
090012441BC708A00079C600 /* DummyStarshipProvider.swift in Sources */,
|
||||
09D7960D1BC7431C003C68EB /* FetchableTrait.swift in Sources */,
|
||||
0900122F1BC6FECA0079C600 /* PlistPersonProvider.swift in Sources */,
|
||||
09D796191BC9BA49003C68EB /* DependencyContainers.swift in Sources */,
|
||||
09D796171BC9B53D003C68EB /* URLSessionNetworkLayer.swift in Sources */,
|
||||
);
|
||||
@@ -489,7 +362,17 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
607FACEC1AFB9204008FA782 /* SWAPIWebServiceTests.swift in Sources */,
|
||||
09D796291BCA86D4003C68EB /* SWAPICommon.swift in Sources */,
|
||||
09D796221BCA8305003C68EB /* NetworkLayer.swift in Sources */,
|
||||
09D796231BCA833E003C68EB /* SWAPIPersonProvider.swift in Sources */,
|
||||
09D796251BCA8345003C68EB /* StarshipProviderAPI.swift in Sources */,
|
||||
09D7962C1BCA8AD4003C68EB /* NetworkMock.swift in Sources */,
|
||||
09D7962F1BCA922E003C68EB /* SWAPIStarshipProviderTests.swift in Sources */,
|
||||
09D796241BCA8345003C68EB /* PersonProviderAPI.swift in Sources */,
|
||||
09D796271BCA8550003C68EB /* Person.swift in Sources */,
|
||||
607FACEC1AFB9204008FA782 /* SWAPIPersonProviderTests.swift in Sources */,
|
||||
09D796261BCA8348003C68EB /* SWAPIStarshipProvider.swift in Sources */,
|
||||
09D796281BCA8550003C68EB /* Starship.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -509,7 +392,6 @@
|
||||
/* Begin XCBuildConfiguration section */
|
||||
0990226F1BC123C000E76F43 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 6AB71DAFECF410F2FB12A44C /* Pods-DipSampleApp.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
@@ -525,7 +407,6 @@
|
||||
};
|
||||
099022701BC123C000E76F43 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = B16085421B606723B72DE694 /* Pods-DipSampleApp.release.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
INFOPLIST_FILE = DipSampleApp/Info.plist;
|
||||
@@ -533,6 +414,7 @@
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.alisoftware.DipSampleApp;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
@@ -579,6 +461,7 @@
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 3.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -615,13 +498,13 @@
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.3;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_VERSION = 3.0;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
607FACF31AFB9204008FA782 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 7E5EDFB4A9194B50CAED7E1A /* Pods-DipTests.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
@@ -636,12 +519,12 @@
|
||||
};
|
||||
607FACF41AFB9204008FA782 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = D9BBF14E74848332935F75C4 /* Pods-DipTests.release.xcconfig */;
|
||||
buildSettings = {
|
||||
INFOPLIST_FILE = Tests/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@@ -657,7 +540,7 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "Dip" */ = {
|
||||
607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "DipSampleApp" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
607FACED1AFB9204008FA782 /* Debug */,
|
||||
@@ -666,7 +549,7 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "DipTests" */ = {
|
||||
607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "DipSampleAppTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
607FACF31AFB9204008FA782 /* Debug */,
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0700"
|
||||
LastUpgradeVersion = "0800"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@@ -17,7 +17,7 @@
|
||||
BlueprintIdentifier = "0990225E1BC123C000E76F43"
|
||||
BuildableName = "DipSampleApp.app"
|
||||
BlueprintName = "DipSampleApp"
|
||||
ReferencedContainer = "container:Dip.xcodeproj">
|
||||
ReferencedContainer = "container:DipSampleApp.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
@@ -29,9 +29,9 @@
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "607FACE41AFB9204008FA782"
|
||||
BuildableName = "DipTests.xctest"
|
||||
BlueprintName = "DipTests"
|
||||
ReferencedContainer = "container:Dip.xcodeproj">
|
||||
BuildableName = "DipSampleAppTests.xctest"
|
||||
BlueprintName = "DipSampleAppTests"
|
||||
ReferencedContainer = "container:DipSampleApp.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
@@ -48,9 +48,9 @@
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "607FACE41AFB9204008FA782"
|
||||
BuildableName = "DipTests.xctest"
|
||||
BlueprintName = "DipTests"
|
||||
ReferencedContainer = "container:Dip.xcodeproj">
|
||||
BuildableName = "DipSampleAppTests.xctest"
|
||||
BlueprintName = "DipSampleAppTests"
|
||||
ReferencedContainer = "container:DipSampleApp.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
@@ -60,7 +60,7 @@
|
||||
BlueprintIdentifier = "0990225E1BC123C000E76F43"
|
||||
BuildableName = "DipSampleApp.app"
|
||||
BlueprintName = "DipSampleApp"
|
||||
ReferencedContainer = "container:Dip.xcodeproj">
|
||||
ReferencedContainer = "container:DipSampleApp.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
@@ -83,7 +83,7 @@
|
||||
BlueprintIdentifier = "0990225E1BC123C000E76F43"
|
||||
BuildableName = "DipSampleApp.app"
|
||||
BlueprintName = "DipSampleApp"
|
||||
ReferencedContainer = "container:Dip.xcodeproj">
|
||||
ReferencedContainer = "container:DipSampleApp.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
@@ -102,7 +102,7 @@
|
||||
BlueprintIdentifier = "0990225E1BC123C000E76F43"
|
||||
BuildableName = "DipSampleApp.app"
|
||||
BlueprintName = "DipSampleApp"
|
||||
ReferencedContainer = "container:Dip.xcodeproj">
|
||||
ReferencedContainer = "container:DipSampleApp.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// AppDelegate.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 04/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Dip
|
||||
|
||||
@UIApplicationMain
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
var window: UIWindow?
|
||||
|
||||
private let container = DependencyContainer()
|
||||
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
|
||||
// Override point for customization after application launch.
|
||||
|
||||
//This is a composition root where container is configured and all dependencies are resolved
|
||||
configure(container: container)
|
||||
|
||||
let personProvider = try! container.resolve() as PersonProviderAPI
|
||||
let starshipProvider = try! container.resolve() as StarshipProviderAPI
|
||||
|
||||
if let tabBarVC = self.window?.rootViewController as? UITabBarController,
|
||||
let vcs = tabBarVC.viewControllers as? [UINavigationController] {
|
||||
if let personListVC = vcs[0].topViewController as? PersonListViewController {
|
||||
personListVC.personProvider = personProvider
|
||||
personListVC.starshipProvider = starshipProvider
|
||||
personListVC.loadFirstPage()
|
||||
}
|
||||
if let starshipListVC = vcs[1].topViewController as? StarshipListViewController {
|
||||
starshipListVC.starshipProvider = starshipProvider
|
||||
starshipListVC.personProvider = personProvider
|
||||
starshipListVC.loadFirstPage()
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 9.8 KiB |
|
Before Width: | Height: | Size: 277 KiB After Width: | Height: | Size: 277 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |