Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7f9c54e484 | |||
| ec177fba78 | |||
| 6b6f85ba4c | |||
| 5f845e6701 | |||
| 0028083289 | |||
| 10dd5a51a5 | |||
| 4e3a53997e | |||
| ae8d56e5d8 | |||
| bc303da493 | |||
| 0db3155835 | |||
| 74112c6051 | |||
| a98a9eed56 | |||
| a4f6db4f8d | |||
| a74b527324 | |||
| 225fb70bd4 | |||
| 368d4f920f | |||
| 61042efb53 | |||
| 4ba6e48fd2 | |||
| 2303aee66f | |||
| 7dd3fc3c5c | |||
| c920c4f425 | |||
| c0833fd92f | |||
| 31673bbf21 | |||
| 219e7fd5c1 | |||
| 6085ce5f21 | |||
| 3bca744c82 | |||
| c311eea591 | |||
| 120a98b157 | |||
| 937709fba2 |
@@ -13,6 +13,7 @@ build/
|
||||
!default.perspectivev3
|
||||
xcuserdata
|
||||
*.xccheckout
|
||||
*.xcscmblueprint
|
||||
profile
|
||||
*.moved-aside
|
||||
DerivedData
|
||||
|
||||
@@ -1,7 +1,68 @@
|
||||
# CHANGELOG
|
||||
|
||||
## 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,11 +1,11 @@
|
||||
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 = "2.0.0"
|
||||
s.summary = "A simple Dependency Resolver: Dependency Injection using Protocol resolution."
|
||||
|
||||
s.description = <<-DESC
|
||||
Dip is a Swift framework to manage your Dependencies between your classes
|
||||
in your app.
|
||||
in your app using Dependency Injection.
|
||||
|
||||
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
|
||||
@@ -15,8 +15,6 @@ Pod::Spec.new do |s|
|
||||
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
|
||||
|
||||
s.homepage = "https://github.com/AliSoftware/Dip"
|
||||
|
||||
@@ -7,68 +7,84 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
097D52E81BC13B0D006C893C /* WebServiceAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 097D52E71BC13B0D006C893C /* WebServiceAPI.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
097D52EA1BC15FFF006C893C /* PersonFactoryAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 097D52E91BC15FFF006C893C /* PersonFactoryAPI.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
097D52ED1BC16091006C893C /* Person.swift in Sources */ = {isa = PBXBuildFile; fileRef = 097D52EC1BC16091006C893C /* Person.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
097D52EF1BC1611C006C893C /* SWAPIWebService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 097D52EE1BC1611C006C893C /* SWAPIWebService.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
097D52F11BC161F7006C893C /* SerializerAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 097D52F01BC161F7006C893C /* SerializerAPI.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
097D52F51BC166F3006C893C /* JSONSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 097D52F41BC166F3006C893C /* JSONSerializer.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
097D52F71BC169C0006C893C /* SWAPIPersonFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 097D52F61BC169C0006C893C /* SWAPIPersonFactory.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
097D52F91BC17418006C893C /* PersonFormatterAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 097D52F81BC17418006C893C /* PersonFormatterAPI.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
097D52FB1BC1745B006C893C /* MassHeightFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 097D52FA1BC1745B006C893C /* MassHeightFormatter.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
097D52FD1BC174B6006C893C /* EyesHairFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 097D52FC1BC174B6006C893C /* EyesHairFormatter.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
097D53011BC31F4A006C893C /* Tags.swift in Sources */ = {isa = PBXBuildFile; fileRef = 097D53001BC31F4A006C893C /* Tags.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
097D53021BC31FA6006C893C /* WebServiceAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 097D52E71BC13B0D006C893C /* WebServiceAPI.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
097D53031BC31FA6006C893C /* SerializerAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 097D52F01BC161F7006C893C /* SerializerAPI.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
097D53041BC31FA6006C893C /* PersonFactoryAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 097D52E91BC15FFF006C893C /* PersonFactoryAPI.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
097D53051BC31FA6006C893C /* PersonFormatterAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 097D52F81BC17418006C893C /* PersonFormatterAPI.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
097D53061BC31FAE006C893C /* SWAPIWebService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 097D52EE1BC1611C006C893C /* SWAPIWebService.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
097D53071BC31FC5006C893C /* Tags.swift in Sources */ = {isa = PBXBuildFile; fileRef = 097D53001BC31F4A006C893C /* Tags.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
097D53081BC32053006C893C /* Person.swift in Sources */ = {isa = PBXBuildFile; fileRef = 097D52EC1BC16091006C893C /* Person.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
097D530A1BC3243D006C893C /* NetworkLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 097D53091BC3243D006C893C /* NetworkLayer.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
097D530C1BC324DA006C893C /* NSURLSessionNetworkLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 097D530B1BC324DA006C893C /* NSURLSessionNetworkLayer.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
097D530D1BC3250B006C893C /* SWAPIPersonFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 097D52F61BC169C0006C893C /* SWAPIPersonFactory.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
097D530E1BC3250E006C893C /* JSONSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 097D52F41BC166F3006C893C /* JSONSerializer.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
097D530F1BC3250E006C893C /* MassHeightFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 097D52FA1BC1745B006C893C /* MassHeightFormatter.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
097D53101BC3250E006C893C /* EyesHairFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 097D52FC1BC174B6006C893C /* EyesHairFormatter.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
097D53111BC32513006C893C /* NetworkLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 097D53091BC3243D006C893C /* NetworkLayer.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
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 = (); }; };
|
||||
099022621BC123C000E76F43 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 099022611BC123C000E76F43 /* AppDelegate.swift */; };
|
||||
099022641BC123C000E76F43 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 099022631BC123C000E76F43 /* ViewController.swift */; };
|
||||
099022671BC123C000E76F43 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 099022651BC123C000E76F43 /* Main.storyboard */; };
|
||||
099022691BC123C000E76F43 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 099022681BC123C000E76F43 /* Assets.xcassets */; };
|
||||
0990226C1BC123C000E76F43 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0990226A1BC123C000E76F43 /* LaunchScreen.storyboard */; };
|
||||
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, ); }; };
|
||||
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 = (); }; };
|
||||
09D796221BCA8305003C68EB /* NetworkLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D796141BC9A5FC003C68EB /* NetworkLayer.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
09D796231BCA833E003C68EB /* SWAPIPersonProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D796121BC9A5BC003C68EB /* SWAPIPersonProvider.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
09D796241BCA8345003C68EB /* PersonProviderAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0900121B1BC6FECA0079C600 /* PersonProviderAPI.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
09D796251BCA8345003C68EB /* StarshipProviderAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0900123C1BC7012A0079C600 /* StarshipProviderAPI.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
09D796261BCA8348003C68EB /* SWAPIStarshipProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D7961A1BC9BE65003C68EB /* SWAPIStarshipProvider.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
09D796271BCA8550003C68EB /* Person.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0900123F1BC704C60079C600 /* Person.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
09D796281BCA8550003C68EB /* Starship.swift in Sources */ = {isa = PBXBuildFile; fileRef = 090012411BC7059E0079C600 /* Starship.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
09D796291BCA86D4003C68EB /* SWAPICommon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D7961C1BC9C62E003C68EB /* SWAPICommon.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
09D7962C1BCA8AD4003C68EB /* NetworkMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D7962A1BCA8AB3003C68EB /* NetworkMock.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
09D7962F1BCA922E003C68EB /* SWAPIStarshipProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09D7962D1BCA91D3003C68EB /* SWAPIStarshipProviderTests.swift */; settings = {ASSET_TAGS = (); }; };
|
||||
607FACEC1AFB9204008FA782 /* SWAPIPersonProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* SWAPIPersonProviderTests.swift */; };
|
||||
7BBD849465D99D9D1987AE6D /* Pods_DipTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 304AD039660A2C58EB08D985 /* Pods_DipTests.framework */; };
|
||||
84D8EBE5B2D583BEFB17C45A /* Pods_DipSampleApp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2FE9C70E965FF88C3F20AC76 /* Pods_DipSampleApp.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
097D52E71BC13B0D006C893C /* WebServiceAPI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WebServiceAPI.swift; sourceTree = "<group>"; };
|
||||
097D52E91BC15FFF006C893C /* PersonFactoryAPI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PersonFactoryAPI.swift; sourceTree = "<group>"; };
|
||||
097D52EC1BC16091006C893C /* Person.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Person.swift; sourceTree = "<group>"; };
|
||||
097D52EE1BC1611C006C893C /* SWAPIWebService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SWAPIWebService.swift; sourceTree = "<group>"; };
|
||||
097D52F01BC161F7006C893C /* SerializerAPI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SerializerAPI.swift; sourceTree = "<group>"; };
|
||||
097D52F41BC166F3006C893C /* JSONSerializer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONSerializer.swift; sourceTree = "<group>"; };
|
||||
097D52F61BC169C0006C893C /* SWAPIPersonFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SWAPIPersonFactory.swift; sourceTree = "<group>"; };
|
||||
097D52F81BC17418006C893C /* PersonFormatterAPI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PersonFormatterAPI.swift; sourceTree = "<group>"; };
|
||||
097D52FA1BC1745B006C893C /* MassHeightFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MassHeightFormatter.swift; sourceTree = "<group>"; };
|
||||
097D52FC1BC174B6006C893C /* EyesHairFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EyesHairFormatter.swift; sourceTree = "<group>"; };
|
||||
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>"; };
|
||||
097D53001BC31F4A006C893C /* Tags.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Tags.swift; sourceTree = "<group>"; };
|
||||
097D53091BC3243D006C893C /* NetworkLayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkLayer.swift; sourceTree = "<group>"; };
|
||||
097D530B1BC324DA006C893C /* NSURLSessionNetworkLayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSURLSessionNetworkLayer.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>"; };
|
||||
099022631BC123C000E76F43 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
|
||||
099022661BC123C000E76F43 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; 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>"; };
|
||||
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>"; };
|
||||
09D796061BC73E8B003C68EB /* StoryboardConstants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StoryboardConstants.swift; sourceTree = "<group>"; };
|
||||
09D7960C1BC7431C003C68EB /* FetchableTrait.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchableTrait.swift; sourceTree = "<group>"; };
|
||||
09D796101BC97809003C68EB /* mainPilot.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = mainPilot.plist; sourceTree = "<group>"; };
|
||||
09D796121BC9A5BC003C68EB /* SWAPIPersonProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SWAPIPersonProvider.swift; sourceTree = "<group>"; };
|
||||
09D796141BC9A5FC003C68EB /* NetworkLayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkLayer.swift; sourceTree = "<group>"; };
|
||||
09D796161BC9B53D003C68EB /* URLSessionNetworkLayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLSessionNetworkLayer.swift; sourceTree = "<group>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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; };
|
||||
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>"; };
|
||||
607FACEB1AFB9204008FA782 /* SWAPIPersonProviderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SWAPIPersonProviderTests.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>"; };
|
||||
@@ -98,60 +114,92 @@
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
097D52E61BC139A8006C893C /* Services */ = {
|
||||
090012141BC6FECA0079C600 /* Cells */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
097D52F21BC16258006C893C /* Protocols */,
|
||||
097D52F31BC16271006C893C /* Implementations */,
|
||||
090012161BC6FECA0079C600 /* BaseCell.swift */,
|
||||
090012171BC6FECA0079C600 /* PersonCell.swift */,
|
||||
09D796021BC72691003C68EB /* StarshipCell.swift */,
|
||||
);
|
||||
path = Services;
|
||||
path = Cells;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
097D52EB1BC16083006C893C /* Model */ = {
|
||||
0900121A1BC6FECA0079C600 /* Providers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
097D52EC1BC16091006C893C /* Person.swift */,
|
||||
09D7961C1BC9C62E003C68EB /* SWAPICommon.swift */,
|
||||
090012371BC6FEEA0079C600 /* APIs */,
|
||||
090012381BC6FEFD0079C600 /* PersonProviders */,
|
||||
090012391BC6FF080079C600 /* StarshipProviders */,
|
||||
09D796161BC9B53D003C68EB /* URLSessionNetworkLayer.swift */,
|
||||
);
|
||||
path = Providers;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
090012201BC6FECA0079C600 /* ViewControllers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
09D7960C1BC7431C003C68EB /* FetchableTrait.swift */,
|
||||
09D795FE1BC71F5A003C68EB /* PersonListViewController.swift */,
|
||||
09D796001BC722C0003C68EB /* StarshipListViewController.swift */,
|
||||
);
|
||||
path = ViewControllers;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
090012371BC6FEEA0079C600 /* APIs */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0900121B1BC6FECA0079C600 /* PersonProviderAPI.swift */,
|
||||
0900123C1BC7012A0079C600 /* StarshipProviderAPI.swift */,
|
||||
09D796141BC9A5FC003C68EB /* NetworkLayer.swift */,
|
||||
);
|
||||
name = APIs;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
090012381BC6FEFD0079C600 /* PersonProviders */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0900121C1BC6FECA0079C600 /* DummyPilotProvider.swift */,
|
||||
0900121E1BC6FECA0079C600 /* PlistPersonProvider.swift */,
|
||||
09D796121BC9A5BC003C68EB /* SWAPIPersonProvider.swift */,
|
||||
);
|
||||
name = PersonProviders;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
090012391BC6FF080079C600 /* StarshipProviders */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
090012431BC708A00079C600 /* DummyStarshipProvider.swift */,
|
||||
0900121D1BC6FECA0079C600 /* HardCodedStarshipProvider.swift */,
|
||||
09D7961A1BC9BE65003C68EB /* SWAPIStarshipProvider.swift */,
|
||||
);
|
||||
name = StarshipProviders;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0900123E1BC704A80079C600 /* Model */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0900123F1BC704C60079C600 /* Person.swift */,
|
||||
090012411BC7059E0079C600 /* Starship.swift */,
|
||||
);
|
||||
path = Model;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
097D52F21BC16258006C893C /* Protocols */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
097D52E71BC13B0D006C893C /* WebServiceAPI.swift */,
|
||||
097D52F01BC161F7006C893C /* SerializerAPI.swift */,
|
||||
097D52E91BC15FFF006C893C /* PersonFactoryAPI.swift */,
|
||||
097D52F81BC17418006C893C /* PersonFormatterAPI.swift */,
|
||||
097D53091BC3243D006C893C /* NetworkLayer.swift */,
|
||||
);
|
||||
path = Protocols;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
097D52F31BC16271006C893C /* Implementations */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
097D52EE1BC1611C006C893C /* SWAPIWebService.swift */,
|
||||
097D52F61BC169C0006C893C /* SWAPIPersonFactory.swift */,
|
||||
097D52F41BC166F3006C893C /* JSONSerializer.swift */,
|
||||
097D52FA1BC1745B006C893C /* MassHeightFormatter.swift */,
|
||||
097D52FC1BC174B6006C893C /* EyesHairFormatter.swift */,
|
||||
097D530B1BC324DA006C893C /* NSURLSessionNetworkLayer.swift */,
|
||||
);
|
||||
path = Implementations;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
099022601BC123C000E76F43 /* DipSampleApp */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
097D52EB1BC16083006C893C /* Model */,
|
||||
097D52E61BC139A8006C893C /* Services */,
|
||||
097D53001BC31F4A006C893C /* Tags.swift */,
|
||||
0900123A1BC6FF4D0079C600 /* Main.storyboard */,
|
||||
099022611BC123C000E76F43 /* AppDelegate.swift */,
|
||||
099022631BC123C000E76F43 /* ViewController.swift */,
|
||||
099022651BC123C000E76F43 /* Main.storyboard */,
|
||||
09D796181BC9BA49003C68EB /* DependencyContainers.swift */,
|
||||
0900123E1BC704A80079C600 /* Model */,
|
||||
0900121A1BC6FECA0079C600 /* Providers */,
|
||||
090012201BC6FECA0079C600 /* ViewControllers */,
|
||||
090012141BC6FECA0079C600 /* Cells */,
|
||||
099022681BC123C000E76F43 /* Assets.xcassets */,
|
||||
09D796061BC73E8B003C68EB /* StoryboardConstants.swift */,
|
||||
0990226A1BC123C000E76F43 /* LaunchScreen.storyboard */,
|
||||
0990226D1BC123C000E76F43 /* Info.plist */,
|
||||
09D796101BC97809003C68EB /* mainPilot.plist */,
|
||||
);
|
||||
path = DipSampleApp;
|
||||
sourceTree = "<group>";
|
||||
@@ -189,7 +237,9 @@
|
||||
607FACE81AFB9204008FA782 /* Tests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
607FACEB1AFB9204008FA782 /* SWAPIWebServiceTests.swift */,
|
||||
09D7962A1BCA8AB3003C68EB /* NetworkMock.swift */,
|
||||
607FACEB1AFB9204008FA782 /* SWAPIPersonProviderTests.swift */,
|
||||
09D7962D1BCA91D3003C68EB /* SWAPIStarshipProviderTests.swift */,
|
||||
607FACE91AFB9204008FA782 /* Supporting Files */,
|
||||
);
|
||||
path = Tests;
|
||||
@@ -310,9 +360,10 @@
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0900123B1BC6FF4D0079C600 /* Main.storyboard in Resources */,
|
||||
0990226C1BC123C000E76F43 /* LaunchScreen.storyboard in Resources */,
|
||||
09D796111BC97809003C68EB /* mainPilot.plist in Resources */,
|
||||
099022691BC123C000E76F43 /* Assets.xcassets in Resources */,
|
||||
099022671BC123C000E76F43 /* Main.storyboard in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -423,21 +474,28 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
097D530A1BC3243D006C893C /* NetworkLayer.swift in Sources */,
|
||||
097D52ED1BC16091006C893C /* Person.swift in Sources */,
|
||||
097D52F11BC161F7006C893C /* SerializerAPI.swift in Sources */,
|
||||
097D52F91BC17418006C893C /* PersonFormatterAPI.swift in Sources */,
|
||||
099022641BC123C000E76F43 /* ViewController.swift in Sources */,
|
||||
097D530C1BC324DA006C893C /* NSURLSessionNetworkLayer.swift in Sources */,
|
||||
097D52F51BC166F3006C893C /* JSONSerializer.swift in Sources */,
|
||||
097D53011BC31F4A006C893C /* Tags.swift in Sources */,
|
||||
09D796151BC9A5FC003C68EB /* NetworkLayer.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 */,
|
||||
097D52F71BC169C0006C893C /* SWAPIPersonFactory.swift in Sources */,
|
||||
097D52EF1BC1611C006C893C /* SWAPIWebService.swift in Sources */,
|
||||
097D52FD1BC174B6006C893C /* EyesHairFormatter.swift in Sources */,
|
||||
097D52FB1BC1745B006C893C /* MassHeightFormatter.swift in Sources */,
|
||||
097D52E81BC13B0D006C893C /* WebServiceAPI.swift in Sources */,
|
||||
097D52EA1BC15FFF006C893C /* PersonFactoryAPI.swift in Sources */,
|
||||
09D796131BC9A5BC003C68EB /* SWAPIPersonProvider.swift in Sources */,
|
||||
090012421BC7059E0079C600 /* Starship.swift in Sources */,
|
||||
0900123D1BC7012A0079C600 /* StarshipProviderAPI.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 */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -445,33 +503,23 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
607FACEC1AFB9204008FA782 /* SWAPIWebServiceTests.swift in Sources */,
|
||||
097D53051BC31FA6006C893C /* PersonFormatterAPI.swift in Sources */,
|
||||
097D53071BC31FC5006C893C /* Tags.swift in Sources */,
|
||||
097D53111BC32513006C893C /* NetworkLayer.swift in Sources */,
|
||||
097D53021BC31FA6006C893C /* WebServiceAPI.swift in Sources */,
|
||||
097D53041BC31FA6006C893C /* PersonFactoryAPI.swift in Sources */,
|
||||
097D530E1BC3250E006C893C /* JSONSerializer.swift in Sources */,
|
||||
097D53031BC31FA6006C893C /* SerializerAPI.swift in Sources */,
|
||||
097D53081BC32053006C893C /* Person.swift in Sources */,
|
||||
097D53101BC3250E006C893C /* EyesHairFormatter.swift in Sources */,
|
||||
097D530F1BC3250E006C893C /* MassHeightFormatter.swift in Sources */,
|
||||
097D530D1BC3250B006C893C /* SWAPIPersonFactory.swift in Sources */,
|
||||
097D53061BC31FAE006C893C /* SWAPIWebService.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;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
099022651BC123C000E76F43 /* Main.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
099022661BC123C000E76F43 /* Base */,
|
||||
);
|
||||
name = Main.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0990226A1BC123C000E76F43 /* LaunchScreen.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
|
||||
@@ -1,25 +1,12 @@
|
||||
//
|
||||
// AppDelegate.swift
|
||||
// DipSampleApp
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 04/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Dip
|
||||
|
||||
let dip: DependencyContainer<PersonFormatterTag> = {
|
||||
let dip = DependencyContainer<PersonFormatterTag>()
|
||||
dip.register(instance: NSURLSessionNetworkLayer() as NetworkLayer)
|
||||
dip.register(instance: SWAPIWebService() as WebServiceAPI)
|
||||
dip.register(instance: SWAPIPersonFactory() as PersonFactoryAPI)
|
||||
dip.register(instance: JSONSerializer() as SerializerAPI)
|
||||
dip.register(.MassHeight, instance: MassHeightFormatter() as PersonFormatterAPI)
|
||||
dip.register(.EyesHair, instance: EyesHairFormatter() as PersonFormatterAPI)
|
||||
return dip
|
||||
}()
|
||||
|
||||
|
||||
@UIApplicationMain
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
@@ -29,6 +16,16 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
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.loadFirstPage()
|
||||
}
|
||||
if let starshipListVC = vcs[1].topViewController as? StarshipListViewController {
|
||||
starshipListVC.loadFirstPage()
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,8 +21,9 @@
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-120.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
@@ -51,13 +52,15 @@
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-76.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-152.png",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
|
||||
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 9.8 KiB |
|
After Width: | Height: | Size: 277 KiB |
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "Churros.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "female.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "female@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "male.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "male@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "person@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "spaceship@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
@@ -1,7 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8150" systemVersion="15A204g" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8191" systemVersion="15A284" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8122"/>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8154"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
@@ -15,8 +16,21 @@
|
||||
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Churros" translatesAutoresizingMaskIntoConstraints="NO" id="Phj-6E-gSz">
|
||||
<rect key="frame" x="0.0" y="20" width="600" height="580"/>
|
||||
<animations/>
|
||||
<color key="backgroundColor" red="0.40392156862745099" green="0.19215686274509805" blue="0.12549019607843137" alpha="1" colorSpace="calibratedRGB"/>
|
||||
</imageView>
|
||||
</subviews>
|
||||
<animations/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstItem="Phj-6E-gSz" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leading" id="LGN-jG-FhR"/>
|
||||
<constraint firstItem="Phj-6E-gSz" firstAttribute="top" secondItem="Llm-lL-Icb" secondAttribute="bottom" id="LqV-hP-9GR"/>
|
||||
<constraint firstItem="xb3-aO-Qok" firstAttribute="top" secondItem="Phj-6E-gSz" secondAttribute="bottom" id="MYa-Zv-jEi"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Phj-6E-gSz" secondAttribute="trailing" id="zwN-fu-K6m"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
@@ -24,4 +38,7 @@
|
||||
<point key="canvasLocation" x="53" y="375"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="Churros" width="200" height="300"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8191" systemVersion="15A284" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8154"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="tne-QT-ifu">
|
||||
<objects>
|
||||
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="DipSampleApp" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" allowsSelection="NO" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="qXh-gx-TLm">
|
||||
<rect key="frame" x="0.0" y="78" width="600" height="522"/>
|
||||
<animations/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<prototypes>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="Cell" textLabel="eJE-RI-YCj" detailTextLabel="bZ8-WN-uod" rowHeight="44" style="IBUITableViewCellStyleSubtitle" id="DrW-4I-t0H">
|
||||
<rect key="frame" x="0.0" y="28" width="600" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="DrW-4I-t0H" id="8qv-kr-bqA">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="eJE-RI-YCj">
|
||||
<rect key="frame" x="15" y="6" width="31.5" height="19.5"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Subtitle" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="bZ8-WN-uod">
|
||||
<rect key="frame" x="15" y="25.5" width="40.5" height="13.5"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="11"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<animations/>
|
||||
</tableViewCellContentView>
|
||||
<animations/>
|
||||
</tableViewCell>
|
||||
</prototypes>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="BYZ-38-t0r" id="VJL-tj-MzD"/>
|
||||
<outlet property="delegate" destination="BYZ-38-t0r" id="3VC-R7-cB4"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="9iY-My-sX6">
|
||||
<rect key="frame" x="373" y="29" width="207" height="29"/>
|
||||
<animations/>
|
||||
<segments>
|
||||
<segment title="Mass & Height"/>
|
||||
<segment title="Hair & Eyes"/>
|
||||
</segments>
|
||||
<connections>
|
||||
<action selector="displayModeChanged:" destination="BYZ-38-t0r" eventType="valueChanged" id="CBv-S7-Hhz"/>
|
||||
</connections>
|
||||
</segmentedControl>
|
||||
<activityIndicatorView hidden="YES" opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="gray" translatesAutoresizingMaskIntoConstraints="NO" id="ZrJ-F8-ur5">
|
||||
<rect key="frame" x="110" y="33" width="20" height="20"/>
|
||||
<animations/>
|
||||
</activityIndicatorView>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ncZ-ht-Ksy">
|
||||
<rect key="frame" x="20" y="28" width="82" height="30"/>
|
||||
<animations/>
|
||||
<state key="normal" title="fetchPeople"/>
|
||||
<connections>
|
||||
<action selector="fetchPeople:" destination="BYZ-38-t0r" eventType="touchUpInside" id="Mt6-Lr-Pil"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<animations/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="qXh-gx-TLm" secondAttribute="trailing" id="9Kr-bh-UDV"/>
|
||||
<constraint firstItem="qXh-gx-TLm" firstAttribute="top" secondItem="ncZ-ht-Ksy" secondAttribute="bottom" constant="20" id="Hmb-DO-Rfc"/>
|
||||
<constraint firstItem="9iY-My-sX6" firstAttribute="centerY" secondItem="ncZ-ht-Ksy" secondAttribute="centerY" id="TBb-VW-yeu"/>
|
||||
<constraint firstItem="ncZ-ht-Ksy" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leading" constant="20" symbolic="YES" id="U15-6S-bXH"/>
|
||||
<constraint firstItem="ZrJ-F8-ur5" firstAttribute="leading" secondItem="ncZ-ht-Ksy" secondAttribute="trailing" constant="8" symbolic="YES" id="YZP-u9-4yj"/>
|
||||
<constraint firstItem="ncZ-ht-Ksy" firstAttribute="top" secondItem="y3c-jy-aDJ" secondAttribute="bottom" constant="8" symbolic="YES" id="Zj6-fq-3iI"/>
|
||||
<constraint firstItem="ZrJ-F8-ur5" firstAttribute="centerY" secondItem="ncZ-ht-Ksy" secondAttribute="centerY" id="g7i-I1-gh8"/>
|
||||
<constraint firstItem="qXh-gx-TLm" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leading" id="hhU-qP-IoI"/>
|
||||
<constraint firstItem="wfy-db-euE" firstAttribute="top" secondItem="qXh-gx-TLm" secondAttribute="bottom" id="koO-On-68B"/>
|
||||
<constraint firstAttribute="trailing" secondItem="9iY-My-sX6" secondAttribute="trailing" constant="20" symbolic="YES" id="wRA-OJ-Uzd"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="activityIndicator" destination="ZrJ-F8-ur5" id="3If-JS-Sph"/>
|
||||
<outlet property="displayModeSelector" destination="9iY-My-sX6" id="UvA-Vu-rkk"/>
|
||||
<outlet property="tableView" destination="qXh-gx-TLm" id="agu-go-Toa"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="390" y="450"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// BaseCell.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 10/09/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
protocol BaseCell {
|
||||
static var identifier: String { get }
|
||||
static var nib: UINib? { get }
|
||||
|
||||
static func register(tableView: UITableView)
|
||||
static func dequeueFromTableView(tableView: UITableView, forIndexPath indexPath: NSIndexPath) -> Self
|
||||
}
|
||||
|
||||
extension BaseCell where Self : UITableViewCell {
|
||||
static var identifier: String {
|
||||
return "\(Self.self)"
|
||||
}
|
||||
static var nib: UINib? { return nil }
|
||||
|
||||
static func register(tableView: UITableView) {
|
||||
if let cellNib = self.nib {
|
||||
tableView.registerNib(cellNib, forCellReuseIdentifier: identifier)
|
||||
} else {
|
||||
tableView.registerClass(Self.self as AnyClass, forCellReuseIdentifier: identifier)
|
||||
}
|
||||
}
|
||||
|
||||
static func dequeueFromTableView(tableView: UITableView, forIndexPath indexPath: NSIndexPath) -> Self {
|
||||
return tableView.dequeueReusableCellWithIdentifier(identifier, forIndexPath: indexPath) as! Self
|
||||
}
|
||||
}
|
||||
|
||||
protocol FillableCell: BaseCell {
|
||||
typealias ObjectType
|
||||
func fillWithObject(object: ObjectType)
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// UserCell.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 10/09/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
final class PersonCell : UITableViewCell, FillableCell {
|
||||
@IBOutlet weak var nameLabel: UILabel!
|
||||
@IBOutlet weak var genderImageView: UIImageView!
|
||||
@IBOutlet weak var heightLabel: UILabel!
|
||||
@IBOutlet weak var massLabel: UILabel!
|
||||
@IBOutlet weak var hairLabel: UILabel!
|
||||
@IBOutlet weak var eyesLabel: UILabel!
|
||||
|
||||
let heightFormatter: NSLengthFormatter = {
|
||||
let f = NSLengthFormatter()
|
||||
f.forPersonHeightUse = true
|
||||
return f
|
||||
}()
|
||||
let massFormatter: NSMassFormatter = {
|
||||
let f = NSMassFormatter()
|
||||
f.forPersonMassUse = true
|
||||
return f
|
||||
}()
|
||||
|
||||
func fillWithObject(person: Person) {
|
||||
nameLabel.text = person.name
|
||||
genderImageView.image = person.gender.flatMap { UIImage(named: $0.rawValue) }
|
||||
heightLabel.text = heightFormatter.stringFromValue(Double(person.height), unit: .Centimeter)
|
||||
massLabel.text = massFormatter.stringFromValue(Double(person.mass), unit: .Kilogram)
|
||||
hairLabel.text = person.hairColor
|
||||
eyesLabel.text = person.eyeColor
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// StarshipCell.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 09/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
final class StarshipCell : UITableViewCell, FillableCell {
|
||||
@IBOutlet weak var nameLabel: UILabel!
|
||||
@IBOutlet weak var modelLabel: UILabel!
|
||||
@IBOutlet weak var manufacturerLabel: UILabel!
|
||||
@IBOutlet weak var crewLabel: UILabel!
|
||||
@IBOutlet weak var passengersLabel: UILabel!
|
||||
|
||||
let numberFormatter = NSNumberFormatter()
|
||||
|
||||
func fillWithObject(starship: Starship) {
|
||||
nameLabel.text = starship.name
|
||||
modelLabel.text = starship.model
|
||||
manufacturerLabel.text = starship.manufacturer
|
||||
crewLabel.text = numberFormatter.stringFromNumber(starship.crew)
|
||||
passengersLabel.text = numberFormatter.stringFromNumber(starship.passengers)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
//
|
||||
// DependencyContainers.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 10/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Dip
|
||||
|
||||
// MARK: Configuration
|
||||
|
||||
/* Change this to toggle between real and fake data */
|
||||
private let FAKE_PERSONS = false
|
||||
private let FAKE_STARSHIPS = false
|
||||
/* ---- */
|
||||
|
||||
|
||||
|
||||
// MARK: Dependency Container for WebServices & NetworkLayer
|
||||
let wsDependencies = DependencyContainer() { dip in
|
||||
|
||||
// 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)
|
||||
|
||||
}
|
||||
|
||||
|
||||
// MARK: Dependency Container for Providers
|
||||
let providerDependencies = DependencyContainer() { dip in
|
||||
|
||||
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)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,364 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8191" systemVersion="15A284" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="Nnt-Mi-Wf8">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8154"/>
|
||||
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Tab Bar Controller-->
|
||||
<scene sceneID="i0H-gd-FLz">
|
||||
<objects>
|
||||
<tabBarController id="Nnt-Mi-Wf8" sceneMemberID="viewController">
|
||||
<tabBar key="tabBar" contentMode="scaleToFill" id="hlX-Lx-tB1">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="49"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<animations/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
</tabBar>
|
||||
<connections>
|
||||
<segue destination="mlz-mZ-4kR" kind="relationship" relationship="viewControllers" id="uTd-4n-koO"/>
|
||||
<segue destination="OOn-QH-lHm" kind="relationship" relationship="viewControllers" id="xes-rT-62n"/>
|
||||
</connections>
|
||||
</tabBarController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="9gk-9q-7Lz" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="-429" y="324"/>
|
||||
</scene>
|
||||
<!--Characters List-->
|
||||
<scene sceneID="aeC-id-DL1">
|
||||
<objects>
|
||||
<tableViewController title="Characters List" id="I87-Zh-w4A" customClass="PersonListViewController" customModule="DipSampleApp" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="95" sectionHeaderHeight="28" sectionFooterHeight="28" id="EYu-RQ-JO9">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<animations/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<prototypes>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="PersonCell" rowHeight="95" id="Sba-Wm-z4c" customClass="PersonCell" customModule="DipSampleApp" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="28" width="600" height="95"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Sba-Wm-z4c" id="UE9-zV-NsG">
|
||||
<rect key="frame" x="0.0" y="0.0" width="567" height="94.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="750" verticalHuggingPriority="251" text="Name:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gVy-Vx-i2h">
|
||||
<rect key="frame" x="8" y="8" width="49" height="19.5"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
|
||||
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="750" verticalHuggingPriority="251" text="Height (cm):" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ymL-8F-Mpa">
|
||||
<rect key="frame" x="8" y="35" width="94" height="19.5"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
|
||||
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="750" verticalHuggingPriority="251" text="Mass (kg):" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9sd-2A-Ixx">
|
||||
<rect key="frame" x="8" y="63" width="79" height="19.5"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
|
||||
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="750" verticalHuggingPriority="251" text="Eyes:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="YPu-dh-Fhf">
|
||||
<rect key="frame" x="378" y="63" width="41" height="19.5"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
|
||||
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="1CQ-rV-Y7c">
|
||||
<rect key="frame" x="539" y="8" width="20" height="20"/>
|
||||
<animations/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="20" id="PK0-f1-YTg"/>
|
||||
<constraint firstAttribute="height" constant="20" id="TOR-23-CAr"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="-name-" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GhU-yA-Nkj">
|
||||
<rect key="frame" x="110" y="7" width="421" height="20.5"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="-height-" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VLd-vh-c8m">
|
||||
<rect key="frame" x="110" y="34" width="260.5" height="20.5"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="-mass-" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="zgG-Ij-dCY">
|
||||
<rect key="frame" x="110" y="62" width="260" height="20.5"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="-hair-" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7TM-Aw-IPT">
|
||||
<rect key="frame" x="427" y="34" width="120" height="20.5"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="-eyes-" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Hv7-qr-iAY">
|
||||
<rect key="frame" x="427" y="62" width="120" height="20.5"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="750" verticalHuggingPriority="251" text="Hair:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="rDV-iQ-Ugd">
|
||||
<rect key="frame" x="378" y="35" width="36.5" height="19.5"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
|
||||
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<animations/>
|
||||
<constraints>
|
||||
<constraint firstItem="Hv7-qr-iAY" firstAttribute="baseline" secondItem="YPu-dh-Fhf" secondAttribute="baseline" id="590-8v-aT3"/>
|
||||
<constraint firstItem="zgG-Ij-dCY" firstAttribute="baseline" secondItem="9sd-2A-Ixx" secondAttribute="baseline" id="62H-PJ-mjV"/>
|
||||
<constraint firstItem="gVy-Vx-i2h" firstAttribute="leading" secondItem="UE9-zV-NsG" secondAttribute="leading" constant="8" id="6PH-YE-0CH"/>
|
||||
<constraint firstAttribute="trailing" secondItem="7TM-Aw-IPT" secondAttribute="trailing" constant="20" symbolic="YES" id="9Wo-lL-3sH"/>
|
||||
<constraint firstItem="VLd-vh-c8m" firstAttribute="leading" secondItem="GhU-yA-Nkj" secondAttribute="leading" id="BdD-7S-2XA"/>
|
||||
<constraint firstItem="7TM-Aw-IPT" firstAttribute="baseline" secondItem="rDV-iQ-Ugd" secondAttribute="baseline" id="DI8-mB-O2Q"/>
|
||||
<constraint firstItem="rDV-iQ-Ugd" firstAttribute="leading" secondItem="UE9-zV-NsG" secondAttribute="trailing" multiplier="2:3" id="FF6-Qm-k9s"/>
|
||||
<constraint firstItem="Hv7-qr-iAY" firstAttribute="leading" secondItem="YPu-dh-Fhf" secondAttribute="trailing" constant="8" symbolic="YES" id="Lfl-NE-XQw"/>
|
||||
<constraint firstItem="GhU-yA-Nkj" firstAttribute="baseline" secondItem="gVy-Vx-i2h" secondAttribute="baseline" id="Ofa-oe-uss"/>
|
||||
<constraint firstItem="ymL-8F-Mpa" firstAttribute="leading" secondItem="gVy-Vx-i2h" secondAttribute="leading" id="PLY-0s-RbV"/>
|
||||
<constraint firstItem="9sd-2A-Ixx" firstAttribute="baseline" secondItem="YPu-dh-Fhf" secondAttribute="baseline" id="T7J-SS-1Xi"/>
|
||||
<constraint firstItem="VLd-vh-c8m" firstAttribute="baseline" secondItem="ymL-8F-Mpa" secondAttribute="baseline" id="Tia-Ni-Vh5"/>
|
||||
<constraint firstItem="9sd-2A-Ixx" firstAttribute="top" secondItem="ymL-8F-Mpa" secondAttribute="bottom" constant="8" symbolic="YES" id="X8o-RN-a1C"/>
|
||||
<constraint firstItem="gVy-Vx-i2h" firstAttribute="top" secondItem="UE9-zV-NsG" secondAttribute="top" constant="8" id="bJk-O2-lbx"/>
|
||||
<constraint firstItem="1CQ-rV-Y7c" firstAttribute="top" secondItem="UE9-zV-NsG" secondAttribute="top" constant="8" id="cYB-OW-rRW"/>
|
||||
<constraint firstItem="7TM-Aw-IPT" firstAttribute="leading" secondItem="Hv7-qr-iAY" secondAttribute="leading" id="cmD-JT-ghd"/>
|
||||
<constraint firstItem="YPu-dh-Fhf" firstAttribute="leading" secondItem="rDV-iQ-Ugd" secondAttribute="leading" id="eKk-NU-W02"/>
|
||||
<constraint firstItem="1CQ-rV-Y7c" firstAttribute="leading" secondItem="GhU-yA-Nkj" secondAttribute="trailing" constant="8" symbolic="YES" id="hTk-Jw-dhO"/>
|
||||
<constraint firstItem="zgG-Ij-dCY" firstAttribute="leading" secondItem="VLd-vh-c8m" secondAttribute="leading" id="hol-S5-LT7"/>
|
||||
<constraint firstItem="9sd-2A-Ixx" firstAttribute="leading" secondItem="gVy-Vx-i2h" secondAttribute="leading" id="jVj-RE-Kv4"/>
|
||||
<constraint firstItem="ymL-8F-Mpa" firstAttribute="top" secondItem="gVy-Vx-i2h" secondAttribute="bottom" constant="8" symbolic="YES" id="jYg-8A-h30"/>
|
||||
<constraint firstItem="YPu-dh-Fhf" firstAttribute="leading" secondItem="zgG-Ij-dCY" secondAttribute="trailing" constant="8" symbolic="YES" id="jgN-Jc-mRd"/>
|
||||
<constraint firstAttribute="trailing" secondItem="1CQ-rV-Y7c" secondAttribute="trailing" constant="8" id="qWa-gr-wSb"/>
|
||||
<constraint firstItem="VLd-vh-c8m" firstAttribute="leading" secondItem="ymL-8F-Mpa" secondAttribute="trailing" constant="8" symbolic="YES" id="qd0-di-L20"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Hv7-qr-iAY" secondAttribute="trailing" constant="20" symbolic="YES" id="rf5-zR-d5A"/>
|
||||
<constraint firstItem="ymL-8F-Mpa" firstAttribute="baseline" secondItem="rDV-iQ-Ugd" secondAttribute="baseline" id="rfc-9C-LV2"/>
|
||||
<constraint firstItem="rDV-iQ-Ugd" firstAttribute="leading" secondItem="VLd-vh-c8m" secondAttribute="trailing" constant="8" symbolic="YES" id="xL3-7N-f8f"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<animations/>
|
||||
<connections>
|
||||
<outlet property="eyesLabel" destination="Hv7-qr-iAY" id="bhd-4V-chX"/>
|
||||
<outlet property="genderImageView" destination="1CQ-rV-Y7c" id="8rr-1s-qr4"/>
|
||||
<outlet property="hairLabel" destination="7TM-Aw-IPT" id="dAf-MI-uUO"/>
|
||||
<outlet property="heightLabel" destination="VLd-vh-c8m" id="kSS-Bb-x2Q"/>
|
||||
<outlet property="massLabel" destination="zgG-Ij-dCY" id="uvZ-9b-t6A"/>
|
||||
<outlet property="nameLabel" destination="GhU-yA-Nkj" id="NhU-k6-3Yf"/>
|
||||
<segue destination="nuL-fZ-hCQ" kind="show" identifier="StarshipsSegue" id="zjp-Bb-fTw"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
</prototypes>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="I87-Zh-w4A" id="PQZ-xC-mLk"/>
|
||||
<outlet property="delegate" destination="I87-Zh-w4A" id="BLg-fj-DdF"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" title="Characters" id="Mue-vf-EYa"/>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="OIv-XM-enw" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1232" y="-39"/>
|
||||
</scene>
|
||||
<!--Starship List-->
|
||||
<scene sceneID="Hu2-NE-Uko">
|
||||
<objects>
|
||||
<tableViewController title="Starship List" id="nuL-fZ-hCQ" customClass="StarshipListViewController" customModule="DipSampleApp" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="102" sectionHeaderHeight="28" sectionFooterHeight="28" id="uPj-BZ-JVx">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<animations/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<prototypes>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="StarshipCell" rowHeight="102" id="rfe-RG-ql1" customClass="StarshipCell" customModule="DipSampleApp" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="28" width="600" height="102"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="rfe-RG-ql1" id="RHz-uO-ANq">
|
||||
<rect key="frame" x="0.0" y="0.0" width="567" height="101.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="750" verticalHuggingPriority="251" text="Name:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pR4-Aq-S9H">
|
||||
<rect key="frame" x="8" y="8" width="49" height="19.5"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
|
||||
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="750" verticalHuggingPriority="251" text="Model:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="V8k-Fh-teX">
|
||||
<rect key="frame" x="8" y="33" width="52" height="19.5"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
|
||||
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="750" verticalHuggingPriority="251" text="Manufacturer:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="iWU-h6-HNF">
|
||||
<rect key="frame" x="8" y="61" width="108" height="19.5"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
|
||||
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="750" verticalHuggingPriority="251" horizontalCompressionResistancePriority="1000" text="Crew:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="JoH-bT-HcN">
|
||||
<rect key="frame" x="460" y="33" width="44.5" height="19.5"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
|
||||
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="750" verticalHuggingPriority="251" horizontalCompressionResistancePriority="1000" text="Pass:" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="arT-4h-pLt">
|
||||
<rect key="frame" x="463" y="61" width="41" height="19.5"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
|
||||
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="-name-" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Lwe-Ix-EQE">
|
||||
<rect key="frame" x="124" y="7" width="423" height="20.5"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="500" text="-model-" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kIz-wz-fGn">
|
||||
<rect key="frame" x="124" y="32" width="328" height="20.5"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="500" text="-manufacturer-" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fVY-W3-78a">
|
||||
<rect key="frame" x="124" y="60" width="331" height="20.5"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="-crew-" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WGV-Ar-PMC">
|
||||
<rect key="frame" x="512" y="32" width="35" height="20.5"/>
|
||||
<animations/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="35" id="tsk-nr-zwr"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="-pass-" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="YnA-qH-8AA">
|
||||
<rect key="frame" x="512" y="60" width="35" height="20.5"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<animations/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="YnA-qH-8AA" secondAttribute="trailing" constant="20" symbolic="YES" id="0iR-Ax-Tba"/>
|
||||
<constraint firstItem="pR4-Aq-S9H" firstAttribute="leading" secondItem="iWU-h6-HNF" secondAttribute="leading" id="1dW-gb-Qyn"/>
|
||||
<constraint firstItem="arT-4h-pLt" firstAttribute="leading" secondItem="fVY-W3-78a" secondAttribute="trailing" constant="8" symbolic="YES" id="47f-0O-zim"/>
|
||||
<constraint firstItem="arT-4h-pLt" firstAttribute="baseline" secondItem="YnA-qH-8AA" secondAttribute="baseline" id="EFd-qL-pg5"/>
|
||||
<constraint firstItem="iWU-h6-HNF" firstAttribute="baseline" secondItem="fVY-W3-78a" secondAttribute="baseline" id="HvJ-2u-LrS"/>
|
||||
<constraint firstItem="YnA-qH-8AA" firstAttribute="leading" secondItem="arT-4h-pLt" secondAttribute="trailing" constant="8" symbolic="YES" id="KYF-WR-rp6"/>
|
||||
<constraint firstItem="pR4-Aq-S9H" firstAttribute="top" secondItem="RHz-uO-ANq" secondAttribute="top" constant="8" id="TiY-OB-yeR"/>
|
||||
<constraint firstItem="fVY-W3-78a" firstAttribute="leading" secondItem="iWU-h6-HNF" secondAttribute="trailing" constant="8" symbolic="YES" id="U0F-Gs-gHJ"/>
|
||||
<constraint firstItem="JoH-bT-HcN" firstAttribute="leading" secondItem="kIz-wz-fGn" secondAttribute="trailing" constant="8" symbolic="YES" id="UZ7-nc-vsM"/>
|
||||
<constraint firstAttribute="trailing" secondItem="WGV-Ar-PMC" secondAttribute="trailing" constant="20" symbolic="YES" id="ZSI-dG-LOG"/>
|
||||
<constraint firstItem="pR4-Aq-S9H" firstAttribute="leading" secondItem="RHz-uO-ANq" secondAttribute="leading" constant="8" id="a1p-vg-3vU"/>
|
||||
<constraint firstItem="V8k-Fh-teX" firstAttribute="baseline" secondItem="JoH-bT-HcN" secondAttribute="baseline" id="b7R-xY-Q2K"/>
|
||||
<constraint firstItem="iWU-h6-HNF" firstAttribute="top" secondItem="V8k-Fh-teX" secondAttribute="bottom" constant="8" symbolic="YES" id="c1W-jc-Ny3"/>
|
||||
<constraint firstItem="V8k-Fh-teX" firstAttribute="baseline" secondItem="kIz-wz-fGn" secondAttribute="baseline" id="c6b-gs-obR"/>
|
||||
<constraint firstItem="WGV-Ar-PMC" firstAttribute="leading" secondItem="JoH-bT-HcN" secondAttribute="trailing" constant="8" symbolic="YES" id="ds0-kr-CtN"/>
|
||||
<constraint firstItem="Lwe-Ix-EQE" firstAttribute="leading" secondItem="kIz-wz-fGn" secondAttribute="leading" id="g1a-qF-dcA"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Lwe-Ix-EQE" secondAttribute="trailing" constant="20" symbolic="YES" id="lp2-Wc-HdY"/>
|
||||
<constraint firstItem="V8k-Fh-teX" firstAttribute="top" secondItem="pR4-Aq-S9H" secondAttribute="bottom" constant="6" id="mdN-0q-C8z"/>
|
||||
<constraint firstItem="kIz-wz-fGn" firstAttribute="leading" secondItem="fVY-W3-78a" secondAttribute="leading" id="qSW-by-cCG"/>
|
||||
<constraint firstItem="pR4-Aq-S9H" firstAttribute="baseline" secondItem="Lwe-Ix-EQE" secondAttribute="baseline" id="qwh-VM-sLX"/>
|
||||
<constraint firstItem="JoH-bT-HcN" firstAttribute="baseline" secondItem="WGV-Ar-PMC" secondAttribute="baseline" id="s6z-70-Htc"/>
|
||||
<constraint firstItem="iWU-h6-HNF" firstAttribute="baseline" secondItem="arT-4h-pLt" secondAttribute="baseline" id="u8F-qk-hFQ"/>
|
||||
<constraint firstItem="pR4-Aq-S9H" firstAttribute="leading" secondItem="V8k-Fh-teX" secondAttribute="leading" id="waE-gT-CGh"/>
|
||||
<constraint firstItem="WGV-Ar-PMC" firstAttribute="leading" secondItem="YnA-qH-8AA" secondAttribute="leading" id="ycM-ic-t05"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<animations/>
|
||||
<connections>
|
||||
<outlet property="crewLabel" destination="WGV-Ar-PMC" id="f6d-9q-59z"/>
|
||||
<outlet property="manufacturerLabel" destination="fVY-W3-78a" id="ABE-NG-bZY"/>
|
||||
<outlet property="modelLabel" destination="kIz-wz-fGn" id="DCN-Xs-efw"/>
|
||||
<outlet property="nameLabel" destination="Lwe-Ix-EQE" id="3Oq-qm-T4Q"/>
|
||||
<outlet property="passengersLabel" destination="YnA-qH-8AA" id="Mns-H6-3Cd"/>
|
||||
<segue destination="I87-Zh-w4A" kind="show" identifier="PilotsSegue" id="Yvy-aQ-caa"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
</prototypes>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="nuL-fZ-hCQ" id="Fzz-8K-PVH"/>
|
||||
<outlet property="delegate" destination="nuL-fZ-hCQ" id="crW-zS-Nsx"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
<navigationItem key="navigationItem" title="Starships" id="krH-S8-MNL"/>
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="2q4-tT-9DC" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1232" y="684"/>
|
||||
</scene>
|
||||
<!--Starships-->
|
||||
<scene sceneID="5hS-an-4XB">
|
||||
<objects>
|
||||
<navigationController title="Starships" id="OOn-QH-lHm" sceneMemberID="viewController">
|
||||
<tabBarItem key="tabBarItem" title="Starships" image="spaceship" id="75v-7I-9RA"/>
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" id="VfI-ho-mqu">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<animations/>
|
||||
</navigationBar>
|
||||
<connections>
|
||||
<segue destination="nuL-fZ-hCQ" kind="relationship" relationship="rootViewController" id="l50-ri-Dfy"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="Z5g-Su-noc" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="345" y="684"/>
|
||||
</scene>
|
||||
<!--Characters-->
|
||||
<scene sceneID="oGL-ha-Mxk">
|
||||
<objects>
|
||||
<navigationController title="Characters" id="mlz-mZ-4kR" sceneMemberID="viewController">
|
||||
<tabBarItem key="tabBarItem" title="Characters" image="person" id="9Al-Aa-Mx2"/>
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" id="YPS-Al-CkA">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<animations/>
|
||||
</navigationBar>
|
||||
<connections>
|
||||
<segue destination="I87-Zh-w4A" kind="relationship" relationship="rootViewController" id="07W-Xm-zjJ"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="A0c-c7-DAG" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="345" y="-39"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="person" width="22" height="22"/>
|
||||
<image name="spaceship" width="22" height="22"/>
|
||||
</resources>
|
||||
<inferredMetricsTieBreakers>
|
||||
<segue reference="zjp-Bb-fTw"/>
|
||||
<segue reference="Yvy-aQ-caa"/>
|
||||
</inferredMetricsTieBreakers>
|
||||
</document>
|
||||
@@ -2,16 +2,23 @@
|
||||
// Person.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 04/10/2015.
|
||||
// Created by Olivier Halligon on 08/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum Gender: String {
|
||||
case Male = "male"
|
||||
case Female = "female"
|
||||
}
|
||||
|
||||
struct Person {
|
||||
var name: String
|
||||
var height: Int
|
||||
var mass: Int
|
||||
var eyesColor: String
|
||||
var hairColor: String
|
||||
var eyeColor: String
|
||||
var gender: Gender?
|
||||
var starshipIDs: [Int]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// Starship.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 08/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct Starship {
|
||||
var name: String
|
||||
var model: String
|
||||
var manufacturer: String
|
||||
var crew: Int
|
||||
var passengers: Int
|
||||
var pilotIDs: [Int]
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// 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]
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// 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]
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// 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]),
|
||||
] + Array(4..<75).map { Starship(name: "Ship #\($0)", model: "AwesomeShip Fighter", manufacturer: "HardCoded Inc.", crew: 1, passengers: 2, pilotIDs: [1]) }
|
||||
|
||||
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])
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// 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<T>() throws -> T {
|
||||
let (data, _) = try self.unwrap()
|
||||
let obj = try NSJSONSerialization.JSONObjectWithData(data, options: [])
|
||||
guard let json = obj as? T else {
|
||||
throw SWAPIError.InvalidJSON
|
||||
}
|
||||
return json
|
||||
}
|
||||
}
|
||||
|
||||
protocol NetworkLayer {
|
||||
func request(path: String, completion: NetworkResponse -> Void)
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
//
|
||||
// PersonProviderAPI.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 10/09/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
protocol PersonProviderAPI {
|
||||
func fetchIDs(completion: [Int] -> Void)
|
||||
func fetch(id: Int, completion: Person? -> Void)
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
//
|
||||
// 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
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// SWAPICommon.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 11/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Dip
|
||||
|
||||
enum SWAPIError: ErrorType {
|
||||
case InvalidJSON
|
||||
}
|
||||
|
||||
enum WebService: String {
|
||||
case PersonWS
|
||||
case StarshipWS
|
||||
var tag: DependencyContainer.Tag { return DependencyContainer.Tag.String(self.rawValue) }
|
||||
}
|
||||
|
||||
func idFromURLString(urlString: String) -> Int? {
|
||||
let url = NSURL(string: urlString)
|
||||
let idString = url.flatMap { $0.lastPathComponent }
|
||||
return idString.flatMap { Int($0) }
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// SWAPIPersonProvider.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 10/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct SWAPIPersonProvider : PersonProviderAPI {
|
||||
let ws = wsDependencies.resolve(WebService.PersonWS.tag) as NetworkLayer
|
||||
|
||||
func fetchIDs(completion: [Int] -> Void) {
|
||||
ws.request("people") { response in
|
||||
do {
|
||||
let dict = try response.json() as NSDictionary
|
||||
guard let results = dict["results"] as? [NSDictionary] else { throw SWAPIError.InvalidJSON }
|
||||
|
||||
// Extract URLs (flatten to ignore invalid ones)
|
||||
let urlStrings = results.flatMap({ $0["url"] as? String })
|
||||
let ids = urlStrings.flatMap(idFromURLString)
|
||||
|
||||
completion(ids)
|
||||
}
|
||||
catch {
|
||||
completion([])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func fetch(id: Int, completion: Person? -> Void) {
|
||||
ws.request("people/\(id)") { response in
|
||||
do {
|
||||
let json = try response.json() as NSDictionary
|
||||
guard
|
||||
let name = json["name"] as? String,
|
||||
let heightStr = json["height"] as? String, height = Int(heightStr),
|
||||
let massStr = json["mass"] as? String, mass = Int(massStr),
|
||||
let hairColor = json["hair_color"] as? String,
|
||||
let eyeColor = json["eye_color"] as? String,
|
||||
let gender = json["gender"] as? String,
|
||||
let starshipURLStrings = json["starships"] as? [String]
|
||||
else {
|
||||
throw SWAPIError.InvalidJSON
|
||||
}
|
||||
|
||||
let person = Person(
|
||||
name: name,
|
||||
height: height,
|
||||
mass: mass,
|
||||
hairColor: hairColor,
|
||||
eyeColor: eyeColor,
|
||||
gender: Gender(rawValue: gender),
|
||||
starshipIDs: starshipURLStrings.flatMap(idFromURLString)
|
||||
)
|
||||
completion(person)
|
||||
}
|
||||
catch {
|
||||
completion(nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// SWAPIStarshipProvider.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 10/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct SWAPIStarshipProvider : StarshipProviderAPI {
|
||||
let ws = wsDependencies.resolve(WebService.StarshipWS.tag) as NetworkLayer
|
||||
|
||||
func fetchIDs(completion: [Int] -> Void) {
|
||||
ws.request("starships") { response in
|
||||
do {
|
||||
let dict = try response.json() as NSDictionary
|
||||
guard let results = dict["results"] as? [NSDictionary] else { throw SWAPIError.InvalidJSON }
|
||||
|
||||
// Extract URLs (flatten to ignore invalid ones)
|
||||
let urlStrings = results.flatMap({ $0["url"] as? String })
|
||||
let ids = urlStrings.flatMap(idFromURLString)
|
||||
|
||||
completion(ids)
|
||||
}
|
||||
catch {
|
||||
completion([])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func fetch(id: Int, completion: Starship? -> Void) {
|
||||
ws.request("starships/\(id)") { response in
|
||||
do {
|
||||
let json = try response.json() as NSDictionary
|
||||
guard
|
||||
let name = json["name"] as? String,
|
||||
let model = json["model"] as? String,
|
||||
let manufacturer = json["manufacturer"] as? String,
|
||||
let crewStr = json["crew"] as? String, crew = Int(crewStr),
|
||||
let passengersStr = json["passengers"] as? String, passengers = Int(passengersStr),
|
||||
let pilotIDStrings = json["pilots"] as? [String]
|
||||
else {
|
||||
throw SWAPIError.InvalidJSON
|
||||
}
|
||||
|
||||
let ship = Starship(
|
||||
name: name,
|
||||
model: model,
|
||||
manufacturer: manufacturer,
|
||||
crew: crew,
|
||||
passengers: passengers,
|
||||
pilotIDs: pilotIDStrings.flatMap(idFromURLString)
|
||||
)
|
||||
completion(ship)
|
||||
}
|
||||
catch {
|
||||
completion(nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
//
|
||||
// StarshipProviderAPI.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 08/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
protocol StarshipProviderAPI {
|
||||
func fetchIDs(completion: [Int] -> Void)
|
||||
func fetch(id: Int, completion: Starship? -> Void)
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// 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,18 +0,0 @@
|
||||
//
|
||||
// EyesHairFormatter.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 04/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class EyesHairFormatter : PersonFormatterAPI {
|
||||
func textForPerson(person: Person) -> String {
|
||||
return person.name
|
||||
}
|
||||
func subtextForPerson(person: Person) -> String {
|
||||
return "\(person.eyesColor) eyes, \(person.hairColor) hair"
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
//
|
||||
// JSONSerializer.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 04/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class JSONSerializer : SerializerAPI {
|
||||
enum Error : ErrorType {
|
||||
case UnexpectedFormat
|
||||
}
|
||||
|
||||
func dictionaryFromData(data: NSData) throws -> [String:AnyObject] {
|
||||
let result = try NSJSONSerialization.JSONObjectWithData(data, options: [])
|
||||
if let json = result as? [String:AnyObject] {
|
||||
return json
|
||||
} else {
|
||||
throw Error.UnexpectedFormat
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
//
|
||||
// MassHeightFormatter.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 04/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class MassHeightFormatter : PersonFormatterAPI {
|
||||
func textForPerson(person: Person) -> String {
|
||||
return person.name
|
||||
}
|
||||
func subtextForPerson(person: Person) -> String {
|
||||
return "\(person.mass)kg, \(person.height)cm"
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
//
|
||||
// NSURLSessionNetworkLayer.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 05/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class NSURLSessionNetworkLayer : NetworkLayer {
|
||||
let session = NSURLSession.sharedSession()
|
||||
|
||||
func fetchURL(url: NSURL, completion: NSData? -> Void) {
|
||||
let task = session.dataTaskWithURL(url) { (data: NSData?, resp: NSURLResponse?, error: NSError?) -> Void in
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
completion(data)
|
||||
}
|
||||
}
|
||||
task.resume()
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
//
|
||||
// SWAPIPersonFactory.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 04/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Dip
|
||||
|
||||
class SWAPIPersonFactory : PersonFactoryAPI {
|
||||
typealias JSONDict = [String:AnyObject]
|
||||
enum Error : ErrorType {
|
||||
case MissingResultsEntry
|
||||
case InvalidPersonSchema
|
||||
}
|
||||
|
||||
let serializer = dip.resolve() as SerializerAPI
|
||||
|
||||
func peopleFromData(personData: NSData) throws -> [Person] {
|
||||
let json = try serializer.dictionaryFromData(personData)
|
||||
if let results = json["results"] as? [JSONDict] {
|
||||
return try results.map { try personFromJSON($0) }
|
||||
} else {
|
||||
throw Error.MissingResultsEntry
|
||||
}
|
||||
}
|
||||
|
||||
func personFromData(personData: NSData) throws -> Person {
|
||||
let json = try serializer.dictionaryFromData(personData)
|
||||
return try personFromJSON(json)
|
||||
}
|
||||
|
||||
private func personFromJSON(json: JSONDict) throws -> Person {
|
||||
guard let name = json["name"] as? String,
|
||||
let heightStr = json["height"] as? String, height = Int(heightStr),
|
||||
let massStr = json["mass"] as? String, mass = Int(massStr),
|
||||
let eyesColor = json["eye_color"] as? String,
|
||||
let hairColor = json["hair_color"] as? String
|
||||
else {
|
||||
throw Error.InvalidPersonSchema
|
||||
}
|
||||
return Person(name: name, height: height, mass: mass, eyesColor: eyesColor, hairColor: hairColor)
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
//
|
||||
// SWAPIWebService.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 04/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Dip
|
||||
|
||||
/// WebService for The StarWars API — see http://swapi.co/documentation
|
||||
class SWAPIWebService : WebServiceAPI {
|
||||
let networkLayer = dip.resolve() as NetworkLayer
|
||||
let personFactory = dip.resolve() as PersonFactoryAPI
|
||||
|
||||
func fetch(completion: [Person]? -> Void) {
|
||||
let url = NSURL(string: "http://swapi.co/api/people/")!
|
||||
networkLayer.fetchURLAndMap(url, completion: completion) { data in
|
||||
return try self.personFactory.peopleFromData(data)
|
||||
}
|
||||
}
|
||||
|
||||
func fetch(id: Int, completion: Person? -> Void) {
|
||||
let url = NSURL(string: "http://swapi.co/api/people/\(id)")!
|
||||
networkLayer.fetchURLAndMap(url, completion: completion) { data in
|
||||
return try self.personFactory.personFromData(data)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
//
|
||||
// NetworkLayer.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 05/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
protocol NetworkLayer {
|
||||
func fetchURL(url: NSURL, completion: NSData? -> Void)
|
||||
func fetchURLAndMap<T>(url: NSURL, completion: T? -> Void, transform: NSData throws -> T)
|
||||
}
|
||||
|
||||
extension NetworkLayer {
|
||||
func fetchURLAndMap<T>(url: NSURL, completion: T? -> Void, transform: NSData throws -> T) {
|
||||
fetchURL(url) { (data: NSData?) -> Void in
|
||||
guard let data = data else {
|
||||
completion(nil)
|
||||
return
|
||||
}
|
||||
let result: T?
|
||||
do {
|
||||
result = try transform(data)
|
||||
} catch {
|
||||
result = nil
|
||||
}
|
||||
completion(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
//
|
||||
// PersonFactoryAPI.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 04/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
protocol PersonFactoryAPI {
|
||||
func peopleFromData(personData: NSData) throws -> [Person]
|
||||
func personFromData(personData: NSData) throws -> Person
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
//
|
||||
// PersonFormatterAPI.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 04/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
protocol PersonFormatterAPI {
|
||||
func textForPerson(person: Person) -> String
|
||||
func subtextForPerson(person: Person) -> String
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
//
|
||||
// SerializerAPI.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 04/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
protocol SerializerAPI {
|
||||
func dictionaryFromData(data: NSData) throws -> [String:AnyObject]
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
//
|
||||
// WebServiceAPI.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 04/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
protocol WebServiceAPI {
|
||||
func fetch(completion: [Person]? -> Void)
|
||||
func fetch(id: Int, completion: Person? -> Void)
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
// Generated using SwiftGen, by O.Halligon — https://github.com/AliSoftware/SwiftGen
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
protocol StoryboardScene : RawRepresentable {
|
||||
static var storyboardName : String { get }
|
||||
static func storyboard() -> UIStoryboard
|
||||
static func initialViewController() -> UIViewController
|
||||
func viewController() -> UIViewController
|
||||
static func viewController(identifier: Self) -> UIViewController
|
||||
}
|
||||
|
||||
extension StoryboardScene where Self.RawValue == String {
|
||||
static func storyboard() -> UIStoryboard {
|
||||
return UIStoryboard(name: self.storyboardName, bundle: nil)
|
||||
}
|
||||
|
||||
static func initialViewController() -> UIViewController {
|
||||
return storyboard().instantiateInitialViewController()!
|
||||
}
|
||||
|
||||
func viewController() -> UIViewController {
|
||||
return Self.storyboard().instantiateViewControllerWithIdentifier(self.rawValue)
|
||||
}
|
||||
static func viewController(identifier: Self) -> UIViewController {
|
||||
return identifier.viewController()
|
||||
}
|
||||
}
|
||||
|
||||
extension UIStoryboard {
|
||||
struct Scene {
|
||||
enum Main {
|
||||
static let storyboardName = "Main"
|
||||
}
|
||||
enum LaunchScreen {
|
||||
static let storyboardName = "LaunchScreen"
|
||||
}
|
||||
}
|
||||
|
||||
struct Segue {
|
||||
enum Main : String {
|
||||
case StarshipsSegue = "StarshipsSegue"
|
||||
case PilotsSegue = "PilotsSegue"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
//
|
||||
// Tags.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 05/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum PersonFormatterTag {
|
||||
case MassHeight
|
||||
case EyesHair
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
//
|
||||
// ViewController.swift
|
||||
// DipSampleApp
|
||||
//
|
||||
// Created by Olivier Halligon on 04/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Dip
|
||||
|
||||
let kCellIdentifier = "Cell"
|
||||
|
||||
class ViewController: UIViewController {
|
||||
let ws = dip.resolve() as WebServiceAPI
|
||||
|
||||
var personList = [Person]()
|
||||
|
||||
@IBOutlet weak var activityIndicator: UIActivityIndicatorView!
|
||||
@IBOutlet weak var tableView: UITableView!
|
||||
@IBOutlet weak var displayModeSelector: UISegmentedControl!
|
||||
|
||||
@IBAction func fetchPeople(sender: UIButton) {
|
||||
sender.enabled = false
|
||||
self.activityIndicator.startAnimating()
|
||||
ws.fetch { persons in
|
||||
self.activityIndicator.stopAnimating()
|
||||
sender.enabled = true
|
||||
self.personList = persons ?? []
|
||||
self.tableView.reloadData()
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func displayModeChanged(sender: UISegmentedControl) {
|
||||
self.tableView.reloadData()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extension ViewController : UITableViewDataSource {
|
||||
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return self.personList.count
|
||||
}
|
||||
|
||||
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
|
||||
let cell = tableView.dequeueReusableCellWithIdentifier(kCellIdentifier, forIndexPath: indexPath)
|
||||
|
||||
let person = personList[indexPath.row]
|
||||
let formatter = dip.resolve(formatterTag) as PersonFormatterAPI
|
||||
cell.textLabel?.text = formatter.textForPerson(person)
|
||||
cell.detailTextLabel?.text = formatter.subtextForPerson(person)
|
||||
|
||||
return cell
|
||||
}
|
||||
|
||||
var formatterTag: PersonFormatterTag {
|
||||
switch displayModeSelector.selectedSegmentIndex {
|
||||
case 0:
|
||||
return .MassHeight
|
||||
default:
|
||||
return .EyesHair
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
//
|
||||
// FetchableTrait.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 09/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
protocol FetchableTrait: class {
|
||||
typealias ObjectType
|
||||
var objects: [ObjectType]? { get set }
|
||||
var batchRequestID: Int { get set }
|
||||
var tableView: UITableView! { get }
|
||||
|
||||
func fetchIDs(completion: [Int] -> Void)
|
||||
func fetchOne(id: Int, completion: ObjectType? -> Void)
|
||||
var fetchProgress: (current: Int, total: Int?) { get set }
|
||||
}
|
||||
|
||||
extension FetchableTrait {
|
||||
func loadObjects(objectIDs: [Int]) {
|
||||
self.batchRequestID += 1
|
||||
let batch = self.batchRequestID
|
||||
|
||||
objects?.removeAll()
|
||||
fetchProgress = (0,objectIDs.count)
|
||||
for objectID in objectIDs {
|
||||
fetchOne(objectID) { (object: ObjectType?) in
|
||||
// Exit if we failed to retrive an object for this ID, or if the request
|
||||
// should be ignored because a new batch request has been started since
|
||||
guard let object = object where batch == self.batchRequestID else { return }
|
||||
|
||||
if self.objects == nil { self.objects = [] }
|
||||
self.objects?.append(object)
|
||||
self.fetchProgress.current = self.objects?.count ?? 0
|
||||
self.tableView?.reloadData()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func loadFirstPage() {
|
||||
self.batchRequestID += 1
|
||||
let batch = self.batchRequestID
|
||||
fetchProgress = (0, nil)
|
||||
fetchIDs() { objectIDs in
|
||||
guard batch == self.batchRequestID else { return }
|
||||
self.loadObjects(objectIDs)
|
||||
}
|
||||
}
|
||||
|
||||
func displayProgressInNavBar(navigationItem: UINavigationItem) {
|
||||
let text: String
|
||||
if let total = fetchProgress.total {
|
||||
if fetchProgress.current == fetchProgress.total {
|
||||
text = "Done."
|
||||
} else {
|
||||
text = "Loading \(fetchProgress.current) / \(total)…"
|
||||
}
|
||||
} else {
|
||||
text = "Loading IDs…"
|
||||
}
|
||||
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
|
||||
label.text = text
|
||||
label.textColor = .grayColor()
|
||||
label.font = .systemFontOfSize(12)
|
||||
label.sizeToFit()
|
||||
navigationItem.rightBarButtonItem = UIBarButtonItem(customView: label)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
//
|
||||
// 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
|
||||
|
||||
func fetchIDs(completion: [Int] -> Void) {
|
||||
let provider = providerDependencies.resolve() as PersonProviderAPI
|
||||
return provider.fetchIDs(completion)
|
||||
}
|
||||
func fetchOne(personID: Int, completion: Person? -> Void) {
|
||||
let provider = providerDependencies.resolve(.Int(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.loadObjects(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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
//
|
||||
// StarshipListViewController.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 09/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Dip
|
||||
|
||||
class StarshipListViewController : UITableViewController, FetchableTrait {
|
||||
var objects: [Starship]?
|
||||
var batchRequestID = 0
|
||||
|
||||
private func provider(tag:Int?) -> StarshipProviderAPI {
|
||||
return providerDependencies.resolve(tag.flatMap { .Int($0) })
|
||||
}
|
||||
|
||||
func fetchIDs(completion: [Int] -> Void) {
|
||||
provider(nil).fetchIDs(completion)
|
||||
}
|
||||
func fetchOne(shipID:Int, completion: Starship? -> Void) {
|
||||
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.loadObjects(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
|
||||
}
|
||||
}
|
||||
@@ -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">
|
||||
<array>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Main Pilot</string>
|
||||
<key>height</key>
|
||||
<integer>175</integer>
|
||||
<key>mass</key>
|
||||
<integer>67</integer>
|
||||
<key>hairColor</key>
|
||||
<string>Dark</string>
|
||||
<key>eyeColor</key>
|
||||
<string>Brown</string>
|
||||
<key>gender</key>
|
||||
<string>male</string>
|
||||
<key>starships</key>
|
||||
<array>
|
||||
<integer>0</integer>
|
||||
<integer>1</integer>
|
||||
<integer>3</integer>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</plist>
|
||||
@@ -1,5 +1,5 @@
|
||||
PODS:
|
||||
- Dip (0.1.0)
|
||||
- Dip (2.0.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
- Dip (from `../`)
|
||||
@@ -9,6 +9,6 @@ EXTERNAL SOURCES:
|
||||
:path: ../
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Dip: c6d545af478b84d3708bf02d986fe687cb3322cc
|
||||
Dip: ae784a32e584d5c57809b2cdc4fd2f287d075f7a
|
||||
|
||||
COCOAPODS: 0.38.2
|
||||
COCOAPODS: 0.39.0
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"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.",
|
||||
"version": "2.0.0",
|
||||
"summary": "A simple Dependency Resolver: Dependency Injection using Protocol resolution.",
|
||||
"description": "Dip is a Swift framework to manage your Dependencies between your classes\nin your app using Dependency Injection.\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.",
|
||||
"homepage": "https://github.com/AliSoftware/Dip",
|
||||
"license": "MIT",
|
||||
"authors": {
|
||||
@@ -10,7 +10,7 @@
|
||||
},
|
||||
"source": {
|
||||
"git": "https://github.com/AliSoftware/Dip.git",
|
||||
"tag": "0.1.0"
|
||||
"tag": "2.0.0"
|
||||
},
|
||||
"social_media_url": "https://twitter.com/aligatr",
|
||||
"platforms": {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
PODS:
|
||||
- Dip (0.1.0)
|
||||
- Dip (2.0.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
- Dip (from `../`)
|
||||
@@ -9,6 +9,6 @@ EXTERNAL SOURCES:
|
||||
:path: ../
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Dip: c6d545af478b84d3708bf02d986fe687cb3322cc
|
||||
Dip: ae784a32e584d5c57809b2cdc4fd2f287d075f7a
|
||||
|
||||
COCOAPODS: 0.38.2
|
||||
COCOAPODS: 0.39.0
|
||||
|
||||
@@ -7,93 +7,92 @@
|
||||
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 */; };
|
||||
233F81BF5C5FCE081EE3E4963D0B28CD /* Pods-DipSampleApp-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6DC6F865EBD27FE4416E8655E73F7426 /* Pods-DipSampleApp-dummy.m */; };
|
||||
3E5EF2244E6759BDB00BF6F862FFAD43 /* Dip-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 98D1A0DC92D3A4A2B32D1B6094DECDA3 /* Dip-dummy.m */; };
|
||||
598949CC3DD0DD2142DFA9759D331DB6 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E4E89230EF59BC255123B67864ACF77 /* Foundation.framework */; };
|
||||
73DFA9D2D6721ED2BF48E815083FC935 /* Dip.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1855646D8AC0B232E538D845A7894FF /* Dip.swift */; };
|
||||
774AC175C524A1E16D01BB9CF19651ED /* Pods-DipTests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 08FDAF80E63D5379C5D67B2C5D37CB44 /* Pods-DipTests-dummy.m */; };
|
||||
8FB62E6448665FAB1B4B40278A9C18B3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E4E89230EF59BC255123B67864ACF77 /* Foundation.framework */; };
|
||||
92915F15583230B1CF7E9FAB6FFD5817 /* Dip-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 9F68496928C5CF49172AFF11B37314C7 /* Dip-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
CE06FE77C65C0BE8BDD6AFB33EAD328F /* Pods-DipSampleApp-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = ACEDE7C6DC726F30DC3F36A7ECD7A8C2 /* Pods-DipSampleApp-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
DF187AAE55CEA68761E21B080E2C2CF2 /* Pods-DipTests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 88B21BAF0A10E4BCDFF1F69039F04287 /* Pods-DipTests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
F8D681A620B7540C44E9B51BD381C514 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E4E89230EF59BC255123B67864ACF77 /* Foundation.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
717E8357C15C9EC952989F1892DAADD9 /* PBXContainerItemProxy */ = {
|
||||
62848E69B71441AB05941E7E2F09E1D8 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 61B2C099D2823B76EB65B5ECC8B08934;
|
||||
remoteGlobalIDString = 28230D259635091F92F106AA282AA138;
|
||||
remoteInfo = Dip;
|
||||
};
|
||||
E1543D580D5FE849EA4540C35848C670 /* PBXContainerItemProxy */ = {
|
||||
F9BC91C90262AF7A128076332A48985F /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 61B2C099D2823B76EB65B5ECC8B08934;
|
||||
remoteGlobalIDString = 28230D259635091F92F106AA282AA138;
|
||||
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>"; };
|
||||
08FDAF80E63D5379C5D67B2C5D37CB44 /* Pods-DipTests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-DipTests-dummy.m"; 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>"; };
|
||||
2F6C88DA4612709E46E6E64B8DE3DF7B /* Pods-DipTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-DipTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
3BFEC463C4346DFBB40CFD331E7B8C8C /* Pods-DipSampleApp-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-DipSampleApp-acknowledgements.plist"; sourceTree = "<group>"; };
|
||||
3E4E89230EF59BC255123B67864ACF77 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
|
||||
4AC7412F56C556428F0902BDB2B9CC74 /* Pods-DipSampleApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-DipSampleApp.debug.xcconfig"; 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>"; };
|
||||
551D96FB45D8D47702C68C545344BB55 /* Dip-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Dip-prefix.pch"; sourceTree = "<group>"; };
|
||||
6418C112ABDD19D3EF1DD98DB3019F05 /* Pods_DipTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_DipTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
6DC6F865EBD27FE4416E8655E73F7426 /* Pods-DipSampleApp-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-DipSampleApp-dummy.m"; sourceTree = "<group>"; };
|
||||
88B21BAF0A10E4BCDFF1F69039F04287 /* Pods-DipTests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-DipTests-umbrella.h"; sourceTree = "<group>"; };
|
||||
8A5334FC48EF0DBABDE182FB6C1E6C3D /* Pods_DipSampleApp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_DipSampleApp.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
98D1A0DC92D3A4A2B32D1B6094DECDA3 /* Dip-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Dip-dummy.m"; sourceTree = "<group>"; };
|
||||
9F68496928C5CF49172AFF11B37314C7 /* Dip-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Dip-umbrella.h"; sourceTree = "<group>"; };
|
||||
A37235974396D8B3A4A2163B9FAF0328 /* Pods-DipSampleApp-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-DipSampleApp-resources.sh"; sourceTree = "<group>"; };
|
||||
ACEDE7C6DC726F30DC3F36A7ECD7A8C2 /* Pods-DipSampleApp-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-DipSampleApp-umbrella.h"; 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; };
|
||||
BDD421F6E0B38080BCB472073DA141EF /* Dip.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = Dip.modulemap; sourceTree = "<group>"; };
|
||||
C9D3BEDF370AEED8CE8D3838C4F8BCB1 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
D1855646D8AC0B232E538D845A7894FF /* Dip.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = Dip.swift; sourceTree = "<group>"; };
|
||||
D431A88F8543B8C4079050ACDD792D51 /* Dip.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Dip.xcconfig; sourceTree = "<group>"; };
|
||||
D70F3F84928AF07F304E2A78BED54F5E /* Pods-DipTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-DipTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
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>"; };
|
||||
E1A14DC75595E6F6652CBCCE34EF2BC2 /* Dip.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Dip.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
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>"; };
|
||||
FCA73F622E211B8366C7D190CE804EA5 /* Pods-DipSampleApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-DipSampleApp.release.xcconfig"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
139BA28D38AF67B41F2223A714A1DE43 /* Frameworks */ = {
|
||||
7054D0CB6C690B6BE41E609084CA0958 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
A56D11EEC8601D29B20437637A398FBE /* Foundation.framework in Frameworks */,
|
||||
8FB62E6448665FAB1B4B40278A9C18B3 /* Foundation.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
7A84D2955EF7C71F5E6AF48E447815A1 /* Frameworks */ = {
|
||||
9E15208AD5F4351018028853ABA69EB9 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
4281B9E4626ED37910E70A6053051095 /* Foundation.framework in Frameworks */,
|
||||
F8D681A620B7540C44E9B51BD381C514 /* Foundation.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
FC3CB05065376B8016B026FD865ABAC0 /* Frameworks */ = {
|
||||
ED999B179D5C9983F80D581113B9D018 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F8BB3BC94ED3830270E0447B6BA4D12D /* Foundation.framework in Frameworks */,
|
||||
598949CC3DD0DD2142DFA9759D331DB6 /* Foundation.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -107,53 +106,44 @@
|
||||
DDDDDD06DF5540C55DA4B0C74E1EC511 /* Pods-DipTests.modulemap */,
|
||||
DD7CF98DF0A99296E41AF2D9C3B473F9 /* Pods-DipTests-acknowledgements.markdown */,
|
||||
4D03528B91AE7D78A28CE55BADFA6159 /* Pods-DipTests-acknowledgements.plist */,
|
||||
B538A5AA13D8CC5A2FB02B8C7E82ACB7 /* Pods-DipTests-dummy.m */,
|
||||
08FDAF80E63D5379C5D67B2C5D37CB44 /* 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 */,
|
||||
88B21BAF0A10E4BCDFF1F69039F04287 /* Pods-DipTests-umbrella.h */,
|
||||
2F6C88DA4612709E46E6E64B8DE3DF7B /* Pods-DipTests.debug.xcconfig */,
|
||||
D70F3F84928AF07F304E2A78BED54F5E /* Pods-DipTests.release.xcconfig */,
|
||||
);
|
||||
name = "Pods-DipTests";
|
||||
path = "Target Support Files/Pods-DipTests";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
331BF982C22B5DA66B25F742D01C5F7D /* Dip */ = {
|
||||
3A648B4C2102C68BD49258688BF389CC /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FAEF7893A179133A40296BA56F7E8846 /* Sources */,
|
||||
7BF12AE4821DF0409A5DD1E494A23CB0 /* Support Files */,
|
||||
E1A14DC75595E6F6652CBCCE34EF2BC2 /* Dip.framework */,
|
||||
8A5334FC48EF0DBABDE182FB6C1E6C3D /* Pods_DipSampleApp.framework */,
|
||||
6418C112ABDD19D3EF1DD98DB3019F05 /* Pods_DipTests.framework */,
|
||||
);
|
||||
name = Dip;
|
||||
path = ../..;
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
46E7572EB1611944AB13E50F656187E9 /* Development Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
331BF982C22B5DA66B25F742D01C5F7D /* Dip */,
|
||||
C40734A4DEEFC0C72EE1D1BCF19DD769 /* Dip */,
|
||||
);
|
||||
name = "Development Pods";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
53F661C0CA7190D2CF05023FB33D61E4 /* iOS */ = {
|
||||
480A2A3476910EE7306AD0610F482D25 /* Support Files */ = {
|
||||
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 */,
|
||||
BDD421F6E0B38080BCB472073DA141EF /* Dip.modulemap */,
|
||||
D431A88F8543B8C4079050ACDD792D51 /* Dip.xcconfig */,
|
||||
98D1A0DC92D3A4A2B32D1B6094DECDA3 /* Dip-dummy.m */,
|
||||
551D96FB45D8D47702C68C545344BB55 /* Dip-prefix.pch */,
|
||||
9F68496928C5CF49172AFF11B37314C7 /* Dip-umbrella.h */,
|
||||
C9D3BEDF370AEED8CE8D3838C4F8BCB1 /* Info.plist */,
|
||||
);
|
||||
name = "Support Files";
|
||||
path = "Example/Pods/Target Support Files/Dip";
|
||||
@@ -165,7 +155,7 @@
|
||||
BA6428E9F66FD5A23C0A2E06ED26CD2F /* Podfile */,
|
||||
46E7572EB1611944AB13E50F656187E9 /* Development Pods */,
|
||||
BC3CA7F9E30CC8F7E2DD044DD34432FC /* Frameworks */,
|
||||
CCA510CFBEA2D207524CDA0D73C3B561 /* Products */,
|
||||
3A648B4C2102C68BD49258688BF389CC /* Products */,
|
||||
A9D31FC7B7A14D2E4651A6C66A1A86EC /* Targets Support Files */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
@@ -182,19 +172,35 @@
|
||||
BC3CA7F9E30CC8F7E2DD044DD34432FC /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
53F661C0CA7190D2CF05023FB33D61E4 /* iOS */,
|
||||
BF6342C8B29F4CEEA088EFF7AB4DE362 /* iOS */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
CCA510CFBEA2D207524CDA0D73C3B561 /* Products */ = {
|
||||
BF6342C8B29F4CEEA088EFF7AB4DE362 /* iOS */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D5CB81F4D94CD0DC953C46A26FA193D9 /* Dip.framework */,
|
||||
65517CECF14CA488E474611D4E6C8A28 /* Pods_DipSampleApp.framework */,
|
||||
649D66F1DA814B5F17F49CA0D5948332 /* Pods_DipTests.framework */,
|
||||
3E4E89230EF59BC255123B67864ACF77 /* Foundation.framework */,
|
||||
);
|
||||
name = Products;
|
||||
name = iOS;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C40734A4DEEFC0C72EE1D1BCF19DD769 /* Dip */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CF3CAD3FD76F762243056FAE7CFCDD9D /* Sources */,
|
||||
480A2A3476910EE7306AD0610F482D25 /* Support Files */,
|
||||
);
|
||||
name = Dip;
|
||||
path = ../..;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
CF3CAD3FD76F762243056FAE7CFCDD9D /* Sources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D1855646D8AC0B232E538D845A7894FF /* Dip.swift */,
|
||||
);
|
||||
path = Sources;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E6EDC7112547C1E567413310A74E6AB2 /* Pods-DipSampleApp */ = {
|
||||
@@ -204,80 +210,54 @@
|
||||
040E6767354650F6353098E4EB50B3F7 /* Pods-DipSampleApp.modulemap */,
|
||||
F5067212B9AFB98F7CCBC7151A60A220 /* Pods-DipSampleApp-acknowledgements.markdown */,
|
||||
3BFEC463C4346DFBB40CFD331E7B8C8C /* Pods-DipSampleApp-acknowledgements.plist */,
|
||||
75D51085C4F230C1CC04D5C97D5CD181 /* Pods-DipSampleApp-dummy.m */,
|
||||
6DC6F865EBD27FE4416E8655E73F7426 /* 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 */,
|
||||
ACEDE7C6DC726F30DC3F36A7ECD7A8C2 /* Pods-DipSampleApp-umbrella.h */,
|
||||
4AC7412F56C556428F0902BDB2B9CC74 /* Pods-DipSampleApp.debug.xcconfig */,
|
||||
FCA73F622E211B8366C7D190CE804EA5 /* 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 */ = {
|
||||
91E0558A996F1C7D67CEF7650719B736 /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
CBC622391FBCC36E48C7E3D295582D5A /* Dip-umbrella.h in Headers */,
|
||||
92915F15583230B1CF7E9FAB6FFD5817 /* Dip-umbrella.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
757551662869B25EE206B19D53CC8F29 /* Headers */ = {
|
||||
BBAC4F3AB5D36D3D0D5D75D8B850C13E /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
760ED030B3F9BF2B88E1F61BB696AF52 /* Pods-DipTests-umbrella.h in Headers */,
|
||||
CE06FE77C65C0BE8BDD6AFB33EAD328F /* Pods-DipSampleApp-umbrella.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
8F49CC8E1874111D7EF4D173435D7A24 /* Headers */ = {
|
||||
DD721702CA080CE29A0491036618E6FD /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F71A77F6FC1D19954985C78BC04FFBCE /* Pods-DipSampleApp-umbrella.h in Headers */,
|
||||
DF187AAE55CEA68761E21B080E2C2CF2 /* Pods-DipTests-umbrella.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
12D3E41651D0F284852A4D526F3256AB /* Pods-DipTests */ = {
|
||||
28230D259635091F92F106AA282AA138 /* Dip */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = D7E091A3E6CE5EC7EA78C29D8A21CA70 /* Build configuration list for PBXNativeTarget "Pods-DipTests" */;
|
||||
buildConfigurationList = 31CFDCC9535978BB70FDA95D6D357629 /* Build configuration list for PBXNativeTarget "Dip" */;
|
||||
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 */,
|
||||
6A1130E1D8B20BCD2F3070FD7541D03E /* Sources */,
|
||||
9E15208AD5F4351018028853ABA69EB9 /* Frameworks */,
|
||||
91E0558A996F1C7D67CEF7650719B736 /* Headers */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@@ -285,25 +265,43 @@
|
||||
);
|
||||
name = Dip;
|
||||
productName = Dip;
|
||||
productReference = D5CB81F4D94CD0DC953C46A26FA193D9 /* Dip.framework */;
|
||||
productReference = E1A14DC75595E6F6652CBCCE34EF2BC2 /* Dip.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
F588C5114410BDD4CA3AF7BF16AF6FC8 /* Pods-DipSampleApp */ = {
|
||||
3A53F07A7DBB3101BFCAD512E679F62C /* Pods-DipSampleApp */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 9ECD5CC6E806AF1E5D7F66D29B6DDADD /* Build configuration list for PBXNativeTarget "Pods-DipSampleApp" */;
|
||||
buildConfigurationList = B70E7A5902F5B0D610680BC908B731F3 /* Build configuration list for PBXNativeTarget "Pods-DipSampleApp" */;
|
||||
buildPhases = (
|
||||
811AA0482F2A12B79AFCB6A2C9AFA4A1 /* Sources */,
|
||||
FC3CB05065376B8016B026FD865ABAC0 /* Frameworks */,
|
||||
8F49CC8E1874111D7EF4D173435D7A24 /* Headers */,
|
||||
A943C34198589805B647072D0565220C /* Sources */,
|
||||
ED999B179D5C9983F80D581113B9D018 /* Frameworks */,
|
||||
BBAC4F3AB5D36D3D0D5D75D8B850C13E /* Headers */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
E87C16215529DC10230F8D3773193425 /* PBXTargetDependency */,
|
||||
394A3171C70875A58CBC5E1A1DC019D7 /* PBXTargetDependency */,
|
||||
);
|
||||
name = "Pods-DipSampleApp";
|
||||
productName = "Pods-DipSampleApp";
|
||||
productReference = 65517CECF14CA488E474611D4E6C8A28 /* Pods_DipSampleApp.framework */;
|
||||
productReference = 8A5334FC48EF0DBABDE182FB6C1E6C3D /* Pods_DipSampleApp.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
A282C21E8EC965D4836B3AECBB21F499 /* Pods-DipTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 35DD63728C36940D0AE695EF42CC6F57 /* Build configuration list for PBXNativeTarget "Pods-DipTests" */;
|
||||
buildPhases = (
|
||||
62BE8684290E236F96D180ADDAB07160 /* Sources */,
|
||||
7054D0CB6C690B6BE41E609084CA0958 /* Frameworks */,
|
||||
DD721702CA080CE29A0491036618E6FD /* Headers */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
5541F443020F2B10F9A04FE23958A4C6 /* PBXTargetDependency */,
|
||||
);
|
||||
name = "Pods-DipTests";
|
||||
productName = "Pods-DipTests";
|
||||
productReference = 6418C112ABDD19D3EF1DD98DB3019F05 /* Pods_DipTests.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
@@ -323,122 +321,64 @@
|
||||
en,
|
||||
);
|
||||
mainGroup = 7DB346D0F39D3F0E887471402A8071AB;
|
||||
productRefGroup = CCA510CFBEA2D207524CDA0D73C3B561 /* Products */;
|
||||
productRefGroup = 3A648B4C2102C68BD49258688BF389CC /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
61B2C099D2823B76EB65B5ECC8B08934 /* Dip */,
|
||||
F588C5114410BDD4CA3AF7BF16AF6FC8 /* Pods-DipSampleApp */,
|
||||
12D3E41651D0F284852A4D526F3256AB /* Pods-DipTests */,
|
||||
28230D259635091F92F106AA282AA138 /* Dip */,
|
||||
3A53F07A7DBB3101BFCAD512E679F62C /* Pods-DipSampleApp */,
|
||||
A282C21E8EC965D4836B3AECBB21F499 /* Pods-DipTests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
27301CA68EAB0531B3E302342BE6B391 /* Sources */ = {
|
||||
62BE8684290E236F96D180ADDAB07160 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
848961CC560A7BF0C4CCEC7F49AD9D93 /* Dip-dummy.m in Sources */,
|
||||
B7AF29D7DFAADCE1D059AB81388DC3A9 /* Dip.swift in Sources */,
|
||||
774AC175C524A1E16D01BB9CF19651ED /* Pods-DipTests-dummy.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
811AA0482F2A12B79AFCB6A2C9AFA4A1 /* Sources */ = {
|
||||
6A1130E1D8B20BCD2F3070FD7541D03E /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B43CB9F263659669B07655407B2663BD /* Pods-DipSampleApp-dummy.m in Sources */,
|
||||
3E5EF2244E6759BDB00BF6F862FFAD43 /* Dip-dummy.m in Sources */,
|
||||
73DFA9D2D6721ED2BF48E815083FC935 /* Dip.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
AAA3A1408B53FD669A84EBE81D8355D0 /* Sources */ = {
|
||||
A943C34198589805B647072D0565220C /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B89AA8E9CD649EA8710AC177891DADF5 /* Pods-DipTests-dummy.m in Sources */,
|
||||
233F81BF5C5FCE081EE3E4963D0B28CD /* Pods-DipSampleApp-dummy.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
59D193CC66DB380EE84635F4E2991CAF /* PBXTargetDependency */ = {
|
||||
394A3171C70875A58CBC5E1A1DC019D7 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
name = Dip;
|
||||
target = 61B2C099D2823B76EB65B5ECC8B08934 /* Dip */;
|
||||
targetProxy = 717E8357C15C9EC952989F1892DAADD9 /* PBXContainerItemProxy */;
|
||||
target = 28230D259635091F92F106AA282AA138 /* Dip */;
|
||||
targetProxy = 62848E69B71441AB05941E7E2F09E1D8 /* PBXContainerItemProxy */;
|
||||
};
|
||||
E87C16215529DC10230F8D3773193425 /* PBXTargetDependency */ = {
|
||||
5541F443020F2B10F9A04FE23958A4C6 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
name = Dip;
|
||||
target = 61B2C099D2823B76EB65B5ECC8B08934 /* Dip */;
|
||||
targetProxy = E1543D580D5FE849EA4540C35848C670 /* PBXContainerItemProxy */;
|
||||
target = 28230D259635091F92F106AA282AA138 /* Dip */;
|
||||
targetProxy = F9BC91C90262AF7A128076332A48985F /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
179C38BF617A5FDB3138E3FBBCFBCF96 /* Debug */ = {
|
||||
1473D344CDCA306DE692B6341E997B38 /* 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 */;
|
||||
baseConfigurationReference = 2F6C88DA4612709E46E6E64B8DE3DF7B /* Pods-DipTests.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
@@ -451,23 +391,25 @@
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MACH_O_TYPE = staticlib;
|
||||
MODULEMAP_FILE = "Target Support Files/Pods-DipTests/Pods-DipTests.modulemap";
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
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 = Release;
|
||||
name = Debug;
|
||||
};
|
||||
956BB501D5CF8EBD179183A55861D46E /* Release */ = {
|
||||
6A72424D270F509461FC20CD059294D4 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 6571AF80F9340C8BBB03E41828B56DAE /* Pods-DipSampleApp.release.xcconfig */;
|
||||
baseConfigurationReference = D431A88F8543B8C4079050ACDD792D51 /* Dip.xcconfig */;
|
||||
buildSettings = {
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
@@ -476,35 +418,6 @@
|
||||
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";
|
||||
@@ -521,6 +434,37 @@
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
78F0B5FBEADFB5A705557C10BE04C413 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 4AC7412F56C556428F0902BDB2B9CC74 /* 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";
|
||||
MACH_O_TYPE = staticlib;
|
||||
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;
|
||||
};
|
||||
A70CDAD61F90AC503C7D04CC22DA2923 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
@@ -560,9 +504,67 @@
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
A72E6B5B0A3D3E28381E5C0A7A93C0A5 /* Debug */ = {
|
||||
B974ED11B24EB1E4C3321062F24469F4 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = CFFD5CBC2BC2688B5A6735AF757D7A13 /* Pods-DipTests.debug.xcconfig */;
|
||||
baseConfigurationReference = D431A88F8543B8C4079050ACDD792D51 /* Dip.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;
|
||||
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;
|
||||
};
|
||||
CBDDB14779D5F8C01DB8F4A9A013509C /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = FCA73F622E211B8366C7D190CE804EA5 /* 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";
|
||||
MACH_O_TYPE = staticlib;
|
||||
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;
|
||||
};
|
||||
F1BFBC0693AAA13A7013B018CED4126C /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = D70F3F84928AF07F304E2A78BED54F5E /* Pods-DipTests.release.xcconfig */;
|
||||
buildSettings = {
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
@@ -575,20 +577,20 @@
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MACH_O_TYPE = staticlib;
|
||||
MODULEMAP_FILE = "Target Support Files/Pods-DipTests/Pods-DipTests.modulemap";
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
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;
|
||||
name = Release;
|
||||
};
|
||||
FB45FFD90572718D82AB9092B750F0CA /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
@@ -636,29 +638,29 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
9ECD5CC6E806AF1E5D7F66D29B6DDADD /* Build configuration list for PBXNativeTarget "Pods-DipSampleApp" */ = {
|
||||
31CFDCC9535978BB70FDA95D6D357629 /* Build configuration list for PBXNativeTarget "Dip" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
1858E18D65A8B61BEAE72BD61ED409B9 /* Debug */,
|
||||
956BB501D5CF8EBD179183A55861D46E /* Release */,
|
||||
B974ED11B24EB1E4C3321062F24469F4 /* Debug */,
|
||||
6A72424D270F509461FC20CD059294D4 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
CA02FBD0A4DFAC6631999B9E5DEAA891 /* Build configuration list for PBXNativeTarget "Dip" */ = {
|
||||
35DD63728C36940D0AE695EF42CC6F57 /* Build configuration list for PBXNativeTarget "Pods-DipTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
179C38BF617A5FDB3138E3FBBCFBCF96 /* Debug */,
|
||||
9867AC43F4246CE452AFD55B859928CC /* Release */,
|
||||
1473D344CDCA306DE692B6341E997B38 /* Debug */,
|
||||
F1BFBC0693AAA13A7013B018CED4126C /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
D7E091A3E6CE5EC7EA78C29D8A21CA70 /* Build configuration list for PBXNativeTarget "Pods-DipTests" */ = {
|
||||
B70E7A5902F5B0D610680BC908B731F3 /* Build configuration list for PBXNativeTarget "Pods-DipSampleApp" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
A72E6B5B0A3D3E28381E5C0A7A93C0A5 /* Debug */,
|
||||
530E51D69A65177A0CB8BA9337627948 /* Release */,
|
||||
78F0B5FBEADFB5A705557C10BE04C413 /* Debug */,
|
||||
CBDDB14779D5F8C01DB8F4A9A013509C /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -7,33 +7,30 @@
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForAnalyzing = "YES"
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
buildForArchiving = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "61B2C099D2823B76EB65B5ECC8B08934"
|
||||
BuildableName = "Dip.framework"
|
||||
BlueprintName = "Dip"
|
||||
ReferencedContainer = "container:Pods.xcodeproj">
|
||||
BuildableIdentifier = 'primary'
|
||||
BlueprintIdentifier = '0CFBD42E9A9E0A9CBD1C8DD7'
|
||||
BlueprintName = 'Dip'
|
||||
ReferencedContainer = 'container:Pods.xcodeproj'
|
||||
BuildableName = 'Dip.framework'>
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
@@ -41,25 +38,17 @@
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
buildConfiguration = "Debug"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "61B2C099D2823B76EB65B5ECC8B08934"
|
||||
BuildableName = "Dip.framework"
|
||||
BlueprintName = "Dip"
|
||||
ReferencedContainer = "container:Pods.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
debugDocumentVersioning = "YES"
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
|
||||
@@ -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
|
||||
@@ -0,0 +1,5 @@
|
||||
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
|
||||
@@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.1.0</string>
|
||||
<string>2.0.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
|
||||
@@ -10,8 +10,10 @@ install_framework()
|
||||
{
|
||||
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
|
||||
local source="${BUILT_PRODUCTS_DIR}/$1"
|
||||
else
|
||||
elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
|
||||
local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
|
||||
elif [ -r "$1" ]; then
|
||||
local source="$1"
|
||||
fi
|
||||
|
||||
local destination="${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
@@ -25,19 +27,31 @@ install_framework()
|
||||
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}"
|
||||
|
||||
local basename
|
||||
basename="$(basename -s .framework "$1")"
|
||||
binary="${destination}/${basename}.framework/${basename}"
|
||||
if ! [ -r "$binary" ]; then
|
||||
binary="${destination}/${basename}"
|
||||
fi
|
||||
|
||||
# Strip invalid architectures so "fat" simulator / device frameworks work on device
|
||||
if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
|
||||
strip_invalid_archs "$binary"
|
||||
fi
|
||||
|
||||
# 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
|
||||
# Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
|
||||
if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
|
||||
local swift_runtime_libs
|
||||
swift_runtime_libs=$(xcrun otool -LX "$binary" | 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
|
||||
fi
|
||||
}
|
||||
|
||||
# Signs a framework with the provided identity
|
||||
@@ -50,10 +64,28 @@ code_sign_if_enabled() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Strip invalid architectures
|
||||
strip_invalid_archs() {
|
||||
binary="$1"
|
||||
# Get architectures for current file
|
||||
archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)"
|
||||
stripped=""
|
||||
for arch in $archs; do
|
||||
if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then
|
||||
# Strip non-valid architectures in-place
|
||||
lipo -remove "$arch" -output "$binary" "$binary" || exit 1
|
||||
stripped="$stripped $arch"
|
||||
fi
|
||||
done
|
||||
if [[ "$stripped" ]]; then
|
||||
echo "Stripped $binary of architectures:$stripped"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
if [[ "$CONFIGURATION" == "Debug" ]]; then
|
||||
install_framework 'Pods-DipSampleApp/Dip.framework'
|
||||
install_framework "Pods-DipSampleApp/Dip.framework"
|
||||
fi
|
||||
if [[ "$CONFIGURATION" == "Release" ]]; then
|
||||
install_framework 'Pods-DipSampleApp/Dip.framework'
|
||||
install_framework "Pods-DipSampleApp/Dip.framework"
|
||||
fi
|
||||
|
||||
@@ -60,7 +60,7 @@ install_resource()
|
||||
|
||||
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
|
||||
if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; 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
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
EMBEDDED_CONTENT_CONTAINS_SWIFT = YES
|
||||
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"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
EMBEDDED_CONTENT_CONTAINS_SWIFT = YES
|
||||
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"
|
||||
|
||||
@@ -10,8 +10,10 @@ install_framework()
|
||||
{
|
||||
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
|
||||
local source="${BUILT_PRODUCTS_DIR}/$1"
|
||||
else
|
||||
elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
|
||||
local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
|
||||
elif [ -r "$1" ]; then
|
||||
local source="$1"
|
||||
fi
|
||||
|
||||
local destination="${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||
@@ -25,19 +27,31 @@ install_framework()
|
||||
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}"
|
||||
|
||||
local basename
|
||||
basename="$(basename -s .framework "$1")"
|
||||
binary="${destination}/${basename}.framework/${basename}"
|
||||
if ! [ -r "$binary" ]; then
|
||||
binary="${destination}/${basename}"
|
||||
fi
|
||||
|
||||
# Strip invalid architectures so "fat" simulator / device frameworks work on device
|
||||
if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
|
||||
strip_invalid_archs "$binary"
|
||||
fi
|
||||
|
||||
# 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
|
||||
# Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
|
||||
if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
|
||||
local swift_runtime_libs
|
||||
swift_runtime_libs=$(xcrun otool -LX "$binary" | 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
|
||||
fi
|
||||
}
|
||||
|
||||
# Signs a framework with the provided identity
|
||||
@@ -50,10 +64,28 @@ code_sign_if_enabled() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Strip invalid architectures
|
||||
strip_invalid_archs() {
|
||||
binary="$1"
|
||||
# Get architectures for current file
|
||||
archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)"
|
||||
stripped=""
|
||||
for arch in $archs; do
|
||||
if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then
|
||||
# Strip non-valid architectures in-place
|
||||
lipo -remove "$arch" -output "$binary" "$binary" || exit 1
|
||||
stripped="$stripped $arch"
|
||||
fi
|
||||
done
|
||||
if [[ "$stripped" ]]; then
|
||||
echo "Stripped $binary of architectures:$stripped"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
if [[ "$CONFIGURATION" == "Debug" ]]; then
|
||||
install_framework 'Pods-DipTests/Dip.framework'
|
||||
install_framework "Pods-DipTests/Dip.framework"
|
||||
fi
|
||||
if [[ "$CONFIGURATION" == "Release" ]]; then
|
||||
install_framework 'Pods-DipTests/Dip.framework'
|
||||
install_framework "Pods-DipTests/Dip.framework"
|
||||
fi
|
||||
|
||||
@@ -60,7 +60,7 @@ install_resource()
|
||||
|
||||
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
|
||||
if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; 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
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
EMBEDDED_CONTENT_CONTAINS_SWIFT = YES
|
||||
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"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
EMBEDDED_CONTENT_CONTAINS_SWIFT = YES
|
||||
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"
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// NetworkMock.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 11/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Dip
|
||||
|
||||
var wsDependencies = DependencyContainer()
|
||||
|
||||
// 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 request(path: String, completion: NetworkResponse -> Void) {
|
||||
let fakeURL = NSURL(string: "stub://")!.URLByAppendingPathComponent(path)
|
||||
if let data = fakeData {
|
||||
let response = NSHTTPURLResponse(URL: fakeURL, statusCode: 200, HTTPVersion: "1.1", headerFields:nil)!
|
||||
completion(.Success(data, response))
|
||||
} else {
|
||||
let response = NSHTTPURLResponse(URL: fakeURL, statusCode: 204, HTTPVersion: "1.1", headerFields:nil)!
|
||||
completion(.Success(NSData(), response))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
//
|
||||
// SWAPIPersonProviderTests.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 11/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
import Dip
|
||||
|
||||
class SWAPIPersonProviderTests: XCTestCase {
|
||||
let fakePerson1 = ["name": "John Doe", "mass": "72", "height": "172", "eye_color": "brown", "hair_color": "black", "gender": "male",
|
||||
"starships": ["stub://starship/7/", "stub://starship/15"], "url": "stub://people/1"]
|
||||
let fakePerson2 = ["name": "Jane Doe", "mass": "63", "height": "167", "eye_color": "blue", "hair_color": "red", "gender": "female",
|
||||
"starships": ["stub://starship/11/"], "url": "stub://people/12"]
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
|
||||
wsDependencies.reset()
|
||||
}
|
||||
|
||||
func testFetchPersonIDs() {
|
||||
let mock = NetworkMock(json: ["results": [fakePerson1, fakePerson2]])
|
||||
wsDependencies.register(WebService.PersonWS.tag, instance: mock as NetworkLayer)
|
||||
|
||||
let provider = SWAPIPersonProvider()
|
||||
provider.fetchIDs { personIDs in
|
||||
XCTAssertNotNil(personIDs)
|
||||
XCTAssertEqual(personIDs.count, 2)
|
||||
|
||||
XCTAssertEqual(personIDs[0], 1)
|
||||
XCTAssertEqual(personIDs[1], 12)
|
||||
}
|
||||
}
|
||||
|
||||
func testFetchOnePerson() {
|
||||
|
||||
let mock = NetworkMock(json: fakePerson1)
|
||||
wsDependencies.register(WebService.PersonWS.tag, instance: mock as NetworkLayer)
|
||||
|
||||
let provider = SWAPIPersonProvider()
|
||||
provider.fetch(1) { person in
|
||||
XCTAssertNotNil(person)
|
||||
XCTAssertEqual(person?.name, "John Doe")
|
||||
XCTAssertEqual(person?.mass, 72)
|
||||
XCTAssertEqual(person?.height, 172)
|
||||
XCTAssertEqual(person?.eyeColor, "brown")
|
||||
XCTAssertEqual(person?.hairColor, "black")
|
||||
XCTAssertEqual(person?.gender, .Male)
|
||||
XCTAssertEqual(person?.starshipIDs.count, 2)
|
||||
XCTAssertEqual(person?.starshipIDs[0], 7)
|
||||
XCTAssertEqual(person?.starshipIDs[1], 15)
|
||||
}
|
||||
}
|
||||
|
||||
func testFetchInvalidPerson() {
|
||||
let json = ["error":"whoops"]
|
||||
let mock = NetworkMock(json: json)
|
||||
wsDependencies.register(WebService.PersonWS.tag, instance: mock as NetworkLayer)
|
||||
|
||||
let provider = SWAPIPersonProvider()
|
||||
provider.fetch(12) { person in
|
||||
XCTAssertNil(person)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
//
|
||||
// SWAPIStarshipProviderTests.swift
|
||||
// Dip
|
||||
//
|
||||
// Created by Olivier Halligon on 11/10/2015.
|
||||
// Copyright © 2015 AliSoftware. All rights reserved.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
import Dip
|
||||
|
||||
class SWAPIStarshipProviderTests: XCTestCase {
|
||||
let fakeShip1 = ["name": "Falcon", "model": "Fighter", "manufacturer": "Fake Industries", "crew": "7", "passengers": "15",
|
||||
"pilots": ["stub://people/1/", "stub://people/9"], "url": "stub://starship/4"]
|
||||
let fakeShip2 = ["name": "Voyager", "model": "Cargo", "manufacturer": "Fake Industries", "crew": "18", "passengers": "150",
|
||||
"pilots": ["stub://people/2/", "stub://people/3"], "url": "stub://starship/31"]
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
|
||||
wsDependencies.reset()
|
||||
}
|
||||
|
||||
func testFetchStarshipIDs() {
|
||||
let mock = NetworkMock(json: ["results": [fakeShip1, fakeShip2]])
|
||||
wsDependencies.register(WebService.StarshipWS.tag, instance: mock as NetworkLayer)
|
||||
|
||||
let provider = SWAPIStarshipProvider()
|
||||
provider.fetchIDs { shipIDs in
|
||||
XCTAssertNotNil(shipIDs)
|
||||
XCTAssertEqual(shipIDs.count, 2)
|
||||
|
||||
XCTAssertEqual(shipIDs[0], 4)
|
||||
XCTAssertEqual(shipIDs[1], 31)
|
||||
}
|
||||
}
|
||||
|
||||
func testFetchOneStarship() {
|
||||
|
||||
let mock = NetworkMock(json: fakeShip1)
|
||||
wsDependencies.register(WebService.StarshipWS.tag, instance: mock as NetworkLayer)
|
||||
|
||||
let provider = SWAPIStarshipProvider()
|
||||
provider.fetch(1) { starship in
|
||||
XCTAssertNotNil(starship)
|
||||
XCTAssertEqual(starship?.name, "Falcon")
|
||||
XCTAssertEqual(starship?.model, "Fighter")
|
||||
XCTAssertEqual(starship?.manufacturer, "Fake Industries")
|
||||
XCTAssertEqual(starship?.crew, 7)
|
||||
XCTAssertEqual(starship?.passengers, 15)
|
||||
XCTAssertNotNil(starship?.pilotIDs)
|
||||
XCTAssertEqual(starship?.pilotIDs[0], 1)
|
||||
XCTAssertEqual(starship?.pilotIDs[1], 9)
|
||||
}
|
||||
}
|
||||
|
||||
func testFetchInvalidStarship() {
|
||||
let json = ["error":"whoops"]
|
||||
let mock = NetworkMock(json: json)
|
||||
wsDependencies.register(WebService.StarshipWS.tag, instance: mock as NetworkLayer)
|
||||
|
||||
let provider = SWAPIStarshipProvider()
|
||||
provider.fetch(12) { starship in
|
||||
XCTAssertNil(starship)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
import UIKit
|
||||
import XCTest
|
||||
import Dip
|
||||
|
||||
|
||||
var dip = DependencyContainer<PersonFormatterTag>()
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,8 @@
|
||||
[](http://cocoapods.org/pods/Dip)
|
||||
[](http://cocoapods.org/pods/Dip)
|
||||
|
||||

|
||||
_Photo by [Matthew Hine](http://www.flickr.com/photos/75771631@N00), 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
|
||||
|
||||
@@ -18,7 +18,7 @@ It's inspired by `.NET`'s [Unity Container](https://msdn.microsoft.com/library/f
|
||||
* 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`.
|
||||
|
||||
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.
|
||||
This allows you to define the real, concrete types only in one place ([e.g. like this in your app](https://github.com/AliSoftware/Dip/blob/master/Example/DipSampleApp/DependencyContainers.swift#L22-L27), and [resetting it in your `setUp` for each Unit Tests](https://github.com/AliSoftware/Dip/blob/master/Example/Tests/SWAPIPersonProviderTests.swift#L17-L21)) and then [only work with `protocols` in your code](https://github.com/AliSoftware/Dip/blob/master/Example/DipSampleApp/Providers/SWAPIStarshipProvider.swift#L12) (which only define an API contract), without worrying about the real implementation.
|
||||
|
||||
## Advantages of DI and loose coupling
|
||||
|
||||
@@ -46,8 +46,7 @@ First, create a `DependencyContainer` and use it to register instances and facto
|
||||
* `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.
|
||||
Typically, to register your dependencies as early as possible in your app life-cycle, you will declare a `let dip: DependencyContainer = { … }()` somewhere (for example [in a dedicated `.swift` file](https://github.com/AliSoftware/Dip/blob/master/Example/DipSampleApp/DependencyContainers.swift#L22-L27)). In your (non-hosted, standalone) unit tests, you'll probably [reset them in your `func setUp()`](https://github.com/AliSoftware/Dip/blob/master/Example/Tests/SWAPIPersonProviderTests.swift#L17-L21) instead.
|
||||
|
||||
### Resolve dependencies
|
||||
|
||||
@@ -55,20 +54,60 @@ Typically, to register your dependencies as early as possible in your app life-c
|
||||
* 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 block-based initialization
|
||||
|
||||
When calling the initializer of `DependencyContainer()`, you can pass a block that will be called right after the initialization. This allows you to have a nice syntax to do all your `register(…)` calls in there, instead of having to do them separately.
|
||||
|
||||
It may not seem to provide much, but given the fact that `DependencyContainers` are typically declared as global constants using a top-level `let`, it gets very useful, because instead of having to do it like this:
|
||||
|
||||
```swift
|
||||
let dip: DependencyContainer = {
|
||||
let dip = DependencyContainer()
|
||||
|
||||
dip.register(instance: ProductionEnvironment(analytics: true) as EnvironmentType)
|
||||
dip.register(instance: WebService() as WebServiceAPI)
|
||||
|
||||
return dip
|
||||
}()
|
||||
```
|
||||
|
||||
You can instead write this exact equivalent code, which is more compact, and indent better in Xcode (as the final closing brack is properly aligned):
|
||||
|
||||
```swift
|
||||
let dip = DependencyContainer { dip in
|
||||
dip.register(instance: ProductionEnvironment(analytics: true) as EnvironmentType)
|
||||
dip.register(instance: WebService() as WebServiceAPI)
|
||||
}
|
||||
```
|
||||
|
||||
### 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)
|
||||
* The tags can be StringLiteralType or IntegerLiteralType. That said you can use plain strings or integers as tags.
|
||||
|
||||
|
||||
### Example
|
||||
```swift
|
||||
enum WebService: String {
|
||||
case PersonWS
|
||||
case StarshipWS
|
||||
var tag: Tag { return Tag.String(self.rawValue) }
|
||||
}
|
||||
|
||||
let wsDependencies = DependencyContainer<WebService>() { dip in
|
||||
dip.register(WebService.PersonWS.tag, instance: URLSessionNetworkLayer(baseURL: "http://prod.myapi.com/api/")! as NetworkLayer)
|
||||
dip.register(WebService.StashipWS.tag, instance: URLSessionNetworkLayer(baseURL: "http://dev.myapi.com/api/")! as NetworkLayer)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Concrete Example
|
||||
|
||||
Somewhere in your App target, register the dependencies:
|
||||
|
||||
```swift
|
||||
let dip: DependencyContainer<String> = {
|
||||
let dip = DependencyContainer<String>()
|
||||
let dip: DependencyContainer = {
|
||||
let dip = DependencyContainer()
|
||||
let env = ProductionEnvironment(analytics: true)
|
||||
dip.register(instance: env as EnvironmentType)
|
||||
dip.register(instance: WebService() as WebServiceType)
|
||||
@@ -111,20 +150,23 @@ This way, when running your app target:
|
||||
|
||||
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.
|
||||
|
||||
### Complete Example Project
|
||||
|
||||
## Work In Progress
|
||||
You can find a complete example in the `Example/DipSampleApp` project provided in this repository.
|
||||
|
||||
* [x] Example project
|
||||
* [ ] Unit Tests
|
||||
* [x] README
|
||||
* [ ] Source Documentation
|
||||
* [ ] Thread-Safety
|
||||
This sample project is a bit more complex, but closer to real-world applications (even if this sample is all about StarWars!),
|
||||
by declaring protocols like `NetworkLayer` which can be resolved to a `URLSessionNetworkLayer` in the real app, but to a dummy
|
||||
network layer returning fixture data during the Unit Tests.
|
||||
|
||||
This sample uses the Star Wars API provided by swapi.co to fetch Star Wars characters and starships info and display them in TableViews.
|
||||
|
||||
|
||||
## Author
|
||||
## Credits
|
||||
|
||||
Olivier Halligon, olivier@halligon.net
|
||||
This library is authored by **Olivier Halligon**, olivier@halligon.net
|
||||
|
||||
## License
|
||||
**Dip** is available under the **MIT license**. See the `LICENSE` file for more info.
|
||||
|
||||
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!
|
||||
|
||||
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_.
|
||||
|
||||
@@ -8,81 +8,192 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
// MARK: - DependencyContainer
|
||||
|
||||
/**
|
||||
* Internal representation of a key to associate protocols & tags to an instance factory
|
||||
*/
|
||||
private struct ProtoTagKey<TagType : Equatable> : Hashable, Equatable, CustomDebugStringConvertible {
|
||||
* _Dip_'s Dependency Containers allow you to do very simple **Dependency Injection**
|
||||
* by associating `protocols` to concrete implementations
|
||||
*/
|
||||
public class DependencyContainer {
|
||||
|
||||
/**
|
||||
Use a tag in case you need to register multiple instances or factories
|
||||
with the same protocol, to differentiate them. Tags can be either String
|
||||
or Int, to your convenience.
|
||||
*/
|
||||
public enum Tag: Equatable {
|
||||
case String(StringLiteralType)
|
||||
case Int(IntegerLiteralType)
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal representation of a key to associate protocols & tags to an instance factory
|
||||
*/
|
||||
private struct LookupKey : Hashable, Equatable, CustomDebugStringConvertible {
|
||||
var protocolType: Any.Type
|
||||
var associatedTag: TagType?
|
||||
var associatedTag: Tag?
|
||||
|
||||
var hashValue: Int {
|
||||
return "\(protocolType)-\(associatedTag)".hashValue
|
||||
return "\(protocolType)-\(associatedTag)".hashValue
|
||||
}
|
||||
|
||||
var debugDescription: String {
|
||||
return "type: \(protocolType), tag: \(associatedTag)"
|
||||
return "type: \(protocolType), tag: \(associatedTag)"
|
||||
}
|
||||
}
|
||||
|
||||
private typealias InstanceType = Any
|
||||
private typealias InstanceFactory = Tag?->InstanceType
|
||||
private typealias Key = LookupKey
|
||||
|
||||
private var dependencies = [Key : InstanceFactory]()
|
||||
private var lock: OSSpinLock = OS_SPINLOCK_INIT
|
||||
|
||||
// MARK: - Init & Reset
|
||||
|
||||
/**
|
||||
Designated initializer for a DependencyContainer
|
||||
|
||||
- parameter configBlock: A configuration block in which you typically put all you `register` calls.
|
||||
|
||||
- note: The `configBlock` is simply called at the end of the `init` to let you configure everything.
|
||||
It is only present for convenience to have a cleaner syntax when declaring and initializing
|
||||
your `DependencyContainer` instances.
|
||||
|
||||
- returns: A new DependencyContainer
|
||||
*/
|
||||
public init(@noescape configBlock: (DependencyContainer->Void) = { _ in }) {
|
||||
configBlock(self)
|
||||
}
|
||||
|
||||
/**
|
||||
Clear all the previously registered dependencies on this container
|
||||
*/
|
||||
public func reset() {
|
||||
lockAndDo {
|
||||
dependencies.removeAll()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Register dependencies
|
||||
|
||||
/**
|
||||
Register a `TagType?->T` factory (which takes the tag as parameter) with a given tag
|
||||
|
||||
- parameter tag: The arbitrary tag to associate this factory with when registering with that protocol. `nil` to associate with any tag.
|
||||
- parameter factory: The factory to register, typed/casted as the protocol you want to register it as
|
||||
|
||||
- note: You must cast the factory return type to the protocol you want to register it with (e.g `MyClass() as MyAPI`)
|
||||
*/
|
||||
public func register<T>(tag: Tag? = nil, factory: Tag?->T) {
|
||||
let key = Key(protocolType: T.self, associatedTag: tag)
|
||||
lockAndDo {
|
||||
dependencies[key] = { factory($0) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Register a Void->T factory (which don't care about the tag used)
|
||||
|
||||
- parameter tag: The arbitrary tag to associate this factory with when registering with that protocol. `nil` to associate with any tag.
|
||||
- parameter factory: The factory to register, typed/casted as the protocol you want to register it as
|
||||
|
||||
- note: You must cast the factory return type to the protocol you want to register it with (e.g `MyClass() as MyAPI`)
|
||||
*/
|
||||
public func register<T>(tag: Tag? = nil, factory: Void->T) {
|
||||
let key = Key(protocolType: T.self, associatedTag: tag)
|
||||
lockAndDo {
|
||||
dependencies[key] = { _ in factory() }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Register a Singleton instance
|
||||
|
||||
|
||||
- parameter tag: The arbitrary tag to associate this instance with when registering with that protocol. `nil` to associate with any tag.
|
||||
- parameter instance: The instance to register, typed/casted as the protocol you want to register it as
|
||||
|
||||
- note: You must cast the instance to the protocol you want to register it with (e.g `MyClass() as MyAPI`)
|
||||
*/
|
||||
public func register<T>(tag: Tag? = nil, @autoclosure(escaping) instance factory: Void->T) {
|
||||
let key = Key(protocolType: T.self, associatedTag: tag)
|
||||
lockAndDo {
|
||||
dependencies[key] = { _ in
|
||||
let instance = factory()
|
||||
self.dependencies[key] = { _ in return instance }
|
||||
return instance
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Resolve dependencies
|
||||
|
||||
/**
|
||||
Resolve a dependency
|
||||
|
||||
- parameter tag: The arbitrary tag to look for when resolving this protocol.
|
||||
If no instance/factory was registered with this `tag` for this `protocol`,
|
||||
it will resolve to the instance/factory associated with `nil` (no tag).
|
||||
*/
|
||||
public func resolve<T>(tag: Tag? = nil) -> T! {
|
||||
let key = Key(protocolType: T.self, associatedTag: tag)
|
||||
let nilKey = Key(protocolType: T.self, associatedTag: nil)
|
||||
var resolved: T!
|
||||
lockAndDo { [unowned self] in
|
||||
guard let factory = self.dependencies[key] ?? self.dependencies[nilKey] else {
|
||||
fatalError("No instance factory registered with \(key)")
|
||||
}
|
||||
resolved = factory(tag) as! T
|
||||
}
|
||||
return resolved
|
||||
}
|
||||
|
||||
// MARK: - Private Helper
|
||||
|
||||
private func lockAndDo(@noescape block: Void->Void) {
|
||||
OSSpinLockLock(&lock)
|
||||
defer { OSSpinLockUnlock(&lock) }
|
||||
block()
|
||||
}
|
||||
}
|
||||
|
||||
private func ==<T>(lhs: ProtoTagKey<T>, rhs: ProtoTagKey<T>) -> Bool {
|
||||
return lhs.protocolType == rhs.protocolType && lhs.associatedTag == rhs.associatedTag
|
||||
// MARK: - Class Extensions
|
||||
|
||||
private func ==(lhs: DependencyContainer.LookupKey, rhs: DependencyContainer.LookupKey) -> Bool {
|
||||
return lhs.protocolType == rhs.protocolType && lhs.associatedTag == rhs.associatedTag
|
||||
}
|
||||
|
||||
// MARK: - DependencyContainer
|
||||
|
||||
public class DependencyContainer<TagType : Equatable> {
|
||||
typealias InstanceType = Any
|
||||
typealias InstanceFactory = TagType?->InstanceType
|
||||
private typealias Key = ProtoTagKey<TagType>
|
||||
|
||||
private var dependencies = [Key : InstanceFactory]()
|
||||
|
||||
public init() {}
|
||||
|
||||
// MARK: Reset all dependencies
|
||||
|
||||
public func reset() {
|
||||
dependencies.removeAll()
|
||||
}
|
||||
|
||||
// MARK: Register dependencies
|
||||
|
||||
/// Register a TagType?->T factory (which takes the tag as parameter)
|
||||
public func register<T : Any>(tag: TagType? = nil, factory: TagType?->T) {
|
||||
let key = Key(protocolType: T.self, associatedTag: tag)
|
||||
dependencies[key] = { factory($0) }
|
||||
}
|
||||
|
||||
/// Register a Void->T factory (which don't care about the tag used)
|
||||
public func register<T : Any>(tag: TagType? = nil, factory: Void->T) {
|
||||
let key = Key(protocolType: T.self, associatedTag: tag)
|
||||
dependencies[key] = { _ in factory() }
|
||||
}
|
||||
|
||||
/// Register a Singleton instance
|
||||
public func register<T : Any>(tag: TagType? = nil, @autoclosure(escaping) instance factory: Void->T) {
|
||||
let key = Key(protocolType: T.self, associatedTag: tag)
|
||||
// FIXME: Make it thread-safe
|
||||
dependencies[key] = { _ in
|
||||
let instance = factory()
|
||||
self.dependencies[key] = { _ in return instance }
|
||||
return instance
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Resolve dependencies
|
||||
|
||||
/// Resolve a dependency
|
||||
///
|
||||
/// **Note** If a tag is given, it will try to resolve using the tag to generate a specific instance,
|
||||
/// and fallback without the tag if not found with it
|
||||
public func resolve<T>(tag: TagType? = nil) -> T! {
|
||||
let key = Key(protocolType: T.self, associatedTag: tag)
|
||||
let nilKey = Key(protocolType: T.self, associatedTag: nil)
|
||||
guard let factory = dependencies[key] ?? dependencies[nilKey] else {
|
||||
fatalError("No instance factory registered with \(key)")
|
||||
}
|
||||
return factory(tag) as! T
|
||||
}
|
||||
extension DependencyContainer.Tag: IntegerLiteralConvertible {
|
||||
public init(integerLiteral value: IntegerLiteralType) {
|
||||
self = .Int(value)
|
||||
}
|
||||
}
|
||||
|
||||
extension DependencyContainer.Tag: StringLiteralConvertible {
|
||||
public typealias ExtendedGraphemeClusterLiteralType = StringLiteralType
|
||||
public typealias UnicodeScalarLiteralType = StringLiteralType
|
||||
|
||||
public init(stringLiteral value: StringLiteralType) {
|
||||
self = .String(value)
|
||||
}
|
||||
|
||||
public init(unicodeScalarLiteral value: UnicodeScalarLiteralType) {
|
||||
self.init(stringLiteral: value)
|
||||
}
|
||||
|
||||
public init(extendedGraphemeClusterLiteral value: ExtendedGraphemeClusterLiteralType) {
|
||||
self.init(stringLiteral: value)
|
||||
}
|
||||
}
|
||||
|
||||
public func ==(lhs: DependencyContainer.Tag, rhs: DependencyContainer.Tag) -> Bool {
|
||||
switch (lhs, rhs) {
|
||||
case let (.String(lhsString), .String(rhsString)):
|
||||
return lhsString == rhsString
|
||||
case let (.Int(lhsInt), .Int(rhsInt)):
|
||||
return lhsInt == rhsInt
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 400 KiB |