diff --git a/License.md b/License.md
new file mode 100644
index 00000000..849ba27c
--- /dev/null
+++ b/License.md
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright YI GU
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/Project 01 - GoodAsOldPhones/GoodAsOldPhones.xcodeproj/project.pbxproj b/Project 01 - GoodAsOldPhones/GoodAsOldPhones.xcodeproj/project.pbxproj
index 73bcd2b2..a57eca6a 100644
--- a/Project 01 - GoodAsOldPhones/GoodAsOldPhones.xcodeproj/project.pbxproj
+++ b/Project 01 - GoodAsOldPhones/GoodAsOldPhones.xcodeproj/project.pbxproj
@@ -100,18 +100,18 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0720;
- LastUpgradeCheck = 0820;
+ LastUpgradeCheck = 1020;
ORGANIZATIONNAME = "Code School";
TargetAttributes = {
197C21091C6686EE00BCCAE8 = {
CreatedOnToolsVersion = 7.2.1;
- LastSwiftMigration = 0800;
+ LastSwiftMigration = 1020;
};
};
};
buildConfigurationList = 197C21051C6686EE00BCCAE8 /* Build configuration list for PBXProject "GoodAsOldPhones" */;
compatibilityVersion = "Xcode 3.2";
- developmentRegion = English;
+ developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
@@ -179,18 +179,27 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -213,7 +222,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 9.2;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -226,18 +235,27 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -254,7 +272,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 9.2;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
@@ -271,7 +289,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.codeschool.GoodAsOldPhones;
PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 3.0;
+ SWIFT_VERSION = 5.0;
};
name = Debug;
};
@@ -283,7 +301,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.codeschool.GoodAsOldPhones;
PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 3.0;
+ SWIFT_VERSION = 5.0;
};
name = Release;
};
diff --git a/Project 29 - Grocr/Grocr/Grocr.entitlements b/Project 01 - GoodAsOldPhones/GoodAsOldPhones.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
similarity index 60%
rename from Project 29 - Grocr/Grocr/Grocr.entitlements
rename to Project 01 - GoodAsOldPhones/GoodAsOldPhones.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
index 1b2730ed..18d98100 100644
--- a/Project 29 - Grocr/Grocr/Grocr.entitlements
+++ b/Project 01 - GoodAsOldPhones/GoodAsOldPhones.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -2,9 +2,7 @@
- keychain-access-groups
-
- $(AppIdentifierPrefix)rw.firebase.gettingstarted
-
+ IDEDidComputeMac32BitWarning
+
diff --git a/Project 01 - GoodAsOldPhones/GoodAsOldPhones.xcodeproj/project.xcworkspace/xcuserdata/Yi.xcuserdatad/UserInterfaceState.xcuserstate b/Project 01 - GoodAsOldPhones/GoodAsOldPhones.xcodeproj/project.xcworkspace/xcuserdata/Yi.xcuserdatad/UserInterfaceState.xcuserstate
index 4a67ac85..e923dabb 100644
Binary files a/Project 01 - GoodAsOldPhones/GoodAsOldPhones.xcodeproj/project.xcworkspace/xcuserdata/Yi.xcuserdatad/UserInterfaceState.xcuserstate and b/Project 01 - GoodAsOldPhones/GoodAsOldPhones.xcodeproj/project.xcworkspace/xcuserdata/Yi.xcuserdatad/UserInterfaceState.xcuserstate differ
diff --git a/Project 01 - GoodAsOldPhones/GoodAsOldPhones.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/GoodAsOldPhones.xcscheme b/Project 01 - GoodAsOldPhones/GoodAsOldPhones.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/GoodAsOldPhones.xcscheme
index bafe8ee3..3f04ac32 100644
--- a/Project 01 - GoodAsOldPhones/GoodAsOldPhones.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/GoodAsOldPhones.xcscheme
+++ b/Project 01 - GoodAsOldPhones/GoodAsOldPhones.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/GoodAsOldPhones.xcscheme
@@ -1,6 +1,6 @@
Bool {
+ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
diff --git a/Project 01 - GoodAsOldPhones/GoodAsOldPhones/Assets.xcassets/AppIcon.appiconset/Contents.json b/Project 01 - GoodAsOldPhones/GoodAsOldPhones/Assets.xcassets/AppIcon.appiconset/Contents.json
index 1d060ed2..d8db8d65 100644
--- a/Project 01 - GoodAsOldPhones/GoodAsOldPhones/Assets.xcassets/AppIcon.appiconset/Contents.json
+++ b/Project 01 - GoodAsOldPhones/GoodAsOldPhones/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -84,6 +84,11 @@
"idiom" : "ipad",
"size" : "83.5x83.5",
"scale" : "2x"
+ },
+ {
+ "idiom" : "ios-marketing",
+ "size" : "1024x1024",
+ "scale" : "1x"
}
],
"info" : {
diff --git a/Project 01 - GoodAsOldPhones/GoodAsOldPhones/Base.lproj/Main.storyboard b/Project 01 - GoodAsOldPhones/GoodAsOldPhones/Base.lproj/Main.storyboard
index 4f73b641..434d68be 100644
--- a/Project 01 - GoodAsOldPhones/GoodAsOldPhones/Base.lproj/Main.storyboard
+++ b/Project 01 - GoodAsOldPhones/GoodAsOldPhones/Base.lproj/Main.storyboard
@@ -1,9 +1,18 @@
-
-
+
+
+
+
+
-
+
+
+
+
+ DamascusBold
+
+
@@ -17,26 +26,33 @@
-
+
-
+
+
+
+
+
+
+
-
@@ -57,79 +73,90 @@
-
+
-
-
+
+
+
+
+
@@ -144,10 +171,10 @@
-
+
-
+
@@ -164,7 +191,6 @@
-
@@ -177,7 +203,7 @@
-
+
@@ -195,8 +221,9 @@
+
-
+
diff --git a/Project 01 - GoodAsOldPhones/GoodAsOldPhones/ContactViewController.swift b/Project 01 - GoodAsOldPhones/GoodAsOldPhones/ContactViewController.swift
index 8ce6e372..365a20e6 100644
--- a/Project 01 - GoodAsOldPhones/GoodAsOldPhones/ContactViewController.swift
+++ b/Project 01 - GoodAsOldPhones/GoodAsOldPhones/ContactViewController.swift
@@ -13,13 +13,19 @@ class ContactViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
-
+
view.addSubview(scrollView)
}
- override func viewWillLayoutSubviews() {
- super.viewWillLayoutSubviews()
+ override func viewDidLayoutSubviews() {
+ super.viewDidLayoutSubviews()
+
+ if #available(iOS 11.0, *) {
+ scrollView.frame = CGRect(x: 0, y: view.safeAreaInsets.top, width: view.frame.width, height: view.frame.height - view.safeAreaInsets.bottom - view.safeAreaInsets.top)
+ } else {
+ scrollView.frame = CGRect(x: 0, y: topLayoutGuide.length, width: view.frame.width, height: view.frame.height - topLayoutGuide.length - bottomLayoutGuide.length)
+ }
- scrollView.contentSize = CGSize(width: 375, height: 800)
+ scrollView.contentSize = CGSize(width: self.view.frame.width, height: 800)
}
}
diff --git a/Project 01 - GoodAsOldPhones/GoodAsOldPhones/ProductViewController.swift b/Project 01 - GoodAsOldPhones/GoodAsOldPhones/ProductViewController.swift
index f8afd490..7376b326 100644
--- a/Project 01 - GoodAsOldPhones/GoodAsOldPhones/ProductViewController.swift
+++ b/Project 01 - GoodAsOldPhones/GoodAsOldPhones/ProductViewController.swift
@@ -24,7 +24,7 @@ class ProductViewController: UIViewController {
}
}
- @IBAction func addToCartPressed(_ sender: AnyObject) {
- print("Hello World")
+ @IBAction func addToCartButtonDidTap(_ sender: AnyObject) {
+ print("Add to cart successfully")
}
}
diff --git a/Project 01 - GoodAsOldPhones/GoodAsOldPhones/ProductsTableViewController.swift b/Project 01 - GoodAsOldPhones/GoodAsOldPhones/ProductsTableViewController.swift
index f41b15de..3f90906b 100644
--- a/Project 01 - GoodAsOldPhones/GoodAsOldPhones/ProductsTableViewController.swift
+++ b/Project 01 - GoodAsOldPhones/GoodAsOldPhones/ProductsTableViewController.swift
@@ -8,48 +8,54 @@
import UIKit
class ProductsTableViewController: UITableViewController {
- var products: [Product]?
+ private var products: [Product]?
+ private let identifer = "productCell"
override func viewDidLoad() {
super.viewDidLoad()
- products = [Product(name: "1907 Wall Set", cellImageName: "image-cell1", fullscreenImageName: "phone-fullscreen1"),
- Product(name: "1921 Dial Phone", cellImageName: "image-cell2", fullscreenImageName: "phone-fullscreen2"),
- Product(name: "1937 Desk Set", cellImageName: "image-cell3", fullscreenImageName: "phone-fullscreen3"),
- Product(name: "1984 Moto Portable", cellImageName: "image-cell4", fullscreenImageName: "phone-fullscreen4")]
+ products = [
+ Product(name: "1907 Wall Set", cellImageName: "image-cell1", fullscreenImageName: "phone-fullscreen1"),
+ Product(name: "1921 Dial Phone", cellImageName: "image-cell2", fullscreenImageName: "phone-fullscreen2"),
+ Product(name: "1937 Desk Set", cellImageName: "image-cell3", fullscreenImageName: "phone-fullscreen3"),
+ Product(name: "1984 Moto Portable", cellImageName: "image-cell4", fullscreenImageName: "phone-fullscreen4")
+ ]
}
- // MARK: - tableView set
- override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- if let products = products {
- return products.count
- }
- return 0
- }
-
- override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
- let identifer = "productCell"
-
- let cell = tableView.dequeueReusableCell(withIdentifier: identifer, for: indexPath)
-
- cell.textLabel?.text = products?[(indexPath as NSIndexPath).row].name
-
- if let imageName = products?[(indexPath as NSIndexPath).row].cellImageName {
- cell.imageView?.image = UIImage(named: imageName)
- }
-
- return cell;
- }
-
+
+ // MARK: - View Transfer
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showProduct" {
- let productVC = segue.destination as? ProductViewController
-
- if let cell = sender as? UITableViewCell {
- if let indexPath = tableView.indexPath(for: cell) {
- productVC?.product = products?[(indexPath as NSIndexPath).row]
- }
+ if let cell = sender as? UITableViewCell,
+ let indexPath = tableView.indexPath(for: cell),
+ let productVC = segue.destination as? ProductViewController {
+ productVC.product = products?[indexPath.row]
}
}
}
}
+
+
+// MARK: - UITableViewDataSource
+extension ProductsTableViewController {
+ override func tableView(_ tableView: UITableView,
+ numberOfRowsInSection section: Int) -> Int
+ {
+ return products?.count ?? 0
+ }
+
+ override func tableView(_ tableView: UITableView,
+ cellForRowAt indexPath: IndexPath) -> UITableViewCell
+ {
+ let cell = tableView.dequeueReusableCell(withIdentifier: identifer, for: indexPath)
+ guard let products = products else { return cell }
+
+ cell.textLabel?.text = products[indexPath.row].name
+
+ if let imageName = products[indexPath.row].cellImageName {
+ cell.imageView?.image = UIImage(named: imageName)
+ }
+
+ return cell;
+ }
+}
diff --git a/Project 01 - GoodAsOldPhones/README.md b/Project 01 - GoodAsOldPhones/README.md
index 20295615..205ee37d 100644
--- a/Project 01 - GoodAsOldPhones/README.md
+++ b/Project 01 - GoodAsOldPhones/README.md
@@ -1,7 +1,7 @@
GoodAsOldPhones
==========
-GoodAsOldPhones is a simple iOS app coded by Swift. Also, it is a demo sample app of Swift tutorial in codeschool.com. This app demonstates basic use and implementation of tab bar controller, navigation controller, scoll view, table view and storyboard.
+GoodAsOldPhones is the demo app of [Swift tutorial](https://www.codeschool.com/courses/app-evolution-with-swift) on code school. This app demonstates basic use and implementation of tab bar controller, navigation controller, scoll view, table view and storyboard.
## Screenshots

diff --git a/Project 02 - LoveTweet/LoveTweet.xcodeproj/project.xcworkspace/xcuserdata/Yi.xcuserdatad/UserInterfaceState.xcuserstate b/Project 02 - LoveTweet/LoveTweet.xcodeproj/project.xcworkspace/xcuserdata/Yi.xcuserdatad/UserInterfaceState.xcuserstate
deleted file mode 100644
index a94ba7df..00000000
Binary files a/Project 02 - LoveTweet/LoveTweet.xcodeproj/project.xcworkspace/xcuserdata/Yi.xcuserdatad/UserInterfaceState.xcuserstate and /dev/null differ
diff --git a/Project 02 - LoveTweet/LoveTweet.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/LoveTweet.xcscheme b/Project 02 - LoveTweet/LoveTweet.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/LoveTweet.xcscheme
deleted file mode 100644
index 9180ae1f..00000000
--- a/Project 02 - LoveTweet/LoveTweet.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/LoveTweet.xcscheme
+++ /dev/null
@@ -1,91 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Project 02 - LoveTweet/LoveTweet.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/xcschememanagement.plist b/Project 02 - LoveTweet/LoveTweet.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/xcschememanagement.plist
deleted file mode 100644
index 2f01a67c..00000000
--- a/Project 02 - LoveTweet/LoveTweet.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/xcschememanagement.plist
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
- SchemeUserState
-
- LoveTweet.xcscheme
-
- orderHint
- 0
-
-
- SuppressBuildableAutocreation
-
- 194C54921C72852900749A4F
-
- primary
-
-
-
-
-
diff --git a/Project 02 - LoveTweet/LoveTweet/AppDelegate.swift b/Project 02 - LoveTweet/LoveTweet/AppDelegate.swift
deleted file mode 100644
index 1df644b6..00000000
--- a/Project 02 - LoveTweet/LoveTweet/AppDelegate.swift
+++ /dev/null
@@ -1,19 +0,0 @@
-//
-// AppDelegate.swift
-// LoveTweet
-//
-// Copyright © 2016 YiGu. All rights reserved.
-//
-
-import UIKit
-
-@UIApplicationMain
-class AppDelegate: UIResponder, UIApplicationDelegate {
-
- var window: UIWindow?
-
- func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
- // Override point for customization after application launch.
- return true
- }
-}
diff --git a/Project 02 - LoveTweet/LoveTweet/Base.lproj/Main.storyboard b/Project 02 - LoveTweet/LoveTweet/Base.lproj/Main.storyboard
deleted file mode 100644
index a02e6837..00000000
--- a/Project 02 - LoveTweet/LoveTweet/Base.lproj/Main.storyboard
+++ /dev/null
@@ -1,184 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Project 02 - LoveTweet/LoveTweet/ViewController.swift b/Project 02 - LoveTweet/LoveTweet/ViewController.swift
deleted file mode 100644
index 984a64c4..00000000
--- a/Project 02 - LoveTweet/LoveTweet/ViewController.swift
+++ /dev/null
@@ -1,86 +0,0 @@
-//
-// ViewController.swift
-// LoveTweet
-//
-// Copyright © 2016 YiGu. All rights reserved.
-//
-
-import UIKit
-import Social
-
-var tweet:String = ""
-
-class ViewController: UIViewController {
-
- // MARK: Outlets
- @IBOutlet weak var nameTextField: UITextField!
- @IBOutlet weak var genderSeg: UISegmentedControl!
- @IBOutlet weak var birthdayPicker: UIDatePicker!
- @IBOutlet weak var workTextField: UITextField!
- @IBOutlet weak var salaryLabel: UILabel!
- @IBOutlet weak var straightSwitch: UISwitch!
-
- override func viewDidLoad() {
- super.viewDidLoad()
- }
-
- @IBAction func salaryHandler(_ sender: AnyObject) {
- let slider = sender as! UISlider
- let i = Int(slider.value)
- salaryLabel.text = "$\(i)k"
- }
-
- @IBAction func tweetTapped(_ sender: AnyObject) {
- if (nameTextField.text == "" || workTextField.text == "" || salaryLabel.text == "") {
- showAlert("Info Miss", message: "Please fill out the form", buttonTitle: "Ok")
- return
- }
-
- let name:String! = nameTextField.text
-
- let work:String! = workTextField.text
- let salary:String! = salaryLabel.text
-
- // get age
- let gregorian = Calendar(identifier: Calendar.Identifier.gregorian)
- let now = Date()
- let components = (gregorian as NSCalendar?)?.components(NSCalendar.Unit.year, from: birthdayPicker.date, to: now, options: [])
- let age:Int! = components?.year
-
- var interestedIn:String! = "Women"
- if (genderSeg.selectedSegmentIndex == 0 && !straightSwitch.isOn) {
- interestedIn = "Men"
- }
- if (genderSeg.selectedSegmentIndex == 1 && straightSwitch.isOn ) {
- interestedIn = "Women"
- }
-
- let tweet = "Hi, I am \(name!). As a \(age!)-year-old \(work!) earning \(salary!)/year, I am interested in \(interestedIn!). Feel free to contact me!"
-
- tweetSLCVC(tweet)
- }
-
- fileprivate func tweetSLCVC(_ tweet: String) {
- if SLComposeViewController.isAvailable(forServiceType: SLServiceTypeTwitter){
- let twitterController:SLComposeViewController = SLComposeViewController(forServiceType: SLServiceTypeTwitter)
- twitterController.setInitialText(tweet)
- self.present(twitterController, animated: true, completion: nil)
- } else {
- showAlert("Twitter Unavailable", message: "Please configure your twitter account on device", buttonTitle: "Ok")
- }
- }
-
- fileprivate func showAlert(_ title:String, message:String, buttonTitle:String) {
- let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
- alert.addAction(UIAlertAction(title: buttonTitle, style: UIAlertActionStyle.default, handler: nil))
- self.present(alert, animated: true, completion: nil)
- }
-
- override func touchesBegan(_ touches: Set, with event: UIEvent?) {
- super.touchesBegan(touches, with: event)
-
- // dismiss keyboard
- view.endEditing(true)
- }
-}
-
diff --git a/Project 02 - LoveTweet/README.md b/Project 02 - LoveTweet/README.md
deleted file mode 100644
index fbc1652c..00000000
--- a/Project 02 - LoveTweet/README.md
+++ /dev/null
@@ -1,9 +0,0 @@
-LoveTweet
-==========
-
-Love Tweet is a Swift iOS App. It demonstrates how to use common UIKit controls such as UILabel, UITextField, UISegmentedControl, UIDatePicker, UISlider, UISwitch, UIButton and UITextView. Also, twitter API is integrated into this app.
-
-## Screenshots
-
-
-
diff --git a/Project 02 - LoveTweet/Screenshots/shot1.png b/Project 02 - LoveTweet/Screenshots/shot1.png
deleted file mode 100644
index 5d5f4870..00000000
Binary files a/Project 02 - LoveTweet/Screenshots/shot1.png and /dev/null differ
diff --git a/Project 02 - LoveTweet/Screenshots/shot2.png b/Project 02 - LoveTweet/Screenshots/shot2.png
deleted file mode 100644
index dca1f763..00000000
Binary files a/Project 02 - LoveTweet/Screenshots/shot2.png and /dev/null differ
diff --git a/Project 03 - Stopwatch/README.md b/Project 02 - Stopwatch/README.md
similarity index 100%
rename from Project 03 - Stopwatch/README.md
rename to Project 02 - Stopwatch/README.md
diff --git a/Project 03 - Stopwatch/Stopwatch.gif b/Project 02 - Stopwatch/Stopwatch.gif
similarity index 100%
rename from Project 03 - Stopwatch/Stopwatch.gif
rename to Project 02 - Stopwatch/Stopwatch.gif
diff --git a/Project 03 - Stopwatch/Stopwatch.xcodeproj/project.pbxproj b/Project 02 - Stopwatch/Stopwatch.xcodeproj/project.pbxproj
similarity index 61%
rename from Project 03 - Stopwatch/Stopwatch.xcodeproj/project.pbxproj
rename to Project 02 - Stopwatch/Stopwatch.xcodeproj/project.pbxproj
index b32e9a62..cf5bedd0 100644
--- a/Project 03 - Stopwatch/Stopwatch.xcodeproj/project.pbxproj
+++ b/Project 02 - Stopwatch/Stopwatch.xcodeproj/project.pbxproj
@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
+ 1931198D20D35E380079AC04 /* StopwatchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1931198C20D35E380079AC04 /* StopwatchTests.swift */; };
197BEE191C76E410005AD5E2 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 197BEE181C76E410005AD5E2 /* AppDelegate.swift */; };
197BEE1B1C76E410005AD5E2 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 197BEE1A1C76E410005AD5E2 /* ViewController.swift */; };
197BEE1E1C76E410005AD5E2 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 197BEE1C1C76E410005AD5E2 /* Main.storyboard */; };
@@ -15,7 +16,20 @@
197BEE2D1C798B47005AD5E2 /* Stopwatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 197BEE2C1C798B47005AD5E2 /* Stopwatch.swift */; };
/* End PBXBuildFile section */
+/* Begin PBXContainerItemProxy section */
+ 1931198F20D35E380079AC04 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 197BEE0D1C76E410005AD5E2 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 197BEE141C76E410005AD5E2;
+ remoteInfo = Stopwatch;
+ };
+/* End PBXContainerItemProxy section */
+
/* Begin PBXFileReference section */
+ 1931198A20D35E380079AC04 /* StopwatchTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StopwatchTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ 1931198C20D35E380079AC04 /* StopwatchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StopwatchTests.swift; sourceTree = ""; };
+ 1931198E20D35E380079AC04 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
197BEE151C76E410005AD5E2 /* Stopwatch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Stopwatch.app; sourceTree = BUILT_PRODUCTS_DIR; };
197BEE181C76E410005AD5E2 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
197BEE1A1C76E410005AD5E2 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
@@ -27,6 +41,13 @@
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
+ 1931198720D35E380079AC04 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
197BEE121C76E410005AD5E2 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -37,10 +58,20 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
+ 1931198B20D35E380079AC04 /* StopwatchTests */ = {
+ isa = PBXGroup;
+ children = (
+ 1931198C20D35E380079AC04 /* StopwatchTests.swift */,
+ 1931198E20D35E380079AC04 /* Info.plist */,
+ );
+ path = StopwatchTests;
+ sourceTree = "";
+ };
197BEE0C1C76E410005AD5E2 = {
isa = PBXGroup;
children = (
197BEE171C76E410005AD5E2 /* Stopwatch */,
+ 1931198B20D35E380079AC04 /* StopwatchTests */,
197BEE161C76E410005AD5E2 /* Products */,
);
sourceTree = "";
@@ -49,6 +80,7 @@
isa = PBXGroup;
children = (
197BEE151C76E410005AD5E2 /* Stopwatch.app */,
+ 1931198A20D35E380079AC04 /* StopwatchTests.xctest */,
);
name = Products;
sourceTree = "";
@@ -70,6 +102,24 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
+ 1931198920D35E380079AC04 /* StopwatchTests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 1931199120D35E380079AC04 /* Build configuration list for PBXNativeTarget "StopwatchTests" */;
+ buildPhases = (
+ 1931198620D35E380079AC04 /* Sources */,
+ 1931198720D35E380079AC04 /* Frameworks */,
+ 1931198820D35E380079AC04 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 1931199020D35E380079AC04 /* PBXTargetDependency */,
+ );
+ name = StopwatchTests;
+ productName = StopwatchTests;
+ productReference = 1931198A20D35E380079AC04 /* StopwatchTests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
197BEE141C76E410005AD5E2 /* Stopwatch */ = {
isa = PBXNativeTarget;
buildConfigurationList = 197BEE271C76E410005AD5E2 /* Build configuration list for PBXNativeTarget "Stopwatch" */;
@@ -93,19 +143,26 @@
197BEE0D1C76E410005AD5E2 /* Project object */ = {
isa = PBXProject;
attributes = {
- LastSwiftUpdateCheck = 0720;
- LastUpgradeCheck = 0820;
+ LastSwiftUpdateCheck = 0940;
+ LastUpgradeCheck = 1020;
ORGANIZATIONNAME = YiGu;
TargetAttributes = {
+ 1931198920D35E380079AC04 = {
+ CreatedOnToolsVersion = 9.4;
+ DevelopmentTeam = 44JDRP3T56;
+ LastSwiftMigration = 1020;
+ ProvisioningStyle = Automatic;
+ TestTargetID = 197BEE141C76E410005AD5E2;
+ };
197BEE141C76E410005AD5E2 = {
CreatedOnToolsVersion = 7.2.1;
- LastSwiftMigration = 0800;
+ LastSwiftMigration = 1020;
};
};
};
buildConfigurationList = 197BEE101C76E410005AD5E2 /* Build configuration list for PBXProject "Stopwatch" */;
compatibilityVersion = "Xcode 3.2";
- developmentRegion = English;
+ developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
@@ -117,11 +174,19 @@
projectRoot = "";
targets = (
197BEE141C76E410005AD5E2 /* Stopwatch */,
+ 1931198920D35E380079AC04 /* StopwatchTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
+ 1931198820D35E380079AC04 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
197BEE131C76E410005AD5E2 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@@ -135,6 +200,14 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
+ 1931198620D35E380079AC04 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 1931198D20D35E380079AC04 /* StopwatchTests.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
197BEE111C76E410005AD5E2 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -147,6 +220,14 @@
};
/* End PBXSourcesBuildPhase section */
+/* Begin PBXTargetDependency section */
+ 1931199020D35E380079AC04 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 197BEE141C76E410005AD5E2 /* Stopwatch */;
+ targetProxy = 1931198F20D35E380079AC04 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
/* Begin PBXVariantGroup section */
197BEE1C1C76E410005AD5E2 /* Main.storyboard */ = {
isa = PBXVariantGroup;
@@ -167,22 +248,86 @@
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
+ 1931199220D35E380079AC04 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ CODE_SIGN_STYLE = Automatic;
+ DEVELOPMENT_TEAM = 44JDRP3T56;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ INFOPLIST_FILE = StopwatchTests/Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.4;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = yigu.StopwatchTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Stopwatch.app/Stopwatch";
+ };
+ name = Debug;
+ };
+ 1931199320D35E380079AC04 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ CODE_SIGN_STYLE = Automatic;
+ DEVELOPMENT_TEAM = 44JDRP3T56;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ INFOPLIST_FILE = StopwatchTests/Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.4;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = yigu.StopwatchTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Stopwatch.app/Stopwatch";
+ };
+ name = Release;
+ };
197BEE251C76E410005AD5E2 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -205,7 +350,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 9.2;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -218,18 +363,27 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -246,7 +400,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 9.2;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
@@ -263,7 +417,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.yigu.Stopwatch;
PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 3.0;
+ SWIFT_VERSION = 5.0;
};
name = Debug;
};
@@ -275,13 +429,22 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.yigu.Stopwatch;
PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 3.0;
+ SWIFT_VERSION = 5.0;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
+ 1931199120D35E380079AC04 /* Build configuration list for PBXNativeTarget "StopwatchTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1931199220D35E380079AC04 /* Debug */,
+ 1931199320D35E380079AC04 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
197BEE101C76E410005AD5E2 /* Build configuration list for PBXProject "Stopwatch" */ = {
isa = XCConfigurationList;
buildConfigurations = (
diff --git a/Project 03 - Stopwatch/Stopwatch.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Project 02 - Stopwatch/Stopwatch.xcodeproj/project.xcworkspace/contents.xcworkspacedata
similarity index 100%
rename from Project 03 - Stopwatch/Stopwatch.xcodeproj/project.xcworkspace/contents.xcworkspacedata
rename to Project 02 - Stopwatch/Stopwatch.xcodeproj/project.xcworkspace/contents.xcworkspacedata
diff --git a/Project 02 - Stopwatch/Stopwatch.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Project 02 - Stopwatch/Stopwatch.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 00000000..18d98100
--- /dev/null
+++ b/Project 02 - Stopwatch/Stopwatch.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/Project 03 - Stopwatch/Stopwatch/AppDelegate.swift b/Project 02 - Stopwatch/Stopwatch/AppDelegate.swift
similarity index 81%
rename from Project 03 - Stopwatch/Stopwatch/AppDelegate.swift
rename to Project 02 - Stopwatch/Stopwatch/AppDelegate.swift
index 708ad41f..66eda8eb 100644
--- a/Project 03 - Stopwatch/Stopwatch/AppDelegate.swift
+++ b/Project 02 - Stopwatch/Stopwatch/AppDelegate.swift
@@ -12,7 +12,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
- func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
+ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
diff --git a/Project 03 - Stopwatch/Stopwatch/Assets.xcassets/AppIcon.appiconset/Contents.json b/Project 02 - Stopwatch/Stopwatch/Assets.xcassets/AppIcon.appiconset/Contents.json
similarity index 100%
rename from Project 03 - Stopwatch/Stopwatch/Assets.xcassets/AppIcon.appiconset/Contents.json
rename to Project 02 - Stopwatch/Stopwatch/Assets.xcassets/AppIcon.appiconset/Contents.json
diff --git a/Project 02 - LoveTweet/LoveTweet/Base.lproj/LaunchScreen.storyboard b/Project 02 - Stopwatch/Stopwatch/Base.lproj/LaunchScreen.storyboard
similarity index 100%
rename from Project 02 - LoveTweet/LoveTweet/Base.lproj/LaunchScreen.storyboard
rename to Project 02 - Stopwatch/Stopwatch/Base.lproj/LaunchScreen.storyboard
diff --git a/Project 03 - Stopwatch/Stopwatch/Base.lproj/Main.storyboard b/Project 02 - Stopwatch/Stopwatch/Base.lproj/Main.storyboard
similarity index 100%
rename from Project 03 - Stopwatch/Stopwatch/Base.lproj/Main.storyboard
rename to Project 02 - Stopwatch/Stopwatch/Base.lproj/Main.storyboard
diff --git a/Project 02 - LoveTweet/LoveTweet/Info.plist b/Project 02 - Stopwatch/Stopwatch/Info.plist
similarity index 100%
rename from Project 02 - LoveTweet/LoveTweet/Info.plist
rename to Project 02 - Stopwatch/Stopwatch/Info.plist
diff --git a/Project 03 - Stopwatch/Stopwatch/Stopwatch.swift b/Project 02 - Stopwatch/Stopwatch/Stopwatch.swift
similarity index 100%
rename from Project 03 - Stopwatch/Stopwatch/Stopwatch.swift
rename to Project 02 - Stopwatch/Stopwatch/Stopwatch.swift
diff --git a/Project 03 - Stopwatch/Stopwatch/ViewController.swift b/Project 02 - Stopwatch/Stopwatch/ViewController.swift
similarity index 79%
rename from Project 03 - Stopwatch/Stopwatch/ViewController.swift
rename to Project 02 - Stopwatch/Stopwatch/ViewController.swift
index 1c650d16..c5b1c165 100644
--- a/Project 03 - Stopwatch/Stopwatch/ViewController.swift
+++ b/Project 02 - Stopwatch/Stopwatch/ViewController.swift
@@ -8,28 +8,28 @@
import UIKit
class ViewController: UIViewController, UITableViewDelegate {
+ // MARK: - Variables
fileprivate let mainStopwatch: Stopwatch = Stopwatch()
fileprivate let lapStopwatch: Stopwatch = Stopwatch()
fileprivate var isPlay: Bool = false
fileprivate var laps: [String] = []
-
- // MARK: disable landscape mode
- override var shouldAutorotate : Bool {
- return false
- }
-
- override var supportedInterfaceOrientations : UIInterfaceOrientationMask {
- return UIInterfaceOrientationMask.portrait
- }
+ // MARK: - UI components
@IBOutlet weak var timerLabel: UILabel!
@IBOutlet weak var lapTimerLabel: UILabel!
@IBOutlet weak var playPauseButton: UIButton!
@IBOutlet weak var lapRestButton: UIButton!
@IBOutlet weak var lapsTableView: UITableView!
+ // MARK: - Life Cycle
override func viewDidLoad() {
super.viewDidLoad()
+
+ let initCircleButton: (UIButton) -> Void = { button in
+ button.layer.cornerRadius = 0.5 * button.bounds.size.width
+ button.backgroundColor = UIColor.white
+ }
+
initCircleButton(playPauseButton)
initCircleButton(lapRestButton)
@@ -39,36 +39,43 @@ class ViewController: UIViewController, UITableViewDelegate {
lapsTableView.dataSource = self;
}
- fileprivate func initCircleButton(_ button: UIButton) {
- button.layer.cornerRadius = 0.5 * button.bounds.size.width
- button.backgroundColor = UIColor.white
+ // MARK: - UI Settings
+ override var shouldAutorotate : Bool {
+ return false
}
- // MARK: hide status bar
override var preferredStatusBarStyle : UIStatusBarStyle {
return UIStatusBarStyle.lightContent
}
- // MARK: play, pause, lap, and reset
+ override var supportedInterfaceOrientations : UIInterfaceOrientationMask {
+ return UIInterfaceOrientationMask.portrait
+ }
+
+ // MARK: - Actions
@IBAction func playPauseTimer(_ sender: AnyObject) {
lapRestButton.isEnabled = true
+
changeButton(lapRestButton, title: "Lap", titleColor: UIColor.black)
+
if !isPlay {
- mainStopwatch.timer = Timer.scheduledTimer(timeInterval: 0.035, target: self, selector: Selector.updateMainTimer, userInfo: nil, repeats: true)
- lapStopwatch.timer = Timer.scheduledTimer(timeInterval: 0.035, target: self, selector: Selector.updateLapTimer, userInfo: nil, repeats: true)
+ unowned let weakSelf = self
- RunLoop.current.add(mainStopwatch.timer, forMode: .commonModes)
- RunLoop.current.add(lapStopwatch.timer, forMode: .commonModes)
+ mainStopwatch.timer = Timer.scheduledTimer(timeInterval: 0.035, target: weakSelf, selector: Selector.updateMainTimer, userInfo: nil, repeats: true)
+ lapStopwatch.timer = Timer.scheduledTimer(timeInterval: 0.035, target: weakSelf, selector: Selector.updateLapTimer, userInfo: nil, repeats: true)
+
+ RunLoop.current.add(mainStopwatch.timer, forMode: RunLoop.Mode.common)
+ RunLoop.current.add(lapStopwatch.timer, forMode: RunLoop.Mode.common)
isPlay = true
changeButton(playPauseButton, title: "Stop", titleColor: UIColor.red)
} else {
+
mainStopwatch.timer.invalidate()
lapStopwatch.timer.invalidate()
isPlay = false
changeButton(playPauseButton, title: "Start", titleColor: UIColor.green)
changeButton(lapRestButton, title: "Reset", titleColor: UIColor.black)
-
}
}
@@ -84,17 +91,18 @@ class ViewController: UIViewController, UITableViewDelegate {
}
lapsTableView.reloadData()
resetLapTimer()
- lapStopwatch.timer = Timer.scheduledTimer(timeInterval: 0.035, target: self, selector: Selector.updateLapTimer, userInfo: nil, repeats: true)
- RunLoop.current.add(lapStopwatch.timer, forMode: .commonModes)
+ unowned let weakSelf = self
+ lapStopwatch.timer = Timer.scheduledTimer(timeInterval: 0.035, target: weakSelf, selector: Selector.updateLapTimer, userInfo: nil, repeats: true)
+ RunLoop.current.add(lapStopwatch.timer, forMode: RunLoop.Mode.common)
}
}
+ // MARK: - Private Helpers
fileprivate func changeButton(_ button: UIButton, title: String, titleColor: UIColor) {
- button.setTitle(title, for: UIControlState())
- button.setTitleColor(titleColor, for: UIControlState())
+ button.setTitle(title, for: UIControl.State())
+ button.setTitleColor(titleColor, for: UIControl.State())
}
- // MARK: reset timer seperately
fileprivate func resetMainTimer() {
resetTimer(mainStopwatch, label: timerLabel)
laps.removeAll()
@@ -110,13 +118,12 @@ class ViewController: UIViewController, UITableViewDelegate {
stopwatch.counter = 0.0
label.text = "00:00:00"
}
-
- // MARK: update two timer labels seperately
- func updateMainTimer() {
+
+ @objc func updateMainTimer() {
updateTimer(mainStopwatch, label: timerLabel)
}
- func updateLapTimer() {
+ @objc func updateLapTimer() {
updateTimer(lapStopwatch, label: lapTimerLabel)
}
@@ -137,7 +144,7 @@ class ViewController: UIViewController, UITableViewDelegate {
}
}
-// MARK: tableView dataSource
+// MARK: - UITableViewDataSource
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return laps.count
@@ -158,8 +165,8 @@ extension ViewController: UITableViewDataSource {
}
}
+// MARK: - Extension
fileprivate extension Selector {
static let updateMainTimer = #selector(ViewController.updateMainTimer)
static let updateLapTimer = #selector(ViewController.updateLapTimer)
}
-
diff --git a/Project 02 - Stopwatch/StopwatchTests/Info.plist b/Project 02 - Stopwatch/StopwatchTests/Info.plist
new file mode 100644
index 00000000..6c40a6cd
--- /dev/null
+++ b/Project 02 - Stopwatch/StopwatchTests/Info.plist
@@ -0,0 +1,22 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ BNDL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1
+
+
diff --git a/Project 17 - BlueLibrarySwift/BlueLibrarySwiftTests/BlueLibrarySwiftTests.swift b/Project 02 - Stopwatch/StopwatchTests/StopwatchTests.swift
similarity index 70%
rename from Project 17 - BlueLibrarySwift/BlueLibrarySwiftTests/BlueLibrarySwiftTests.swift
rename to Project 02 - Stopwatch/StopwatchTests/StopwatchTests.swift
index 5d26e007..515fc7de 100644
--- a/Project 17 - BlueLibrarySwift/BlueLibrarySwiftTests/BlueLibrarySwiftTests.swift
+++ b/Project 02 - Stopwatch/StopwatchTests/StopwatchTests.swift
@@ -1,15 +1,14 @@
//
-// BlueLibrarySwiftTests.swift
-// BlueLibrarySwiftTests
+// StopwatchTests.swift
+// StopwatchTests
//
-// Created by Vincent Ngo on 11/1/14.
-// Copyright (c) 2014 Raywenderlich. All rights reserved.
+// Created by Yi Gu on 6/14/18.
+// Copyright © 2018 YiGu. All rights reserved.
//
-import UIKit
import XCTest
-class BlueLibrarySwiftTests: XCTestCase {
+class StopwatchTests: XCTestCase {
override func setUp() {
super.setUp()
@@ -23,12 +22,12 @@ class BlueLibrarySwiftTests: XCTestCase {
func testExample() {
// This is an example of a functional test case.
- XCTAssert(true, "Pass")
+ // Use XCTAssert and related functions to verify your tests produce the correct results.
}
func testPerformanceExample() {
// This is an example of a performance test case.
- self.measure() {
+ self.measure {
// Put the code you want to measure the time of here.
}
}
diff --git a/Project 03 - FacebookMe/FacebookMe.gif b/Project 03 - FacebookMe/FacebookMe.gif
new file mode 100644
index 00000000..755d1cd3
Binary files /dev/null and b/Project 03 - FacebookMe/FacebookMe.gif differ
diff --git a/Project 03 - FacebookMe/FacebookMe.xcodeproj/project.pbxproj b/Project 03 - FacebookMe/FacebookMe.xcodeproj/project.pbxproj
new file mode 100644
index 00000000..62a8ab8c
--- /dev/null
+++ b/Project 03 - FacebookMe/FacebookMe.xcodeproj/project.pbxproj
@@ -0,0 +1,377 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 191804011EB67FC9007753C4 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 191804001EB67FC9007753C4 /* AppDelegate.swift */; };
+ 191804081EB67FC9007753C4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 191804071EB67FC9007753C4 /* Assets.xcassets */; };
+ 1918040B1EB67FC9007753C4 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 191804091EB67FC9007753C4 /* LaunchScreen.storyboard */; };
+ 191804131EB68093007753C4 /* FBMeBaseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 191804121EB68093007753C4 /* FBMeBaseViewController.swift */; };
+ 191804161EB6819F007753C4 /* Specs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 191804151EB6819F007753C4 /* Specs.swift */; };
+ 191804191EB68395007753C4 /* UIColor+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 191804181EB68395007753C4 /* UIColor+Extension.swift */; };
+ 1918041B1EB684F6007753C4 /* FBMeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1918041A1EB684F6007753C4 /* FBMeViewController.swift */; };
+ 1918041D1EB686AA007753C4 /* FBMeBaseCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1918041C1EB686AA007753C4 /* FBMeBaseCell.swift */; };
+ 191804201EB693D3007753C4 /* FBMeUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1918041F1EB693D3007753C4 /* FBMeUser.swift */; };
+ 191804231EB69AF5007753C4 /* TableKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = 191804221EB69AF5007753C4 /* TableKeys.swift */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 191803FD1EB67FC9007753C4 /* FacebookMe.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FacebookMe.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 191804001EB67FC9007753C4 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ 191804071EB67FC9007753C4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ 1918040A1EB67FC9007753C4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
+ 1918040C1EB67FC9007753C4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ 191804121EB68093007753C4 /* FBMeBaseViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FBMeBaseViewController.swift; sourceTree = ""; };
+ 191804151EB6819F007753C4 /* Specs.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Specs.swift; sourceTree = ""; };
+ 191804181EB68395007753C4 /* UIColor+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+Extension.swift"; sourceTree = ""; };
+ 1918041A1EB684F6007753C4 /* FBMeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FBMeViewController.swift; sourceTree = ""; };
+ 1918041C1EB686AA007753C4 /* FBMeBaseCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FBMeBaseCell.swift; sourceTree = ""; };
+ 1918041F1EB693D3007753C4 /* FBMeUser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FBMeUser.swift; sourceTree = ""; };
+ 191804221EB69AF5007753C4 /* TableKeys.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableKeys.swift; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 191803FA1EB67FC9007753C4 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 191803F41EB67FC9007753C4 = {
+ isa = PBXGroup;
+ children = (
+ 191803FF1EB67FC9007753C4 /* FacebookMe */,
+ 191803FE1EB67FC9007753C4 /* Products */,
+ );
+ sourceTree = "";
+ };
+ 191803FE1EB67FC9007753C4 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 191803FD1EB67FC9007753C4 /* FacebookMe.app */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 191803FF1EB67FC9007753C4 /* FacebookMe */ = {
+ isa = PBXGroup;
+ children = (
+ 191804001EB67FC9007753C4 /* AppDelegate.swift */,
+ 191804171EB681B2007753C4 /* Helper */,
+ 191804141EB68099007753C4 /* ViewController */,
+ 1918041E1EB686B1007753C4 /* View */,
+ 191804211EB69401007753C4 /* Model */,
+ 191804091EB67FC9007753C4 /* LaunchScreen.storyboard */,
+ 1918040C1EB67FC9007753C4 /* Info.plist */,
+ 191804071EB67FC9007753C4 /* Assets.xcassets */,
+ );
+ path = FacebookMe;
+ sourceTree = "";
+ };
+ 191804141EB68099007753C4 /* ViewController */ = {
+ isa = PBXGroup;
+ children = (
+ 191804121EB68093007753C4 /* FBMeBaseViewController.swift */,
+ 1918041A1EB684F6007753C4 /* FBMeViewController.swift */,
+ );
+ name = ViewController;
+ sourceTree = "";
+ };
+ 191804171EB681B2007753C4 /* Helper */ = {
+ isa = PBXGroup;
+ children = (
+ 191804151EB6819F007753C4 /* Specs.swift */,
+ 191804181EB68395007753C4 /* UIColor+Extension.swift */,
+ 191804221EB69AF5007753C4 /* TableKeys.swift */,
+ );
+ name = Helper;
+ sourceTree = "";
+ };
+ 1918041E1EB686B1007753C4 /* View */ = {
+ isa = PBXGroup;
+ children = (
+ 1918041C1EB686AA007753C4 /* FBMeBaseCell.swift */,
+ );
+ name = View;
+ sourceTree = "";
+ };
+ 191804211EB69401007753C4 /* Model */ = {
+ isa = PBXGroup;
+ children = (
+ 1918041F1EB693D3007753C4 /* FBMeUser.swift */,
+ );
+ name = Model;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 191803FC1EB67FC9007753C4 /* FacebookMe */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 1918040F1EB67FC9007753C4 /* Build configuration list for PBXNativeTarget "FacebookMe" */;
+ buildPhases = (
+ 191803F91EB67FC9007753C4 /* Sources */,
+ 191803FA1EB67FC9007753C4 /* Frameworks */,
+ 191803FB1EB67FC9007753C4 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = FacebookMe;
+ productName = FacebookMe;
+ productReference = 191803FD1EB67FC9007753C4 /* FacebookMe.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 191803F51EB67FC9007753C4 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastSwiftUpdateCheck = 0830;
+ LastUpgradeCheck = 1020;
+ ORGANIZATIONNAME = "Yi Gu";
+ TargetAttributes = {
+ 191803FC1EB67FC9007753C4 = {
+ CreatedOnToolsVersion = 8.3.2;
+ DevelopmentTeam = 44JDRP3T56;
+ LastSwiftMigration = 1020;
+ ProvisioningStyle = Automatic;
+ };
+ };
+ };
+ buildConfigurationList = 191803F81EB67FC9007753C4 /* Build configuration list for PBXProject "FacebookMe" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 191803F41EB67FC9007753C4;
+ productRefGroup = 191803FE1EB67FC9007753C4 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 191803FC1EB67FC9007753C4 /* FacebookMe */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 191803FB1EB67FC9007753C4 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 1918040B1EB67FC9007753C4 /* LaunchScreen.storyboard in Resources */,
+ 191804081EB67FC9007753C4 /* Assets.xcassets in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 191803F91EB67FC9007753C4 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 1918041B1EB684F6007753C4 /* FBMeViewController.swift in Sources */,
+ 191804161EB6819F007753C4 /* Specs.swift in Sources */,
+ 1918041D1EB686AA007753C4 /* FBMeBaseCell.swift in Sources */,
+ 191804011EB67FC9007753C4 /* AppDelegate.swift in Sources */,
+ 191804131EB68093007753C4 /* FBMeBaseViewController.swift in Sources */,
+ 191804191EB68395007753C4 /* UIColor+Extension.swift in Sources */,
+ 191804231EB69AF5007753C4 /* TableKeys.swift in Sources */,
+ 191804201EB693D3007753C4 /* FBMeUser.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ 191804091EB67FC9007753C4 /* LaunchScreen.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 1918040A1EB67FC9007753C4 /* Base */,
+ );
+ name = LaunchScreen.storyboard;
+ sourceTree = "";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 1918040D1EB67FC9007753C4 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 1918040E1EB67FC9007753C4 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 191804101EB67FC9007753C4 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ DEVELOPMENT_TEAM = 44JDRP3T56;
+ GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+ INFOPLIST_FILE = FacebookMe/Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 10.0;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = yigu.FacebookMe;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Debug;
+ };
+ 191804111EB67FC9007753C4 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ DEVELOPMENT_TEAM = 44JDRP3T56;
+ GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+ INFOPLIST_FILE = FacebookMe/Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 10.0;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = yigu.FacebookMe;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 191803F81EB67FC9007753C4 /* Build configuration list for PBXProject "FacebookMe" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1918040D1EB67FC9007753C4 /* Debug */,
+ 1918040E1EB67FC9007753C4 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 1918040F1EB67FC9007753C4 /* Build configuration list for PBXNativeTarget "FacebookMe" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 191804101EB67FC9007753C4 /* Debug */,
+ 191804111EB67FC9007753C4 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 191803F51EB67FC9007753C4 /* Project object */;
+}
diff --git a/Project 02 - LoveTweet/LoveTweet.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Project 03 - FacebookMe/FacebookMe.xcodeproj/project.xcworkspace/contents.xcworkspacedata
similarity index 70%
rename from Project 02 - LoveTweet/LoveTweet.xcodeproj/project.xcworkspace/contents.xcworkspacedata
rename to Project 03 - FacebookMe/FacebookMe.xcodeproj/project.xcworkspace/contents.xcworkspacedata
index 81b6b941..425a07f6 100644
--- a/Project 02 - LoveTweet/LoveTweet.xcodeproj/project.xcworkspace/contents.xcworkspacedata
+++ b/Project 03 - FacebookMe/FacebookMe.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -2,6 +2,6 @@
+ location = "self:FacebookMe.xcodeproj">
diff --git a/Project 03 - FacebookMe/FacebookMe.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Project 03 - FacebookMe/FacebookMe.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 00000000..18d98100
--- /dev/null
+++ b/Project 03 - FacebookMe/FacebookMe.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/Project 03 - FacebookMe/FacebookMe/AppDelegate.swift b/Project 03 - FacebookMe/FacebookMe/AppDelegate.swift
new file mode 100644
index 00000000..c556e345
--- /dev/null
+++ b/Project 03 - FacebookMe/FacebookMe/AppDelegate.swift
@@ -0,0 +1,24 @@
+//
+// AppDelegate.swift
+// FacebookMe
+//
+// Copyright © 2017 Yi Gu. All rights reserved.
+//
+
+import UIKit
+
+@UIApplicationMain
+class AppDelegate: UIResponder, UIApplicationDelegate {
+
+ var window: UIWindow?
+
+ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
+
+ window = UIWindow(frame: UIScreen.main.bounds)
+ window?.rootViewController = UINavigationController(rootViewController: FBMeViewController())
+ window?.makeKeyAndVisible()
+
+ return true
+ }
+}
+
diff --git a/Project 18 - ClassicPhotos/ClassicPhotos/Images.xcassets/AppIcon.appiconset/Contents.json b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/AppIcon.appiconset/Contents.json
similarity index 100%
rename from Project 18 - ClassicPhotos/ClassicPhotos/Images.xcassets/AppIcon.appiconset/Contents.json
rename to Project 03 - FacebookMe/FacebookMe/Assets.xcassets/AppIcon.appiconset/Contents.json
diff --git a/Project 04 - Todo/Todo/Assets.xcassets/Contents.json b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/Contents.json
similarity index 100%
rename from Project 04 - Todo/Todo/Assets.xcassets/Contents.json
rename to Project 03 - FacebookMe/FacebookMe/Assets.xcassets/Contents.json
diff --git a/Project 28 - SlidebarMenu/SlidebarMenu/Assets.xcassets/map.imageset/Contents.json b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/bayMax.imageset/Contents.json
similarity index 88%
rename from Project 28 - SlidebarMenu/SlidebarMenu/Assets.xcassets/map.imageset/Contents.json
rename to Project 03 - FacebookMe/FacebookMe/Assets.xcassets/bayMax.imageset/Contents.json
index 7150a8c9..fb82202d 100644
--- a/Project 28 - SlidebarMenu/SlidebarMenu/Assets.xcassets/map.imageset/Contents.json
+++ b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/bayMax.imageset/Contents.json
@@ -2,7 +2,6 @@
"images" : [
{
"idiom" : "universal",
- "filename" : "map.png",
"scale" : "1x"
},
{
@@ -11,6 +10,7 @@
},
{
"idiom" : "universal",
+ "filename" : "images.jpeg",
"scale" : "3x"
}
],
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/bayMax.imageset/images.jpeg b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/bayMax.imageset/images.jpeg
new file mode 100644
index 00000000..c3f9a464
Binary files /dev/null and b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/bayMax.imageset/images.jpeg differ
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_education.imageset/Contents.json b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_education.imageset/Contents.json
new file mode 100644
index 00000000..cb23eab2
--- /dev/null
+++ b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_education.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "fb_glyphs_education_20_20x20_@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "fb_glyphs_education_20_20x20_@3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_education.imageset/fb_glyphs_education_20_20x20_@2x.png b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_education.imageset/fb_glyphs_education_20_20x20_@2x.png
new file mode 100644
index 00000000..8f794cda
Binary files /dev/null and b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_education.imageset/fb_glyphs_education_20_20x20_@2x.png differ
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_education.imageset/fb_glyphs_education_20_20x20_@3x.png b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_education.imageset/fb_glyphs_education_20_20x20_@3x.png
new file mode 100644
index 00000000..88e70d32
Binary files /dev/null and b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_education.imageset/fb_glyphs_education_20_20x20_@3x.png differ
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_events.imageset/Contents.json b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_events.imageset/Contents.json
new file mode 100644
index 00000000..6d36d37d
--- /dev/null
+++ b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_events.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "fb_glyphs_calendar_20_20x20_@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "fb_glyphs_calendar_20_20x20_@3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_events.imageset/fb_glyphs_calendar_20_20x20_@2x.png b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_events.imageset/fb_glyphs_calendar_20_20x20_@2x.png
new file mode 100644
index 00000000..cf558c64
Binary files /dev/null and b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_events.imageset/fb_glyphs_calendar_20_20x20_@2x.png differ
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_events.imageset/fb_glyphs_calendar_20_20x20_@3x.png b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_events.imageset/fb_glyphs_calendar_20_20x20_@3x.png
new file mode 100644
index 00000000..8bdba013
Binary files /dev/null and b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_events.imageset/fb_glyphs_calendar_20_20x20_@3x.png differ
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_friends.imageset/Contents.json b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_friends.imageset/Contents.json
new file mode 100644
index 00000000..478399b9
--- /dev/null
+++ b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_friends.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "fb_glyphs_friend-friends_20_20x20_@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "fb_glyphs_friend-friends_20_20x20_@3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_friends.imageset/fb_glyphs_friend-friends_20_20x20_@2x.png b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_friends.imageset/fb_glyphs_friend-friends_20_20x20_@2x.png
new file mode 100644
index 00000000..11984937
Binary files /dev/null and b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_friends.imageset/fb_glyphs_friend-friends_20_20x20_@2x.png differ
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_friends.imageset/fb_glyphs_friend-friends_20_20x20_@3x.png b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_friends.imageset/fb_glyphs_friend-friends_20_20x20_@3x.png
new file mode 100644
index 00000000..6c8e1832
Binary files /dev/null and b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_friends.imageset/fb_glyphs_friend-friends_20_20x20_@3x.png differ
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_games.imageset/Contents.json b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_games.imageset/Contents.json
new file mode 100644
index 00000000..e4486088
--- /dev/null
+++ b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_games.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "fb_glyphs_games_20_20x20_@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "fb_glyphs_games_20_20x20_@3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_games.imageset/fb_glyphs_games_20_20x20_@2x.png b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_games.imageset/fb_glyphs_games_20_20x20_@2x.png
new file mode 100644
index 00000000..53031427
Binary files /dev/null and b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_games.imageset/fb_glyphs_games_20_20x20_@2x.png differ
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_games.imageset/fb_glyphs_games_20_20x20_@3x.png b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_games.imageset/fb_glyphs_games_20_20x20_@3x.png
new file mode 100644
index 00000000..0c4a43c5
Binary files /dev/null and b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_games.imageset/fb_glyphs_games_20_20x20_@3x.png differ
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_groups.imageset/Contents.json b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_groups.imageset/Contents.json
new file mode 100644
index 00000000..3494b7c4
--- /dev/null
+++ b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_groups.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "fb_glyphs_app-groups_20_20x20_@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "fb_glyphs_app-groups_20_20x20_@3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_groups.imageset/fb_glyphs_app-groups_20_20x20_@2x.png b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_groups.imageset/fb_glyphs_app-groups_20_20x20_@2x.png
new file mode 100644
index 00000000..11f88df4
Binary files /dev/null and b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_groups.imageset/fb_glyphs_app-groups_20_20x20_@2x.png differ
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_groups.imageset/fb_glyphs_app-groups_20_20x20_@3x.png b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_groups.imageset/fb_glyphs_app-groups_20_20x20_@3x.png
new file mode 100644
index 00000000..3a61c813
Binary files /dev/null and b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_groups.imageset/fb_glyphs_app-groups_20_20x20_@3x.png differ
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_help_and_support.imageset/Contents.json b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_help_and_support.imageset/Contents.json
new file mode 100644
index 00000000..515eb486
--- /dev/null
+++ b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_help_and_support.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "fb_glyphs_question_20_20x20_@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "fb_glyphs_question_20_20x20_@3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_help_and_support.imageset/fb_glyphs_question_20_20x20_@2x.png b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_help_and_support.imageset/fb_glyphs_question_20_20x20_@2x.png
new file mode 100644
index 00000000..1d26f150
Binary files /dev/null and b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_help_and_support.imageset/fb_glyphs_question_20_20x20_@2x.png differ
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_help_and_support.imageset/fb_glyphs_question_20_20x20_@3x.png b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_help_and_support.imageset/fb_glyphs_question_20_20x20_@3x.png
new file mode 100644
index 00000000..4b255daf
Binary files /dev/null and b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_help_and_support.imageset/fb_glyphs_question_20_20x20_@3x.png differ
diff --git a/Project 04 - Todo/Todo/Assets.xcassets/selected/shopping-cart-selected.imageset/Contents.json b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_placeholder.imageset/Contents.json
similarity index 75%
rename from Project 04 - Todo/Todo/Assets.xcassets/selected/shopping-cart-selected.imageset/Contents.json
rename to Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_placeholder.imageset/Contents.json
index 9c5ca47f..55433427 100644
--- a/Project 04 - Todo/Todo/Assets.xcassets/selected/shopping-cart-selected.imageset/Contents.json
+++ b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_placeholder.imageset/Contents.json
@@ -6,11 +6,12 @@
},
{
"idiom" : "universal",
- "filename" : "shopping-cart-selected@2x.png",
+ "filename" : "fb_placeholder@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
+ "filename" : "fb_placeholder@3x.png",
"scale" : "3x"
}
],
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_placeholder.imageset/fb_placeholder@2x.png b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_placeholder.imageset/fb_placeholder@2x.png
new file mode 100644
index 00000000..26e0f446
Binary files /dev/null and b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_placeholder.imageset/fb_placeholder@2x.png differ
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_placeholder.imageset/fb_placeholder@3x.png b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_placeholder.imageset/fb_placeholder@3x.png
new file mode 100644
index 00000000..24753256
Binary files /dev/null and b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_placeholder.imageset/fb_placeholder@3x.png differ
diff --git a/Project 04 - Todo/Todo/Assets.xcassets/selected/phone-selected.imageset/Contents.json b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_privacy_shortcuts.imageset/Contents.json
similarity index 71%
rename from Project 04 - Todo/Todo/Assets.xcassets/selected/phone-selected.imageset/Contents.json
rename to Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_privacy_shortcuts.imageset/Contents.json
index 5981edc5..c4b0f437 100644
--- a/Project 04 - Todo/Todo/Assets.xcassets/selected/phone-selected.imageset/Contents.json
+++ b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_privacy_shortcuts.imageset/Contents.json
@@ -6,11 +6,12 @@
},
{
"idiom" : "universal",
- "filename" : "phone-selected@2x.png",
+ "filename" : "fb_glyphs_lock_20_20x20_@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
+ "filename" : "fb_glyphs_lock_20_20x20_@3x.png",
"scale" : "3x"
}
],
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_privacy_shortcuts.imageset/fb_glyphs_lock_20_20x20_@2x.png b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_privacy_shortcuts.imageset/fb_glyphs_lock_20_20x20_@2x.png
new file mode 100644
index 00000000..a4a4adc8
Binary files /dev/null and b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_privacy_shortcuts.imageset/fb_glyphs_lock_20_20x20_@2x.png differ
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_privacy_shortcuts.imageset/fb_glyphs_lock_20_20x20_@3x.png b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_privacy_shortcuts.imageset/fb_glyphs_lock_20_20x20_@3x.png
new file mode 100644
index 00000000..0df56424
Binary files /dev/null and b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_privacy_shortcuts.imageset/fb_glyphs_lock_20_20x20_@3x.png differ
diff --git a/Project 04 - Todo/Todo/Assets.xcassets/selected/travel-selected.imageset/Contents.json b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_settings.imageset/Contents.json
similarity index 71%
rename from Project 04 - Todo/Todo/Assets.xcassets/selected/travel-selected.imageset/Contents.json
rename to Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_settings.imageset/Contents.json
index 5c9158b2..8c333624 100644
--- a/Project 04 - Todo/Todo/Assets.xcassets/selected/travel-selected.imageset/Contents.json
+++ b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_settings.imageset/Contents.json
@@ -6,11 +6,12 @@
},
{
"idiom" : "universal",
- "filename" : "travel-selected@2x.png",
+ "filename" : "fb_glyphs_gear_20_20x20_@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
+ "filename" : "fb_glyphs_gear_20_20x20_@3x.png",
"scale" : "3x"
}
],
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_settings.imageset/fb_glyphs_gear_20_20x20_@2x.png b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_settings.imageset/fb_glyphs_gear_20_20x20_@2x.png
new file mode 100644
index 00000000..9bd6c8b6
Binary files /dev/null and b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_settings.imageset/fb_glyphs_gear_20_20x20_@2x.png differ
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_settings.imageset/fb_glyphs_gear_20_20x20_@3x.png b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_settings.imageset/fb_glyphs_gear_20_20x20_@3x.png
new file mode 100644
index 00000000..f306fe49
Binary files /dev/null and b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_settings.imageset/fb_glyphs_gear_20_20x20_@3x.png differ
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_town_hall.imageset/Contents.json b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_town_hall.imageset/Contents.json
new file mode 100644
index 00000000..f54b6fee
--- /dev/null
+++ b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_town_hall.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "fb_glyphs_house_20_20x20_@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "fb_glyphs_house_20_20x20_@3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_town_hall.imageset/fb_glyphs_house_20_20x20_@2x.png b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_town_hall.imageset/fb_glyphs_house_20_20x20_@2x.png
new file mode 100644
index 00000000..3ab1b17f
Binary files /dev/null and b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_town_hall.imageset/fb_glyphs_house_20_20x20_@2x.png differ
diff --git a/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_town_hall.imageset/fb_glyphs_house_20_20x20_@3x.png b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_town_hall.imageset/fb_glyphs_house_20_20x20_@3x.png
new file mode 100644
index 00000000..b2504648
Binary files /dev/null and b/Project 03 - FacebookMe/FacebookMe/Assets.xcassets/fb_town_hall.imageset/fb_glyphs_house_20_20x20_@3x.png differ
diff --git a/Project 04 - Todo/Todo/Base.lproj/LaunchScreen.storyboard b/Project 03 - FacebookMe/FacebookMe/Base.lproj/LaunchScreen.storyboard
similarity index 65%
rename from Project 04 - Todo/Todo/Base.lproj/LaunchScreen.storyboard
rename to Project 03 - FacebookMe/FacebookMe/Base.lproj/LaunchScreen.storyboard
index 2e721e18..62ccb99b 100644
--- a/Project 04 - Todo/Todo/Base.lproj/LaunchScreen.storyboard
+++ b/Project 03 - FacebookMe/FacebookMe/Base.lproj/LaunchScreen.storyboard
@@ -1,7 +1,12 @@
-
-
+
+
+
+
+
-
+
+
+
@@ -13,10 +18,9 @@
-
+
-
-
+
diff --git a/Project 03 - FacebookMe/FacebookMe/FBMeBaseCell.swift b/Project 03 - FacebookMe/FacebookMe/FBMeBaseCell.swift
new file mode 100644
index 00000000..2239f9d3
--- /dev/null
+++ b/Project 03 - FacebookMe/FacebookMe/FBMeBaseCell.swift
@@ -0,0 +1,27 @@
+//
+// FBMeBaseCell.swift
+// FacebookMe
+//
+// Copyright © 2017 Yi Gu. All rights reserved.
+//
+
+import UIKit
+
+class FBMeBaseCell: UITableViewCell {
+ static let identifier = "FBMeBaseCell"
+
+ override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
+ super.init(style: .default, reuseIdentifier: reuseIdentifier)
+
+ backgroundColor = Specs.color.white
+ textLabel?.textColor = Specs.color.black
+ textLabel?.font = Specs.font.large
+
+ detailTextLabel?.font = Specs.font.small
+ detailTextLabel?.textColor = Specs.color.gray
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+}
diff --git a/Project 03 - FacebookMe/FacebookMe/FBMeBaseViewController.swift b/Project 03 - FacebookMe/FacebookMe/FBMeBaseViewController.swift
new file mode 100644
index 00000000..f8c9c6e1
--- /dev/null
+++ b/Project 03 - FacebookMe/FacebookMe/FBMeBaseViewController.swift
@@ -0,0 +1,15 @@
+//
+// FBMeBaseViewController.swift
+// FacebookMe
+//
+// Copyright © 2017 Yi Gu. All rights reserved.
+//
+
+import UIKit
+
+class FBMeBaseViewController: UIViewController {
+ override func viewDidLoad() {
+ super.viewDidLoad()
+ view.backgroundColor = Specs.color.gray
+ }
+}
diff --git a/Project 03 - FacebookMe/FacebookMe/FBMeUser.swift b/Project 03 - FacebookMe/FacebookMe/FBMeUser.swift
new file mode 100644
index 00000000..5f064dd4
--- /dev/null
+++ b/Project 03 - FacebookMe/FacebookMe/FBMeUser.swift
@@ -0,0 +1,20 @@
+//
+// FBMeUser.swift
+// FacebookMe
+//
+// Copyright © 2017 Yi Gu. All rights reserved.
+//
+
+import UIKit
+
+class FBMeUser {
+ var name: String
+ var avatarName: String
+ var education: String
+
+ init(name: String, avatarName: String = "bayMax", education: String) {
+ self.name = name
+ self.avatarName = avatarName
+ self.education = education
+ }
+}
diff --git a/Project 03 - FacebookMe/FacebookMe/FBMeViewController.swift b/Project 03 - FacebookMe/FacebookMe/FBMeViewController.swift
new file mode 100644
index 00000000..d74c52dd
--- /dev/null
+++ b/Project 03 - FacebookMe/FacebookMe/FBMeViewController.swift
@@ -0,0 +1,138 @@
+//
+// FBMeViewController.swift
+// FacebookMe
+//
+// Copyright © 2017 Yi Gu. All rights reserved.
+//
+
+import UIKit
+
+class FBMeViewController: FBMeBaseViewController {
+
+ typealias RowModel = [String: String]
+
+ fileprivate var user: FBMeUser {
+ get {
+ return FBMeUser(name: "BayMax", education: "CMU")
+ }
+ }
+
+ fileprivate var tableViewDataSource: [[String: Any]] {
+ get {
+ return TableKeys.populate(withUser: user)
+ }
+ }
+
+ private let tableView: UITableView = {
+ let view = UITableView(frame: .zero, style: .grouped)
+ view.register(FBMeBaseCell.self, forCellReuseIdentifier: FBMeBaseCell.identifier)
+ return view
+ }()
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ title = "Facebook"
+ navigationController?.navigationBar.barTintColor = Specs.color.tint
+
+ tableView.delegate = self
+ tableView.dataSource = self
+ view.addSubview(tableView)
+
+ // Set layout for tableView.
+ tableView.translatesAutoresizingMaskIntoConstraints = false
+ view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[tableView]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["tableView": tableView]))
+ view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[tableView]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["tableView": tableView]))
+ }
+
+ fileprivate func rows(at section: Int) -> [Any] {
+ return tableViewDataSource[section][TableKeys.Rows] as! [Any]
+ }
+
+ fileprivate func title(at section: Int) -> String? {
+ return tableViewDataSource[section][TableKeys.Section] as? String
+ }
+
+ fileprivate func rowModel(at indexPath: IndexPath) -> RowModel {
+ return rows(at: indexPath.section)[indexPath.row] as! RowModel
+ }
+}
+
+extension FBMeViewController: UITableViewDataSource {
+ func numberOfSections(in tableView: UITableView) -> Int {
+ return tableViewDataSource.count
+ }
+
+ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ return rows(at: section).count
+ }
+
+ func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
+ return title(at: section)
+ }
+
+ func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+ let modelForRow = rowModel(at: indexPath)
+ var cell = UITableViewCell()
+
+ guard let title = modelForRow[TableKeys.Title] else {
+ return cell
+ }
+
+ if title == user.name {
+ cell = UITableViewCell.init(style: .subtitle, reuseIdentifier: nil)
+ } else {
+ cell = tableView.dequeueReusableCell(withIdentifier: FBMeBaseCell.identifier, for: indexPath)
+ }
+
+ cell.textLabel?.text = title
+
+ if let imageName = modelForRow[TableKeys.ImageName] {
+ cell.imageView?.image = UIImage(named: imageName)
+ } else if title != TableKeys.logout {
+ cell.imageView?.image = UIImage(named: Specs.imageName.placeholder)
+ }
+
+ if title == user.name {
+ cell.detailTextLabel?.text = modelForRow[TableKeys.SubTitle]
+ }
+
+ return cell
+ }
+}
+
+extension FBMeViewController: UITableViewDelegate {
+ func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
+ let modelForRow = rowModel(at: indexPath)
+
+ guard let title = modelForRow[TableKeys.Title] else {
+ return 0.0
+ }
+
+ if title == user.name {
+ return 64.0
+ } else {
+ return 44.0
+ }
+ }
+
+ func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
+ let modelForRow = rowModel(at: indexPath)
+
+ guard let title = modelForRow[TableKeys.Title] else {
+ return
+ }
+
+ if title == TableKeys.seeMore || title == TableKeys.addFavorites {
+ cell.textLabel?.textColor = Specs.color.tint
+ cell.accessoryType = .none
+ } else if title == TableKeys.logout {
+ cell.textLabel?.centerXAnchor.constraint(equalTo: cell.centerXAnchor).isActive = true
+ cell.textLabel?.textColor = Specs.color.red
+ cell.textLabel?.textAlignment = .center
+ cell.accessoryType = .none
+ } else {
+ cell.accessoryType = .disclosureIndicator
+ }
+ }
+}
diff --git a/Project 04 - Todo/Todo/Info.plist b/Project 03 - FacebookMe/FacebookMe/Info.plist
similarity index 92%
rename from Project 04 - Todo/Todo/Info.plist
rename to Project 03 - FacebookMe/FacebookMe/Info.plist
index 40c6215d..c12df3b8 100644
--- a/Project 04 - Todo/Todo/Info.plist
+++ b/Project 03 - FacebookMe/FacebookMe/Info.plist
@@ -16,16 +16,12 @@
APPL
CFBundleShortVersionString
1.0
- CFBundleSignature
- ????
CFBundleVersion
1
LSRequiresIPhoneOS
UILaunchStoryboardName
LaunchScreen
- UIMainStoryboardFile
- Main
UIRequiredDeviceCapabilities
armv7
diff --git a/Project 03 - FacebookMe/FacebookMe/Specs.swift b/Project 03 - FacebookMe/FacebookMe/Specs.swift
new file mode 100644
index 00000000..d68757a9
--- /dev/null
+++ b/Project 03 - FacebookMe/FacebookMe/Specs.swift
@@ -0,0 +1,66 @@
+//
+// Specs.swift
+// FacebookMe
+//
+// Copyright © 2017 Yi Gu. All rights reserved.
+//
+
+import UIKit
+
+public struct Specs {
+ public struct Color {
+ public let tint = UIColor(hex: 0x3b5998)
+ public let red = UIColor.red
+ public let white = UIColor.white
+ public let black = UIColor.black
+ public let gray = UIColor.lightGray
+ }
+
+ public struct FontSize {
+ public let tiny: CGFloat = 10
+ public let small: CGFloat = 12
+ public let regular: CGFloat = 14
+ public let large: CGFloat = 16
+ }
+
+ public struct Font {
+ private static let regularName = "Helvetica Neue"
+ private static let boldName = "Helvetica Neue Bold"
+ public let tiny = UIFont(name: regularName, size: Specs.fontSize.tiny)
+ public let small = UIFont(name: regularName, size: Specs.fontSize.small)
+ public let regular = UIFont(name: regularName, size: Specs.fontSize.regular)
+ public let large = UIFont(name: regularName, size: Specs.fontSize.large)
+ public let smallBold = UIFont(name: boldName, size: Specs.fontSize.small)
+ public let regularBold = UIFont(name: boldName, size: Specs.fontSize.regular)
+ public let largeBold = UIFont(name: boldName, size: Specs.fontSize.large)
+ }
+
+ public struct ImageName {
+ public let friends = "fb_friends"
+ public let events = "fb_events"
+ public let groups = "fb_groups"
+ public let education = "fb_education"
+ public let townHall = "fb_town_hall"
+ public let instantGames = "fb_games"
+ public let settings = "fb_settings"
+ public let privacyShortcuts = "fb_privacy_shortcuts"
+ public let helpSupport = "fb_help_and_support"
+ public let placeholder = "fb_placeholder"
+ }
+
+ public static var color: Color {
+ return Color()
+ }
+
+ public static var fontSize: FontSize {
+ return FontSize()
+ }
+
+ public static var font: Font {
+ return Font()
+ }
+
+ public static var imageName: ImageName {
+ return ImageName()
+ }
+}
diff --git a/Project 03 - FacebookMe/FacebookMe/TableKeys.swift b/Project 03 - FacebookMe/FacebookMe/TableKeys.swift
new file mode 100644
index 00000000..6f657e10
--- /dev/null
+++ b/Project 03 - FacebookMe/FacebookMe/TableKeys.swift
@@ -0,0 +1,60 @@
+//
+// TableKeys.swift
+// FacebookMe
+//
+// Copyright © 2017 Yi Gu. All rights reserved.
+//
+
+import Foundation
+
+public struct TableKeys {
+ static let Section = "section"
+ static let Rows = "rows"
+ static let ImageName = "imageName"
+ static let Title = "title"
+ static let SubTitle = "subTitle"
+ static let seeMore = "See More..."
+ static let addFavorites = "Add Favorites..."
+ static let logout = "Log Out"
+
+ static func populate(withUser user: FBMeUser) -> [[String: Any]] {
+ return [
+ [
+ TableKeys.Rows: [
+ [TableKeys.ImageName: user.avatarName, TableKeys.Title: user.name, TableKeys.SubTitle: "View your profile"]
+ ]
+ ],
+ [
+ TableKeys.Rows: [
+ [TableKeys.ImageName: Specs.imageName.friends, TableKeys.Title: "Friends"],
+ [TableKeys.ImageName: Specs.imageName.events, TableKeys.Title: "Events"],
+ [TableKeys.ImageName: Specs.imageName.groups, TableKeys.Title: "Groups"],
+ [TableKeys.ImageName: Specs.imageName.education, TableKeys.Title: user.education],
+ [TableKeys.ImageName: Specs.imageName.townHall, TableKeys.Title: "Town Hall"],
+ [TableKeys.ImageName: Specs.imageName.instantGames, TableKeys.Title: "Instant Games"],
+ [TableKeys.Title: TableKeys.seeMore]
+ ]
+ ],
+ [
+ TableKeys.Section: "FAVORITES",
+ TableKeys.Rows: [
+ [TableKeys.Title: TableKeys.addFavorites]
+ ]
+ ],
+ [
+ TableKeys.Rows: [
+ [TableKeys.ImageName: Specs.imageName.settings, TableKeys.Title: "Settings"],
+ [TableKeys.ImageName: Specs.imageName.privacyShortcuts, TableKeys.Title: "Privacy Shortcuts"],
+ [TableKeys.ImageName: Specs.imageName.helpSupport, TableKeys.Title: "Help and Support"]
+ ]
+ ],
+ [
+ TableKeys.Rows: [
+ [TableKeys.Title: TableKeys.logout]
+ ]
+ ]
+ ]
+ }
+}
+
+
diff --git a/Project 03 - FacebookMe/FacebookMe/UIColor+Extension.swift b/Project 03 - FacebookMe/FacebookMe/UIColor+Extension.swift
new file mode 100644
index 00000000..9262a12f
--- /dev/null
+++ b/Project 03 - FacebookMe/FacebookMe/UIColor+Extension.swift
@@ -0,0 +1,18 @@
+//
+// UIColor+Extension.swift
+// FacebookMe
+//
+// Copyright © 2017 Yi Gu. All rights reserved.
+//
+
+import UIKit
+
+public extension UIColor {
+ convenience init(r: Int, g: Int, b: Int, a: CGFloat) {
+ self.init(red: CGFloat(r) / 255, green: CGFloat(g) / 255, blue: CGFloat(b) / 255, alpha: a)
+ }
+
+ convenience init(hex: Int) {
+ self.init(r: (hex & 0xff0000) >> 16, g: (hex & 0xff00) >> 8, b: (hex & 0xff), a: 1)
+ }
+}
diff --git a/Project 03 - FacebookMe/README.md b/Project 03 - FacebookMe/README.md
new file mode 100644
index 00000000..d966db16
--- /dev/null
+++ b/Project 03 - FacebookMe/README.md
@@ -0,0 +1,6 @@
+FacebookMe
+==========
+FacebookMe is a Swift App Mimics the personal profile tab of Facebook. It demos one simple way to implement a UITableView with mutiple sections and different types of cells.
+
+## Screenshots
+
diff --git a/Project 03 - Stopwatch/Stopwatch.xcodeproj/project.xcworkspace/xcuserdata/Yi.xcuserdatad/UserInterfaceState.xcuserstate b/Project 03 - Stopwatch/Stopwatch.xcodeproj/project.xcworkspace/xcuserdata/Yi.xcuserdatad/UserInterfaceState.xcuserstate
deleted file mode 100644
index 2ae97376..00000000
Binary files a/Project 03 - Stopwatch/Stopwatch.xcodeproj/project.xcworkspace/xcuserdata/Yi.xcuserdatad/UserInterfaceState.xcuserstate and /dev/null differ
diff --git a/Project 03 - Stopwatch/Stopwatch.xcodeproj/xcuserdata/Yi.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/Project 03 - Stopwatch/Stopwatch.xcodeproj/xcuserdata/Yi.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
deleted file mode 100644
index fe2b4541..00000000
--- a/Project 03 - Stopwatch/Stopwatch.xcodeproj/xcuserdata/Yi.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
diff --git a/Project 03 - Stopwatch/Stopwatch.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/Stopwatch.xcscheme b/Project 03 - Stopwatch/Stopwatch.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/Stopwatch.xcscheme
deleted file mode 100644
index 35235328..00000000
--- a/Project 03 - Stopwatch/Stopwatch.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/Stopwatch.xcscheme
+++ /dev/null
@@ -1,91 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Project 03 - Stopwatch/Stopwatch.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/xcschememanagement.plist b/Project 03 - Stopwatch/Stopwatch.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/xcschememanagement.plist
deleted file mode 100644
index 17e1bb60..00000000
--- a/Project 03 - Stopwatch/Stopwatch.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/xcschememanagement.plist
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
- SchemeUserState
-
- Stopwatch.xcscheme
-
- orderHint
- 0
-
-
- SuppressBuildableAutocreation
-
- 197BEE141C76E410005AD5E2
-
- primary
-
-
-
-
-
diff --git a/Project 04 - Todo/README.md b/Project 04 - Todo/README.md
deleted file mode 100644
index 7c972ca0..00000000
--- a/Project 04 - Todo/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-Todo
-==========
-Todo is iOS App written by Swift. It is inspired by Jakelin's course in imooc.com and demonstrates how to manipulate tableview. This app shows a way to implement tableview add, edit and delete functions.
-
-## Screenshots
-
diff --git a/Project 04 - Todo/Todo.gif b/Project 04 - Todo/Todo.gif
deleted file mode 100644
index 4bc1c49d..00000000
Binary files a/Project 04 - Todo/Todo.gif and /dev/null differ
diff --git a/Project 04 - Todo/Todo.xcodeproj/project.xcworkspace/xcuserdata/Yi.xcuserdatad/UserInterfaceState.xcuserstate b/Project 04 - Todo/Todo.xcodeproj/project.xcworkspace/xcuserdata/Yi.xcuserdatad/UserInterfaceState.xcuserstate
deleted file mode 100644
index b38d3fca..00000000
Binary files a/Project 04 - Todo/Todo.xcodeproj/project.xcworkspace/xcuserdata/Yi.xcuserdatad/UserInterfaceState.xcuserstate and /dev/null differ
diff --git a/Project 04 - Todo/Todo.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/Todo.xcscheme b/Project 04 - Todo/Todo.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/Todo.xcscheme
deleted file mode 100644
index 275da6ef..00000000
--- a/Project 04 - Todo/Todo.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/Todo.xcscheme
+++ /dev/null
@@ -1,91 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Project 04 - Todo/Todo.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/xcschememanagement.plist b/Project 04 - Todo/Todo.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/xcschememanagement.plist
deleted file mode 100644
index 11cd46f0..00000000
--- a/Project 04 - Todo/Todo.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/xcschememanagement.plist
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
- SchemeUserState
-
- Todo.xcscheme
-
- orderHint
- 0
-
-
- SuppressBuildableAutocreation
-
- 19515F891C8558F800DC2284
-
- primary
-
-
-
-
-
diff --git a/Project 04 - Todo/Todo/AppDelegate.swift b/Project 04 - Todo/Todo/AppDelegate.swift
deleted file mode 100644
index 1f315b4a..00000000
--- a/Project 04 - Todo/Todo/AppDelegate.swift
+++ /dev/null
@@ -1,20 +0,0 @@
-//
-// AppDelegate.swift
-// Todo
-//
-// Copyright © 2016 YiGu. All rights reserved.
-//
-
-import UIKit
-
-@UIApplicationMain
-class AppDelegate: UIResponder, UIApplicationDelegate {
-
- var window: UIWindow?
-
- func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
- // Override point for customization after application launch.
- return true
- }
-}
-
diff --git a/Project 04 - Todo/Todo/Assets.xcassets/selected/child-selected.imageset/child-selected@2x.png b/Project 04 - Todo/Todo/Assets.xcassets/selected/child-selected.imageset/child-selected@2x.png
deleted file mode 100644
index f4286d1e..00000000
Binary files a/Project 04 - Todo/Todo/Assets.xcassets/selected/child-selected.imageset/child-selected@2x.png and /dev/null differ
diff --git a/Project 04 - Todo/Todo/Assets.xcassets/selected/phone-selected.imageset/phone-selected@2x.png b/Project 04 - Todo/Todo/Assets.xcassets/selected/phone-selected.imageset/phone-selected@2x.png
deleted file mode 100644
index 58456fd3..00000000
Binary files a/Project 04 - Todo/Todo/Assets.xcassets/selected/phone-selected.imageset/phone-selected@2x.png and /dev/null differ
diff --git a/Project 04 - Todo/Todo/Assets.xcassets/selected/shopping-cart-selected.imageset/shopping-cart-selected@2x.png b/Project 04 - Todo/Todo/Assets.xcassets/selected/shopping-cart-selected.imageset/shopping-cart-selected@2x.png
deleted file mode 100644
index 34813b71..00000000
Binary files a/Project 04 - Todo/Todo/Assets.xcassets/selected/shopping-cart-selected.imageset/shopping-cart-selected@2x.png and /dev/null differ
diff --git a/Project 04 - Todo/Todo/Assets.xcassets/selected/travel-selected.imageset/travel-selected@2x.png b/Project 04 - Todo/Todo/Assets.xcassets/selected/travel-selected.imageset/travel-selected@2x.png
deleted file mode 100644
index 8b2f1669..00000000
Binary files a/Project 04 - Todo/Todo/Assets.xcassets/selected/travel-selected.imageset/travel-selected@2x.png and /dev/null differ
diff --git a/Project 04 - Todo/Todo/Assets.xcassets/unselected/child.imageset/child@2x.png b/Project 04 - Todo/Todo/Assets.xcassets/unselected/child.imageset/child@2x.png
deleted file mode 100644
index d7027a4f..00000000
Binary files a/Project 04 - Todo/Todo/Assets.xcassets/unselected/child.imageset/child@2x.png and /dev/null differ
diff --git a/Project 04 - Todo/Todo/Assets.xcassets/unselected/phone.imageset/Contents.json b/Project 04 - Todo/Todo/Assets.xcassets/unselected/phone.imageset/Contents.json
deleted file mode 100644
index 5274fd54..00000000
--- a/Project 04 - Todo/Todo/Assets.xcassets/unselected/phone.imageset/Contents.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "images" : [
- {
- "idiom" : "universal",
- "scale" : "1x"
- },
- {
- "idiom" : "universal",
- "filename" : "phone@2x.png",
- "scale" : "2x"
- },
- {
- "idiom" : "universal",
- "scale" : "3x"
- }
- ],
- "info" : {
- "version" : 1,
- "author" : "xcode"
- }
-}
\ No newline at end of file
diff --git a/Project 04 - Todo/Todo/Assets.xcassets/unselected/phone.imageset/phone@2x.png b/Project 04 - Todo/Todo/Assets.xcassets/unselected/phone.imageset/phone@2x.png
deleted file mode 100644
index 55d29179..00000000
Binary files a/Project 04 - Todo/Todo/Assets.xcassets/unselected/phone.imageset/phone@2x.png and /dev/null differ
diff --git a/Project 04 - Todo/Todo/Assets.xcassets/unselected/shopping-cart.imageset/Contents.json b/Project 04 - Todo/Todo/Assets.xcassets/unselected/shopping-cart.imageset/Contents.json
deleted file mode 100644
index 43c62af1..00000000
--- a/Project 04 - Todo/Todo/Assets.xcassets/unselected/shopping-cart.imageset/Contents.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "images" : [
- {
- "idiom" : "universal",
- "scale" : "1x"
- },
- {
- "idiom" : "universal",
- "filename" : "shopping-cart@2x.png",
- "scale" : "2x"
- },
- {
- "idiom" : "universal",
- "scale" : "3x"
- }
- ],
- "info" : {
- "version" : 1,
- "author" : "xcode"
- }
-}
\ No newline at end of file
diff --git a/Project 04 - Todo/Todo/Assets.xcassets/unselected/shopping-cart.imageset/shopping-cart@2x.png b/Project 04 - Todo/Todo/Assets.xcassets/unselected/shopping-cart.imageset/shopping-cart@2x.png
deleted file mode 100644
index 2e194702..00000000
Binary files a/Project 04 - Todo/Todo/Assets.xcassets/unselected/shopping-cart.imageset/shopping-cart@2x.png and /dev/null differ
diff --git a/Project 04 - Todo/Todo/Assets.xcassets/unselected/travel.imageset/travel@2x.png b/Project 04 - Todo/Todo/Assets.xcassets/unselected/travel.imageset/travel@2x.png
deleted file mode 100644
index cc573e90..00000000
Binary files a/Project 04 - Todo/Todo/Assets.xcassets/unselected/travel.imageset/travel@2x.png and /dev/null differ
diff --git a/Project 04 - Todo/Todo/Base.lproj/Main.storyboard b/Project 04 - Todo/Todo/Base.lproj/Main.storyboard
deleted file mode 100644
index 32134e17..00000000
--- a/Project 04 - Todo/Todo/Base.lproj/Main.storyboard
+++ /dev/null
@@ -1,245 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Project 04 - Todo/Todo/DetailViewController.swift b/Project 04 - Todo/Todo/DetailViewController.swift
deleted file mode 100644
index 49b99c98..00000000
--- a/Project 04 - Todo/Todo/DetailViewController.swift
+++ /dev/null
@@ -1,108 +0,0 @@
-//
-// DetailViewController.swift
-// Todo
-//
-// Copyright © 2016 YiGu. All rights reserved.
-//
-
-import UIKit
-
-class DetailViewController: UIViewController {
-
- @IBOutlet weak var childButton: UIButton!
- @IBOutlet weak var phoneButton: UIButton!
- @IBOutlet weak var shoppingCartButton: UIButton!
- @IBOutlet weak var travelButton: UIButton!
- @IBOutlet weak var todoTitleLabel: UITextField!
- @IBOutlet weak var todoDatePicker: UIDatePicker!
-
- var todo: ToDoItem?
-
- override func viewDidLoad() {
- super.viewDidLoad()
-
- if let todo = todo {
- self.title = "Edit Todo"
- if todo.image == "child-selected"{
- childButton.isSelected = true
- }
- else if todo.image == "phone-selected"{
- phoneButton.isSelected = true
- }
- else if todo.image == "shopping-cart-selected"{
- shoppingCartButton.isSelected = true
- }
- else if todo.image == "travel-selected"{
- travelButton.isSelected = true
- }
-
- todoTitleLabel.text = todo.title
- todoDatePicker.setDate(todo.date, animated: false)
- } else {
- title = "New Todo"
- childButton.isSelected = true
- }
- }
-
- // MARK: type select
- @IBAction func selectChild(_ sender: AnyObject) {
- resetButtons()
- childButton.isSelected = true
- }
-
- @IBAction func selectPhone(_ sender: AnyObject) {
- resetButtons()
- phoneButton.isSelected = true
- }
-
- @IBAction func selectShoppingCart(_ sender: AnyObject) {
- resetButtons()
- shoppingCartButton.isSelected = true
- }
-
- @IBAction func selectTravel(_ sender: AnyObject) {
- resetButtons()
- travelButton.isSelected = true
- }
-
- func resetButtons() {
- childButton.isSelected = false
- phoneButton.isSelected = false
- shoppingCartButton.isSelected = false
- travelButton.isSelected = false
- }
-
- // MARK: create or edit a new todo
- @IBAction func tapDone(_ sender: AnyObject) {
- var image = ""
- if childButton.isSelected {
- image = "child-selected"
- }
- else if phoneButton.isSelected {
- image = "phone-selected"
- }
- else if shoppingCartButton.isSelected {
- image = "shopping-cart-selected"
- }
- else if travelButton.isSelected {
- image = "travel-selected"
- }
-
- if let todo = todo {
- todo.image = image
- todo.title = todoTitleLabel.text!
- todo.date = todoDatePicker.date
- } else {
- let uuid = UUID().uuidString
- todo = ToDoItem(id: uuid, image: image, title: todoTitleLabel.text!, date: todoDatePicker.date)
- todos.append(todo!)
- }
-
- let _ = navigationController?.popToRootViewController(animated: true)
- }
-
- override func touchesBegan(_ touches: Set, with event: UIEvent?) {
- super.touchesBegan(touches, with: event)
- view.endEditing(true)
- }
-}
diff --git a/Project 04 - Todo/Todo/ToDoItem.swift b/Project 04 - Todo/Todo/ToDoItem.swift
deleted file mode 100644
index ae9a2127..00000000
--- a/Project 04 - Todo/Todo/ToDoItem.swift
+++ /dev/null
@@ -1,22 +0,0 @@
-//
-// ToDoItem.swift
-// Todo
-//
-// Copyright © 2016 YiGu. All rights reserved.
-//
-
-import Foundation
-
-class ToDoItem: NSObject {
- var id: String
- var image: String
- var title: String
- var date: Date
-
- init(id: String, image: String, title: String, date: Date) {
- self.id = id
- self.image = image
- self.title = title
- self.date = date
- }
-}
diff --git a/Project 04 - Todo/Todo/Utils.swift b/Project 04 - Todo/Todo/Utils.swift
deleted file mode 100644
index 23c13cb1..00000000
--- a/Project 04 - Todo/Todo/Utils.swift
+++ /dev/null
@@ -1,20 +0,0 @@
-//
-// Utils.swift
-// Todo
-//
-// Copyright © 2016 YiGu. All rights reserved.
-//
-
-import Foundation
-
-func dateFromString(_ date: String) -> Date? {
- let dateFormatter = DateFormatter()
- dateFormatter.dateFormat = "yyyy-MM-dd"
- return dateFormatter.date(from: date)
-}
-
-func stringFromDate(_ date: Date) -> String {
- let dateFormatter = DateFormatter()
- dateFormatter.dateFormat = "yyyy-MM-dd"
- return dateFormatter.string(from: date)
-}
diff --git a/Project 04 - Todo/Todo/ViewController.swift b/Project 04 - Todo/Todo/ViewController.swift
deleted file mode 100644
index a7153305..00000000
--- a/Project 04 - Todo/Todo/ViewController.swift
+++ /dev/null
@@ -1,115 +0,0 @@
-//
-// ViewController.swift
-// Todo
-//
-// Copyright © 2016 YiGu. All rights reserved.
-//
-
-import UIKit
-
-var todos: [ToDoItem] = []
-
-class ViewController: UIViewController {
-
- @IBOutlet weak var todoTableView: UITableView!
-
- override func viewDidLoad() {
- super.viewDidLoad()
-
- navigationItem.leftBarButtonItem = editButtonItem
-
- todos = [ToDoItem(id: "1", image: "child-selected", title: "Go to Disney", date: dateFromString("2014-10-20")!),
- ToDoItem(id: "2", image: "shopping-cart-selected", title: "Cicso Shopping", date: dateFromString("2014-10-28")!),
- ToDoItem(id: "3", image: "phone-selected", title: "Phone to Jobs", date: dateFromString("2014-10-30")!),
- ToDoItem(id: "4", image: "travel-selected", title: "Plan to Europe", date: dateFromString("2014-10-31")!)]
- }
-
- override func viewWillAppear(_ animated: Bool) {
- super.viewWillAppear(animated)
- todoTableView.reloadData()
- }
-
- // MARK - helper func
- func setMessageLabel(_ messageLabel: UILabel, frame: CGRect, text: String, textColor: UIColor, numberOfLines: Int, textAlignment: NSTextAlignment, font: UIFont) {
- messageLabel.frame = frame
- messageLabel.text = text
- messageLabel.textColor = textColor
- messageLabel.numberOfLines = numberOfLines
- messageLabel.textAlignment = textAlignment
- messageLabel.font = font
- messageLabel.sizeToFit()
- }
-
- func setCellWithTodoItem(_ cell: UITableViewCell, todo: ToDoItem) {
- let imageView: UIImageView = cell.viewWithTag(11) as! UIImageView
- let titleLabel: UILabel = cell.viewWithTag(12) as! UILabel
- let dateLabel: UILabel = cell.viewWithTag(13) as! UILabel
-
- imageView.image = UIImage(named: todo.image)
- titleLabel.text = todo.title
- dateLabel.text = stringFromDate(todo.date)
- }
-
- override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
- if segue.identifier == "editTodo" {
- let vc = segue.destination as! DetailViewController
- let indexPath = todoTableView.indexPathForSelectedRow
- if let indexPath = indexPath {
- vc.todo = todos[(indexPath as NSIndexPath).row]
- }
- }
- }
-}
-
-extension ViewController: UITableViewDataSource {
- func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
-
- if todos.count != 0 {
- return todos.count
- } else {
- let messageLabel: UILabel = UILabel()
-
- setMessageLabel(messageLabel, frame: CGRect(x: 0, y: 0, width: self.view.bounds.size.width, height: self.view.bounds.size.height), text: "No data is currently available.", textColor: UIColor.black, numberOfLines: 0, textAlignment: NSTextAlignment.center, font: UIFont(name:"Palatino-Italic", size: 20)!)
-
- self.todoTableView.backgroundView = messageLabel
- self.todoTableView.separatorStyle = UITableViewCellSeparatorStyle.none
-
- return 0
- }
- }
-
- func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
- let cellIdentifier: String = "todoCell"
- let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath)
-
- setCellWithTodoItem(cell, todo: todos[(indexPath as NSIndexPath).row])
-
- return cell
- }
-}
-
-extension ViewController: UITableViewDelegate {
- // Edit mode
- override func setEditing(_ editing: Bool, animated: Bool) {
- super.setEditing(editing, animated: animated)
- todoTableView.setEditing(editing, animated: true)
- }
-
- // Delete the cell
- func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
- if editingStyle == UITableViewCellEditingStyle.delete {
- todos.remove(at: (indexPath as NSIndexPath).row)
- todoTableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.automatic)
- }
- }
-
- // Move the cell
- func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
- return self.isEditing
- }
-
- func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
- let todo = todos.remove(at: (sourceIndexPath as NSIndexPath).row)
- todos.insert(todo, at: (destinationIndexPath as NSIndexPath).row)
- }
-}
diff --git a/Project 04 - TodoTDD/README.md b/Project 04 - TodoTDD/README.md
new file mode 100644
index 00000000..60ac2e0b
--- /dev/null
+++ b/Project 04 - TodoTDD/README.md
@@ -0,0 +1,7 @@
+ToDoTDD
+==========
+TodoTDD is a simple to do list iOS App. It is inspired by Dr. Dominik Hauser's book *Test-Driven iOS Developement with Swift 4* and demonstrates how to write unit / UI tests for UI components, network layer, data serizalization, and etc. by following the test driven development process. The code test coverage is 91.9%.
+
+## Screenshots
+
+
diff --git a/Project 04 - TodoTDD/ToDo.xcodeproj/project.pbxproj b/Project 04 - TodoTDD/ToDo.xcodeproj/project.pbxproj
new file mode 100644
index 00000000..ce115a71
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDo.xcodeproj/project.pbxproj
@@ -0,0 +1,738 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 48;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 1962BCA4228768A9000130AD /* APIClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1962BCA3228768A9000130AD /* APIClient.swift */; };
+ 1962BCA6228768CB000130AD /* APIClientTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1962BCA5228768CB000130AD /* APIClientTests.swift */; };
+ 1962BCAB22876BC6000130AD /* Token.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1962BCAA22876BC6000130AD /* Token.swift */; };
+ 1962BCAD2290C8C9000130AD /* StoryboardTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1962BCAC2290C8C9000130AD /* StoryboardTests.swift */; };
+ 19946964227E3B5C00138341 /* InputViewControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19946963227E3B5C00138341 /* InputViewControllerTests.swift */; };
+ 19946966227E3B9200138341 /* InputViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19946965227E3B9200138341 /* InputViewController.swift */; };
+ 19E866A822D180DE001FFAB1 /* ToDoUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19E866A722D180DE001FFAB1 /* ToDoUITests.swift */; };
+ EE47EF1E2141DA5D00C76F03 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE47EF1D2141DA5D00C76F03 /* AppDelegate.swift */; };
+ EE47EF232141DA5D00C76F03 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EE47EF212141DA5D00C76F03 /* Main.storyboard */; };
+ EE47EF252141DA5D00C76F03 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EE47EF242141DA5D00C76F03 /* Assets.xcassets */; };
+ EE47EF282141DA5D00C76F03 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EE47EF262141DA5D00C76F03 /* LaunchScreen.storyboard */; };
+ EE47EF412141DAA700C76F03 /* ToDoItemTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE47EF402141DAA700C76F03 /* ToDoItemTests.swift */; };
+ EE47EF432141DAE500C76F03 /* ToDoItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE47EF422141DAE500C76F03 /* ToDoItem.swift */; };
+ EE47EF462141DFDE00C76F03 /* LocationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE47EF452141DFDE00C76F03 /* LocationTests.swift */; };
+ EE47EF482141DFF300C76F03 /* Location.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE47EF472141DFF300C76F03 /* Location.swift */; };
+ EE47EF4A2141E48700C76F03 /* ToDoItemManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE47EF492141E48700C76F03 /* ToDoItemManagerTests.swift */; };
+ EE47EF4C2141E49F00C76F03 /* ToDoItemManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE47EF4B2141E49F00C76F03 /* ToDoItemManager.swift */; };
+ EE665594215C174500D42DB6 /* ItemCellTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE665593215C174500D42DB6 /* ItemCellTests.swift */; };
+ EE6655E32164492200D42DB6 /* DetailViewControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE6655E22164492200D42DB6 /* DetailViewControllerTests.swift */; };
+ EE6655E52164498C00D42DB6 /* DetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE6655E42164498C00D42DB6 /* DetailViewController.swift */; };
+ EE9333822151C8E8006939C4 /* ItemListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE9333812151C8E8006939C4 /* ItemListViewController.swift */; };
+ EE9333852151C935006939C4 /* ItemListViewControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE9333842151C935006939C4 /* ItemListViewControllerTests.swift */; };
+ EE9333882151F66F006939C4 /* ItemListDataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE9333872151F66F006939C4 /* ItemListDataProvider.swift */; };
+ EE9333A021546ED7006939C4 /* ItemListDataProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE93339F21546ED7006939C4 /* ItemListDataProviderTests.swift */; };
+ EE9333A521547C7F006939C4 /* ItemCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE9333A421547C7F006939C4 /* ItemCell.swift */; };
+ EE9333A82155BC25006939C4 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE9333A72155BC25006939C4 /* Constants.swift */; };
+ EE9333A92155BCCB006939C4 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE9333A121547348006939C4 /* Constants.swift */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 19E866AA22D180DE001FFAB1 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = EE47EF122141DA5D00C76F03 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = EE47EF192141DA5D00C76F03;
+ remoteInfo = ToDo;
+ };
+ EE47EF2F2141DA5D00C76F03 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = EE47EF122141DA5D00C76F03 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = EE47EF192141DA5D00C76F03;
+ remoteInfo = ToDo;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ 1962BCA3228768A9000130AD /* APIClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIClient.swift; sourceTree = ""; };
+ 1962BCA5228768CB000130AD /* APIClientTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIClientTests.swift; sourceTree = ""; };
+ 1962BCAA22876BC6000130AD /* Token.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Token.swift; sourceTree = ""; };
+ 1962BCAC2290C8C9000130AD /* StoryboardTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoryboardTests.swift; sourceTree = ""; };
+ 19946963227E3B5C00138341 /* InputViewControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputViewControllerTests.swift; sourceTree = ""; };
+ 19946965227E3B9200138341 /* InputViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputViewController.swift; sourceTree = ""; };
+ 19E866A522D180DE001FFAB1 /* ToDoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ToDoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ 19E866A722D180DE001FFAB1 /* ToDoUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToDoUITests.swift; sourceTree = ""; };
+ 19E866A922D180DE001FFAB1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ EE47EF1A2141DA5D00C76F03 /* ToDo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ToDo.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ EE47EF1D2141DA5D00C76F03 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ EE47EF222141DA5D00C76F03 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
+ EE47EF242141DA5D00C76F03 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ EE47EF272141DA5D00C76F03 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
+ EE47EF292141DA5D00C76F03 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ EE47EF2E2141DA5D00C76F03 /* ToDoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ToDoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ EE47EF342141DA5D00C76F03 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ EE47EF402141DAA700C76F03 /* ToDoItemTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToDoItemTests.swift; sourceTree = ""; };
+ EE47EF422141DAE500C76F03 /* ToDoItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToDoItem.swift; sourceTree = ""; };
+ EE47EF452141DFDE00C76F03 /* LocationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationTests.swift; sourceTree = ""; };
+ EE47EF472141DFF300C76F03 /* Location.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Location.swift; sourceTree = ""; };
+ EE47EF492141E48700C76F03 /* ToDoItemManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToDoItemManagerTests.swift; sourceTree = ""; };
+ EE47EF4B2141E49F00C76F03 /* ToDoItemManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToDoItemManager.swift; sourceTree = ""; };
+ EE665593215C174500D42DB6 /* ItemCellTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemCellTests.swift; sourceTree = ""; };
+ EE6655E22164492200D42DB6 /* DetailViewControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailViewControllerTests.swift; sourceTree = ""; };
+ EE6655E42164498C00D42DB6 /* DetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailViewController.swift; sourceTree = ""; };
+ EE9333812151C8E8006939C4 /* ItemListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemListViewController.swift; sourceTree = ""; };
+ EE9333842151C935006939C4 /* ItemListViewControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemListViewControllerTests.swift; sourceTree = ""; };
+ EE9333872151F66F006939C4 /* ItemListDataProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemListDataProvider.swift; sourceTree = ""; };
+ EE93339F21546ED7006939C4 /* ItemListDataProviderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemListDataProviderTests.swift; sourceTree = ""; };
+ EE9333A121547348006939C4 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; };
+ EE9333A421547C7F006939C4 /* ItemCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemCell.swift; sourceTree = ""; };
+ EE9333A72155BC25006939C4 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 19E866A222D180DE001FFAB1 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ EE47EF172141DA5D00C76F03 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ EE47EF2B2141DA5D00C76F03 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 1962BCA8228768E8000130AD /* Network */ = {
+ isa = PBXGroup;
+ children = (
+ 1962BCA3228768A9000130AD /* APIClient.swift */,
+ 1962BCAA22876BC6000130AD /* Token.swift */,
+ );
+ path = Network;
+ sourceTree = "";
+ };
+ 1962BCA9228768F4000130AD /* Network */ = {
+ isa = PBXGroup;
+ children = (
+ 1962BCA5228768CB000130AD /* APIClientTests.swift */,
+ );
+ path = Network;
+ sourceTree = "";
+ };
+ 19E866A622D180DE001FFAB1 /* ToDoUITests */ = {
+ isa = PBXGroup;
+ children = (
+ 19E866A722D180DE001FFAB1 /* ToDoUITests.swift */,
+ 19E866A922D180DE001FFAB1 /* Info.plist */,
+ );
+ path = ToDoUITests;
+ sourceTree = "";
+ };
+ EE47EF112141DA5D00C76F03 = {
+ isa = PBXGroup;
+ children = (
+ EE47EF1C2141DA5D00C76F03 /* ToDo */,
+ EE47EF312141DA5D00C76F03 /* ToDoTests */,
+ 19E866A622D180DE001FFAB1 /* ToDoUITests */,
+ EE47EF1B2141DA5D00C76F03 /* Products */,
+ );
+ sourceTree = "";
+ };
+ EE47EF1B2141DA5D00C76F03 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ EE47EF1A2141DA5D00C76F03 /* ToDo.app */,
+ EE47EF2E2141DA5D00C76F03 /* ToDoTests.xctest */,
+ 19E866A522D180DE001FFAB1 /* ToDoUITests.xctest */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ EE47EF1C2141DA5D00C76F03 /* ToDo */ = {
+ isa = PBXGroup;
+ children = (
+ 1962BCA8228768E8000130AD /* Network */,
+ EE9333A621547C86006939C4 /* Views */,
+ EE47EF3E2141DA7800C76F03 /* ViewControllers */,
+ EE47EF442141DAF000C76F03 /* Models */,
+ EE47EF3F2141DA8700C76F03 /* Storyboards */,
+ EE47EF3D2141DA7000C76F03 /* Others */,
+ );
+ path = ToDo;
+ sourceTree = "";
+ };
+ EE47EF312141DA5D00C76F03 /* ToDoTests */ = {
+ isa = PBXGroup;
+ children = (
+ 1962BCA9228768F4000130AD /* Network */,
+ EE665595215C174F00D42DB6 /* Views */,
+ EE9333832151C915006939C4 /* Models */,
+ EE9333862151C940006939C4 /* ViewControllers */,
+ EE9333A3215473B3006939C4 /* Others */,
+ );
+ path = ToDoTests;
+ sourceTree = "";
+ };
+ EE47EF3D2141DA7000C76F03 /* Others */ = {
+ isa = PBXGroup;
+ children = (
+ EE9333A72155BC25006939C4 /* Constants.swift */,
+ EE47EF1D2141DA5D00C76F03 /* AppDelegate.swift */,
+ EE47EF242141DA5D00C76F03 /* Assets.xcassets */,
+ EE47EF292141DA5D00C76F03 /* Info.plist */,
+ );
+ path = Others;
+ sourceTree = "";
+ };
+ EE47EF3E2141DA7800C76F03 /* ViewControllers */ = {
+ isa = PBXGroup;
+ children = (
+ EE9333812151C8E8006939C4 /* ItemListViewController.swift */,
+ EE9333872151F66F006939C4 /* ItemListDataProvider.swift */,
+ EE6655E42164498C00D42DB6 /* DetailViewController.swift */,
+ 19946965227E3B9200138341 /* InputViewController.swift */,
+ );
+ path = ViewControllers;
+ sourceTree = "";
+ };
+ EE47EF3F2141DA8700C76F03 /* Storyboards */ = {
+ isa = PBXGroup;
+ children = (
+ EE47EF212141DA5D00C76F03 /* Main.storyboard */,
+ EE47EF262141DA5D00C76F03 /* LaunchScreen.storyboard */,
+ );
+ path = Storyboards;
+ sourceTree = "";
+ };
+ EE47EF442141DAF000C76F03 /* Models */ = {
+ isa = PBXGroup;
+ children = (
+ EE47EF422141DAE500C76F03 /* ToDoItem.swift */,
+ EE47EF472141DFF300C76F03 /* Location.swift */,
+ EE47EF4B2141E49F00C76F03 /* ToDoItemManager.swift */,
+ );
+ path = Models;
+ sourceTree = "";
+ };
+ EE665595215C174F00D42DB6 /* Views */ = {
+ isa = PBXGroup;
+ children = (
+ EE665593215C174500D42DB6 /* ItemCellTests.swift */,
+ 1962BCAC2290C8C9000130AD /* StoryboardTests.swift */,
+ );
+ path = Views;
+ sourceTree = "";
+ };
+ EE9333832151C915006939C4 /* Models */ = {
+ isa = PBXGroup;
+ children = (
+ EE47EF402141DAA700C76F03 /* ToDoItemTests.swift */,
+ EE47EF452141DFDE00C76F03 /* LocationTests.swift */,
+ EE47EF492141E48700C76F03 /* ToDoItemManagerTests.swift */,
+ );
+ path = Models;
+ sourceTree = "";
+ };
+ EE9333862151C940006939C4 /* ViewControllers */ = {
+ isa = PBXGroup;
+ children = (
+ EE9333842151C935006939C4 /* ItemListViewControllerTests.swift */,
+ EE93339F21546ED7006939C4 /* ItemListDataProviderTests.swift */,
+ EE6655E22164492200D42DB6 /* DetailViewControllerTests.swift */,
+ 19946963227E3B5C00138341 /* InputViewControllerTests.swift */,
+ );
+ path = ViewControllers;
+ sourceTree = "";
+ };
+ EE9333A3215473B3006939C4 /* Others */ = {
+ isa = PBXGroup;
+ children = (
+ EE9333A121547348006939C4 /* Constants.swift */,
+ EE47EF342141DA5D00C76F03 /* Info.plist */,
+ );
+ path = Others;
+ sourceTree = "";
+ };
+ EE9333A621547C86006939C4 /* Views */ = {
+ isa = PBXGroup;
+ children = (
+ EE9333A421547C7F006939C4 /* ItemCell.swift */,
+ );
+ path = Views;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 19E866A422D180DE001FFAB1 /* ToDoUITests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 19E866AE22D180DE001FFAB1 /* Build configuration list for PBXNativeTarget "ToDoUITests" */;
+ buildPhases = (
+ 19E866A122D180DE001FFAB1 /* Sources */,
+ 19E866A222D180DE001FFAB1 /* Frameworks */,
+ 19E866A322D180DE001FFAB1 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 19E866AB22D180DE001FFAB1 /* PBXTargetDependency */,
+ );
+ name = ToDoUITests;
+ productName = ToDoUITests;
+ productReference = 19E866A522D180DE001FFAB1 /* ToDoUITests.xctest */;
+ productType = "com.apple.product-type.bundle.ui-testing";
+ };
+ EE47EF192141DA5D00C76F03 /* ToDo */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = EE47EF372141DA5D00C76F03 /* Build configuration list for PBXNativeTarget "ToDo" */;
+ buildPhases = (
+ EE47EF162141DA5D00C76F03 /* Sources */,
+ EE47EF172141DA5D00C76F03 /* Frameworks */,
+ EE47EF182141DA5D00C76F03 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = ToDo;
+ productName = ToDo;
+ productReference = EE47EF1A2141DA5D00C76F03 /* ToDo.app */;
+ productType = "com.apple.product-type.application";
+ };
+ EE47EF2D2141DA5D00C76F03 /* ToDoTests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = EE47EF3A2141DA5D00C76F03 /* Build configuration list for PBXNativeTarget "ToDoTests" */;
+ buildPhases = (
+ EE47EF2A2141DA5D00C76F03 /* Sources */,
+ EE47EF2B2141DA5D00C76F03 /* Frameworks */,
+ EE47EF2C2141DA5D00C76F03 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ EE47EF302141DA5D00C76F03 /* PBXTargetDependency */,
+ );
+ name = ToDoTests;
+ productName = ToDoTests;
+ productReference = EE47EF2E2141DA5D00C76F03 /* ToDoTests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ EE47EF122141DA5D00C76F03 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastSwiftUpdateCheck = 1020;
+ LastUpgradeCheck = 1020;
+ ORGANIZATIONNAME = "gu, yi";
+ TargetAttributes = {
+ 19E866A422D180DE001FFAB1 = {
+ CreatedOnToolsVersion = 10.2.1;
+ ProvisioningStyle = Automatic;
+ TestTargetID = EE47EF192141DA5D00C76F03;
+ };
+ EE47EF192141DA5D00C76F03 = {
+ CreatedOnToolsVersion = 9.2;
+ LastSwiftMigration = 1020;
+ ProvisioningStyle = Automatic;
+ };
+ EE47EF2D2141DA5D00C76F03 = {
+ CreatedOnToolsVersion = 9.2;
+ LastSwiftMigration = 1020;
+ ProvisioningStyle = Automatic;
+ TestTargetID = EE47EF192141DA5D00C76F03;
+ };
+ };
+ };
+ buildConfigurationList = EE47EF152141DA5D00C76F03 /* Build configuration list for PBXProject "ToDo" */;
+ compatibilityVersion = "Xcode 8.0";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = EE47EF112141DA5D00C76F03;
+ productRefGroup = EE47EF1B2141DA5D00C76F03 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ EE47EF192141DA5D00C76F03 /* ToDo */,
+ EE47EF2D2141DA5D00C76F03 /* ToDoTests */,
+ 19E866A422D180DE001FFAB1 /* ToDoUITests */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 19E866A322D180DE001FFAB1 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ EE47EF182141DA5D00C76F03 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ EE47EF282141DA5D00C76F03 /* LaunchScreen.storyboard in Resources */,
+ EE47EF252141DA5D00C76F03 /* Assets.xcassets in Resources */,
+ EE47EF232141DA5D00C76F03 /* Main.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ EE47EF2C2141DA5D00C76F03 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 19E866A122D180DE001FFAB1 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 19E866A822D180DE001FFAB1 /* ToDoUITests.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ EE47EF162141DA5D00C76F03 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ EE6655E52164498C00D42DB6 /* DetailViewController.swift in Sources */,
+ 19946966227E3B9200138341 /* InputViewController.swift in Sources */,
+ EE9333A521547C7F006939C4 /* ItemCell.swift in Sources */,
+ 1962BCAB22876BC6000130AD /* Token.swift in Sources */,
+ EE47EF432141DAE500C76F03 /* ToDoItem.swift in Sources */,
+ EE9333882151F66F006939C4 /* ItemListDataProvider.swift in Sources */,
+ 1962BCA4228768A9000130AD /* APIClient.swift in Sources */,
+ EE9333822151C8E8006939C4 /* ItemListViewController.swift in Sources */,
+ EE47EF482141DFF300C76F03 /* Location.swift in Sources */,
+ EE47EF1E2141DA5D00C76F03 /* AppDelegate.swift in Sources */,
+ EE9333A82155BC25006939C4 /* Constants.swift in Sources */,
+ EE47EF4C2141E49F00C76F03 /* ToDoItemManager.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ EE47EF2A2141DA5D00C76F03 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ EE9333A021546ED7006939C4 /* ItemListDataProviderTests.swift in Sources */,
+ EE9333A92155BCCB006939C4 /* Constants.swift in Sources */,
+ 1962BCAD2290C8C9000130AD /* StoryboardTests.swift in Sources */,
+ EE47EF462141DFDE00C76F03 /* LocationTests.swift in Sources */,
+ 1962BCA6228768CB000130AD /* APIClientTests.swift in Sources */,
+ EE47EF4A2141E48700C76F03 /* ToDoItemManagerTests.swift in Sources */,
+ EE665594215C174500D42DB6 /* ItemCellTests.swift in Sources */,
+ EE47EF412141DAA700C76F03 /* ToDoItemTests.swift in Sources */,
+ 19946964227E3B5C00138341 /* InputViewControllerTests.swift in Sources */,
+ EE9333852151C935006939C4 /* ItemListViewControllerTests.swift in Sources */,
+ EE6655E32164492200D42DB6 /* DetailViewControllerTests.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ 19E866AB22D180DE001FFAB1 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = EE47EF192141DA5D00C76F03 /* ToDo */;
+ targetProxy = 19E866AA22D180DE001FFAB1 /* PBXContainerItemProxy */;
+ };
+ EE47EF302141DA5D00C76F03 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = EE47EF192141DA5D00C76F03 /* ToDo */;
+ targetProxy = EE47EF2F2141DA5D00C76F03 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+ EE47EF212141DA5D00C76F03 /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ EE47EF222141DA5D00C76F03 /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "";
+ };
+ EE47EF262141DA5D00C76F03 /* LaunchScreen.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ EE47EF272141DA5D00C76F03 /* Base */,
+ );
+ name = LaunchScreen.storyboard;
+ sourceTree = "";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 19E866AC22D180DE001FFAB1 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CODE_SIGN_STYLE = Automatic;
+ DEVELOPMENT_TEAM = 44JDRP3T56;
+ INFOPLIST_FILE = ToDoUITests/Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.2;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = yigu.ToDoUITests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_TARGET_NAME = ToDo;
+ };
+ name = Debug;
+ };
+ 19E866AD22D180DE001FFAB1 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CODE_SIGN_STYLE = Automatic;
+ DEVELOPMENT_TEAM = 44JDRP3T56;
+ INFOPLIST_FILE = ToDoUITests/Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.2;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ MTL_FAST_MATH = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = yigu.ToDoUITests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_TARGET_NAME = ToDo;
+ };
+ name = Release;
+ };
+ EE47EF352141DA5D00C76F03 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ };
+ name = Debug;
+ };
+ EE47EF362141DA5D00C76F03 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ EE47EF382141DA5D00C76F03 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_STYLE = Automatic;
+ INFOPLIST_FILE = ToDo/Others/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = yigu.com.ToDo;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ EE47EF392141DA5D00C76F03 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_STYLE = Automatic;
+ INFOPLIST_FILE = ToDo/Others/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = yigu.com.ToDo;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+ EE47EF3B2141DA5D00C76F03 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CODE_SIGN_STYLE = Automatic;
+ INFOPLIST_FILE = ToDoTests/Others/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = yigu.com.ToDoTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ToDo.app/ToDo";
+ };
+ name = Debug;
+ };
+ EE47EF3C2141DA5D00C76F03 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CODE_SIGN_STYLE = Automatic;
+ INFOPLIST_FILE = ToDoTests/Others/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = yigu.com.ToDoTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ToDo.app/ToDo";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 19E866AE22D180DE001FFAB1 /* Build configuration list for PBXNativeTarget "ToDoUITests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 19E866AC22D180DE001FFAB1 /* Debug */,
+ 19E866AD22D180DE001FFAB1 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ EE47EF152141DA5D00C76F03 /* Build configuration list for PBXProject "ToDo" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ EE47EF352141DA5D00C76F03 /* Debug */,
+ EE47EF362141DA5D00C76F03 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ EE47EF372141DA5D00C76F03 /* Build configuration list for PBXNativeTarget "ToDo" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ EE47EF382141DA5D00C76F03 /* Debug */,
+ EE47EF392141DA5D00C76F03 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ EE47EF3A2141DA5D00C76F03 /* Build configuration list for PBXNativeTarget "ToDoTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ EE47EF3B2141DA5D00C76F03 /* Debug */,
+ EE47EF3C2141DA5D00C76F03 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = EE47EF122141DA5D00C76F03 /* Project object */;
+}
diff --git a/Project 04 - Todo/Todo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Project 04 - TodoTDD/ToDo.xcodeproj/project.xcworkspace/contents.xcworkspacedata
similarity index 73%
rename from Project 04 - Todo/Todo.xcodeproj/project.xcworkspace/contents.xcworkspacedata
rename to Project 04 - TodoTDD/ToDo.xcodeproj/project.xcworkspace/contents.xcworkspacedata
index 19476363..cec21847 100644
--- a/Project 04 - Todo/Todo.xcodeproj/project.xcworkspace/contents.xcworkspacedata
+++ b/Project 04 - TodoTDD/ToDo.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -2,6 +2,6 @@
+ location = "self:ToDo.xcodeproj">
diff --git a/Project 04 - TodoTDD/ToDo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Project 04 - TodoTDD/ToDo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 00000000..18d98100
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/Project 11 - Animations/Animations.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/Animations.xcscheme b/Project 04 - TodoTDD/ToDo.xcodeproj/xcshareddata/xcschemes/ToDo.xcscheme
similarity index 67%
rename from Project 11 - Animations/Animations.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/Animations.xcscheme
rename to Project 04 - TodoTDD/ToDo.xcodeproj/xcshareddata/xcschemes/ToDo.xcscheme
index 44f9fbed..2b5cfb43 100644
--- a/Project 11 - Animations/Animations.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/Animations.xcscheme
+++ b/Project 04 - TodoTDD/ToDo.xcodeproj/xcshareddata/xcschemes/ToDo.xcscheme
@@ -1,6 +1,6 @@
+ BlueprintIdentifier = "EE47EF192141DA5D00C76F03"
+ BuildableName = "ToDo.app"
+ BlueprintName = "ToDo"
+ ReferencedContainer = "container:ToDo.xcodeproj">
@@ -26,36 +26,37 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+ codeCoverageEnabled = "YES"
shouldUseLaunchSchemeArgsEnv = "YES">
+ BlueprintIdentifier = "EE47EF2D2141DA5D00C76F03"
+ BuildableName = "ToDoTests.xctest"
+ BlueprintName = "ToDoTests"
+ ReferencedContainer = "container:ToDo.xcodeproj">
+ BlueprintIdentifier = "19E866A422D180DE001FFAB1"
+ BuildableName = "ToDoUITests.xctest"
+ BlueprintName = "ToDoUITests"
+ ReferencedContainer = "container:ToDo.xcodeproj">
+ BlueprintIdentifier = "EE47EF192141DA5D00C76F03"
+ BuildableName = "ToDo.app"
+ BlueprintName = "ToDo"
+ ReferencedContainer = "container:ToDo.xcodeproj">
@@ -75,10 +76,10 @@
runnableDebuggingMode = "0">
+ BlueprintIdentifier = "EE47EF192141DA5D00C76F03"
+ BuildableName = "ToDo.app"
+ BlueprintName = "ToDo"
+ ReferencedContainer = "container:ToDo.xcodeproj">
@@ -94,10 +95,10 @@
runnableDebuggingMode = "0">
+ BlueprintIdentifier = "EE47EF192141DA5D00C76F03"
+ BuildableName = "ToDo.app"
+ BlueprintName = "ToDo"
+ ReferencedContainer = "container:ToDo.xcodeproj">
diff --git a/Project 04 - TodoTDD/ToDo/Models/Location.swift b/Project 04 - TodoTDD/ToDo/Models/Location.swift
new file mode 100644
index 00000000..74662fce
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDo/Models/Location.swift
@@ -0,0 +1,60 @@
+//
+// Location.swift
+// ToDo
+//
+// Created by gu, yi on 9/6/18.
+// Copyright © 2018 gu, yi. All rights reserved.
+//
+
+import Foundation
+import CoreLocation
+
+struct Location {
+ let name: String
+ let coordinate: CLLocationCoordinate2D?
+
+ // plist
+ private let nameKey = "nameKey"
+ private let latitudeKey = "latitudeKey"
+ private let longitudeKey = "longitudeKey"
+
+ var plistDict: [String:Any] {
+ var dict = [String:Any]()
+
+ dict[nameKey] = name
+ if let coordinate = coordinate {
+ dict[latitudeKey] = coordinate.latitude
+ dict[longitudeKey] = coordinate.longitude
+ }
+
+ return dict
+ }
+
+ init(name: String, coordinate: CLLocationCoordinate2D? = nil) {
+ self.name = name
+ self.coordinate = coordinate
+ }
+
+ init?(dict: [String: Any]) {
+ guard let name = dict[nameKey] as? String else {
+ return nil
+ }
+
+ let coordinate: CLLocationCoordinate2D?
+ if let latitude = dict[latitudeKey] as? Double,
+ let longitude = dict[longitudeKey] as? Double {
+ coordinate = CLLocationCoordinate2DMake(latitude, longitude)
+ } else {
+ coordinate = nil
+ }
+
+ self.name = name
+ self.coordinate = coordinate
+ }
+}
+
+extension Location: Equatable {
+ static func ==(lhs: Location, rhs: Location) -> Bool {
+ return lhs.name == rhs.name && lhs.coordinate?.latitude == rhs.coordinate?.latitude && lhs.coordinate?.longitude == rhs.coordinate?.longitude
+ }
+}
diff --git a/Project 04 - TodoTDD/ToDo/Models/ToDoItem.swift b/Project 04 - TodoTDD/ToDo/Models/ToDoItem.swift
new file mode 100644
index 00000000..0e077a21
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDo/Models/ToDoItem.swift
@@ -0,0 +1,67 @@
+//
+// ToDOItem.swift
+// ToDo
+//
+// Created by gu, yi on 9/6/18.
+// Copyright © 2018 gu, yi. All rights reserved.
+//
+
+import Foundation
+
+struct ToDoItem {
+ let title: String
+ let itemDescription: String?
+ let timestamp: Double?
+ let location: Location?
+
+ // plist related
+ private let titleKey = "titleKey"
+ private let itemDescriptionKey = "itemDescriptionKey"
+ private let timestampKey = "timestampKey"
+ private let locationKey = "locationKey"
+
+ var plistDict: [String:Any] {
+ var dict = [String:Any]()
+
+ dict[titleKey] = title
+ if let itemDescription = itemDescription {
+ dict[itemDescriptionKey] = itemDescription
+ }
+ if let timestamp = timestamp {
+ dict[timestampKey] = timestamp
+ }
+ if let location = location {
+ let locationDict = location.plistDict
+ dict[locationKey] = locationDict
+ }
+ return dict
+ }
+
+ init(title: String, itemDescription: String? = nil, timeStamp: Double? = nil, location: Location? = nil) {
+ self.title = title
+ self.itemDescription = itemDescription
+ self.timestamp = timeStamp
+ self.location = location
+ }
+
+ init?(dict: [String: Any]) {
+ guard let title = dict[titleKey] as? String else {
+ return nil
+ }
+
+ self.title = title
+ self.itemDescription = dict[itemDescriptionKey] as? String
+ self.timestamp = dict[timestampKey] as? Double
+ if let locationDict = dict[locationKey] as? [String: Any] {
+ self.location = Location(dict: locationDict)
+ } else {
+ self.location = nil
+ }
+ }
+}
+
+extension ToDoItem: Equatable {
+ static func ==(lhs: ToDoItem, rhs: ToDoItem) -> Bool {
+ return lhs.title == rhs.title && lhs.location?.name == rhs.location?.name
+ }
+}
diff --git a/Project 04 - TodoTDD/ToDo/Models/ToDoItemManager.swift b/Project 04 - TodoTDD/ToDo/Models/ToDoItemManager.swift
new file mode 100644
index 00000000..03b83884
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDo/Models/ToDoItemManager.swift
@@ -0,0 +1,94 @@
+//
+// ToDoItemManager.swift
+// ToDo
+//
+// Created by gu, yi on 9/6/18.
+// Copyright © 2018 gu, yi. All rights reserved.
+//
+
+import UIKit
+
+class ToDoItemManager {
+ var toDoCount: Int { return toDoItems.count }
+ var doneCount: Int { return doneItems.count }
+
+ private var toDoItems = [ToDoItem]()
+ private var doneItems = [ToDoItem]()
+
+ // plist related
+ var toDoPathURL: URL {
+ let fileURLs = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
+
+ guard let documentURL = fileURLs.first else {
+ fatalError("Something went wrong. Documents url could not be found")
+ }
+
+ return documentURL.appendingPathComponent("toDoItems.plist")
+ }
+
+ init() {
+ NotificationCenter.default.addObserver(self, selector: #selector(save), name: UIApplication.willResignActiveNotification, object: nil)
+
+ if let nsToDoItems = NSArray(contentsOf: toDoPathURL) {
+ for dict in nsToDoItems {
+ if let toDoItem = ToDoItem(dict: dict as! [String:Any]) {
+ toDoItems.append(toDoItem)
+ }
+ }
+ }
+ }
+
+ deinit {
+ NotificationCenter.default.removeObserver(self)
+ save()
+ }
+
+ @objc func save() {
+ let nsToDoItems = toDoItems.map { $0.plistDict }
+
+ guard nsToDoItems.count > 0 else {
+ try? FileManager.default.removeItem(at: toDoPathURL)
+ return
+ }
+
+ do {
+ let plistData = try PropertyListSerialization.data(
+ fromPropertyList: nsToDoItems,
+ format: PropertyListSerialization.PropertyListFormat.xml,
+ options: PropertyListSerialization.WriteOptions(0)
+ )
+ try plistData.write(to: toDoPathURL,
+ options: Data.WritingOptions.atomic)
+ } catch {
+ print(error)
+ }
+ }
+
+
+ func add(_ item: ToDoItem) {
+ toDoItems.append(item)
+ }
+
+ func item(at index: Int) -> ToDoItem {
+ return toDoItems[index]
+ }
+
+ func doneItem(at index: Int) -> ToDoItem {
+ return doneItems[index]
+ }
+
+ func checkItem(at index: Int) {
+ let checkedItem = toDoItems.remove(at: index)
+ doneItems.append(checkedItem)
+ }
+
+ func uncheckItem(at index: Int) {
+ let uncheckedItem = doneItems.remove(at: index)
+ toDoItems.append(uncheckedItem)
+ }
+
+ func removeAll() {
+ toDoItems.removeAll()
+ doneItems.removeAll()
+ }
+}
diff --git a/Project 04 - TodoTDD/ToDo/Network/APIClient.swift b/Project 04 - TodoTDD/ToDo/Network/APIClient.swift
new file mode 100644
index 00000000..f7a8dce5
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDo/Network/APIClient.swift
@@ -0,0 +1,57 @@
+//
+// APIClient.swift
+// ToDo
+//
+// Created by Yi Gu on 5/11/19.
+// Copyright © 2019 gu, yi. All rights reserved.
+//
+
+import Foundation
+
+enum NetworkError : Error {
+ case DataEmptyError
+}
+
+class APIClient {
+
+ lazy var session: Sessionable = URLSession.shared
+
+ func loginUser(with name:String , password: String, completion: @escaping (Token?, Error?) -> Void) {
+
+ let query = "username=\(Constants.userName)&password=\(Constants.password)"
+ guard let url = URL(string: "https://awesometodos.com/login?\(query)") else {
+ fatalError()
+ }
+
+ session.dataTask(with: url) { (data, response, error) in
+ if let error = error {
+ completion(nil, error)
+ return
+ }
+
+ guard let data = data else {
+ completion(nil, NetworkError.DataEmptyError)
+ return
+ }
+
+ do {
+ let dict = try JSONSerialization.jsonObject(with: data, options: []) as? [String:String]
+
+ var token: Token? = nil
+
+ if let tokenString = dict?["token"] {
+ token = Token(id: tokenString)
+ }
+ completion(token, nil)
+ } catch {
+ completion(nil, error)
+ }
+ }.resume()
+ }
+}
+
+extension URLSession: Sessionable { }
+
+protocol Sessionable {
+ func dataTask(with url: URL, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask
+}
diff --git a/Project 04 - TodoTDD/ToDo/Network/Token.swift b/Project 04 - TodoTDD/ToDo/Network/Token.swift
new file mode 100644
index 00000000..25794a81
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDo/Network/Token.swift
@@ -0,0 +1,14 @@
+//
+// Token.swift
+// ToDo
+//
+// Created by Yi Gu on 5/11/19.
+// Copyright © 2019 gu, yi. All rights reserved.
+//
+
+import Foundation
+
+struct Token {
+
+ var id: String
+}
diff --git a/Project 04 - TodoTDD/ToDo/Others/AppDelegate.swift b/Project 04 - TodoTDD/ToDo/Others/AppDelegate.swift
new file mode 100644
index 00000000..896a1d48
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDo/Others/AppDelegate.swift
@@ -0,0 +1,23 @@
+//
+// AppDelegate.swift
+// ToDo
+//
+// Created by gu, yi on 9/6/18.
+// Copyright © 2018 gu, yi. All rights reserved.
+//
+
+import UIKit
+
+@UIApplicationMain
+class AppDelegate: UIResponder, UIApplicationDelegate {
+
+ var window: UIWindow?
+
+
+ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
+ // Override point for customization after application launch.
+ return true
+ }
+
+}
+
diff --git a/Project 28 - SlidebarMenu/SlidebarMenu/Assets.xcassets/AppIcon.appiconset/Contents.json b/Project 04 - TodoTDD/ToDo/Others/Assets.xcassets/AppIcon.appiconset/Contents.json
similarity index 100%
rename from Project 28 - SlidebarMenu/SlidebarMenu/Assets.xcassets/AppIcon.appiconset/Contents.json
rename to Project 04 - TodoTDD/ToDo/Others/Assets.xcassets/AppIcon.appiconset/Contents.json
diff --git a/Project 04 - TodoTDD/ToDo/Others/Constants.swift b/Project 04 - TodoTDD/ToDo/Others/Constants.swift
new file mode 100644
index 00000000..477121f1
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDo/Others/Constants.swift
@@ -0,0 +1,25 @@
+//
+// File.swift
+// ToDo
+//
+// Created by gu, yi on 9/21/18.
+// Copyright © 2018 gu, yi. All rights reserved.
+//
+
+import Foundation
+
+struct Constants {
+ static let MainBundleIdentifer = "Main"
+ static let ItemListViewControllerIdentifier = "ItemListViewController"
+ static let DetailViewControllerIdentifier = "DetailViewController"
+ static let InputViewControllerIndentifier = "InputViewController"
+
+ static let ItemCellIdentifier = "ItemCell"
+
+ static let userName = "Crystal"
+ static let password = "1234"
+}
+
+extension Notification {
+ static let ItemSelectedNotification = Notification.Name("ItemSelectedNotification")
+}
diff --git a/Project 28 - SlidebarMenu/SlidebarMenu/Info.plist b/Project 04 - TodoTDD/ToDo/Others/Info.plist
similarity index 97%
rename from Project 28 - SlidebarMenu/SlidebarMenu/Info.plist
rename to Project 04 - TodoTDD/ToDo/Others/Info.plist
index d0524738..16be3b68 100644
--- a/Project 28 - SlidebarMenu/SlidebarMenu/Info.plist
+++ b/Project 04 - TodoTDD/ToDo/Others/Info.plist
@@ -3,7 +3,7 @@
CFBundleDevelopmentRegion
- en
+ $(DEVELOPMENT_LANGUAGE)
CFBundleExecutable
$(EXECUTABLE_NAME)
CFBundleIdentifier
diff --git a/Project 04 - TodoTDD/ToDo/Storyboards/Base.lproj/LaunchScreen.storyboard b/Project 04 - TodoTDD/ToDo/Storyboards/Base.lproj/LaunchScreen.storyboard
new file mode 100644
index 00000000..f83f6fd5
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDo/Storyboards/Base.lproj/LaunchScreen.storyboard
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Project 04 - TodoTDD/ToDo/Storyboards/Base.lproj/Main.storyboard b/Project 04 - TodoTDD/ToDo/Storyboards/Base.lproj/Main.storyboard
new file mode 100644
index 00000000..d5426957
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDo/Storyboards/Base.lproj/Main.storyboard
@@ -0,0 +1,265 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Project 04 - TodoTDD/ToDo/ViewControllers/DetailViewController.swift b/Project 04 - TodoTDD/ToDo/ViewControllers/DetailViewController.swift
new file mode 100644
index 00000000..e5333888
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDo/ViewControllers/DetailViewController.swift
@@ -0,0 +1,43 @@
+//
+// DetailViewController.swift
+// ToDo
+//
+// Created by gu, yi on 10/2/18.
+// Copyright © 2018 gu, yi. All rights reserved.
+//
+
+import UIKit
+import MapKit
+
+class DetailViewController: UIViewController {
+
+ @IBOutlet var titleLabel: UILabel!
+ @IBOutlet var mapView: MKMapView!
+ @IBOutlet var locationLabel: UILabel!
+
+ var item: ToDoItem?
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ guard let item = item else {
+ return
+ }
+
+ titleLabel.text = item.title
+
+ if let location = item.location {
+ locationLabel.text = location.name
+ if let cooridnate = location.coordinate {
+ centerMapOnLocation(with: cooridnate)
+ }
+ }
+ }
+
+ private func centerMapOnLocation(with coordinate: CLLocationCoordinate2D) {
+ let regionRadius: CLLocationDistance = 1000
+
+ let coordinateRegion = MKCoordinateRegion(center: coordinate, latitudinalMeters: regionRadius, longitudinalMeters: regionRadius)
+ mapView.setRegion(coordinateRegion, animated: true)
+ }
+}
diff --git a/Project 04 - TodoTDD/ToDo/ViewControllers/InputViewController.swift b/Project 04 - TodoTDD/ToDo/ViewControllers/InputViewController.swift
new file mode 100644
index 00000000..9496c2a0
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDo/ViewControllers/InputViewController.swift
@@ -0,0 +1,105 @@
+//
+// InputViewController.swift
+// ToDo
+//
+// Created by Yi Gu on 5/4/19.
+// Copyright © 2019 gu, yi. All rights reserved.
+//
+
+import UIKit
+import CoreLocation
+
+class InputViewController: UIViewController {
+
+ @IBOutlet var titleTextField: UITextField!
+ @IBOutlet var locationTextField: UITextField!
+ @IBOutlet var descriptionTextField: UITextField!
+ @IBOutlet var datePicker: UIDatePicker!
+ @IBOutlet var cancelButton: UIButton!
+ @IBOutlet var saveButton: UIButton!
+
+ lazy var geocoder = CLGeocoder()
+ var itemManager: ToDoItemManager?
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ titleTextField.delegate = self
+ locationTextField.delegate = self
+ descriptionTextField.delegate = self
+ }
+
+ override func touchesBegan(_ touches: Set, with event: UIEvent?) {
+ view.endEditing(true)
+ }
+
+ @IBAction func save() {
+ guard let titleString = titleTextField.text,
+ titleString.count > 0 else {
+ return
+ }
+
+ // datePicker could be nil if the view controller is init via code
+ var date: Date?
+ if datePicker != nil {
+ date = datePicker.date
+ }
+
+ // descriptionTextField could be nil if the view controller is init via code
+ var descriptionString: String?
+ if descriptionTextField != nil {
+ descriptionString = descriptionTextField.text
+ }
+
+ // locationTextField could be nil if the view controller is init via code
+ var placeMark: CLPlacemark?
+ var locationName: String?
+
+ if locationTextField != nil {
+ locationName = locationTextField.text
+ if let locationName = locationName, locationName.count > 0 {
+ geocoder.geocodeAddressString(locationName) { [weak self] placeMarks, _ in
+ placeMark = placeMarks?.first
+
+ let item = ToDoItem(title: titleString,
+ itemDescription: descriptionString,
+ timeStamp: date?.timeIntervalSince1970,
+ location: Location(name: locationName, coordinate: placeMark?.location?.coordinate))
+
+ DispatchQueue.main.async {
+ self?.itemManager?.add(item)
+ self?.dismiss(animated: true)
+ }
+ }
+ } else {
+ let item = ToDoItem(title: titleString,
+ itemDescription: descriptionString,
+ timeStamp: date?.timeIntervalSince1970,
+ location: nil)
+ self.itemManager?.add(item)
+ dismiss(animated: true)
+ }
+ } else {
+ let item = ToDoItem(
+ title: titleString,
+ itemDescription: descriptionString,
+ timeStamp: date?.timeIntervalSince1970)
+
+ self.itemManager?.add(item)
+ dismiss(animated: true)
+ }
+ }
+
+ @IBAction func cancel() {
+ dismiss(animated: true, completion: nil)
+ }
+}
+
+extension InputViewController: UITextFieldDelegate {
+ func textFieldShouldReturn(_ textField: UITextField) -> Bool {
+ resignFirstResponder()
+ view.endEditing(true)
+ return false
+ }
+}
+
diff --git a/Project 04 - TodoTDD/ToDo/ViewControllers/ItemListDataProvider.swift b/Project 04 - TodoTDD/ToDo/ViewControllers/ItemListDataProvider.swift
new file mode 100644
index 00000000..922cc185
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDo/ViewControllers/ItemListDataProvider.swift
@@ -0,0 +1,120 @@
+//
+// ItemListDataProvider.swift
+// ToDo
+//
+// Created by gu, yi on 9/18/18.
+// Copyright © 2018 gu, yi. All rights reserved.
+//
+
+import UIKit
+
+enum Section: Int {
+ case toDo
+ case done
+}
+
+class ItemListDataProvider: NSObject {
+ var itemManager: ToDoItemManager?
+}
+
+extension ItemListDataProvider: UITableViewDataSource {
+ func numberOfSections(in tableView: UITableView) -> Int {
+ return 2
+ }
+
+ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ guard let itemManager = itemManager else {
+ return 0
+ }
+ guard let itemSection = Section(rawValue: section) else {
+ fatalError()
+ }
+
+ let numberOfRows: Int
+
+ switch itemSection {
+ case .toDo:
+ numberOfRows = itemManager.toDoCount
+ case .done:
+ numberOfRows = itemManager.doneCount
+ }
+
+ return numberOfRows
+ }
+
+ func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+ let cell = tableView.dequeueReusableCell(withIdentifier: Constants.ItemCellIdentifier, for: indexPath) as! ItemCell
+
+ guard let itemManager = itemManager else {
+ fatalError()
+ }
+ guard let itemSection = Section(rawValue: indexPath.section) else {
+ fatalError()
+ }
+
+ let item: ToDoItem
+
+ switch itemSection {
+ case .toDo:
+ item = itemManager.item(at: indexPath.row)
+ case .done:
+ item = itemManager.doneItem(at: indexPath.row)
+ }
+
+ cell.configCell(with: item)
+
+ return cell
+ }
+}
+
+extension ItemListDataProvider: UITableViewDelegate {
+ func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? {
+
+ guard let itemSection = Section(rawValue: indexPath.section) else {
+ fatalError()
+ }
+
+ let deleteTitle: String
+
+ switch itemSection {
+ case .toDo:
+ deleteTitle = "Check"
+ case .done:
+ deleteTitle = "Uncheck"
+ }
+
+ return deleteTitle
+ }
+
+ func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
+
+ guard let itemSection = Section(rawValue: indexPath.section) else {
+ fatalError()
+ }
+
+ switch itemSection {
+ case .toDo:
+ itemManager?.checkItem(at: indexPath.row)
+ case .done:
+ itemManager?.uncheckItem(at: indexPath.row)
+ }
+
+ tableView.reloadData()
+ }
+
+ func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+ guard let itemSection = Section(rawValue: indexPath.section) else {
+ fatalError()
+ }
+
+ switch itemSection {
+ case .toDo:
+ NotificationCenter.default.post(
+ name: Notification.ItemSelectedNotification,
+ object: self,
+ userInfo: ["index": indexPath.row])
+ case .done:
+ break
+ }
+ }
+}
diff --git a/Project 04 - TodoTDD/ToDo/ViewControllers/ItemListViewController.swift b/Project 04 - TodoTDD/ToDo/ViewControllers/ItemListViewController.swift
new file mode 100644
index 00000000..bf640b4b
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDo/ViewControllers/ItemListViewController.swift
@@ -0,0 +1,60 @@
+//
+// ItemListViewController.swift
+// ToDo
+//
+// Created by gu, yi on 9/18/18.
+// Copyright © 2018 gu, yi. All rights reserved.
+//
+
+import UIKit
+
+class ItemListViewController: UIViewController {
+
+ @IBOutlet var tableView: UITableView!
+ @IBOutlet var dataProvider: ItemListDataProvider!
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ tableView.dataSource = dataProvider
+ tableView.delegate = dataProvider
+
+ dataProvider.itemManager = ToDoItemManager()
+
+ NotificationCenter.default.addObserver(self, selector: #selector(showDetails(_:)), name: Notification.ItemSelectedNotification,
+ object: nil)
+ }
+
+ override func viewWillAppear(_ animated: Bool) {
+ super.viewWillAppear(animated)
+
+ tableView.reloadData()
+ }
+
+ @objc func showDetails(_ sender: Notification) {
+ guard let index = sender.userInfo?["index"] as? Int else {
+ fatalError()
+ }
+
+ if let nextViewController = storyboard?.instantiateViewController(withIdentifier: Constants.DetailViewControllerIdentifier) as? DetailViewController,
+ let itemManager = dataProvider.itemManager {
+
+ guard index < itemManager.toDoCount else {
+ return
+ }
+
+ nextViewController.item = itemManager.item(at: index)
+
+ navigationController?.pushViewController(nextViewController, animated: true)
+ }
+ }
+
+ @IBAction func addItem(_ sender: UIBarButtonItem) {
+ guard let inputViewController = storyboard?.instantiateViewController(withIdentifier: "InputViewController") as? InputViewController else {
+ return
+ }
+ inputViewController.itemManager = dataProvider.itemManager
+
+ present(inputViewController, animated: true, completion: nil)
+ }
+}
diff --git a/Project 04 - TodoTDD/ToDo/Views/ItemCell.swift b/Project 04 - TodoTDD/ToDo/Views/ItemCell.swift
new file mode 100644
index 00000000..b8d32674
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDo/Views/ItemCell.swift
@@ -0,0 +1,53 @@
+//
+// ItemCell.swift
+// ToDo
+//
+// Created by gu, yi on 9/20/18.
+// Copyright © 2018 gu, yi. All rights reserved.
+//
+
+import UIKit
+
+class ItemCell: UITableViewCell {
+
+ @IBOutlet weak var titleLabel: UILabel!
+ @IBOutlet weak var locationLabel: UILabel!
+ @IBOutlet weak var dateLabel: UILabel!
+
+ lazy var dateFormatter: DateFormatter = {
+ let dateFormatter = DateFormatter()
+ dateFormatter.dateFormat = "MM/dd/yyyy"
+ return dateFormatter
+ }()
+
+ override func awakeFromNib() {
+ super.awakeFromNib()
+ // Initialization code
+ }
+
+ override func setSelected(_ selected: Bool, animated: Bool) {
+ super.setSelected(selected, animated: animated)
+ }
+
+ func configCell(with item: ToDoItem, isChecked: Bool = false) {
+ if isChecked {
+ let attributedString = NSAttributedString(string: item.title, attributes: [NSAttributedString.Key.strikethroughStyle: NSUnderlineStyle.single.rawValue])
+
+ titleLabel.attributedText = attributedString
+ dateLabel.text = nil
+ locationLabel.text = nil
+ } else {
+ titleLabel.text = item.title
+
+ if let timestamp = item.timestamp {
+ let date = Date(timeIntervalSince1970: timestamp)
+ dateLabel.text = dateFormatter.string(from: date)
+ }
+
+ if let location = item.location {
+ locationLabel.text = location.name
+ }
+ }
+ }
+
+}
diff --git a/Project 04 - TodoTDD/ToDoTDD.gif b/Project 04 - TodoTDD/ToDoTDD.gif
new file mode 100644
index 00000000..475531c4
Binary files /dev/null and b/Project 04 - TodoTDD/ToDoTDD.gif differ
diff --git a/Project 04 - TodoTDD/ToDoTests/Models/LocationTests.swift b/Project 04 - TodoTDD/ToDoTests/Models/LocationTests.swift
new file mode 100644
index 00000000..19b6d291
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDoTests/Models/LocationTests.swift
@@ -0,0 +1,59 @@
+//
+// LocationTests.swift
+// ToDoTests
+//
+// Created by gu, yi on 9/6/18.
+// Copyright © 2018 gu, yi. All rights reserved.
+//
+
+import XCTest
+import CoreLocation
+@testable import ToDo
+
+class LocationTests: XCTestCase {
+
+ let locationName = "LocationName"
+ let latitude = 1.0
+ let longitude = 2.0
+
+ override func setUp() {
+ super.setUp()
+ }
+
+ override func tearDown() {
+ super.tearDown()
+ }
+
+ func test_init_givenName_setsName() {
+ let location = Location(name: locationName)
+
+ XCTAssertEqual(location.name, locationName, "should set name")
+ }
+
+ func test_init_givenCoordinate_setsCoordinate() {
+ let coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
+ let location = Location(name: "", coordinate: coordinate)
+
+ XCTAssertEqual(location.coordinate?.latitude, latitude, "should set latitude")
+ XCTAssertEqual(location.coordinate?.longitude, longitude, "should set longitude")
+ }
+
+ func test_init_hasPlistDictionaryProperty() {
+ let location = Location(name: "Home")
+ let dictionary = location.plistDict
+
+ XCTAssertNotNil(dictionary)
+ }
+
+ func test_canBeSerializedAndDeserialized() {
+ let location = Location(
+ name: "Home",
+ coordinate: CLLocationCoordinate2DMake(50.0, 6.0))
+
+ let dict = location.plistDict
+ let recreatedLocation = Location(dict: dict)
+
+ XCTAssertEqual(recreatedLocation, location)
+
+ }
+}
diff --git a/Project 04 - TodoTDD/ToDoTests/Models/ToDoItemManagerTests.swift b/Project 04 - TodoTDD/ToDoTests/Models/ToDoItemManagerTests.swift
new file mode 100644
index 00000000..7a07fb1c
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDoTests/Models/ToDoItemManagerTests.swift
@@ -0,0 +1,113 @@
+//
+// ToDoItemManagerTests.swift
+// ToDoTests
+//
+// Created by gu, yi on 9/6/18.
+// Copyright © 2018 gu, yi. All rights reserved.
+//
+
+import XCTest
+@testable import ToDo
+
+class ToDoItemManagerTests: XCTestCase {
+
+ var itemManager: ToDoItemManager!
+ let titleForFirstToAdd = "first"
+ let titleForSecondToAdd = "second"
+
+ override func setUp() {
+ super.setUp()
+
+ itemManager = ToDoItemManager()
+ }
+
+ override func tearDown() {
+ itemManager.removeAll()
+ itemManager = nil
+
+ super.tearDown()
+ }
+
+ func test_init_toDoCountIsZero() {
+ XCTAssertEqual(itemManager.toDoCount, 0, "toDoCount should be 0")
+ }
+
+ func test_init_doneCountIsZero() {
+ XCTAssertEqual(itemManager.doneCount, 0, "toDoCount should be 0")
+ }
+
+ func test_addItem_increaseToDoCountByOne() {
+ let expectToDoCount = itemManager.toDoCount + 1
+ itemManager.add(ToDoItem(title: ""))
+
+ XCTAssertEqual(itemManager.toDoCount, expectToDoCount, "toDoCount should increase by 1")
+ }
+
+ func test_itemAt_givenLastIndex_returnsAddedItem() {
+ let item = ToDoItem(title: titleForFirstToAdd)
+ itemManager.add(item)
+
+ XCTAssertEqual(itemManager.item(at: itemManager.toDoCount - 1), item, "should return added item")
+ }
+
+ func test_checkItemAt_givenFirstIndex_removesFromToDoItems() {
+ let firstItem = ToDoItem(title: titleForFirstToAdd)
+ let secondItem = ToDoItem(title: titleForSecondToAdd)
+
+ itemManager.add(firstItem)
+ itemManager.add(secondItem)
+
+ XCTAssertEqual(itemManager.item(at: 0), firstItem, "first item should be added")
+
+ let expectToDoCount = itemManager.toDoCount - 1
+
+ itemManager.checkItem(at: 0)
+
+ XCTAssertEqual(itemManager.item(at: 0), secondItem, "first item should be removed")
+ XCTAssertEqual(itemManager.toDoCount, expectToDoCount, "toDoCount should decrease by 1")
+ }
+
+ func test_checkItemAt_givenFirstIndex_addsToDoneItems() {
+ let firstItem = ToDoItem(title: titleForFirstToAdd)
+ let secondItem = ToDoItem(title: titleForSecondToAdd)
+
+ itemManager.add(firstItem)
+ itemManager.add(secondItem)
+
+ XCTAssertEqual(itemManager.doneCount, 0, "done items should be empty")
+
+ let expectDoneCount = itemManager.doneCount + 1
+
+ itemManager.checkItem(at: 0)
+
+ XCTAssertEqual(itemManager.doneItem(at: 0), firstItem, "first item should be removed")
+ XCTAssertEqual(itemManager.doneCount, expectDoneCount, "doneCount should increase by 1")
+ }
+
+ func test_removeAll_clearsItems() {
+ let firstItem = ToDoItem(title: titleForFirstToAdd)
+ let secondItem = ToDoItem(title: titleForSecondToAdd)
+
+ itemManager.add(firstItem)
+ itemManager.add(secondItem)
+
+ itemManager.removeAll()
+
+ XCTAssertEqual(itemManager.toDoCount, 0, "toDoCount should be 0")
+ XCTAssertEqual(itemManager.doneCount, 0, "doneCount should be 0")
+ }
+
+ func test_ToDoItemsGetSerialized() {
+ let firstItem = ToDoItem(title: "First")
+ itemManager.add(firstItem)
+
+ let secondItem = ToDoItem(title: "Second")
+ itemManager.add(secondItem)
+
+ NotificationCenter.default.post(name: UIApplication.willResignActiveNotification, object: nil)
+
+ XCTAssertEqual(itemManager?.toDoCount, 2)
+ XCTAssertEqual(itemManager?.item(at: 0), firstItem)
+ XCTAssertEqual(itemManager?.item(at: 1), secondItem)
+ }
+}
diff --git a/Project 04 - TodoTDD/ToDoTests/Models/ToDoItemTests.swift b/Project 04 - TodoTDD/ToDoTests/Models/ToDoItemTests.swift
new file mode 100644
index 00000000..b8c2e9a5
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDoTests/Models/ToDoItemTests.swift
@@ -0,0 +1,71 @@
+//
+// ToDoItemTests.swift
+// ToDoTests
+//
+// Created by gu, yi on 9/6/18.
+// Copyright © 2018 gu, yi. All rights reserved.
+//
+
+import XCTest
+@testable import ToDo
+
+class ToDoItemTests: XCTestCase {
+
+ let timestamp = 0.0
+ let locationName = "Location"
+
+ override func setUp() {
+ super.setUp()
+ // Put setup code here. This method is called before the invocation of each test method in the class.
+ }
+
+ override func tearDown() {
+ // Put teardown code here. This method is called after the invocation of each test method in the class.
+ super.tearDown()
+ }
+
+ func test_init_givenTitle_setsTitle() {
+ let toDoItem = ToDoItem(title: Foo)
+
+ XCTAssertEqual(toDoItem.title, Foo, "should set title")
+ }
+
+ func test_init_givenItemDescription_setsItemDescription() {
+ let toDoItem = ToDoItem(title: Foo, itemDescription: Bar)
+
+ XCTAssertEqual(toDoItem.title, Foo, "should set title")
+ XCTAssertEqual(toDoItem.itemDescription, Bar, "should set itemDescription")
+ }
+
+ func test_init_givenTimeStamp_setsTimeStamp() {
+ let toDoItem = ToDoItem(title: Foo, timeStamp: timestamp)
+
+ XCTAssertEqual(toDoItem.timestamp, timestamp, "should set timeStamp")
+ }
+
+ func test_init_givenLocation_setsLocation() {
+
+ let location = Location(name: locationName)
+ let toDoItem = ToDoItem(title: Foo, location: Location(name: locationName))
+
+ XCTAssertEqual(toDoItem.location, location, "should set location")
+ }
+
+ func test_init_hasPlistDictionaryProperty() {
+ let toDoItem = ToDoItem(title: "First")
+ let dictionary = toDoItem.plistDict
+
+ XCTAssertNotNil(dictionary)
+ }
+
+ func test_canBeCreatedFromPlistDictionary() {
+ let location = Location(name: "Bar")
+ let toDoItem = ToDoItem(title: "Foo", itemDescription: "Baz", timeStamp: 1.0, location: location)
+
+ let dict = toDoItem.plistDict
+ let recreatedItem = ToDoItem(dict: dict)
+
+ XCTAssertEqual(recreatedItem, toDoItem)
+ }
+
+}
diff --git a/Project 04 - TodoTDD/ToDoTests/Network/APIClientTests.swift b/Project 04 - TodoTDD/ToDoTests/Network/APIClientTests.swift
new file mode 100644
index 00000000..f45d8a30
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDoTests/Network/APIClientTests.swift
@@ -0,0 +1,189 @@
+//
+// APIClientTests.swift
+// ToDoTests
+//
+// Created by Yi Gu on 5/11/19.
+// Copyright © 2019 gu, yi. All rights reserved.
+//
+
+import XCTest
+@testable import ToDo
+
+class APIClientTests: XCTestCase {
+
+ var apiClient: APIClient!
+ var urlSession: MockURLSession!
+
+ override func setUp() {
+ apiClient = APIClient()
+ urlSession = MockURLSession()
+
+ apiClient.session = urlSession
+ }
+
+ override func tearDown() {
+ super.tearDown()
+ }
+
+ func test_login_usesExpectedHost() {
+
+ let completion = { (token: Token?, error: Error?) in }
+ apiClient.loginUser(with: Constants.userName, password: Constants.password, completion: completion)
+
+ guard let _ = urlSession.url else {
+ XCTFail();
+ return
+ }
+
+ XCTAssertEqual(urlSession.urlComponents?.host, "awesometodos.com")
+ }
+
+ func test_login_usesExpectedPath() {
+ let completion = { (token: Token?, error: Error?) in }
+ apiClient.loginUser(with: Constants.userName, password: Constants.password, completion: completion)
+
+ guard let _ = urlSession.url else {
+ XCTFail();
+ return
+ }
+
+ XCTAssertEqual(urlSession.urlComponents?.path, "/login")
+ }
+
+ func test_login_usesExpectedQuery() {
+ let completion = { (token: Token?, error: Error?) in }
+ apiClient.loginUser(with: Constants.userName, password: Constants.password, completion: completion)
+
+ guard let _ = urlSession.url else {
+ XCTFail();
+ return
+ }
+
+ XCTAssertEqual(urlSession.urlComponents?.query, "username=\(Constants.userName)&password=\(Constants.password)")
+ }
+
+ func test_login_givenSuccessResponse_createsToken() {
+
+ let jsonData = "{\"token\": \"1234567890\"}".data(using: .utf8)
+ let mockURLSession = MockURLSession(data: jsonData)
+ apiClient.session = mockURLSession
+
+ let tokenExpectation = expectation(description: "Token")
+
+ var caughtToken: Token?
+ apiClient.loginUser(with: Constants.userName, password: Constants.password) { (token, _) in
+ caughtToken = token
+ tokenExpectation.fulfill()
+ }
+
+ waitForExpectations(timeout: 1) { _ in
+ XCTAssertEqual(caughtToken?.id, "1234567890")
+ }
+ }
+
+ func test_login_givenJSONIsInvalid_returnsError() {
+
+ let mockURLSession = MockURLSession(data: Data())
+ apiClient.session = mockURLSession
+
+ let errorExpectation = expectation(description: "Error")
+
+ var catchedError: Error?
+ apiClient.loginUser(with: Constants.userName, password: Constants.password) { (_, error) in
+ catchedError = error
+ errorExpectation.fulfill()
+ }
+
+ waitForExpectations(timeout: 1) { _ in
+ XCTAssertNotNil(catchedError)
+ }
+ }
+
+ func test_login_givenJSONIsNil_returnsError() {
+
+ let mockURLSession = MockURLSession()
+ apiClient.session = mockURLSession
+
+ let errorExpectation = expectation(description: "Error")
+
+ var catchedError: Error?
+ apiClient.loginUser(with: Constants.userName, password: Constants.password) { (_, error) in
+ catchedError = error
+ errorExpectation.fulfill()
+ }
+
+ waitForExpectations(timeout: 1) { _ in
+ XCTAssertNotNil(catchedError)
+ }
+ }
+
+ func test_login_givenFailResponse_returnsError() {
+
+ let jsonData = "{\"token\": \"1234567890\"}".data(using: .utf8)
+ let error = NSError(domain: "SomeError", code: 1234, userInfo: nil)
+ let mockURLSession = MockURLSession(data: jsonData, error: error)
+ apiClient.session = mockURLSession
+
+ let errorExpectation = expectation(description: "Error")
+
+ var catchedError: Error?
+ apiClient.loginUser(with: Constants.userName, password: Constants.password) { (_, error) in
+ catchedError = error
+ errorExpectation.fulfill()
+ }
+
+ waitForExpectations(timeout: 1) { _ in
+ XCTAssertNotNil(catchedError)
+ }
+ }
+}
+
+extension APIClientTests {
+ class MockURLSession: Sessionable {
+
+ var url: URL?
+ var urlComponents: URLComponents? {
+ guard let url = url else {
+ return nil
+ }
+ return URLComponents(url: url, resolvingAgainstBaseURL: true)
+ }
+
+ private let dataTask: MockTask
+
+ init(data: Data? = nil, urlResponse: URLResponse? = nil, error: Error? = nil) {
+ dataTask = MockTask(data: data, urlResponse: urlResponse, error: error)
+ }
+
+ func dataTask(with url: URL, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask {
+
+ self.url = url
+ dataTask.completionHandler = completionHandler
+
+ return dataTask
+ }
+ }
+
+ class MockTask: URLSessionDataTask {
+
+ private let data: Data?
+ private let urlResponse: URLResponse?
+ private let responseError: Error?
+
+ var completionHandler: ((Data?, URLResponse?, Error?) -> Void)?
+
+ init(data: Data?, urlResponse: URLResponse?, error: Error?) {
+ self.data = data
+ self.urlResponse = urlResponse
+ self.responseError = error
+ }
+
+ override func resume() {
+ DispatchQueue.main.async() {
+ self.completionHandler?(self.data,
+ self.urlResponse,
+ self.responseError)
+ }
+ }
+ }
+}
diff --git a/Project 04 - TodoTDD/ToDoTests/Others/Constants.swift b/Project 04 - TodoTDD/ToDoTests/Others/Constants.swift
new file mode 100644
index 00000000..730b4aca
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDoTests/Others/Constants.swift
@@ -0,0 +1,12 @@
+//
+// Constants.swift
+// ToDo
+//
+// Created by gu, yi on 9/20/18.
+// Copyright © 2018 gu, yi. All rights reserved.
+//
+
+let Foo = "Foo"
+let Bar = "Bar"
+
+let testDate = "09/08/2018"
diff --git a/Project 04 - TodoTDD/ToDoTests/Others/Info.plist b/Project 04 - TodoTDD/ToDoTests/Others/Info.plist
new file mode 100644
index 00000000..6c40a6cd
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDoTests/Others/Info.plist
@@ -0,0 +1,22 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ BNDL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1
+
+
diff --git a/Project 04 - TodoTDD/ToDoTests/ViewControllers/DetailViewControllerTests.swift b/Project 04 - TodoTDD/ToDoTests/ViewControllers/DetailViewControllerTests.swift
new file mode 100644
index 00000000..a8a60afe
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDoTests/ViewControllers/DetailViewControllerTests.swift
@@ -0,0 +1,63 @@
+//
+// DetailViewControllerTests.swift
+// ToDoTests
+//
+// Created by gu, yi on 10/2/18.
+// Copyright © 2018 gu, yi. All rights reserved.
+//
+
+import XCTest
+import CoreLocation
+@testable import ToDo
+
+class DetailViewControllerTests: XCTestCase {
+
+ var detailViewController: DetailViewController!
+
+ override func setUp() {
+ super.setUp()
+
+ let storyboard = UIStoryboard(name: Constants.MainBundleIdentifer, bundle: nil)
+ detailViewController = (storyboard.instantiateViewController(withIdentifier: Constants.DetailViewControllerIdentifier) as! DetailViewController)
+
+ detailViewController.loadViewIfNeeded()
+ }
+
+ override func tearDown() {
+ detailViewController.item = nil
+
+ super.tearDown()
+ }
+
+ func test_init_hasTitleLabel() {
+ XCTAssertTrue(detailViewController.titleLabel.isDescendant(of: detailViewController.view))
+ }
+
+ func test_init_hasLocationLabel() {
+ XCTAssertTrue(detailViewController.locationLabel.isDescendant(of: detailViewController.view))
+ }
+
+ func test_init_hasMapView() {
+ XCTAssertTrue(detailViewController.mapView.isDescendant(of: detailViewController.view))
+ }
+
+ func test_viewDidLoad_givenItem_hasItem() {
+ let coordinate = CLLocationCoordinate2DMake(1.0,
+ 2.0)
+ let timestamp = 1456095600.0
+ let testItem = ToDoItem(title: "Foo",
+ itemDescription: "Bar",
+ timeStamp: timestamp,
+ location: Location(name: "Infinite Loop 1, Cupertino",
+ coordinate: coordinate))
+
+ detailViewController.item = testItem
+
+ detailViewController.viewDidLoad()
+
+ XCTAssertEqual(detailViewController.titleLabel.text, testItem.title)
+ XCTAssertEqual(detailViewController.locationLabel.text, testItem.location!.name)
+ XCTAssertEqual(ceil(detailViewController.mapView.centerCoordinate.latitude), testItem.location!.coordinate!.latitude)
+ XCTAssertEqual(ceil(detailViewController.mapView.centerCoordinate.longitude), testItem.location!.coordinate!.longitude)
+ }
+}
diff --git a/Project 04 - TodoTDD/ToDoTests/ViewControllers/InputViewControllerTests.swift b/Project 04 - TodoTDD/ToDoTests/ViewControllers/InputViewControllerTests.swift
new file mode 100644
index 00000000..bf47bd09
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDoTests/ViewControllers/InputViewControllerTests.swift
@@ -0,0 +1,210 @@
+//
+// InputViewControllerTests.swift
+// ToDoTests
+//
+// Created by Yi Gu on 5/4/19.
+// Copyright © 2019 gu, yi. All rights reserved.
+//
+
+import XCTest
+import CoreLocation
+@testable import ToDo
+
+class InputViewControllerTests: XCTestCase {
+
+ var inputViewController: InputViewController!
+ var placemark: MockPlacemark!
+
+ override func setUp() {
+ super.setUp()
+
+ let storyboard = UIStoryboard(name: Constants.MainBundleIdentifer, bundle: nil)
+ inputViewController = (storyboard.instantiateViewController(withIdentifier: Constants.InputViewControllerIndentifier) as! InputViewController)
+
+ inputViewController.loadViewIfNeeded()
+ }
+
+ override func tearDown() {
+ inputViewController.itemManager?.removeAll()
+
+ super.tearDown()
+ }
+
+ func test_init_hasTitleTextField() {
+ XCTAssertTrue(inputViewController.titleTextField.isDescendant(of: inputViewController.view))
+ }
+
+ func test_init_hasLocationTextField() {
+ XCTAssertTrue(inputViewController.locationTextField.isDescendant(of: inputViewController.view))
+ }
+
+ func test_init_hasDescriptionTextField() {
+ XCTAssertTrue(inputViewController.descriptionTextField.isDescendant(of: inputViewController.view))
+ }
+
+ func test_init_hasDatePicker() {
+ XCTAssertTrue(inputViewController.datePicker.isDescendant(of: inputViewController.view))
+ }
+
+ func test_init_hasCanelButton() {
+ XCTAssertTrue(inputViewController.cancelButton.isDescendant(of: inputViewController.view))
+ }
+
+ func test_init_hasSaveButton() {
+ XCTAssertTrue(inputViewController.saveButton.isDescendant(of: inputViewController.view))
+ }
+
+ func test_init_hasSaveAction() {
+ let saveButton = inputViewController.saveButton
+
+ guard let actions = saveButton?.actions(forTarget: inputViewController, forControlEvent: .touchUpInside) else {
+ XCTFail()
+ return
+ }
+
+ XCTAssertTrue(actions.contains("save"))
+ }
+
+ func test_save_usesGeocoderToGetCoordinateFromAddress() {
+ let mockInputViewController = MockInputViewController()
+ mockInputViewController.titleTextField = UITextField()
+ mockInputViewController.datePicker = UIDatePicker()
+ mockInputViewController.descriptionTextField = UITextField()
+ mockInputViewController.locationTextField = UITextField()
+
+ mockInputViewController.titleTextField.text = "Foo"
+
+ // input a new item and save
+ let dateFormatter = DateFormatter()
+ dateFormatter.dateFormat = "MM/dd/yyyy"
+ let timestamp = 1456095600.0
+ let date = Date(timeIntervalSince1970: timestamp)
+ mockInputViewController.datePicker.date = date
+
+ mockInputViewController.descriptionTextField.text = "Bar"
+ mockInputViewController.locationTextField.text = "Infinite Loop 1, Cupertino"
+
+ let mockGeocoder = MockGeocoder()
+ mockInputViewController.geocoder = mockGeocoder
+
+ mockInputViewController.itemManager = ToDoItemManager()
+
+ let dismissExpectation = expectation(description: "Dismiss")
+
+ mockInputViewController.completionHandler = {
+ dismissExpectation.fulfill()
+ }
+
+ mockInputViewController.save()
+
+ placemark = MockPlacemark()
+ let coordinate = CLLocationCoordinate2DMake(37.3316851,
+ -122.0300674)
+ placemark.mockCoordinate = coordinate
+ mockGeocoder.completionHandler?([placemark], nil)
+
+ waitForExpectations(timeout: 3, handler: nil)
+
+ // create the expected item
+ let testItem = ToDoItem(title: "Foo",
+ itemDescription: "Bar",
+ timeStamp: timestamp,
+ location: Location(name: "Infinite Loop 1, Cupertino",
+ coordinate: coordinate))
+
+ let item = mockInputViewController.itemManager?.item(at: 0)
+ XCTAssertEqual(item, testItem)
+
+ mockInputViewController.itemManager?.removeAll()
+ }
+
+ func test_save_dismissSelf() {
+ let mockInputViewController = MockInputViewController()
+
+ mockInputViewController.titleTextField = UITextField()
+ mockInputViewController.titleTextField.text = "Foo"
+
+ mockInputViewController.save()
+
+ XCTAssertTrue(mockInputViewController.dismissGotCalled)
+
+ mockInputViewController.itemManager?.removeAll()
+ }
+
+ func test_cancel_dismissSelf() {
+ let mockInputViewController = MockInputViewController()
+
+ mockInputViewController.cancel()
+
+ XCTAssertTrue(mockInputViewController.dismissGotCalled)
+
+ mockInputViewController.itemManager?.removeAll()
+ }
+
+ func test_Geocoder_FetchesCoordinates() {
+ let geocoderAnswered = expectation(description: "Geocoder")
+
+ let address = "Infinite Loop 1, Cupertino"
+
+ CLGeocoder().geocodeAddressString(address) { placemarks, error -> Void in
+ let coordinate = placemarks?.first?.location?.coordinate
+
+ guard let latitude = coordinate?.latitude else {
+ XCTFail()
+ return
+ }
+ guard let longitude = coordinate?.longitude else {
+ XCTFail()
+ return
+ }
+
+ XCTAssertEqual(latitude, 37.3316, accuracy: 0.001)
+ XCTAssertEqual(longitude, -122.0301, accuracy: 0.001)
+
+ geocoderAnswered.fulfill()
+ }
+
+ waitForExpectations(timeout: 3, handler: nil)
+ }
+}
+
+extension InputViewControllerTests {
+ class MockGeocoder: CLGeocoder {
+
+ var completionHandler: CLGeocodeCompletionHandler?
+
+ override func geocodeAddressString(
+ _ addressString: String,
+ completionHandler: @escaping CLGeocodeCompletionHandler) {
+
+ self.completionHandler = completionHandler
+ }
+ }
+
+ class MockPlacemark : CLPlacemark {
+
+ var mockCoordinate: CLLocationCoordinate2D?
+
+ override var location: CLLocation? {
+ guard let coordinate = mockCoordinate else {
+ return CLLocation()
+ }
+
+ return CLLocation(latitude: coordinate.latitude,
+ longitude: coordinate.longitude)
+ }
+ }
+
+ class MockInputViewController : InputViewController {
+
+ var dismissGotCalled = false
+ var completionHandler: (() -> Void)?
+
+ override func dismiss(animated flag: Bool,
+ completion: (() -> Void)? = nil) {
+
+ dismissGotCalled = true
+ completionHandler?()
+ }
+ }
+}
diff --git a/Project 04 - TodoTDD/ToDoTests/ViewControllers/ItemListDataProviderTests.swift b/Project 04 - TodoTDD/ToDoTests/ViewControllers/ItemListDataProviderTests.swift
new file mode 100644
index 00000000..8fc5e3ee
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDoTests/ViewControllers/ItemListDataProviderTests.swift
@@ -0,0 +1,235 @@
+//
+// ItemListDataProviderTests.swift
+// ToDoTests
+//
+// Created by gu, yi on 9/20/18.
+// Copyright © 2018 gu, yi. All rights reserved.
+//
+
+import XCTest
+@testable import ToDo
+
+class ItemListDataProviderTests: XCTestCase {
+
+ // MARK: - Variables
+ var tableView: UITableView!
+ var dataProvider: ItemListDataProvider!
+ var itemManager: ToDoItemManager!
+
+ // MARK: - Life Cycle
+ override func setUp() {
+ super.setUp()
+
+ let storyboard = UIStoryboard(name: Constants.MainBundleIdentifer, bundle: nil)
+ let controller = storyboard.instantiateViewController(withIdentifier: Constants.ItemListViewControllerIdentifier) as! ItemListViewController
+ controller.loadViewIfNeeded()
+ tableView = controller.tableView
+
+ dataProvider = ItemListDataProvider()
+ itemManager = ToDoItemManager()
+
+ dataProvider.itemManager = itemManager
+ tableView.dataSource = dataProvider
+ }
+
+ override func tearDown() {
+ itemManager.removeAll()
+
+ super.tearDown()
+ }
+
+ // MARK: - NumberOfSections
+ func test_numberOfSections_init_isTwo() {
+ XCTAssertEqual(tableView.numberOfSections, 2, "number of sections should be 2")
+ }
+
+ // MARK: - NumberOfRows
+ func test_numberOfRowsOfToDoSection_init_isToDoCount() {
+ XCTAssertEqual(tableView.numberOfRows(inSection: 0), 0, "number of rows in toDo section should be 0 at first")
+ XCTAssertEqual(tableView.numberOfRows(inSection: 0), itemManager.toDoCount, "number of rows in toDo section should be equal to toDoCount of itemManager")
+ }
+
+ func test_numberOfRowsOfToDoSection_addToDoItem_isToDoCount() {
+ itemManager.add(ToDoItem(title: Foo))
+
+ tableView.reloadData()
+
+ XCTAssertEqual(tableView.numberOfRows(inSection: 0), 1, "number of rows in toDo section increase to be 1 after adding a new item")
+ XCTAssertEqual(tableView.numberOfRows(inSection: 0), itemManager.toDoCount, "number of rows in toDo section should be equal to toDoCount of itemManager")
+ }
+
+ func test_numberOfRowsOfToDoSection_checkToDoItem_isToDoCount() {
+ itemManager.add(ToDoItem(title: Foo))
+ itemManager.checkItem(at: 0)
+
+ tableView.reloadData()
+
+ XCTAssertEqual(tableView.numberOfRows(inSection: 0), 0, "number of rows in toDo section should be 0 after all items checked")
+ XCTAssertEqual(tableView.numberOfRows(inSection: 0), itemManager.toDoCount, "number of rows in toDo section should be equal to toDoCount of itemManager")
+ }
+
+ func test_numberOfRowsOfToDoSection_removeAllItems_isToDoCount() {
+ itemManager.add(ToDoItem(title: Foo))
+ itemManager.removeAll()
+
+ tableView.reloadData()
+
+ XCTAssertEqual(tableView.numberOfRows(inSection: 0), 0, "number of rows in toDo section should be 0 after all items removed")
+ XCTAssertEqual(tableView.numberOfRows(inSection: 0), itemManager.toDoCount, "number of rows in toDo section should be equal to toDoCount of itemManager")
+ }
+
+ func test_numberOfRowsOfDoneSection_init_isDoneCount() {
+ XCTAssertEqual(tableView.numberOfRows(inSection: 1), 0, "number of rows in done section should be 0 at first")
+ XCTAssertEqual(tableView.numberOfRows(inSection: 1), itemManager.doneCount, "number of rows in done section should be equal to doneCount of itemManager")
+ }
+
+ func test_numberOfRowsOfDoneSection_addDoneItem_isDoneCount() {
+ itemManager.add(ToDoItem(title: Foo))
+
+ tableView.reloadData()
+
+ XCTAssertEqual(tableView.numberOfRows(inSection: 1), 0, "number of rows in done section should keep to be 0 after adding a new item")
+ XCTAssertEqual(tableView.numberOfRows(inSection: 1), itemManager.doneCount, "number of rows in done section should be equal to doneCount of itemManager")
+ }
+
+ func test_numberOfRowsOfDoneSection_checkToDoItem_isDoneCount() {
+ itemManager.add(ToDoItem(title: Foo))
+ itemManager.checkItem(at: 0)
+
+ tableView.reloadData()
+
+ XCTAssertEqual(tableView.numberOfRows(inSection: 1), 1, "number of rows in done section should be 1 after one item checked")
+ XCTAssertEqual(tableView.numberOfRows(inSection: 1), itemManager.doneCount, "number of rows in done section should be equal to doneCount of itemManager")
+ }
+
+ func test_numberOfRowsOfDoneSection_removeAllItems_isDoneCount() {
+ itemManager.add(ToDoItem(title: Foo))
+ itemManager.removeAll()
+
+ tableView.reloadData()
+
+ XCTAssertEqual(tableView.numberOfRows(inSection: 1), 0, "number of rows in done section should be 0 after all items removed")
+ XCTAssertEqual(tableView.numberOfRows(inSection: 1), itemManager.doneCount, "number of rows in done section should be equal to doneCount of itemManager")
+ }
+
+ // MARK: - CellForRow
+ func test_cellForRow_init_isItemCell() {
+ itemManager.add(ToDoItem(title: Foo))
+ tableView.reloadData()
+
+ // if tableView is not init from storyboard, it cannot configure cell to ItemCell as it cannot find the right identifier
+ let cell = tableView.cellForRow(at: IndexPath(row: 0, section: 0))
+
+ XCTAssertTrue(cell is ItemCell, "should be ItemCell")
+ }
+
+ func test_cellForRow_givenToDoItem_callsCellDequeue() {
+ let mockTableView = MockTableView.mockTableView(withDataSource: dataProvider)
+
+ itemManager.add(ToDoItem(title: Foo))
+ mockTableView.reloadData()
+
+ _ = mockTableView.cellForRow(at: IndexPath(row: 0, section: 0))
+ XCTAssertTrue(mockTableView.dequeueCellGotCalled, "cell should be dequeued")
+ }
+
+ func test_cellForRow_givenToDoItem_callsConfigCell() {
+ let mockTableView = MockTableView.mockTableView(withDataSource: dataProvider)
+
+ let item = ToDoItem(title: Foo)
+ itemManager.add(item)
+ mockTableView.reloadData()
+
+ let cell = mockTableView.cellForRow(at: IndexPath(row: 0, section: 0)) as! MockItemCell
+ XCTAssertTrue(cell.configCellGotCalled, "cell should be dequeued")
+ XCTAssertEqual(cell.cachedItem, item, "config item should be the one added")
+ }
+
+ func test_cellForRow_givenDoneItem_callsConfigCell() {
+ let mockTableView = MockTableView.mockTableView(withDataSource: dataProvider)
+
+ let item = ToDoItem(title: Foo)
+ itemManager.add(item)
+ itemManager.checkItem(at: 0)
+ mockTableView.reloadData()
+
+ let cell = mockTableView.cellForRow(at: IndexPath(row: 0, section: 1)) as! MockItemCell
+ XCTAssertTrue(cell.configCellGotCalled, "cell should be dequeued")
+ XCTAssertEqual(cell.cachedItem, item, "config item should be the one added")
+ }
+
+ // MARK: - UITableViewDelegate
+ func test_deleteButton_inToDoSection_showsTitleCheck() {
+ let deleteButtonTitle = tableView.delegate?.tableView?(
+ tableView,
+ titleForDeleteConfirmationButtonForRowAt: IndexPath(row: 0,
+ section: 0))
+
+ XCTAssertEqual(deleteButtonTitle, "Check")
+ }
+
+ func test_deleteButton_inDoneSection_showsTitleCheck() {
+ let deleteButtonTitle = tableView.delegate?.tableView?(tableView, titleForDeleteConfirmationButtonForRowAt: IndexPath(row: 0, section: 1))
+
+ XCTAssertEqual(deleteButtonTitle, "Uncheck")
+ }
+
+ func test_checkAnItem_inToDoSection_changesItemsNum() {
+ itemManager.add(ToDoItem(title: Foo))
+
+ tableView.dataSource?.tableView?(tableView, commit: .delete, forRowAt: IndexPath(row: 0, section: 0))
+
+ XCTAssertEqual(itemManager.toDoCount, 0, "should remove toDo item")
+ XCTAssertEqual(itemManager.doneCount, 1, "should add done item")
+ XCTAssertEqual(tableView.numberOfRows(inSection: 0), 0, "toDo item number should be 0")
+ XCTAssertEqual(tableView.numberOfRows(inSection: 1), 1, "done item number should be 1")
+ }
+
+ func test_checkAnItem_inDoneSection_changesItemsNum() {
+ itemManager.add(ToDoItem(title: Foo))
+ itemManager.checkItem(at: 0)
+ tableView.reloadData()
+
+ tableView.dataSource?.tableView?(tableView, commit: .delete, forRowAt: IndexPath(row: 0, section: 1))
+
+ XCTAssertEqual(itemManager.toDoCount, 1, "should add toDo item")
+ XCTAssertEqual(itemManager.doneCount, 0, "should remove done item")
+ XCTAssertEqual(tableView.numberOfRows(inSection: 0), 1, "toDo item number should be 1")
+ XCTAssertEqual(tableView.numberOfRows(inSection: 1), 0, "done item number should be 0")
+ }
+
+}
+
+extension ItemListDataProviderTests {
+ // Mock a table view to ensure the dequeCell function is called.
+ class MockTableView: UITableView {
+ var dequeueCellGotCalled = false
+
+ override func dequeueReusableCell(withIdentifier identifier: String, for indexPath: IndexPath) -> UITableViewCell {
+
+ dequeueCellGotCalled = true
+
+ return super.dequeueReusableCell(withIdentifier: identifier, for: indexPath)
+ }
+
+ class func mockTableView(withDataSource dataSource: UITableViewDataSource) -> MockTableView {
+ let mockTableView = MockTableView()
+
+ mockTableView.dataSource = dataSource
+ mockTableView.register(MockItemCell.self, forCellReuseIdentifier: Constants.ItemCellIdentifier)
+
+ return mockTableView
+ }
+ }
+
+ class MockItemCell: ItemCell {
+ var configCellGotCalled = false
+ var cachedItem: ToDoItem?
+
+ override func configCell(with item: ToDoItem, isChecked: Bool = false) {
+
+ configCellGotCalled = true
+ cachedItem = item
+ }
+ }
+}
diff --git a/Project 04 - TodoTDD/ToDoTests/ViewControllers/ItemListViewControllerTests.swift b/Project 04 - TodoTDD/ToDoTests/ViewControllers/ItemListViewControllerTests.swift
new file mode 100644
index 00000000..e9d3fecd
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDoTests/ViewControllers/ItemListViewControllerTests.swift
@@ -0,0 +1,166 @@
+//
+// ItemListViewControllerTests.swift
+// ToDoTests
+//
+// Created by gu, yi on 9/18/18.
+// Copyright © 2018 gu, yi. All rights reserved.
+//
+
+import XCTest
+@testable import ToDo
+
+class ItemListViewControllerTests: XCTestCase {
+
+ var itemListViewController: ItemListViewController!
+
+ override func setUp() {
+ super.setUp()
+
+ let storyboard = UIStoryboard(name: "Main", bundle: nil)
+
+ itemListViewController = (storyboard.instantiateViewController(withIdentifier: "ItemListViewController") as! ItemListViewController)
+
+ itemListViewController.loadViewIfNeeded()
+ }
+
+ override func tearDown() {
+ super.tearDown()
+ }
+
+ func test_init_hasTableView() {
+
+ XCTAssertTrue(itemListViewController.tableView.isDescendant(of: itemListViewController.view))
+ }
+
+ func test_init_givenDataProvider_setsTableViewDataSource() {
+
+ XCTAssertTrue(itemListViewController.tableView.dataSource is ItemListDataProvider, "dataProvider should be the dataSource to tableView")
+ }
+
+ func test_init_givenDataProvider_setsTableViewDelegate() {
+
+ XCTAssertTrue(itemListViewController.tableView.delegate is ItemListDataProvider, "dataProvider should be the dataSource to tableView")
+ }
+
+ func test_init_givenDataProvider_dataSourceEqualsDelegate() {
+
+ XCTAssertEqual(itemListViewController.tableView.dataSource as? ItemListDataProvider,
+ itemListViewController.tableView.delegate as? ItemListDataProvider, "dataSource and delegate should be the same")
+ }
+
+ func test_init_itemListViewController_hasAddBarButtonWithSelfAsTarget() {
+
+ let target = itemListViewController.navigationItem.rightBarButtonItem?.target
+ XCTAssertEqual(target as? UIViewController, itemListViewController)
+ }
+
+ func test_addItem_inputViewController_shouldPresent() {
+
+ XCTAssertNil(itemListViewController.presentedViewController)
+
+ _test_performAddItem()
+
+ XCTAssertNotNil(itemListViewController.presentedViewController)
+ XCTAssertTrue(itemListViewController.presentedViewController is InputViewController)
+ }
+
+ func test_addItem_inputViewController_sharesItemManagerWithItemListViewController() {
+ _test_performAddItem()
+
+ guard let inputViewController = itemListViewController.presentedViewController as? InputViewController else {
+ XCTFail()
+ return
+ }
+ guard let inputItemManager = inputViewController.itemManager else {
+ XCTFail()
+ return
+ }
+
+ guard let itemManager = itemListViewController.dataProvider.itemManager else {
+ XCTFail()
+ return
+ }
+
+ XCTAssert(itemManager === inputItemManager)
+ }
+
+ func test_addItem_givenSave_shouldHaveNewItem() {
+ _test_performAddItem()
+
+ XCTAssertEqual(itemListViewController.tableView.numberOfRows(inSection: Section.toDo.rawValue), 0)
+
+ guard let inputViewController = itemListViewController.presentedViewController as? InputViewController else {
+ XCTFail()
+ return
+ }
+
+ inputViewController.titleTextField = UITextField()
+ inputViewController.titleTextField.text = "Foo"
+ inputViewController.save()
+
+ // trigger view will appear
+ itemListViewController.viewWillAppear(true)
+
+ XCTAssertEqual(itemListViewController.tableView.numberOfRows(inSection: Section.toDo.rawValue), 1)
+ }
+
+ private func _test_performAddItem() {
+ guard let addItemButton = itemListViewController.navigationItem.rightBarButtonItem else {
+ return XCTFail()
+ }
+ guard let action = addItemButton.action else {
+ return XCTFail()
+ }
+
+ // set item list view controller as root so that it is visible in view hierachy
+ UIApplication.shared.keyWindow?.rootViewController = itemListViewController
+
+ itemListViewController.performSelector(onMainThread: action,
+ with: addItemButton,
+ waitUntilDone: true)
+ }
+
+ func test_selectToDoItemCell_shouldPresentDetailViewController() {
+ let mockNavigationController = MockNavigationController(rootViewController: itemListViewController)
+
+ UIApplication.shared.keyWindow?.rootViewController = mockNavigationController
+
+ let testItem = ToDoItem(title: "foo")
+ itemListViewController.dataProvider.itemManager = ToDoItemManager()
+ itemListViewController.dataProvider.itemManager?.add(testItem)
+
+ // reload data to make sure tableview gets updated
+ itemListViewController.tableView.reloadData()
+
+ // select row 0
+ NotificationCenter.default.post(
+ name: Notification.ItemSelectedNotification,
+ object: self,
+ userInfo: ["index": 0])
+
+ guard let detailViewController = mockNavigationController.lastPushedViewController as? DetailViewController else {
+ return XCTFail()
+ }
+
+ guard let detailItem = detailViewController.item else {
+ return XCTFail()
+ }
+
+ detailViewController.loadViewIfNeeded()
+
+ XCTAssertEqual(detailItem, testItem)
+ }
+}
+
+extension ItemListViewControllerTests {
+ class MockNavigationController : UINavigationController {
+
+ var lastPushedViewController: UIViewController?
+
+ override func pushViewController(_ viewController: UIViewController, animated: Bool) {
+ lastPushedViewController = viewController
+ super.pushViewController(viewController, animated: animated)
+ }
+ }
+}
+
diff --git a/Project 04 - TodoTDD/ToDoTests/Views/ItemCellTests.swift b/Project 04 - TodoTDD/ToDoTests/Views/ItemCellTests.swift
new file mode 100644
index 00000000..0a325412
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDoTests/Views/ItemCellTests.swift
@@ -0,0 +1,107 @@
+//
+// ItemCellTests.swift
+// ToDoTests
+//
+// Created by gu, yi on 9/26/18.
+// Copyright © 2018 gu, yi. All rights reserved.
+//
+
+import XCTest
+@testable import ToDo
+
+class ItemCellTests: XCTestCase {
+
+ var cell: ItemCell!
+
+ override func setUp() {
+ super.setUp()
+
+ let storyboard = UIStoryboard(name: Constants.MainBundleIdentifer, bundle: nil)
+ let itemListViewController = storyboard.instantiateViewController(withIdentifier: Constants.ItemListViewControllerIdentifier) as! ItemListViewController
+ itemListViewController.loadViewIfNeeded()
+
+ let tableView = itemListViewController.tableView
+ let fakeDataSource = FakeDataSource()
+ tableView?.dataSource = fakeDataSource
+
+ cell = (tableView?.dequeueReusableCell(withIdentifier: Constants.ItemCellIdentifier, for: IndexPath(row: 0, section: 0)) as! ItemCell)
+ }
+
+ override func tearDown() {
+ super.tearDown()
+ }
+
+ // MARK: - init
+ func test_init_givenTableViewDataSource_hasNameLabel() {
+ // make sure it is not nil is not enough, we have to make sure it is in the content view
+ XCTAssertTrue(cell.titleLabel.isDescendant(of: cell.contentView))
+ }
+
+ func test_init_givenTableViewDataSource_hasLocationLabel() {
+ XCTAssertTrue(cell.locationLabel.isDescendant(of: cell.contentView))
+ }
+
+ func test_init_givenTableViewDataSource_hasDateLabel() {
+ XCTAssertTrue(cell.dateLabel.isDescendant(of: cell.contentView))
+ }
+
+ // MARK: - configCell
+ func test_configCell_givenTitle_setsTitle() {
+ let toDoItem = ToDoItem(title: Foo)
+
+ cell.configCell(with: toDoItem)
+
+ XCTAssertEqual(cell.titleLabel.text, toDoItem.title)
+ }
+
+ func test_configCell_givenLocation_setsLocation() {
+ let location = Location(name: Bar)
+ let toDoItem = ToDoItem(title: Foo, location: location)
+
+ cell.configCell(with: toDoItem)
+
+ XCTAssertEqual(cell.locationLabel.text, Bar)
+ }
+
+ func test_configCell_givenDate_setsDate() {
+ let dateFormatter = DateFormatter()
+ dateFormatter.dateFormat = "MM/dd/yyyy"
+ let date = dateFormatter.date(from: testDate)
+ let timeStamp = date?.timeIntervalSince1970
+
+ let toDoItem = ToDoItem(title: Foo, timeStamp: timeStamp)
+
+ cell.configCell(with: toDoItem)
+
+ XCTAssertEqual(cell.dateLabel.text, testDate)
+ }
+
+ func test_configCell_itemIsChecked_titleIsStrokeThrough() {
+ let location = Location(name: Bar)
+ let toDoItem = ToDoItem(title: Foo, timeStamp: 1456150025, location: location)
+
+ cell.configCell(with: toDoItem, isChecked: true)
+
+ let attributedString = NSAttributedString(
+ string: Foo,
+ attributes: [NSAttributedString.Key.strikethroughStyle:
+ NSUnderlineStyle.single.rawValue])
+
+ XCTAssertEqual(cell.titleLabel.attributedText, attributedString)
+ XCTAssertNil(cell.locationLabel.text)
+ XCTAssertNil(cell.dateLabel.text)
+ }
+}
+
+extension ItemCellTests {
+ class FakeDataSource: NSObject, UITableViewDataSource {
+
+ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ return 1
+ }
+
+ func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+ return UITableViewCell()
+ }
+ }
+}
diff --git a/Project 04 - TodoTDD/ToDoTests/Views/StoryboardTests.swift b/Project 04 - TodoTDD/ToDoTests/Views/StoryboardTests.swift
new file mode 100644
index 00000000..8330a672
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDoTests/Views/StoryboardTests.swift
@@ -0,0 +1,31 @@
+//
+// StoryboardTests.swift
+// ToDoTests
+//
+// Created by Yi Gu on 5/18/19.
+// Copyright © 2019 gu, yi. All rights reserved.
+//
+
+import XCTest
+@testable import ToDo
+
+class StoryboardTests: XCTestCase {
+
+ override func setUp() {
+ }
+
+ override func tearDown() {
+ }
+
+ func test_init_initialViewController_isItemListViewController() {
+ let storyboard = UIStoryboard(name: Constants.MainBundleIdentifer, bundle: nil)
+
+ let navigationController =
+ storyboard.instantiateInitialViewController()
+ as! UINavigationController
+
+ let rootViewController = navigationController.viewControllers[0]
+
+ XCTAssertTrue(rootViewController is ItemListViewController)
+ }
+}
diff --git a/Project 04 - TodoTDD/ToDoUITests/Info.plist b/Project 04 - TodoTDD/ToDoUITests/Info.plist
new file mode 100644
index 00000000..6c40a6cd
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDoUITests/Info.plist
@@ -0,0 +1,22 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ BNDL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1
+
+
diff --git a/Project 04 - TodoTDD/ToDoUITests/ToDoUITests.swift b/Project 04 - TodoTDD/ToDoUITests/ToDoUITests.swift
new file mode 100644
index 00000000..9bdc7226
--- /dev/null
+++ b/Project 04 - TodoTDD/ToDoUITests/ToDoUITests.swift
@@ -0,0 +1,63 @@
+//
+// ToDoUITests.swift
+// ToDoUITests
+//
+// Created by Yi Gu on 7/6/19.
+// Copyright © 2019 gu, yi. All rights reserved.
+//
+
+import XCTest
+
+class ToDoUITests: XCTestCase {
+
+ override func setUp() {
+ // Put setup code here. This method is called before the invocation of each test method in the class.
+
+ // In UI tests it is usually best to stop immediately when a failure occurs.
+ continueAfterFailure = false
+
+ // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
+ XCUIApplication().launch()
+
+ // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
+ }
+
+ override func tearDown() {
+
+ }
+
+ // make sure 'Hardware -> Keyboard -> Connect hardware keyboard' is off.
+ func testAddToDo() {
+
+ let app = XCUIApplication()
+ app.navigationBars["ToDo.ItemListView"].buttons["Add"].tap()
+
+ let titleTextField = app.textFields["Title"]
+ titleTextField.tap()
+ titleTextField.typeText("Meeting")
+
+ let addressTextField = app.textFields["Address"]
+ addressTextField.tap()
+ addressTextField.typeText("650 Castro St, Mountain View")
+
+ let descriptionTextField = app.textFields["Description"]
+ descriptionTextField.tap()
+ descriptionTextField.typeText("Quora")
+
+ // Please change the value of pickerWheels to today to make the test work
+ let datePickersQuery = app.datePickers
+ datePickersQuery.pickerWheels["2019"].adjust(toPickerWheelValue: "2019")
+ datePickersQuery.pickerWheels["July"].adjust(toPickerWheelValue: "April")
+ datePickersQuery.pickerWheels["7"].adjust(toPickerWheelValue: "1")
+
+ // tap anywhere to dismiss keyboard
+ app.keyboards.buttons["return"].tap()
+
+ // go back to previous page
+ app.buttons["Save"].tap()
+
+ XCTAssertTrue(app.tables.staticTexts["Meeting"].exists)
+ XCTAssertTrue(app.tables.staticTexts["04/01/2019"].exists)
+ XCTAssertTrue(app.tables.staticTexts["650 Castro St, Mountain View"].exists)
+ }
+}
diff --git a/Project 05 - Artistry/Artistry.xcodeproj/project.pbxproj b/Project 05 - Artistry/Artistry.xcodeproj/project.pbxproj
index 19279828..ae44a809 100644
--- a/Project 05 - Artistry/Artistry.xcodeproj/project.pbxproj
+++ b/Project 05 - Artistry/Artistry.xcodeproj/project.pbxproj
@@ -143,18 +143,18 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0720;
- LastUpgradeCheck = 0800;
+ LastUpgradeCheck = 1020;
ORGANIZATIONNAME = RayWenderlich;
TargetAttributes = {
A2D7F3041C8CE3F60097399A = {
CreatedOnToolsVersion = 7.2.1;
- LastSwiftMigration = 0800;
+ LastSwiftMigration = 1020;
};
};
};
buildConfigurationList = A2D7F3001C8CE3F60097399A /* Build configuration list for PBXProject "Artistry" */;
compatibilityVersion = "Xcode 3.2";
- developmentRegion = English;
+ developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
@@ -225,18 +225,27 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -259,7 +268,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 9.2;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -272,18 +281,27 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -300,7 +318,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 9.2;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
@@ -317,7 +335,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = RW.Artistry;
PRODUCT_NAME = Artistry;
- SWIFT_VERSION = 3.0;
+ SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
};
name = Debug;
@@ -330,7 +348,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = RW.Artistry;
PRODUCT_NAME = Artistry;
- SWIFT_VERSION = 3.0;
+ SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
};
name = Release;
diff --git a/Project 05 - Artistry/Artistry.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Project 05 - Artistry/Artistry.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 00000000..18d98100
--- /dev/null
+++ b/Project 05 - Artistry/Artistry.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/Project 05 - Artistry/Artistry.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/Artistry.xcscheme b/Project 05 - Artistry/Artistry.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/Artistry.xcscheme
index 80901b91..9b92e2bf 100644
--- a/Project 05 - Artistry/Artistry.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/Artistry.xcscheme
+++ b/Project 05 - Artistry/Artistry.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/Artistry.xcscheme
@@ -1,6 +1,6 @@
Bool {
+ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
UINavigationBar.appearance().tintColor = UIColor.white
return true
diff --git a/Project 05 - Artistry/Artistry/ArtistDetailViewController.swift b/Project 05 - Artistry/Artistry/ArtistDetailViewController.swift
index d771ef3e..66434fc5 100644
--- a/Project 05 - Artistry/Artistry/ArtistDetailViewController.swift
+++ b/Project 05 - Artistry/Artistry/ArtistDetailViewController.swift
@@ -34,10 +34,10 @@ class ArtistDetailViewController: UIViewController {
super.viewDidLoad()
title = selectedArtist.name
- tableView.rowHeight = UITableViewAutomaticDimension
+ tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 300
- NotificationCenter.default.addObserver(forName: .UIContentSizeCategoryDidChange, object: .none, queue: OperationQueue.main) { [weak self] _ in
+ NotificationCenter.default.addObserver(forName: UIContentSizeCategory.didChangeNotification, object: .none, queue: OperationQueue.main) { [weak self] _ in
self?.tableView.reloadData()
}
}
@@ -64,8 +64,8 @@ extension ArtistDetailViewController: UITableViewDataSource {
cell.moreInfoTextView.text = work.isExpanded ? work.info : moreInfoText
cell.moreInfoTextView.textAlignment = work.isExpanded ? .left : .center
- cell.workTitleLabel.font = UIFont.preferredFont(forTextStyle: UIFontTextStyle.headline)
- cell.moreInfoTextView.font = UIFont.preferredFont(forTextStyle: UIFontTextStyle.footnote)
+ cell.workTitleLabel.font = UIFont.preferredFont(forTextStyle: UIFont.TextStyle.headline)
+ cell.moreInfoTextView.font = UIFont.preferredFont(forTextStyle: UIFont.TextStyle.footnote)
return cell
}
diff --git a/Project 05 - Artistry/Artistry/ArtistListViewController.swift b/Project 05 - Artistry/Artistry/ArtistListViewController.swift
index f0a746fd..26affd5c 100644
--- a/Project 05 - Artistry/Artistry/ArtistListViewController.swift
+++ b/Project 05 - Artistry/Artistry/ArtistListViewController.swift
@@ -31,10 +31,10 @@ class ArtistListViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
- tableView.rowHeight = UITableViewAutomaticDimension
+ tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 140
- NotificationCenter.default.addObserver(forName: .UIContentSizeCategoryDidChange, object: .none, queue: OperationQueue.main) { [weak self] _ in
+ NotificationCenter.default.addObserver(forName: UIContentSizeCategory.didChangeNotification, object: .none, queue: OperationQueue.main) { [weak self] _ in
self?.tableView.reloadData()
}
}
diff --git a/Project 06 - CandySearch/CandySearch.xcodeproj/project.pbxproj b/Project 06 - CandySearch/CandySearch.xcodeproj/project.pbxproj
index 8b023a93..75341ccb 100644
--- a/Project 06 - CandySearch/CandySearch.xcodeproj/project.pbxproj
+++ b/Project 06 - CandySearch/CandySearch.xcodeproj/project.pbxproj
@@ -96,18 +96,18 @@
171E0C721B8E5B84001E6242 /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0820;
+ LastUpgradeCheck = 1020;
ORGANIZATIONNAME = "Peartree Developers";
TargetAttributes = {
171E0C791B8E5B84001E6242 = {
CreatedOnToolsVersion = 7.0;
- LastSwiftMigration = 0800;
+ LastSwiftMigration = 1020;
};
};
};
buildConfigurationList = 171E0C751B8E5B84001E6242 /* Build configuration list for PBXProject "CandySearch" */;
compatibilityVersion = "Xcode 3.2";
- developmentRegion = English;
+ developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
@@ -174,18 +174,27 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -208,7 +217,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -221,18 +230,27 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@@ -249,7 +267,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
@@ -266,7 +284,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.razeware.CandySearch;
PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 3.0;
+ SWIFT_VERSION = 5.0;
};
name = Debug;
};
@@ -278,7 +296,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.razeware.CandySearch;
PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 3.0;
+ SWIFT_VERSION = 5.0;
};
name = Release;
};
diff --git a/Project 06 - CandySearch/CandySearch.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Project 06 - CandySearch/CandySearch.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 00000000..18d98100
--- /dev/null
+++ b/Project 06 - CandySearch/CandySearch.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/Project 06 - CandySearch/CandySearch.xcodeproj/project.xcworkspace/xcuserdata/Yi.xcuserdatad/UserInterfaceState.xcuserstate b/Project 06 - CandySearch/CandySearch.xcodeproj/project.xcworkspace/xcuserdata/Yi.xcuserdatad/UserInterfaceState.xcuserstate
index 286c2c1a..1a5c5ec6 100644
Binary files a/Project 06 - CandySearch/CandySearch.xcodeproj/project.xcworkspace/xcuserdata/Yi.xcuserdatad/UserInterfaceState.xcuserstate and b/Project 06 - CandySearch/CandySearch.xcodeproj/project.xcworkspace/xcuserdata/Yi.xcuserdatad/UserInterfaceState.xcuserstate differ
diff --git a/Project 06 - CandySearch/CandySearch.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/CandySearch.xcscheme b/Project 06 - CandySearch/CandySearch.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/CandySearch.xcscheme
index 2d87faee..1b08d2cf 100644
--- a/Project 06 - CandySearch/CandySearch.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/CandySearch.xcscheme
+++ b/Project 06 - CandySearch/CandySearch.xcodeproj/xcuserdata/Yi.xcuserdatad/xcschemes/CandySearch.xcscheme
@@ -1,6 +1,6 @@
Bool {
+ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let splitViewController = window!.rootViewController as! UISplitViewController
let navigationController = splitViewController.viewControllers[splitViewController.viewControllers.count-1] as! UINavigationController
diff --git a/Project 06 - CandySearch/CandySearch/MasterViewController.swift b/Project 06 - CandySearch/CandySearch/MasterViewController.swift
index 9a9af816..79d5ea27 100644
--- a/Project 06 - CandySearch/CandySearch/MasterViewController.swift
+++ b/Project 06 - CandySearch/CandySearch/MasterViewController.swift
@@ -59,18 +59,27 @@ class MasterViewController: UITableViewController {
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
definesPresentationContext = true
- tableView.tableHeaderView = searchController.searchBar
searchController.searchBar.scopeButtonTitles = ["All", "Chocolate", "Hard", "Other"]
searchController.searchBar.delegate = self
+ if #available(iOS 11, *) {
+ self.navigationItem.searchController = searchController
+ self.navigationItem.searchController?.isActive = true
+ self.navigationItem.hidesSearchBarWhenScrolling = false
+ } else {
+ tableView.tableHeaderView = searchController.searchBar
+ }
}
func filterContentForSearchText(_ searchText: String, scope: String = "All") {
- filteredCandies = candies.filter { candy in
- let categoryMatch = (scope == "All") || (candy.category == scope)
- return categoryMatch && candy.name.lowercased().contains(searchText.lowercased())
- }
-
- tableView.reloadData()
+ filteredCandies = candies.filter { candy in
+ if !(candy.category == scope) && scope != "All" {
+ return false
+ }
+
+ return candy.name.lowercased().contains(searchText.lowercased()) || searchText == ""
+ }
+
+ tableView.reloadData()
}
override func viewWillAppear(_ animated: Bool) {
@@ -88,7 +97,7 @@ class MasterViewController: UITableViewController {
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- if searchController.isActive && searchController.searchBar.text != "" {
+ if searchController.isActive {
return filteredCandies.count
}
return candies.count
@@ -98,7 +107,7 @@ class MasterViewController: UITableViewController {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let candy: Candy
- if searchController.isActive && searchController.searchBar.text != "" {
+ if searchController.isActive {
candy = filteredCandies[(indexPath as NSIndexPath).row]
} else {
candy = candies[(indexPath as NSIndexPath).row]
@@ -113,7 +122,7 @@ class MasterViewController: UITableViewController {
if segue.identifier == "showDetail" {
if let indexPath = tableView.indexPathForSelectedRow {
let candy: Candy
- if searchController.isActive && searchController.searchBar.text != "" {
+ if searchController.isActive {
candy = filteredCandies[(indexPath as NSIndexPath).row]
} else {
candy = candies[(indexPath as NSIndexPath).row]
diff --git a/Project 07 - PokedexGo/Podfile b/Project 07 - PokedexGo/Podfile
index 7dfce12e..0a95938e 100644
--- a/Project 07 - PokedexGo/Podfile
+++ b/Project 07 - PokedexGo/Podfile
@@ -4,7 +4,7 @@ target 'PokedexGo' do
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!
- pod 'RxSwift', '~> 3.0.0-beta.1'
- pod 'RxCocoa', '~> 3.0.0-beta.1'
+ pod 'RxSwift', '~> 3.0.0'
+ pod 'RxCocoa', '~> 3.0.0'
end
diff --git a/Project 07 - PokedexGo/Podfile.lock b/Project 07 - PokedexGo/Podfile.lock
index 472ea3ac..84b82015 100644
--- a/Project 07 - PokedexGo/Podfile.lock
+++ b/Project 07 - PokedexGo/Podfile.lock
@@ -1,16 +1,16 @@
PODS:
- - RxCocoa (3.0.0-beta.1):
- - RxSwift (~> 3.0.0-beta.1)
- - RxSwift (3.0.0-beta.1)
+ - RxCocoa (3.0.1):
+ - RxSwift (~> 3.0)
+ - RxSwift (3.0.1)
DEPENDENCIES:
- - RxCocoa (~> 3.0.0-beta.1)
- - RxSwift (~> 3.0.0-beta.1)
+ - RxCocoa (~> 3.0.0)
+ - RxSwift (~> 3.0.0)
SPEC CHECKSUMS:
- RxCocoa: 8cecf331302b8ae5381bbab1bccba4ede2eae6a8
- RxSwift: 0823e8d7969c23bfa9ddfb2afa4881e424a1a710
+ RxCocoa: 15a52fc590dcc700cb4a690a633b5c5184ce3a78
+ RxSwift: af5680055c4ad04480189c52d28385b1029493a6
-PODFILE CHECKSUM: 31520e96dfb6135d161b1a6bb218b7c0ec40fe04
+PODFILE CHECKSUM: a0a772563440e97813d5a19acc777d48b93573ca
-COCOAPODS: 1.1.0.beta.2
+COCOAPODS: 1.2.0.beta.1
diff --git a/Project 07 - PokedexGo/Pods/Manifest.lock b/Project 07 - PokedexGo/Pods/Manifest.lock
index 472ea3ac..84b82015 100644
--- a/Project 07 - PokedexGo/Pods/Manifest.lock
+++ b/Project 07 - PokedexGo/Pods/Manifest.lock
@@ -1,16 +1,16 @@
PODS:
- - RxCocoa (3.0.0-beta.1):
- - RxSwift (~> 3.0.0-beta.1)
- - RxSwift (3.0.0-beta.1)
+ - RxCocoa (3.0.1):
+ - RxSwift (~> 3.0)
+ - RxSwift (3.0.1)
DEPENDENCIES:
- - RxCocoa (~> 3.0.0-beta.1)
- - RxSwift (~> 3.0.0-beta.1)
+ - RxCocoa (~> 3.0.0)
+ - RxSwift (~> 3.0.0)
SPEC CHECKSUMS:
- RxCocoa: 8cecf331302b8ae5381bbab1bccba4ede2eae6a8
- RxSwift: 0823e8d7969c23bfa9ddfb2afa4881e424a1a710
+ RxCocoa: 15a52fc590dcc700cb4a690a633b5c5184ce3a78
+ RxSwift: af5680055c4ad04480189c52d28385b1029493a6
-PODFILE CHECKSUM: 31520e96dfb6135d161b1a6bb218b7c0ec40fe04
+PODFILE CHECKSUM: a0a772563440e97813d5a19acc777d48b93573ca
-COCOAPODS: 1.1.0.beta.2
+COCOAPODS: 1.2.0.beta.1
diff --git a/Project 07 - PokedexGo/Pods/Pods.xcodeproj/project.pbxproj b/Project 07 - PokedexGo/Pods/Pods.xcodeproj/project.pbxproj
index b22889e7..78276a94 100644
--- a/Project 07 - PokedexGo/Pods/Pods.xcodeproj/project.pbxproj
+++ b/Project 07 - PokedexGo/Pods/Pods.xcodeproj/project.pbxproj
@@ -7,575 +7,594 @@
objects = {
/* Begin PBXBuildFile section */
- 000B063FD301679731F8FFF30B6E5733 /* Observable+Creation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E76C507568E7ADA82A3ED8A726F5358 /* Observable+Creation.swift */; };
- 0226A0AEE44C36AF973682CB4E1F7AA8 /* DelegateProxyType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4ECD634CA1C212F31539A5E94F027EEB /* DelegateProxyType.swift */; };
- 023ACADEFB83DF1D3C198C428DCF38AA /* _RXObjCRuntime.m in Sources */ = {isa = PBXBuildFile; fileRef = 67A7308A253850F00B05819855D27377 /* _RXObjCRuntime.m */; };
- 02ED9C39332CDA21BC1ABB82D3C0CBD0 /* String+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 875AD7325E306F32D856D41E705AFBE8 /* String+Rx.swift */; };
- 02EEDEC0A12BC1A14F24D1B4CC20313C /* NSObject+Rx+RawRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F73756FE68B6364B365C9083D70B121 /* NSObject+Rx+RawRepresentable.swift */; };
- 03349F7DB26471557DBA3BEC6AD66AA7 /* NopDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 923D369B7E87DEBE70A5D19C80932394 /* NopDisposable.swift */; };
- 038E7D217E8AF9B056F12B6022607BAC /* ObservableType+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEA91F7AF9BF7F6119E6D1CFBA138B64 /* ObservableType+Extensions.swift */; };
- 05375DD8BA8B0C62D6BD5CB8136C23F2 /* CombineLatest+CollectionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA042F18C4D096E30CA6636B17CEC3C4 /* CombineLatest+CollectionType.swift */; };
- 060BB7EDFED8C8F38EAB1C75419A6984 /* UILabel+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 601AE0DC6A3E86F516609C6D06CB60E2 /* UILabel+Rx.swift */; };
- 065CB7E7FCD725744876B59BBCDA7173 /* Using.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58AB0072B17C75AB1A21ECC38A91ACA1 /* Using.swift */; };
- 067820A308D5CCAAA9EF50952578CD61 /* HistoricalSchedulerTimeConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F122B20E85DCC0A43C1773DA9A43FD01 /* HistoricalSchedulerTimeConverter.swift */; };
- 0738F0FAE4360B87C55BFCA3BCC1B30B /* Observable+Time.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5496796606D494C97794B6F90DF06136 /* Observable+Time.swift */; };
- 0923FCEEF2D4FCADE1727D61D99BDF05 /* ObservableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80671F727A9868EBE4018ED741F933D5 /* ObservableType.swift */; };
- 099DA1BDFD5892901146348B998D3D66 /* Lock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 974451D2E3E510B8E8A63654E04ACDD5 /* Lock.swift */; };
- 0BFAFB96C3AAACEDF809C2C85EEE7D9B /* LockOwnerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78D9CB1DCF4A368A286D9D843A1A4000 /* LockOwnerType.swift */; };
- 0C5587DCDD5C7DBB42B0B8A02882B368 /* UIAlertAction+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = B323F07EDFADF3FA093F86A088170A96 /* UIAlertAction+Rx.swift */; };
- 0EC4CEF1E3132FB1AEB0D781818D6D6D /* BinaryDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E3FBE0F1D7C28F9585CE363E110E1E /* BinaryDisposable.swift */; };
- 0FD76A04CAC5537F85A14A05E41B7AF1 /* Sample.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7771C5D99A775DA150DF545D573C1EF /* Sample.swift */; };
- 1032B74EC7A00AF022076C108643AD7E /* UIScrollView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = E68FEF97896DC2C7B815D611FE2A2997 /* UIScrollView+Rx.swift */; };
- 10530B2996D799370BF1D002D3EA9286 /* RxCollectionViewDataSourceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F48A7A2FF100CA7C630D332D34B7F3D /* RxCollectionViewDataSourceProxy.swift */; };
- 1083539F27F8C4A38F263A9655B3EB6B /* Skip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E3556A091491F30496F2E31FD3DCCAF /* Skip.swift */; };
- 10E959E45D4D428635056928219C5475 /* MessageSentObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = C24EA368C4E55B5D1ADDAFB78767AB90 /* MessageSentObserver.swift */; };
- 114AF7633716B810F80CD33CC340B909 /* KVORepresentable+CoreGraphics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 763DCEB0D5A66E991CC1B858DDC91E5F /* KVORepresentable+CoreGraphics.swift */; };
- 11C6D2B3912E2C8D012A347429216A97 /* TakeUntil.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3EA8D80D27873339FD839408A4206D3 /* TakeUntil.swift */; };
- 121D0412D6ED7B71C1AAC420CC31DE0A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 75BB3296A6C3E9773C545F0323C2659E /* Foundation.framework */; };
- 12CB5D267916999E0DCE991355A51F49 /* CompositeDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C919C040B85DF8BA3198306E66C6217 /* CompositeDisposable.swift */; };
- 139F2DDB3C00644885AC74E0DC7D69D8 /* CombineLatest+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = C012DED32C78F3BC4893FBB11ADB1866 /* CombineLatest+arity.swift */; };
- 13A3A6073FA3C3C35FB71D7F068CD495 /* ObserveOn.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02811E0858D470F34B739A6BFD2056F3 /* ObserveOn.swift */; };
- 14928CC74400DA81629E25E7E5AB08AF /* UISlider+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 438E2DC43570497DBE921AEB89518230 /* UISlider+Rx.swift */; };
- 1591B5BD6CA1678FD501EF69D85EDB22 /* UIPageControl+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF298074EB8EE70D6C90A0F816301B1B /* UIPageControl+Rx.swift */; };
- 159E21E449E35A0B0AD11826D1C2E911 /* TextInput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14BF84797953369156C57EB5452EBF9E /* TextInput.swift */; };
- 1FA72CFE5EA8AD4AF5B50822AD02DE32 /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63DA3DD4CA65031F9D6C2404057153C5 /* Logging.swift */; };
- 21E47814734174E5577E9B6E489DB2EB /* Throttle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4E71A7E8F33A5D0D3B543950D968DCC /* Throttle.swift */; };
- 2469ABD273088B429C3D2D5F81F3F754 /* RefCount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E41312BC41502D9EC683B790A5DEC59 /* RefCount.swift */; };
- 250B4E7CF26413EF2FB28815B1B62C3B /* WithLatestFrom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00ED64DA988B533B84EB169AFCED363E /* WithLatestFrom.swift */; };
- 2546F9E0F230393F3116C65D708CD339 /* RxTextViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD2637FEE9AF1F14498DE84B56DAC41F /* RxTextViewDelegateProxy.swift */; };
- 258DDC4D40D56198DBAA5750B20167D5 /* Observable+Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3777004EB16505CA6386B7D9FDBD7ED7 /* Observable+Debug.swift */; };
- 26381F45E3C7A769E893500A9185B214 /* ConcurrentMainScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B365A38BCEEABC88B67EA39D80A861F /* ConcurrentMainScheduler.swift */; };
- 264DB6CCFB81FD481F9505279EDCCAAD /* ScheduledItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 383F17D9EBD7C4F32343FBA6C5743F68 /* ScheduledItem.swift */; };
- 26C95DD0018660F8458E31B0CB1A671E /* ControlProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 360DB4FE725B14D1B4A919CAE6C07BD0 /* ControlProperty.swift */; };
- 27B825CB7B26AA4455DE2DB1EBAE68D4 /* UIRefreshControl+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = C04FFC0F79AC98E453AA5ECC691D397A /* UIRefreshControl+Rx.swift */; };
- 29EC70D2CA454BE2052C9EC3CB904FEA /* NSTextStorage+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E727D5CC6EEBE70CCC6502058E01F37 /* NSTextStorage+Rx.swift */; };
- 2A1C6A8E7B0DB05623F91821D3988FC8 /* _RXKVOObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = A63EFF26965AFE7FFE18E68C039E6555 /* _RXKVOObserver.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 2DE2638032226CA289337A10058BA8CC /* ScheduledItemType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3193F1228BF29C5E2A301B4B72B7980E /* ScheduledItemType.swift */; };
- 2F1A3059466F0A841A3254B0DBD8BACD /* Observable+Bind.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2FFC8DFE23B2D54E75C8888A95AA6C1 /* Observable+Bind.swift */; };
- 2FE6A5B69FF76C6573D8C9B8D8EB5789 /* RecursiveScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE6847941FEFEBAD130A00A342EB2462 /* RecursiveScheduler.swift */; };
- 31673C97F052AF47444F89EFEE80403F /* UISegmentedControl+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D320004447B001CBF0382B778DA6BEB /* UISegmentedControl+Rx.swift */; };
- 32FA55C677F991160DE3F2658E843217 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 75BB3296A6C3E9773C545F0323C2659E /* Foundation.framework */; };
- 3484D496EC5F2E7A300319F44A5710CF /* AnonymousDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59CA3C0ABB91378BF6FE484D94481D88 /* AnonymousDisposable.swift */; };
- 39090DBB52FF620EAD0813499C55F238 /* VirtualTimeConverterType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C642634FB859E1CBD5D098944AA629E7 /* VirtualTimeConverterType.swift */; };
- 3AEF12CACDD31E3E49F34D33372F4D1A /* SubjectType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52CCD0DF27D758124EE0BE12C033A336 /* SubjectType.swift */; };
- 3B34B15249AE1BD1BE4187FAC9873EA6 /* Just.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24EDBAF23688A76BA859735A2C8F3194 /* Just.swift */; };
- 3B8F5148F9F09D670822F3C34B58D871 /* Never.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B5D4368EAAEDBE617887F4EFB6EB0FB /* Never.swift */; };
- 3DA26A5A37F9D76BD7F425906B08A561 /* ReplaySubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58ECDE291B6C4966870B10DAAAC54753 /* ReplaySubject.swift */; };
- 3E0A23FB1C4EECC5DD016E55E4F8EC5C /* UITabBarItem+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1186161B975100A7DFC409B8C396D8B0 /* UITabBarItem+Rx.swift */; };
- 402E8D815B06D252DD6E6D527FB031A1 /* RxSwift-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = DE59B946AC888EB09684FEE661093D15 /* RxSwift-dummy.m */; };
- 410081D0FC3368E5FEEE568AC262BF63 /* SingleAsync.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD760FDEF3325452D1956E31DA16DF94 /* SingleAsync.swift */; };
- 4210F63FDD2369A54E4142B218F2D716 /* RxCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A47F6ED70808C18751C82FE05C97E84 /* RxCocoa.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 4270933FB3F4B96E628CE1FA13A10F2B /* DelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9E7251AB28157263C195FC6E7D0D6A8 /* DelegateProxy.swift */; };
- 4354A4AB284D5CB7F60170EC9AA45C56 /* SynchronizedDisposeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 815BE4D54328DCCC3EC688E99D515B84 /* SynchronizedDisposeType.swift */; };
- 43577F0B35EDE5C8CAD3985C85AED6BB /* ObserverType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93307CD2F54897156D970EBDF97FA4F6 /* ObserverType.swift */; };
- 43D6ACABD794D862A6E86F6B52868B55 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 75BB3296A6C3E9773C545F0323C2659E /* Foundation.framework */; };
- 44FC239A0596D8DF873A3335E9CB9D54 /* UISwitch+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = D39FA6AC4938B92E4C0E1C3BFA0BBC38 /* UISwitch+Rx.swift */; };
- 478243AB17606EA714C45C1C745968D6 /* RxTabBarDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47C615A0C1C7CB0D93B1B59AAE7AE2FF /* RxTabBarDelegateProxy.swift */; };
- 49DEE03177E6DC81647C32BE0D3FAAEB /* SubscriptionDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = E42385DC3EDBFE2B12B9925A28D2F600 /* SubscriptionDisposable.swift */; };
- 4A6969C2FF43B8F29467829DA857ED58 /* ControlTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4742034066CBC30A03A7231BA909C2B8 /* ControlTarget.swift */; };
- 4BC7122279FAA452B5FFFF73BD3EAE9F /* RxCocoa-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = E14999237B0ADBAEE8885532CFF4C230 /* RxCocoa-dummy.m */; };
- 4EDE709A8D80B39DAFF8E8AAE8FDF7D2 /* Concat.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7437F81B9A645215265A83BA900C24E /* Concat.swift */; };
- 526F658B2DFB22E2B897D95CAB61459A /* Delay.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC1D5F202F14E89C94DC8C8E9D3F2C35 /* Delay.swift */; };
- 5302D92F05F8E1F5DD28E2F733B89A3E /* _RX.h in Headers */ = {isa = PBXBuildFile; fileRef = 5912F2821234C2DC94784AB7BA0E7F3E /* _RX.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 54C485DCB6BA1622B49FC3089DEBFBC1 /* Producer.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDE391691D8B5DF2142BD6D8E5BED61C /* Producer.swift */; };
- 562385BF0FC589222A183666DCDA5400 /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = D402D1E02B23CC1DAFF711945E6C7C01 /* Error.swift */; };
- 568B2FF1D4BEF3605B4738BB5024D2E8 /* Driver+Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B14971A9FD6B467BD6C09B2379A9395 /* Driver+Operators.swift */; };
- 585C95DBEFB469249E9EF27658647965 /* Platform.Darwin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD593F3D0565668D7CC5990CE36818C /* Platform.Darwin.swift */; };
- 5ADA010E21F0DD0418EBF462DF0459EA /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56D9D0405D1B795B6655805AC1CC4429 /* Filter.swift */; };
- 5BA6238EB2518E8DB7EA41BFB453F64C /* ShareReplay1.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF811611BEC6E64AEDFA7326DDB269C6 /* ShareReplay1.swift */; };
- 5BEA1515F5BF10D217029C67551F19B3 /* RxTextStorageDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14C6018EB8ED3D2D4687001C575AFF19 /* RxTextStorageDelegateProxy.swift */; };
- 5BEAF300718433931253845E3ED3B29E /* UIBarButtonItem+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 322CA81233C08A654C0E044DCDC6F33D /* UIBarButtonItem+Rx.swift */; };
- 5D7EBAE24A93B4C36D704B7959A68D91 /* ObserveOnSerialDispatchQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9909A3B04F5BD9E0986A29DF4B5C9934 /* ObserveOnSerialDispatchQueue.swift */; };
- 5DA1DA267B7C6F0C6F0E740CA08B0ACF /* Disposables.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE7470DD24D55539FE38B33354609932 /* Disposables.swift */; };
- 5DF4F3950FC69C869DCD333388F9A2AC /* ConnectableObservableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 614501176A095DC28303FD6091BAF437 /* ConnectableObservableType.swift */; };
- 5EE6A029304C5322AE71A0BAC6395DBB /* DistinctUntilChanged.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43FC3978A8C9F39C7800B21748B1C0EF /* DistinctUntilChanged.swift */; };
- 5F2D15A384B5E4A0FC6DE365D6D3574E /* Observable+StandardSequenceOperators.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3F95B7A11DFE661FB160F43DBA4B0B4 /* Observable+StandardSequenceOperators.swift */; };
- 5F65FAFF82D57FEE3D17D9D97006D914 /* Observable+Single.swift in Sources */ = {isa = PBXBuildFile; fileRef = F435E99579B5D417F9A5FFC0F7965B24 /* Observable+Single.swift */; };
- 5F847F03D5F09995DB0784844F330A21 /* Pods-PokedexGo-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 48AF5E6DB322F1C2C0209B854CE73993 /* Pods-PokedexGo-dummy.m */; };
- 61BEF0E4F3056C2AE5244886D9E8CD6A /* RxCollectionViewReactiveArrayDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7715463243BDD5175442CD871B06B2C /* RxCollectionViewReactiveArrayDataSource.swift */; };
- 62CC7CCAB23419773EA8F05FD1BF8F46 /* DispatchQueueSchedulerQOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16BBBD04181474EAD0A97986ADBDE173 /* DispatchQueueSchedulerQOS.swift */; };
- 6416015FB86AEEED018CB78AAA46790E /* Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69A4F803D759819D60EA7B093FEBBE3E /* Driver.swift */; };
- 64241BCF6445B010E2A1EB0670AA3D42 /* InvocableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86FF2384DCA4A4841ADF1FC2C0A9B331 /* InvocableType.swift */; };
- 654B482A8926A6C774C98664388658C5 /* UIApplication+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CADEFCECC0EB186A12C0B291342D1CC /* UIApplication+Rx.swift */; };
- 65743D917885947A81777BAEE977C456 /* InfiniteSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBA62AF7E35D7F2AA1960DCF36A8A854 /* InfiniteSequence.swift */; };
- 66C957B4D0415A249E3EE833E4371994 /* Variable+Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AF7610675E023203BE8EEE19C0F3F40 /* Variable+Driver.swift */; };
- 6942EB131AD4F0CCD6E5B60F88B8EDAB /* BehaviorSubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4B00B3C6C7431F4D4550AD43C84F160 /* BehaviorSubject.swift */; };
- 6E6C0314350BCDE34E2BDC540FD6FFF2 /* Zip+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7120F33703B8BB8862848546B1FD3393 /* Zip+arity.swift */; };
- 6ED51F4BFCEFBAD3C2AA38CB9293FEB2 /* DispatchQueueConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = C09A7A805374E513BC23516FE2414379 /* DispatchQueueConfiguration.swift */; };
- 6F07E168515898D6C8878BB88C50D72C /* RxSwift-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = EBA4D3419DA92747E9480E3892A0C2A1 /* RxSwift-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 6F4D85A44A7CA416C9F280D4B00D2597 /* Debunce.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B207B09ACA2B7C1A5955D4A670DF155 /* Debunce.swift */; };
- 6F95234234C5A7E07EB683381130F423 /* UITabBar+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9175FC6544DCDA825575330E821C7D3F /* UITabBar+Rx.swift */; };
- 7169C08262F574788CB29875468617EB /* SynchronizedOnType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 257340FD101A7D19D51F5261F0468333 /* SynchronizedOnType.swift */; };
- 718D7B7FB427D42DFDEA6FE094F36DCA /* UIViewController+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03A4D1610491EEC726F17C86B0EEADB0 /* UIViewController+Rx.swift */; };
- 71B42A3E2FB3C7F7CE0EAD2710F59C0A /* UITextView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = E15CFC2139EC375288323D99AF8ED04F /* UITextView+Rx.swift */; };
- 7363ACC8A29B4B8D4F6804BC5929B3E8 /* RxCollectionViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73D332413223B3E4D33CDBF39A1C0F62 /* RxCollectionViewDelegateProxy.swift */; };
- 75E8D0BA3AE5FBDE9A73C4F68B61F9BF /* _RXDelegateProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DE82875BF092ABF63F0129F1D66C342 /* _RXDelegateProxy.m */; };
- 76F654CD972132327C048291F268C8B0 /* KVORepresentable+Swift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D4B079C6BF22EB60FB4059831740F9A /* KVORepresentable+Swift.swift */; };
- 798D24B759179C918B3C181E9C7A99CB /* _RXKVOObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = A070DEC2D90F2C3579F76D9FE69599F5 /* _RXKVOObserver.m */; };
- 79978C870BB6B31A0CF9B4B3DCC4FC0A /* Zip+CollectionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F1518F3631A490DAC3F9FCF8B227E1D /* Zip+CollectionType.swift */; };
- 799A9FC2149DF784CABC966AE38308B0 /* Queue.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58B58F4778B78D196858693A192BFEC /* Queue.swift */; };
- 7A0E20A7C149A126249CE2764497FF13 /* RxSearchBarDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0FAFF56A663DBECFB5CCB4D170959B3 /* RxSearchBarDelegateProxy.swift */; };
- 7A7CFAEEC2DCD04B97FDD4C24DAE8146 /* ControlEvent+Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C948102FFA85AF99FA4BDC4B31CEF66 /* ControlEvent+Driver.swift */; };
- 7B711100E8EC1981415FBC7F63D0B7FD /* Reduce.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27AC0F00E0539EE6BB3CA625F08F2A21 /* Reduce.swift */; };
- 7BE874E302F827B41F0DA43B1DDE68DE /* RxTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6CAB229EDDF2297965B52C92A2B5A76 /* RxTarget.swift */; };
- 7BF138F0EA1C2F1B831531B5A6C0A64F /* SynchronizedSubscribeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A1611E18D67AF94FDC0B20D1CAF3A5F /* SynchronizedSubscribeType.swift */; };
- 7C5493B6455831A091803F51972CDA8E /* Observable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77092120A3A3512BD4BC7DD2BF7F07B5 /* Observable.swift */; };
- 7E748810A566B9CD0BD8AB40A667F929 /* Range.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAF80653BBA27BB38CCC9ADB1B8989F7 /* Range.swift */; };
- 7F0E8DBC543D0E81FE073E2E3F39FA09 /* Pods-PokedexGo-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = CD0C2708ACBC7809074D8DBFBAE2CF6F /* Pods-PokedexGo-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 7F49FDF50F834786A24A1595D5C50718 /* MainScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 357DF1CCC5063151569BCAC8BF4E9C6D /* MainScheduler.swift */; };
- 7F8D3FAEA342967C3B01FA6564D516E8 /* RxImagePickerDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = F27D858F62ECFB1BA73D63121A6A8EF0 /* RxImagePickerDelegateProxy.swift */; };
- 7FAE419D4D86D5809B677DF91CD043E7 /* RxTableViewDataSourceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68902A22C3070C8404E89BEF8A6F5FE5 /* RxTableViewDataSourceProxy.swift */; };
- 80D411ABB47575CEC00B164415356439 /* InvocableScheduledItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B19D13BC17648E846D58611097F395F6 /* InvocableScheduledItem.swift */; };
- 822B9B2D31DBEB3BC1470891BB9E346F /* ImmediateScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = DABE43FFA22A5DC6DB547C6A26CA3F12 /* ImmediateScheduler.swift */; };
- 827F5BFFA3091EB4E72B617586A8F1A5 /* Map.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45B87E1492D431B8BA1E5AEB616A1AB4 /* Map.swift */; };
- 82B80B81D224402623C4DB4E358D32E6 /* BooleanDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF7C0B8064B13EF1B178438E7E83C24F /* BooleanDisposable.swift */; };
- 842DAA3E11FE3F9528597D860F6DA6D6 /* DisposeBag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F597BF92F8C72C9FD96C8DAE1655E9B /* DisposeBag.swift */; };
- 84814A43FA9B7B3B881073E583427380 /* Empty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67E42E4C26C38702416C0FA860FE4966 /* Empty.swift */; };
- 84E8EAFEAB5002513564F99F9C14C3C4 /* SingleAssignmentDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3ADEF916724C3CD33414826B3075629D /* SingleAssignmentDisposable.swift */; };
- 853B999E3BCE9F97DE3A615190A0C8A1 /* Observable+Aggregate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FE90752083D12290474BC5BAA176969 /* Observable+Aggregate.swift */; };
- 8692E98F7E2FB3C77B77CBA3FBA511FC /* DisposeBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D2E6375EF514E682DD5E099DEEA3C10 /* DisposeBase.swift */; };
- 8963FB3DD4ED2AE1D2747CD27AB29F79 /* _RXObjCRuntime.h in Headers */ = {isa = PBXBuildFile; fileRef = 622E80E3BE45B199242F59CB43CB499B /* _RXObjCRuntime.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 898D45A6CB05AC31969F4ECBF4CB05AE /* RxScrollViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67C395039E40CCBAAF192350C12B9B6A /* RxScrollViewDelegateProxy.swift */; };
- 8A7B6E452DF412F5A64E9ECD424D2F22 /* RxCollectionViewDataSourceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDBDF06D1B6E91266A572AA103E794F /* RxCollectionViewDataSourceType.swift */; };
- 8B45821DCADB3F6BC24F3E2711C42E3B /* AsyncLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 804BC3384434439D1B1A243BE02DAD4A /* AsyncLock.swift */; };
- 8B65BFC93E68DEB7F12D1B27FD57BC13 /* UINavigationItem+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58F525F5B278210733C9EFC92FFEE06C /* UINavigationItem+Rx.swift */; };
- 8C00CB51D3C776341791C661ACA57C2B /* UISearchBar+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4706890E176FBF3A8D3F02AC3051B9CC /* UISearchBar+Rx.swift */; };
- 8CE91102D2CE432063BA65003DCB7475 /* Zip.swift in Sources */ = {isa = PBXBuildFile; fileRef = F91980105679FB515A28F75DC6473584 /* Zip.swift */; };
- 8D18BFDA8A1C379934E7C76A0DBBAD79 /* AnonymousInvocable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D0141EACF4F5D67D5961B4AA466A47 /* AnonymousInvocable.swift */; };
- 902D49F6915B5AA29CACDBDA87321FD3 /* Observable+Multiple.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A111DDC4C1EB87CD4BE69AB57654306 /* Observable+Multiple.swift */; };
- 9043847379ECC7C512BDC6B89C0030AE /* Bag.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB11497F37FF7943862F286A1651D042 /* Bag.swift */; };
- 9095FFEE4A59CDC37E05F226E25C665A /* AnonymousObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDDC303D9A217476756CF5B9D1EBA5B7 /* AnonymousObservable.swift */; };
- 9244FC69DDCCA91D041F5EEAB590C29B /* TakeLast.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1EC5D0239E634C375CA320C1CA5F9FDF /* TakeLast.swift */; };
- 9325E91F0D5BCABEA1A221652D95AE53 /* Driver+Operators+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0291CC41E092EBFDF54D42B02E6424D3 /* Driver+Operators+arity.swift */; };
- 936D423DA529913F7A96CD1EDE161446 /* SynchronizedUnsubscribeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FA875C719138BA80C24ECFC28FDBF53 /* SynchronizedUnsubscribeType.swift */; };
- 93987D0C6E16433D86D9DD338F07795A /* UIBindingObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D0291CEF66C870D5E9E719C0EA72C1B /* UIBindingObserver.swift */; };
- 9534FB6966E51DFA0116C5AD6422C026 /* UIGestureRecognizer+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C939E6C52D2B5B921536AB609A6DF9A /* UIGestureRecognizer+Rx.swift */; };
- 9B0C23910EF280F64DC2EC303FF903D0 /* DelaySubscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6709E98277C4B1371C21EEF7734944C /* DelaySubscription.swift */; };
- 9CBF604FF8CF14BD6DAD363F4BFE1AD5 /* ShareReplay1WhileConnected.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FAF129F0D5E633DA019E3F6BD799E0B /* ShareReplay1WhileConnected.swift */; };
- 9D9AA21DCD5F437F30AF75A4DBC6C32D /* Do.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E65FFF0964AFA4A351C3DC3DCB3049 /* Do.swift */; };
- 9EEE7265F1B76348C5ED599076DCFFCD /* VirtualTimeScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = A45E326290449ED1728E999DE8CD3CE2 /* VirtualTimeScheduler.swift */; };
- 9F165611E7FC0E29356C3BC02956BEAF /* Timer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A056920DC5F216195680972D62F4E985 /* Timer.swift */; };
- A057AE65C3CCA3CE2A6AA15A253D2450 /* Generate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CD370C39CCD9BFAD67AB8BD32F90797 /* Generate.swift */; };
- A0B69A7A4559D8C3A628299126D263BD /* Switch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E09E844F9BC7D5598D6EF366D27BCA9 /* Switch.swift */; };
- A10C76937225217C6056E552E03B230A /* RxSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 397ED6A120A7323FEFFD443352B8A3B8 /* RxSwift.framework */; };
- A2A95C5735862A712D566BEA75D200CE /* RefCountDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD661F853C0E03E91523D62109EFAE7E /* RefCountDisposable.swift */; };
- A2BC4F1279CFA1C735ECCA7125A70B2E /* NSNotificationCenter+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52AA199050F22DB9F9654B0E79A1B72D /* NSNotificationCenter+Rx.swift */; };
- A459DB9C44891DD97058C0C2499C96FB /* Platform.Linux.swift in Sources */ = {isa = PBXBuildFile; fileRef = 692544D6FE00282284D2344E91536B0F /* Platform.Linux.swift */; };
- A56C60396A7689818FA6D5D12B41FABB /* Sequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = F231F1E47F983ACDA69EFC946613F57A /* Sequence.swift */; };
- A5FF9B1CEDB7FD51B137660A49B48565 /* NSObject+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 945831043EEFA936E358129A58ED1C11 /* NSObject+Rx.swift */; };
- A6AC25617FC2ED12F0A27CFD039AA3F1 /* NSObject+Rx+KVORepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 363274368317697F561BB2ED8F6AB66A /* NSObject+Rx+KVORepresentable.swift */; };
- A6CE70378DC461284BC023DC93FCEEFA /* Window.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40AAB2FCC33C7D3618DF8098E641D159 /* Window.swift */; };
- A70295D2F70FF80D9490A9AB377E0E2B /* PublishSubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E9940D9817166477856DE65094A6260 /* PublishSubject.swift */; };
- A76AD9032F03DA4799CE35D58DB5F8EA /* SchedulerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83C0B77EBE2FB832EAE703B2C7CBC016 /* SchedulerType.swift */; };
- A86474A13C3C51C31371E82963801E42 /* UISearchController+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7CFFB1B95915EA0A6DEAC76D897C750 /* UISearchController+Rx.swift */; };
- AAF1D9A9C0EFD64F9F2C72CF446A58A6 /* Observable+Binding.swift in Sources */ = {isa = PBXBuildFile; fileRef = B26E3722D77F9BA616724AD27F4B8306 /* Observable+Binding.swift */; };
- AB5F231DEC1BD5467A23076BEFB7B9BA /* ConnectableObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32F23A0961AAA6C01A1397AD90EDA9AA /* ConnectableObservable.swift */; };
- AC2935ED54A42D1AEA1990451BE7734B /* ObservableConvertibleType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15466AD4A01ACC05B816711C276C94B7 /* ObservableConvertibleType.swift */; };
- AC37CDEAC53525CFFECC9DC7B2E672A7 /* _RXDelegateProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 9AC9BD3FAF4ABFC987FFA707AB9FCB90 /* _RXDelegateProxy.h */; settings = {ATTRIBUTES = (Public, ); }; };
- AC67EBBE20EA95E7146E8A8FE1D3DFD7 /* ObservableConvertibleType+Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC52A4B9B72983EFAAA1E64B54FCFB1C /* ObservableConvertibleType+Driver.swift */; };
- AD29D9597C9C927EB1B8F56CE5D38FF4 /* ControlProperty+Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 286DB0BF724E24E942AE4449F63394D1 /* ControlProperty+Driver.swift */; };
- AE65348724534E93B2F12589A22C1034 /* KVOObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 199CEC87F4AF077D9B4762389FF6570A /* KVOObservable.swift */; };
- B0CE7A0CB812B682E338EF2AD0EC3F42 /* RxTableViewReactiveArrayDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A3E07C7438E3C2F64512F819995155B /* RxTableViewReactiveArrayDataSource.swift */; };
- B15872FCE46CA6CF1DE4C47CD53BE6F3 /* SubscribeOn.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AED7DC8C3D8A832530DA381920BFB08 /* SubscribeOn.swift */; };
- B1E3FDBB4CC2D72ABE41FFAAF7397A6D /* Sink.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF856C60360336D059EF8E28D4E2D337 /* Sink.swift */; };
- B1FB6E4AC5DDA34A5AA2A263D0AA75FF /* _RX.m in Sources */ = {isa = PBXBuildFile; fileRef = 1BD6B800FB60FC0B73E545E9998902FA /* _RX.m */; };
- B47060D878E1E37F85DCEDB36800C85C /* ToArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9CBA23DF232206FCB1D8C7619BBCF69 /* ToArray.swift */; };
- B4D7E64AD57C0D46B75EB92E32172892 /* Repeat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56CD2AB385BBA88DE1DE00A07B0CA260 /* Repeat.swift */; };
- BB619071AF0E86D7A5B22924D2142E6D /* HistoricalScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60A3F4FA5EC0032B138E22C350C8571D /* HistoricalScheduler.swift */; };
- BBB15CC012D05C82D5338A8E23835850 /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 643BFED33D2FF050AB233EDE00E2796B /* Errors.swift */; };
- BBF577DD793C204677DA247DF29FE125 /* Timeout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F9CB9AD270F4ADB7C1CF43E412EFB8B /* Timeout.swift */; };
- BC0BC892C8CECA95BE8FA2436D0FBBDB /* OperationQueueScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6D9A74A10BE89BAE9BD57C3C3EF0B5 /* OperationQueueScheduler.swift */; };
- BD83F0B46F36278289C9EEEF35191B7B /* Take.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4331958ADDFBB46E5D9FAAE5F90CFFCA /* Take.swift */; };
- BE34E1CAB4AF783460B78882BF8344F0 /* Observable+Concurrency.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0691E2AF4F4BC07A24EC93D184A3FDEB /* Observable+Concurrency.swift */; };
- BFF516A585EDECC462E0BB1A572C3D6A /* ScheduledDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1285CF0D4E016A4A056142FBCEC4BDB /* ScheduledDisposable.swift */; };
- C0631C19397001DC37B9D308F8110316 /* UITextField+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C4EF32E91A5BCD94FC3E346B25FA5E6 /* UITextField+Rx.swift */; };
- C2F7ED905D7C6A7C599451D158769447 /* ElementAt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 659A04497CFF6C207849FC691F605817 /* ElementAt.swift */; };
- C4C426FCC9B13409E9EAB9596258AD24 /* StableCompositeDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1DD88DD612366A084B53815C8B8EC26 /* StableCompositeDisposable.swift */; };
- C5C304C12FCEFCE027BE90A90B026FBD /* RxPickerViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7154F41F690DF671B3D84AA233D0EF4F /* RxPickerViewDelegateProxy.swift */; };
- C6FDF37E3DD19B89482B19C6156F4590 /* RxSearchControllerDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32070195AC7FF295DC13483699433136 /* RxSearchControllerDelegateProxy.swift */; };
- C7AB004966EA8C686A1B82A576ECFE93 /* Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC83E68B8055E29D4512897B677B4A6E /* Rx.swift */; };
- C7EB0E6F0E403DBCF935D755AD0A3A89 /* UIImageView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3355C93B63CA5FE5B47101DF7E77B25F /* UIImageView+Rx.swift */; };
- C803E2EEE84433D4E14F3145C688585C /* Driver+Subscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08999F9E91C67F502F2B31AB37B21F34 /* Driver+Subscription.swift */; };
- C8D30BE8CAFEA991769593EDABBFA3F5 /* SkipWhile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53EA419F2CBBC7553305D19102BB4686 /* SkipWhile.swift */; };
- CCE710FCE321C50437747CA48DFB550D /* RxTableViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B71409803A083925CFBC4C15E50F28A /* RxTableViewDelegateProxy.swift */; };
- D1253B52A297F8C2EC822749D3578A1D /* KVOObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF62970ED89CFEB3578CE909A25AAAD7 /* KVOObserver.swift */; };
- D1BE7B3C706DC2904142838BAB01C9FA /* RetryWhen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B20CE34F081F11DCAF386BDBD06A858 /* RetryWhen.swift */; };
- D2DD8831B9B685F798DB590503187BBF /* UICollectionView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48CC2FA6C0E67819D548633EB23EA5A1 /* UICollectionView+Rx.swift */; };
- D3FA548E4A33EA8679AFA023EEADEAA8 /* UIProgressView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF31863D0607B6C66F28E0D629CCD337 /* UIProgressView+Rx.swift */; };
- D4A8376AE4BAE44614DC25EA4ACBE610 /* TakeWhile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E928C29A41850F7AC97548FE0213AF0 /* TakeWhile.swift */; };
- D4E5C3266245EEC495A4A7598146AC23 /* TailRecursiveSink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F3B2427854E0EBD6D65C83D0820471B /* TailRecursiveSink.swift */; };
- D58DC4FD347A34D3524377C5F6CFC8E6 /* Amb.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1DDC1727726DF2FBA676B44135BAD22 /* Amb.swift */; };
- D73D0168BE4DBFFCB4149A5C46B6C3F3 /* AnonymousObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3E6953D9F4B6EAC7C0C428E98BC2111 /* AnonymousObserver.swift */; };
- D7B9459FB76EC99338E8C900294F6D27 /* ControlEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1C16CDD1C24EF1E943954022D241AB1 /* ControlEvent.swift */; };
- D912ACF721DA79933899B1E5372716ED /* RxMutableBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51588A5611E67C994212A30648416D83 /* RxMutableBox.swift */; };
- D970DE2C185F97A198B7785855940664 /* RxCocoa.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6DE40FA76E07D0387C2A2F07829B2D8 /* RxCocoa.swift */; };
- DB0E4476A1328740B85AF1C5A9DB649A /* Reactive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35BCDAFC104DCC94AF1FE83D7487AA10 /* Reactive.swift */; };
- DC6EC6A53C277DF95A872F6C21744024 /* SchedulerServices+Emulation.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9D1250F3B0AF2AF712290A1D5F29022 /* SchedulerServices+Emulation.swift */; };
- DE41ADC85BDBD18D3660715B3731FA4F /* SerialDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEAE74107F4B28F464DC349437C5F181 /* SerialDisposable.swift */; };
- DE7B7B17930E25419A5FF8B5F2CA0686 /* NSLayoutConstraint+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB9FB80A2BE7A2D6D2CEBC2DA6C23241 /* NSLayoutConstraint+Rx.swift */; };
- DF02AD7321CB3A3DCC21ABCD8F699B20 /* Disposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EB6106BD2433BD6C6302174B3572DF5 /* Disposable.swift */; };
- DFDE6995FAD0DAFBB4DCBD3C2F03C991 /* Cancelable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D14F1E665D122388B423977C35B4E23C /* Cancelable.swift */; };
- E0020D79307C9C0603A63451915BEC3F /* Buffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58F5BFFF06B17780F8789D51CED460B1 /* Buffer.swift */; };
- E003D58EBFEFCB2342B73D1429EA5691 /* UIView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05B527152D8472611DE378D3CA32C5C /* UIView+Rx.swift */; };
- E018ACB5AB39E7A76183EF702F879E5E /* Catch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B4B0240401064916F34863D58160922 /* Catch.swift */; };
- E110CA5AA9DF7F7921382B26E776A1DE /* SectionedViewDataSourceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AD5AD248511D190A6E701665766BBDD /* SectionedViewDataSourceType.swift */; };
- E1B0183CCE4F47767FB7134A9E4B167C /* UIStepper+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F4E301F50554D39406C9FFC72A4E37 /* UIStepper+Rx.swift */; };
- E526DE33BD7DF1D7384983EB3C0922AA /* AnyObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37B3D6613A18DC598DA7ABCA1D9CED33 /* AnyObserver.swift */; };
- E5F9E74AE2732FB04E0F2B83FDF979E9 /* DeallocObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F083B32C768C775786BB21ECF548208 /* DeallocObservable.swift */; };
- E60781387E03838FAF4376F5DBAA49C8 /* AddRef.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CDB77694CD9C3932E642FFB98BD6507 /* AddRef.swift */; };
- E64EB054C5BC86969A52B038C7AB0DE1 /* RxTableViewDataSourceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07938BBC6989A110F1642C7C78A2A03A /* RxTableViewDataSourceType.swift */; };
- E6AEC992D0816418D9B16BA1F71DA944 /* ItemEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 765B1BE6E4F79831A8A7224E12E11764 /* ItemEvents.swift */; };
- E7CBA70E9DB022D4BB1AE80E941342BC /* Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D255DFA39931004E6FBAE8524E21D29 /* Debug.swift */; };
- E816355A0C00B33C263C008913E3C33D /* PriorityQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 023474758DA44A2BFAF627F30F635E6B /* PriorityQueue.swift */; };
- E942407C1EC578C56138EE876E94B219 /* Merge.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCD947C828DA82D599B109870F06B1FA /* Merge.swift */; };
- EAE88874696C2D88074A70271C8890DF /* UIControl+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E99330FCEF837CF0D351DB099579357 /* UIControl+Rx.swift */; };
- EB30D8D46F7ED6D7FE623FE4F43DF543 /* UIActivityIndicatorView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 934E59DFC7BBF5FBC3A87F0CE7EA73C3 /* UIActivityIndicatorView+Rx.swift */; };
- EDCA0BFDCE78E404FF02B958DC257F6D /* StartWith.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E6D3537ED14D45E6751B0AD3FEBCCA /* StartWith.swift */; };
- EE480903C0C190CB08FCFB2228F1563F /* ConcurrentDispatchQueueScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFF6F9B62AB6F4362CE23C73E7687DA9 /* ConcurrentDispatchQueueScheduler.swift */; };
- EEF0428CEA5E57201723EA7A976AEE53 /* UIPickerView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B9F3F843F9671E9FD1952F33BCE7253 /* UIPickerView+Rx.swift */; };
- EF27EC21F4788A2C5683826659E39BF2 /* CombineLatest.swift in Sources */ = {isa = PBXBuildFile; fileRef = B23153EC62F1F9EA1CEB3C4F8B959BA6 /* CombineLatest.swift */; };
- F153A4BE3B383C99D7E5F24CE3B2E3C3 /* KVORepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 366E4D0AB9A75F2A5712473C8D3EAE38 /* KVORepresentable.swift */; };
- F2EC2531D78764CE4516986208318567 /* ObserverBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = F194F3656CC6F93A70571D3B8B010A40 /* ObserverBase.swift */; };
- F317E84799C431E809E84B37BE3B7132 /* SkipUntil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A58EC30FC7221C14AC9ACB41355285E /* SkipUntil.swift */; };
- F3B7A8258B85F1F2D521D80762EF9475 /* UIButton+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50DD92299AA92A6C6145174B972294EE /* UIButton+Rx.swift */; };
- F3E515690F406E9BD1AC7C6DF0D58AE5 /* Multicast.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0D835DD2D2251EAB0B27F31CB72B341 /* Multicast.swift */; };
- F4535646B0A55879A1654F882D81C599 /* Deferred.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00053BD5230150E958799E47A48EA895 /* Deferred.swift */; };
- F6736CCAC15E8F96F162FBF35874A2A1 /* Scan.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D8B5E655F870573D98C16B1C6D1D89E /* Scan.swift */; };
- F7D64A5BD270F910BAD37A383C4870DF /* Event.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4EDF14B3F8E3980581A28E403F9D60F /* Event.swift */; };
- F82E6FC0DD274C938779B0A7D0F5B929 /* UIDatePicker+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE39B9E067C4AFC9544CBF93C985681 /* UIDatePicker+Rx.swift */; };
- F98E2131336DAD30F560EEC7DA762CF8 /* ImmediateSchedulerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24189EB6F723B40C817F8408B893EB7B /* ImmediateSchedulerType.swift */; };
- FB716709367B7BA7ED37B0358A6F72BB /* UITableView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59C8995F28CDF1F322C4DE32ED3DD05E /* UITableView+Rx.swift */; };
- FBB63CBC2A63B540B0AA1DA3DFC53C23 /* RxCocoa-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = E1C4AE2D0D182DAB04E7BC7722F8596B /* RxCocoa-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
- FC19866931A6FA56F72616BAAA03ABA2 /* SerialDispatchQueueScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D7F8AC7906D8F3573813543E119E9C2 /* SerialDispatchQueueScheduler.swift */; };
- FC5248937A4EDF3CDB88810F7E1AA581 /* CurrentThreadScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF524EC65D9848AEED1A00F4EFB42E2A /* CurrentThreadScheduler.swift */; };
- FF077555B87FBF2DCF0468D215AC5D94 /* Variable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23966E1D2B24C6547A2B15D92C5671D0 /* Variable.swift */; };
- FF25F4E9276C786626D891B65EEA1E54 /* NSURLSession+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC4A87492F76B55135B5E95225CFE327 /* NSURLSession+Rx.swift */; };
+ 000BB78BE73265E73FA8E67AAB060D9B /* RxCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 87BC050FB87821C41A468209D2009104 /* RxCocoa.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 021F03CC102E3F7283E76D686B414011 /* RxTableViewDataSourceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A6B4401BAE249952C98F64BBC95B2F2 /* RxTableViewDataSourceProxy.swift */; };
+ 0383E4D8A2C2C9924F5CF0D2C646D60D /* SectionedViewDataSourceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75ABE3C993505D8042AD462010472F26 /* SectionedViewDataSourceType.swift */; };
+ 05C2B48F96C07F82511E666001B5FE47 /* ConcurrentDispatchQueueScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5C23F45A786EB4A2BD40E493EF53048 /* ConcurrentDispatchQueueScheduler.swift */; };
+ 064ABF8291397CFE3E961D56D9238BFA /* Sequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 610DB064B05FCBD4916354840E5F3BB9 /* Sequence.swift */; };
+ 07BA8B2610299686205DDCCB468FC0F6 /* SingleAssignmentDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F6F79C0E9CA7600FB215083C59C7A24 /* SingleAssignmentDisposable.swift */; };
+ 07C2568F53ED8C6B08A1CA2D15A56F51 /* Disposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63A4ACA827648C32714CC30BD1C8ACFF /* Disposable.swift */; };
+ 08BC583AC7D5B2CB1977896CBD6A6280 /* UIBindingObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 901947D2C0E18FFE2271B6FD7F73BB9A /* UIBindingObserver.swift */; };
+ 09C7DE145B7D88971EE597EE4C0806FE /* Zip.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD7EED0AA031AA341A779500B334BD8A /* Zip.swift */; };
+ 0A2A3E1539B4293B3BC2247FFBBCD572 /* _RXDelegateProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 5C3EDF144FD709E2DDA039349EE33AFE /* _RXDelegateProxy.m */; };
+ 0AF1F8216E9E91A6ACBDABA550AFBA03 /* RefCountDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 586104488AC56629FFE01E4729C93D2F /* RefCountDisposable.swift */; };
+ 0C3C7020F10AB56539A4CD967E44E336 /* Disposables.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04627568BE8263B246C8542E44BEB84E /* Disposables.swift */; };
+ 0FC07576E903FD7D08710B3B13AA8E04 /* Observable+Binding.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAA446133815BDAB6DA48EA5D2B04EA7 /* Observable+Binding.swift */; };
+ 10649A07433609593448F997B93A2D43 /* RxCollectionViewDataSourceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05154EFEAF12E5BBAE9E13E095EDFAEA /* RxCollectionViewDataSourceProxy.swift */; };
+ 1084A71F235AF15198D7515E937143A8 /* BehaviorSubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DC7413C45CB819C77DBA74D1CE67334 /* BehaviorSubject.swift */; };
+ 10A93C53F966AC5C47EF907A7F0BC704 /* Observable+Concurrency.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DE5921D384D083F148002565A98CA7D /* Observable+Concurrency.swift */; };
+ 129D651BFE1C326871BBDB3D0E1B7E19 /* SubscriptionDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EF39FC951C6CC263EDFD7124E057FCF /* SubscriptionDisposable.swift */; };
+ 12C9843D7C50B3F5D662DCE99A2AF6DF /* UIButton+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBE355A845BA6A27C05F9442D9F089A2 /* UIButton+Rx.swift */; };
+ 1346B85CAB24326BF8E5E56A6954AC93 /* Zip+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35DBF02092FEBD822B83924EB54C422A /* Zip+arity.swift */; };
+ 14452F1421140835B1A5466E3967A8CE /* UINavigationItem+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CEFCBF2EC15CC86F7A0399EC348D23D /* UINavigationItem+Rx.swift */; };
+ 14667FE180867DE13DEDD46D7F09B285 /* Throttle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B29D89D8E6B5E4D8F0779ED978A0A8C5 /* Throttle.swift */; };
+ 1576FC7D9496DF6373ADD504879C67B5 /* CombineLatest+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58B871E4C2567F0F4779EF41BA4CEC0E /* CombineLatest+arity.swift */; };
+ 1579E04D9661BF972D1C98FA0B5DC722 /* RxCollectionViewReactiveArrayDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE6EDEF18E45893ED7529E82BE61D19F /* RxCollectionViewReactiveArrayDataSource.swift */; };
+ 16904F77708C5B0F20F0FCCA32BD31E9 /* ObservableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30DFCE2B63D2C2FE3331E73B770B4903 /* ObservableType.swift */; };
+ 172B7BFFF98FF4EBDD46CA46BA79BEF7 /* Timeout.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8D4D84407A974744557BF4FC86C0EA9 /* Timeout.swift */; };
+ 1A1AE8136C2802D337B7120D661ADA17 /* TakeUntil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A746282E628E8F2A9EB17EE33CD0C91 /* TakeUntil.swift */; };
+ 1B90B20CE3E6AB0DC8F94293885A5BBF /* Platform.Linux.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5F1CEA9B9E1814EFE1F235EC30A2E20 /* Platform.Linux.swift */; };
+ 1D5FEDD333ED9BCF9C1DCD7ED4BD24C4 /* NSObject+Rx+KVORepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F47D6CBA7260571DF35B88A530815708 /* NSObject+Rx+KVORepresentable.swift */; };
+ 1DE8724FC95C791AD47F6B885DF855F0 /* RxTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4879DF6BE30A70D84B8CD0F3EB6F87C /* RxTarget.swift */; };
+ 1DEBDBAE98CCCF73742931B465A3D98B /* UIBarButtonItem+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B0EA98FA3B129968C423DB5EF0ABEF8 /* UIBarButtonItem+Rx.swift */; };
+ 1F7D93BFD36480AC8A33333A7D936A33 /* Variable+SharedSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = A550F2813AC8DAA63F881EBF2D00ADF1 /* Variable+SharedSequence.swift */; };
+ 23F552367F9F12149C16697309FA1528 /* _RXKVOObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = C0DDE7EC5814AA6C8E13CA02A487C60F /* _RXKVOObserver.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 241D0F6C662A3991A43CF9B059E5FDC4 /* Bag.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBD99D2D368A3A8AFE7C5DA7E99FA61F /* Bag.swift */; };
+ 24C4C1C4E196867335B31FAD70A91620 /* Pods-PokedexGo-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 48AF5E6DB322F1C2C0209B854CE73993 /* Pods-PokedexGo-dummy.m */; };
+ 25860974D252E772F986A088D4C9053F /* UIScrollView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCFB96B6EC2B0114D1FCE5362270E334 /* UIScrollView+Rx.swift */; };
+ 25F0AB43C7575360296292D9BB64842D /* RxSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 397ED6A120A7323FEFFD443352B8A3B8 /* RxSwift.framework */; };
+ 27CF960A8BA7BA8EF791CC060F81C1E7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4E6CE1422565F9D01918EE903F3772E /* Foundation.framework */; };
+ 287C1FFD2C49BE2C49A16B8AD59E15C6 /* ControlProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D0F791088E9C7CC17CC8E64A0BCF99D /* ControlProperty.swift */; };
+ 29B16EB7250FD61AEDD066D0AEB359D9 /* Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AB5988F61EF072B265241572954BDCF /* Debug.swift */; };
+ 2A166D31F5542BA58657104BF3A2982D /* Observable+Multiple.swift in Sources */ = {isa = PBXBuildFile; fileRef = 864CE2D64C2CB6BAF14E112E648566F7 /* Observable+Multiple.swift */; };
+ 2A477B3B0B9FB4231B48456AB5A3BC1D /* Platform.Linux.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDB32327B68A41D415AC5BDAF953BD49 /* Platform.Linux.swift */; };
+ 2AF03C41DF03B943B3B94C671C9D9AFD /* UIImageView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 420ED71D6CB2021AB9A4176B03D0C320 /* UIImageView+Rx.swift */; };
+ 2B004C68074139E480C4252B98B4C948 /* ElementAt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1491FA56387C07FA701050A6BAB1217B /* ElementAt.swift */; };
+ 2C0861DB041620D38C38F5A4491343CA /* UIView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBFCF9BC4A552C0B77721F53808F4173 /* UIView+Rx.swift */; };
+ 2C61F409436BDADA9DC4F3AE6095B83B /* _RXDelegateProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C5D30C37343EEFCC746F2C0DAE0E218 /* _RXDelegateProxy.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 2C66E75B76300F1C931A514421FF6D99 /* SerialDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 769CCB9780B036CB1F097BC2E027FD0F /* SerialDisposable.swift */; };
+ 2D7384435B6637373A311D6901A9CB60 /* StartWith.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00243578A2429FC5E1FFE03292FAFF64 /* StartWith.swift */; };
+ 2DC629C569D7275E0D6CD34ED9752B16 /* Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 796281A7F1F3D29CE27096717B6AE3F7 /* Rx.swift */; };
+ 2E05A63DD51D9C9C9FA46BAE2C8E71C9 /* ControlEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7155FD418E3EC3A8C86E9E3BA0B79EF /* ControlEvent.swift */; };
+ 2E11D6FCF111D03B708A65640DDC4ADF /* ObserveOnSerialDispatchQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29639B573EB1412C4230E3B09B9ECAC5 /* ObserveOnSerialDispatchQueue.swift */; };
+ 325E76037DE7CBCD52DA4AEFC1ACB654 /* NSLayoutConstraint+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC21BF5E703ACB95DC96961494CE91A1 /* NSLayoutConstraint+Rx.swift */; };
+ 33112944329971F27C0AAA50E34D6128 /* RxSearchControllerDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D3967211EDE74A259D45C68D0919CCD /* RxSearchControllerDelegateProxy.swift */; };
+ 339086CD50565C77FA81089DBF7F8226 /* UIApplication+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5071B74B5041F60D8DAFC145DDADAB26 /* UIApplication+Rx.swift */; };
+ 340C0536EEE1DAC84A49C73A61212813 /* Range.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4FC7AAE283EB68E81E9D97FDF1162BB /* Range.swift */; };
+ 353D56ABF6CB45B1C7964AD8B011C576 /* Observable+Single.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14F32DA16234790E73FEEB15D52896DA /* Observable+Single.swift */; };
+ 3635855E261991611001B8F34AB61CBB /* _RX.h in Headers */ = {isa = PBXBuildFile; fileRef = 313763C6108D9C46316D32780D3A5ED1 /* _RX.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 39E7036C42C3E751AA0F53ADCFCDFD3C /* RxMutableBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B983B555CBEC50516E21B9835EBA92E /* RxMutableBox.swift */; };
+ 3CE2FC3AF82CF03D3CD41D066F728ADF /* RxTableViewReactiveArrayDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D25AAE822F5498D26DE6953DC295481 /* RxTableViewReactiveArrayDataSource.swift */; };
+ 3D69CC680C7E06ADEAFDBCB607713AD8 /* RxTableViewDataSourceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48E7453369B45B5ED73A948623A3B1CD /* RxTableViewDataSourceType.swift */; };
+ 3D9349C31A2B054BC382CA29015CAFF8 /* UIRefreshControl+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = C17B264E2D2E13B18D5DEFA475D436F4 /* UIRefreshControl+Rx.swift */; };
+ 3D9C6FDE282B84AF9237FF7B99114663 /* Buffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 532E8934BACCE9965E1B50AAD52DFB1C /* Buffer.swift */; };
+ 3F586EE283532EDAABAF75439961D6ED /* HistoricalSchedulerTimeConverter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4610BE88BD9A69E7311E15CCA3C9C30D /* HistoricalSchedulerTimeConverter.swift */; };
+ 3FC471D71E9182035347995A85DA4F3D /* RxCocoa-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F942E49DBEB13C498BFF44B05FBFF97 /* RxCocoa-dummy.m */; };
+ 3FDDEE9E82EEADE6F95943B544A329D5 /* Using.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90897DE0AF5AED02A7EE2AC32B3E4F3B /* Using.swift */; };
+ 408D29A066137BAAA90A78A012CD3C91 /* UIDatePicker+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FAD8B62333EE46C5A33F9FE50E5918A /* UIDatePicker+Rx.swift */; };
+ 4202EFAB59455AE74D9B1E6C9AB520BB /* SchedulerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3B1490DA3282F84E441342FFF586BFB /* SchedulerType.swift */; };
+ 428629547475AF8293C1F7022581804B /* KVORepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0949D3D804F8DA073BC481DA1ACA5DFE /* KVORepresentable.swift */; };
+ 435C75AEE249942C6E9B7BE323CB52BD /* UISlider+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98B128798CB6E65617AC3DA66FE5C6FC /* UISlider+Rx.swift */; };
+ 43D9DB2E6CC9E5A1985B19025A29D184 /* DelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6D96B5553D499A43AC75B225DDA1B0 /* DelegateProxy.swift */; };
+ 45293DF3ECBC150338C9AC23AF0B0609 /* DisposeBag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EDE28D1EE46BE33F7AD632B68E1E56A /* DisposeBag.swift */; };
+ 463B3383D3134496D0D532AD9C6F5C6F /* ShareReplay1WhileConnected.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF8BF315C6E2458176C75F8D0F0C4B9B /* ShareReplay1WhileConnected.swift */; };
+ 467A45A5CBD7A8C257EE1C954540284E /* Delay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30D2A54F9FD3E9B455E0BC2E62C15FA3 /* Delay.swift */; };
+ 4871C259D8B4ED46266C0A8CCFBBB473 /* CompositeDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1C61FB2FCFAB4944005E3BAF9EEADC1 /* CompositeDisposable.swift */; };
+ 48986E4E74B3F796261DBC6FF5839951 /* ObserverType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E88037730944DBB5C828F0A95E996EA1 /* ObserverType.swift */; };
+ 4A182820143401A8DA92E419DFE4A4BB /* UISwitch+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF6A14B15E0BEB5A7B777FEB4AE1B914 /* UISwitch+Rx.swift */; };
+ 4A99A445C54B950702B8AF395618776B /* CombineLatest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 122E690AFB6AC805905FAC5D63EE4098 /* CombineLatest.swift */; };
+ 4B136E06955AE58FB2476F824F7B341B /* ControlProperty+Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34CAF15FDB134CCB47A9BE558BA936CE /* ControlProperty+Driver.swift */; };
+ 4BBF1CD267DDD66996B161F0B1B48B98 /* SkipUntil.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA37963CF786335E8A84A7085375C732 /* SkipUntil.swift */; };
+ 4BEB0D2BB14D3E01EF142F82C9DDFC7B /* Event.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFA3361761013BBC637D1DBBBFF0726 /* Event.swift */; };
+ 4CC9B3F615375E6A51B543CD3DF2E55E /* Do.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26CF7CCE8663939B828C53DF2B9BA2B4 /* Do.swift */; };
+ 4CEE20D554A8B09D045F3E480CA3DD47 /* ControlTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13E02371A6891FF6803B48F80CEB4A26 /* ControlTarget.swift */; };
+ 4DAAC12BAA13E8509170E5146770BB28 /* LockOwnerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C2907A619D445EBAC4FE4C582FFBFC6 /* LockOwnerType.swift */; };
+ 4EBF1EB98F7D5EFCDDA461543814097A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4E6CE1422565F9D01918EE903F3772E /* Foundation.framework */; };
+ 4FCB88884951824DFAA64E759DABB9BC /* UITextField+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4488DC730219AA10C54CA340A3D5E405 /* UITextField+Rx.swift */; };
+ 518963F1BF2447CB199C044BBF6004C6 /* SchedulerServices+Emulation.swift in Sources */ = {isa = PBXBuildFile; fileRef = E37AD316312C2037DAE0A3063683AA3A /* SchedulerServices+Emulation.swift */; };
+ 524E9615DCAB7C2F76E33B84668C7372 /* TextInput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 054F1DF36495EC9708AF0BFF1889B1B1 /* TextInput.swift */; };
+ 5316DAA30B39C49DCDA7EC5B7A715533 /* Platform.Darwin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B44F83E55B949CDDD1F0AFEAEC880E /* Platform.Darwin.swift */; };
+ 53B96D4F73D2A55B475D1DFE041FB50C /* Variable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE16A12DC1A9C64C2730087402ABA7F4 /* Variable.swift */; };
+ 5605DC169D11F66A44CD43EFC2E2D70B /* InvocableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B619CE407B9403711BDFBAEE67207A9 /* InvocableType.swift */; };
+ 57D5464BE825AB76759A09437D8AD4FA /* Bag+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 771BE5F88179512E7E55B1693BFDE338 /* Bag+Rx.swift */; };
+ 59BE4366D2801AD5BA180CF437EDF32A /* ImmediateSchedulerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 20184E13B8706FF2BEC9F6F5162F5287 /* ImmediateSchedulerType.swift */; };
+ 5A11E733104FC70E013E6E27EF79D557 /* Observable+Bind.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3379A9C5DF632BB854582CE0439F9A48 /* Observable+Bind.swift */; };
+ 5F16CFCB025D837C01C9B9BEEB65B81E /* AnonymousDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C48857A37E0B818288C17716A394120 /* AnonymousDisposable.swift */; };
+ 603B785802BD341E287793B385D8763D /* Platform.Darwin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0390599D2CE39A885EAF2242027BEDFB /* Platform.Darwin.swift */; };
+ 60AF9D34182321D50BE60739EDEFDEBB /* WithLatestFrom.swift in Sources */ = {isa = PBXBuildFile; fileRef = E451C04B736566F48C34167C04D48251 /* WithLatestFrom.swift */; };
+ 60C4522593BA7DADA33970F71B1FECB9 /* Producer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 516D56CA8911D20905D7832AE8C17587 /* Producer.swift */; };
+ 60D48C9B7E5C80DAD307F4F287D83047 /* Bag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 001721082AD1820BF14628A28649996E /* Bag.swift */; };
+ 61400AADE7F027101B5CA629B3CE369C /* UIGestureRecognizer+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5329F8CBE02FC97E42D8E68A6440EDD3 /* UIGestureRecognizer+Rx.swift */; };
+ 625ADF703FECA0E43978A031BADF5D48 /* Pods-PokedexGo-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = CD0C2708ACBC7809074D8DBFBAE2CF6F /* Pods-PokedexGo-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 6470CAE016FF5FE6E6870ADE258250B8 /* ConnectableObservableType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E50FF775C27E7F52C4BE67E387384E3D /* ConnectableObservableType.swift */; };
+ 65BCCEEFE86506F966D67EDE583D1D9A /* ObserverBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = E39BD822F4B90F9AAF1FA187CFD88D80 /* ObserverBase.swift */; };
+ 666F856983371B01BEBBAF4440848E44 /* Variable+Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = F16765FC78C53140C4109BCCE206E88C /* Variable+Driver.swift */; };
+ 67630EE9AE15DAB11D827E99583E7CBA /* UIViewController+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAFF1EF43696A19F3C0BA1A4B9629DFD /* UIViewController+Rx.swift */; };
+ 69379C3A91EED16179E67B84640F58BD /* NSTextStorage+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C4D8309F4A7F25A8EC6FE8843F5CCC0 /* NSTextStorage+Rx.swift */; };
+ 696454199FBCE2017184A47B1848318E /* RecursiveScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9ECCB50F74580AB2A9E02A3B96EF07BB /* RecursiveScheduler.swift */; };
+ 6D1204F2C17D25FBD642EEF8EAD4B9AA /* Observable+Time.swift in Sources */ = {isa = PBXBuildFile; fileRef = E0BEBBB4958B7F4D65A5DA54FF0580E7 /* Observable+Time.swift */; };
+ 6E385BB132724A37AA78D523E6773F69 /* RxTableViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58BB980A41382A481029292D36611E1F /* RxTableViewDelegateProxy.swift */; };
+ 6FD69465008280047A400FCBC575B0FA /* RxSearchBarDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E36B0DA3408346FB92A93AB6C45E069 /* RxSearchBarDelegateProxy.swift */; };
+ 725767C408C8475FD46184A92160B63F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4E6CE1422565F9D01918EE903F3772E /* Foundation.framework */; };
+ 72C0F0BFD26DF413287E7C2D9EF2AC2A /* SharedSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95BDAA537E0F690A0B8FED31611B5D85 /* SharedSequence.swift */; };
+ 74B86089474801570A75A89A63E33073 /* Skip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87FCD9ED2C7E8DF83D4C84940FF4D5D5 /* Skip.swift */; };
+ 756AEEF4CF2F709810B050B97889CC3E /* SharedSequence+Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 313873C00506CBE738D855EED5608303 /* SharedSequence+Operators.swift */; };
+ 77566600D46D25410ED8911CF00A67ED /* AddRef.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9466E765E5E6CE61C67AC9380B9DB093 /* AddRef.swift */; };
+ 77C182D0C24A813074A53AE5E1632356 /* _RX.m in Sources */ = {isa = PBXBuildFile; fileRef = 782FC7557C91148E434A34BB30E17340 /* _RX.m */; };
+ 78BD7AA53EFFC1B1E6FA8E7904091BD4 /* KVORepresentable+Swift.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC8CD3A95BB52F3F626088379FCBECE6 /* KVORepresentable+Swift.swift */; };
+ 78DDE64BDA461DDD99164B6F57B7A6B1 /* UIControl+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = E474A1E0AB9BFBD84BC89E665507E060 /* UIControl+Rx.swift */; };
+ 79110C3D44003087AF3A6F50F33B4A25 /* VirtualTimeConverterType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46529E285EEFBC21FADDCE1616A0D778 /* VirtualTimeConverterType.swift */; };
+ 7A5531D8F6637F601A458D558873F321 /* RxTabBarDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F8D42C676712C383D2B710A1F35C6F7 /* RxTabBarDelegateProxy.swift */; };
+ 7B4A012AB83EA24B0109584FA3E412CD /* UIAlertAction+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2679310F5C1EFC93514C61E7D4946C9 /* UIAlertAction+Rx.swift */; };
+ 7E4578403AF9E519B2F5E8C8F22FA7B7 /* Timer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AE6BC71DAEFE73CEC12110AAF4933D0 /* Timer.swift */; };
+ 7E52A9625C18CA8C1BE5B25DFCE3799A /* AnonymousInvocable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFA5AFEC44A99D12BF2AAB9FF9B30CD0 /* AnonymousInvocable.swift */; };
+ 821413DA27D4C52186989ACF6F4CAAEB /* ImmediateScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCBD161681343C2F0E2EDA6686257063 /* ImmediateScheduler.swift */; };
+ 822C8B28E86F2C841327CA3376FE78B3 /* Observable+Creation.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1DEE4224C3135D5E03DE40DC0095DCB /* Observable+Creation.swift */; };
+ 825D11BB5580546AD789880EAD4B8C62 /* ItemEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D6C7D1B059B7CAD9ED94FDB26655FF4 /* ItemEvents.swift */; };
+ 844C335CA2C61EB6E5B131CB61386509 /* ShareReplay1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 477CA47455652DA6E23FF8C42DCD3247 /* ShareReplay1.swift */; };
+ 84F8E9C004DF457E558BEB5350893A74 /* Switch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50627C97E6A0FDF747368316C1A7E9B8 /* Switch.swift */; };
+ 85491F58B4BD3DD0CFC771F861A660D3 /* NSObject+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = D740BC5E318263CF4C86F2FF57AAB534 /* NSObject+Rx.swift */; };
+ 856332B9A729EDEAE7CC0302027CDC0F /* Catch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A6C92C57DEAD46320212E648D6FEE52 /* Catch.swift */; };
+ 85782EC2598D333ADC637BB955FE36FC /* DispatchQueue+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30F24BBC537B71BDBC5816F0B5117B87 /* DispatchQueue+Extensions.swift */; };
+ 86AC77160E0C5DD95BEB019628E879E6 /* CombineLatest+Collection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35A28FA391DB06D29D19DA4447AD37CA /* CombineLatest+Collection.swift */; };
+ 8726DEDCA5817E614592ADE14FB76BB6 /* RefCount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5269C00D54CBA238331E7D259F465609 /* RefCount.swift */; };
+ 88EB3F9158721C0195CBC3E6E88FFAC4 /* RxSwift-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 275C278EB8ECC1D443F42A7648BE8554 /* RxSwift-dummy.m */; };
+ 8AA42C32C0B2DBED3EAF429A231CDB21 /* BooleanDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22954F1D4615BBFF718FD64924CADC93 /* BooleanDisposable.swift */; };
+ 8B57DE6CED50D92E8E27C4FD267DA15E /* SubscribeOn.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3DC6CF6E770FCD8D53D32AF0F9DA126 /* SubscribeOn.swift */; };
+ 8BC2D471DF877174F872D957FE534419 /* Reduce.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DA1E31F9BB5BC5A606A2C48ECE47B24 /* Reduce.swift */; };
+ 8BDF3002A8ED36B2B13CFD9C4C6FCDC0 /* String+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B00D7B6E0CBFE12E1D5A6C30B939190 /* String+Rx.swift */; };
+ 8C13E631B96C8A69BFC2D6082E9FA241 /* ObservableConvertibleType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BE0D1B70A2AD1DA432E686EAC99DB0D /* ObservableConvertibleType.swift */; };
+ 8CC6BE81F2727BDD00091E8EDC3DC797 /* Sample.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFC8BCA7484913B73E111710A621095F /* Sample.swift */; };
+ 8D03029BB0EEC41E0A024682FF09EE6A /* DistinctUntilChanged.swift in Sources */ = {isa = PBXBuildFile; fileRef = 703AFAD4C44A49D75794591FD54C09FC /* DistinctUntilChanged.swift */; };
+ 8DA194776C8097962BC733989FDD632D /* Take.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B2526BF51A53AAF05BAC6CB090FE6EA /* Take.swift */; };
+ 8DFE7A2870E6C91810945B8E80241C5C /* UICollectionView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = B37CED7A1B33FD4AF9119A53F2C13769 /* UICollectionView+Rx.swift */; };
+ 8E167D3B396C7D754C8E8DE80F38477E /* Reactive.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99AB1D099C10F2E5620A6BDF34588975 /* Reactive.swift */; };
+ 8E7DFE12E409B4A1E5EEC52FEFE399D3 /* RxCocoa.swift in Sources */ = {isa = PBXBuildFile; fileRef = E733411C01B6E1B1C9923630CA83DF0D /* RxCocoa.swift */; };
+ 8F08A0A21CAD3869D45C2F7D8C74E256 /* AsyncLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AD6F3F3F6855D2DDD205D5E9C2FF90B /* AsyncLock.swift */; };
+ 8FC74123F7EDFCF0E2E9CB8F12D75565 /* AnonymousObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68392D6EEA0ED3393891F448EC65B15F /* AnonymousObservable.swift */; };
+ 9044181820DB4607D7438D84F31874D0 /* RxPickerViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 960737347ABB0497D5D165AF6F04383D /* RxPickerViewDelegateProxy.swift */; };
+ 90A1D93A172B7D93D12A546EAD1BFE19 /* Cancelable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 310E2059CCB59758D74FA623B7341F35 /* Cancelable.swift */; };
+ 944B2C6C4BB844DF8B653A08E009D3D1 /* OperationQueueScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97627C4204F674A421353E2CC5C35C59 /* OperationQueueScheduler.swift */; };
+ 954B0A0489598AB2D063241B46F62C8C /* DispatchQueue+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E5396250362A8B8FCE1C3628C7D789F /* DispatchQueue+Extensions.swift */; };
+ 957639EF75D0DBDC62FBFBE54364B973 /* UISearchBar+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD056A186F36500A58F7BAB90D9785B0 /* UISearchBar+Rx.swift */; };
+ 96D3B761549C658F3BBE325C3D6E9AD3 /* ObserveOn.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DBADAF4942134897BCBFC9D3F0ECCCE /* ObserveOn.swift */; };
+ 97AE0A128FB54CC0A02A65DD22A371CA /* UITabBar+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55AFE841CAB03336F9EE30E219DB303F /* UITabBar+Rx.swift */; };
+ 99F3866ABEC5BBE8E325CDA76B27BE57 /* AnyObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9CAD519CA31004643A5A6D099089890 /* AnyObserver.swift */; };
+ 9A1AC9703382C22DAB05E2F8AEC95C32 /* SynchronizedOnType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DF9CCC07A8F8899DAA3468E098F34B2 /* SynchronizedOnType.swift */; };
+ 9A46E657438F1EADB4F3C013925408FE /* InfiniteSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 006A85CAF9C458F13EBCC787756720A2 /* InfiniteSequence.swift */; };
+ 9AADC4D8700A16928411D2C269422474 /* TakeLast.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8DBBA77CC1DEEE524C517B5F5ECFF34 /* TakeLast.swift */; };
+ 9B38F5893F0D186AEAD699466A3B8836 /* Observable+Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F702A0D040E23B8F7C4A2B2D7BF3D6D /* Observable+Debug.swift */; };
+ 9E8F409E27A4179D15B755B5B3B2832C /* Queue.swift in Sources */ = {isa = PBXBuildFile; fileRef = D14765FD8943F9837F5C8428CA03C7F7 /* Queue.swift */; };
+ 9EB7A8CE5046636E0437BB98CF496ED0 /* ScheduledItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB9C7DEE1C140DE14C9A3D09E024BC3 /* ScheduledItem.swift */; };
+ 9FE76BDCD0A12B8A09F394733F26A516 /* SynchronizedSubscribeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11C615CBD6201F948CE3830F3EFABFA3 /* SynchronizedSubscribeType.swift */; };
+ A462ED2113ECD649E947018C08E1715B /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AC09569D823CC48FED33FF4592029CF /* Logging.swift */; };
+ A4E00A2CAD0ECB2F148C419F3558DA07 /* UIPageControl+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC38374D82B1743060DCD93295E41C3D /* UIPageControl+Rx.swift */; };
+ A62F38C06D02956EF0FEE7CB545DFF0B /* VirtualTimeScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A4169BB7B76EC937D94F6BEF9FB9E0B /* VirtualTimeScheduler.swift */; };
+ A7542150C35BE5A5C48B202E928066C6 /* RxCollectionViewDataSourceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0261DA91C20FBC3AFF3A0D05B073CBA7 /* RxCollectionViewDataSourceType.swift */; };
+ A7DD8CDCEA4132FDBB931915303513DB /* Never.swift in Sources */ = {isa = PBXBuildFile; fileRef = 187761E03C1F7B58183B7320406658AE /* Never.swift */; };
+ A8F46A9F07392BE6AD81A6181EF0592E /* SerialDispatchQueueScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6349A034EDF8823A796F029B3FC91AB1 /* SerialDispatchQueueScheduler.swift */; };
+ A918EBE37A98B6A9E7AE09490969A6F7 /* SynchronizedDisposeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9D1CEBFA68ED0016AF36A402C8AA348 /* SynchronizedDisposeType.swift */; };
+ A91C34EC6DD5EE9250AD2D9F241E09B3 /* UIStepper+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02229AFE0B4BCF0FFE5A1F61A6A3E6E3 /* UIStepper+Rx.swift */; };
+ AB4D751C9E2AB7A713033C10D3D8706D /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06AA53BF1102449A2CF3379F0B8C89C7 /* Filter.swift */; };
+ ABC1261AF722C75EBB5034EF5CF2910D /* Map.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57C98EC1D350E642FD6513F7DC84A7B7 /* Map.swift */; };
+ AD58B2E686C181A5E2A38340E6382AA6 /* ObservableConvertibleType+Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9680E698A96391123754AEF6500344A /* ObservableConvertibleType+Driver.swift */; };
+ AE02FD1657561DFB785E09AC35BBCD72 /* Deferred.swift in Sources */ = {isa = PBXBuildFile; fileRef = F041C3A61D24A55BA6D02865982F4948 /* Deferred.swift */; };
+ AE3E0437C711028E325A0930030B90E4 /* Concat.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3FBA08BED4CF780F286F7C578ABE18D /* Concat.swift */; };
+ AF164AC62EF67AE504DD0C2F5F804A33 /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FBD523F1A092AD394DD5292F1ECB3EC /* Errors.swift */; };
+ B07B93E8533A80E21077FE81985D8F6A /* Observable+Aggregate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F443EFBEEE15048C942B3E1F2FEC5B3 /* Observable+Aggregate.swift */; };
+ B3424BF565F7184D27EF7D67E88F7B12 /* Queue.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8B1297039F6EA16D423A90A12D7CC06 /* Queue.swift */; };
+ B79D764BF6355209267A93A6685333A5 /* _RXObjCRuntime.m in Sources */ = {isa = PBXBuildFile; fileRef = EB09B4EEFE017AD8A7AA8A8C1F163812 /* _RXObjCRuntime.m */; };
+ B7A9C4B9DB5E7B1D77DD3775C49B3E66 /* SharedSequence+Operators+arity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FB449CBDFAE6FD7EE6029B5BEFBFE5E /* SharedSequence+Operators+arity.swift */; };
+ BB7DCB75FA9AC2458ED3A5662BA40ED7 /* SubjectType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60C321E6B0BC2E19F7F38DD6F2C09E62 /* SubjectType.swift */; };
+ BD530FCAC7D4C00EC656A7CA17206CD1 /* Observable+StandardSequenceOperators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 772E2994B6C7F8AF414BCF19AF96C9CD /* Observable+StandardSequenceOperators.swift */; };
+ BD549F5A74F74D82D543C792C27F049E /* Amb.swift in Sources */ = {isa = PBXBuildFile; fileRef = B741543663BD6C9BAD832B9EE5B969BF /* Amb.swift */; };
+ BDB52602A520BBC270E051F0A669A7FF /* MainScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 368C2CCC6A55F4D761B07A4A01E238F8 /* MainScheduler.swift */; };
+ BEC06180957AED23FABD97CFAF33ACF6 /* PriorityQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 934C51BE545B2C1E082E7D38BE92D043 /* PriorityQueue.swift */; };
+ C0E21F295CC1608BCF28C9C03C45DE1A /* HistoricalScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17FAD3C510F874695845F53E92CDEFCE /* HistoricalScheduler.swift */; };
+ C1E3BDD55C24EC009C5DE956D1F7C7D7 /* Merge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02E3FD64DE9F3F7935D3A66FC3A660AD /* Merge.swift */; };
+ C459E1CB96638B30A7BE880452A188CD /* Lock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2BD37F2E2DCDC1316E634A329394F90C /* Lock.swift */; };
+ C5494AA6BD2FEBDBC7BA8C12153614E1 /* DisposeBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F204260242C3B57DA94787B81F9A379 /* DisposeBase.swift */; };
+ C5F5AA378B2A55CA3EABD6A83C7317F2 /* Zip+Collection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9DCFB51A1C7EA0AC6AD367B4C3872DA1 /* Zip+Collection.swift */; };
+ C61B877F57B32344E031D0E5A72A979C /* Window.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE171203123A28D26CC10698CA05898 /* Window.swift */; };
+ C823788D0F5829EA6AEB13E9AE81FCC5 /* RetryWhen.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDAAB3AB88BA20FDE9B79631F269019B /* RetryWhen.swift */; };
+ C83F71D4EE4E02BA7C4D150F136D42CF /* UITableView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A1A0CB1F9C1205703FF5508B7DEEDC6 /* UITableView+Rx.swift */; };
+ CA1E15B731CBF82AEE676915A6226DF4 /* NopDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3887B94073C7C1FFAEA8E2F5181F29E3 /* NopDisposable.swift */; };
+ CAC20FE152F2C44B01217125C9248E8E /* Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76F3D3BBF234D5C633588D9B4E75987C /* Error.swift */; };
+ CACD9B0932614E29AB490A7D1990E2AB /* ObservableType+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E64EE928569D9CE1F1B07ECF93FEA6D /* ObservableType+Extensions.swift */; };
+ CB51294DAF1ECC45EC6167BECCFFACF4 /* CurrentThreadScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C72045F1DD316A8D8D667EBBC62BCCAA /* CurrentThreadScheduler.swift */; };
+ CBE99CCFFFCB849212B6FB6D2F9A53E6 /* DelegateProxyType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B109B815703349C9B6BB84A3259F9FD7 /* DelegateProxyType.swift */; };
+ CC1EB4C5C523C46291EF99F9F0A66E97 /* Generate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24241E179BF63060B757331E8BD99D63 /* Generate.swift */; };
+ CD7400ADE6FF0E05F394324483FCB151 /* AnonymousObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E895275489876F09F432CA67FE21439 /* AnonymousObserver.swift */; };
+ CF2F08EA082E653EF617D7FBC4A001FA /* ConcurrentMainScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75783B38979EC3CF3F54AAF108D075E8 /* ConcurrentMainScheduler.swift */; };
+ D0CEC81294324172CE1D575D5C80C50F /* UIProgressView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6379DC98FC6B0CAF284139D189FD8DA4 /* UIProgressView+Rx.swift */; };
+ D0EA7B4C3BCEF31050AABF47A9374E32 /* ControlEvent+Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 500B41C5329236B01D0FEA05256B9F5B /* ControlEvent+Driver.swift */; };
+ D1D616533BC802BD3BE04E6EE1D0A8DA /* ReplaySubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F16912A8FB1C45DBFADC2B5B479072A /* ReplaySubject.swift */; };
+ D21B2AF6315E5232DA13772993018C7F /* ScheduledDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 785EBC3F90F0A66D18749E6F62C511CD /* ScheduledDisposable.swift */; };
+ D251342CAD00B3A0E7EC3678592B650A /* NSNotificationCenter+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = A54D6A8E2EA2035685149FA65AE9DE1E /* NSNotificationCenter+Rx.swift */; };
+ D27AACEB710DB866716A338DB3B84694 /* RxCocoaRuntime.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C2D178E75F7BE054DFB902ECC4E1A7A /* RxCocoaRuntime.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ D2C3EA028CBF9B6A7384EAD8C06CC3F1 /* Multicast.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55A20BFFF5369A00113A30E4B7F15842 /* Multicast.swift */; };
+ D3BF51C7656E71BB071936417BFD8177 /* UILabel+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92099190C99C0C391E3B475FA824CA7B /* UILabel+Rx.swift */; };
+ D472D1486D700F27A6D2EE4C04DD8B25 /* UIPickerView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B97480CAF8B38BAFCC58CA4C786FC9B /* UIPickerView+Rx.swift */; };
+ D5D6327F15D70764FC1C2074D149B5F8 /* InvocableScheduledItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE315409B48FCE8A0AC462617E487561 /* InvocableScheduledItem.swift */; };
+ D62ED4125C3C5D7EF9058163D7AAC96A /* UISegmentedControl+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE749C4F2DBA7A407D5B33D5DF514412 /* UISegmentedControl+Rx.swift */; };
+ D7D77A6D4E380168BC2F7F0814447B43 /* KVORepresentable+CoreGraphics.swift in Sources */ = {isa = PBXBuildFile; fileRef = A45777551AC14459252CB963743F760D /* KVORepresentable+CoreGraphics.swift */; };
+ D82AD2D5137003784582FC3F27860574 /* RxScrollViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A28F295BCB3239E3D8E97C8253DEF32 /* RxScrollViewDelegateProxy.swift */; };
+ D833970A227876D7037712FEEB20B58D /* Debunce.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33E24CBC32BF736F401E2C0002F4C163 /* Debunce.swift */; };
+ DBAE3679FFD79C4092885470CE375B2D /* SynchronizedUnsubscribeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 323235124BDF04A1A2262894B9B69BF0 /* SynchronizedUnsubscribeType.swift */; };
+ DC5D4611375E3C8D187CBC2BC359BCF1 /* SkipWhile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A72650E19D579EB5CDDC6E40B590B11 /* SkipWhile.swift */; };
+ DE14A09490B74F598F7836CFC456E8F3 /* _RXObjCRuntime.h in Headers */ = {isa = PBXBuildFile; fileRef = 01DBF7C725D0BA477B3AA3A94377F2C9 /* _RXObjCRuntime.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ E2133A288FFB0418CF6D3C65D758E4C4 /* RxSwift-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 2CA4CF3BFBE7871ADCF8FBBE747810FE /* RxSwift-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ E27C8069BE899CCA7E53D4BFBEF8F627 /* Observable.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABE1BFBE9D3B127015A516D9CB9F9F7E /* Observable.swift */; };
+ E2F43F799241F99480D799BE7DC6F0E6 /* URLSession+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = E73E7800B5D05C4608E7658D76BB09F6 /* URLSession+Rx.swift */; };
+ E34B5956A142C76A16BE8E0A47614C76 /* RxCollectionViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B35A50095178D9C3BC723C286B94F534 /* RxCollectionViewDelegateProxy.swift */; };
+ E3D9C194890984A380E38076AF97EE74 /* DispatchQueueConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 250DB34FC592CA01F9AC40F5B72D1E4E /* DispatchQueueConfiguration.swift */; };
+ E452567751DB804F05E8C7DB56231FF6 /* UITabBarItem+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F286BF9AEB10DD62CD1CF950796B015 /* UITabBarItem+Rx.swift */; };
+ E58994E13807BF5B2632CB07829FB897 /* ConnectableObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2836FC17C9639B40E5BE53E2A461D59D /* ConnectableObservable.swift */; };
+ E6DD4FC5B7A12BF6711D0D6C893A4947 /* RxCocoa-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A84C7DDCCB01DD68DB69FDFAF2A317D /* RxCocoa-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ E7EB802E0E101339BEBF8787B22CA823 /* _RXKVOObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = B2DA51A804997AC8E091499D75D9B949 /* _RXKVOObserver.m */; };
+ E85CE4AC7329B2A28C3962A44CC74954 /* DelaySubscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0563A182248FB9D6E2EE2A227B4278CB /* DelaySubscription.swift */; };
+ E85DC682EBB400586E00721AAD6A40AA /* ToArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32ECE316C2C08F2FBD9CD6146C162FE8 /* ToArray.swift */; };
+ E88CB065BEF379BD60E2AD72A871EA07 /* Empty.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC4CE9E69BD3692E25435DFF08150281 /* Empty.swift */; };
+ E8B5392D7D672E1DD3D9C1F4D92DF86C /* RxTextViewDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = D65D17F873F72D6B1E8794F5ACEAEB44 /* RxTextViewDelegateProxy.swift */; };
+ EDC6A6B90C7D781DABBD5B532280290D /* Scan.swift in Sources */ = {isa = PBXBuildFile; fileRef = C16C8AA6F97D21BFD0A3AF26373731E2 /* Scan.swift */; };
+ EEA9485CD9D29F85D2E5B3C2B4BFBF80 /* PriorityQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C79970530D93F05F8B7C9A8203921AE /* PriorityQueue.swift */; };
+ EFEC1B345021E5A2BE3133767DDF7E6C /* Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41C211BF6B589CAD8CA0808923658DA3 /* Driver.swift */; };
+ F1911CB1828788BCFD2429BF4F5C0B9D /* ScheduledItemType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5293B9C508D858D18F9BE98E4D8B1CC8 /* ScheduledItemType.swift */; };
+ F294ADC6B119C71445AE2255E11864CD /* RxTextStorageDelegateProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A652EC57C21EEA7396AB93AEEBB70CC /* RxTextStorageDelegateProxy.swift */; };
+ F2A94E48D7DF9478DB6FF71D6C313BB6 /* SingleAsync.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6BF6EC7286419E2A0093926F0D54024 /* SingleAsync.swift */; };
+ F4C471FA29B17704F82CD8E7C836EB96 /* Repeat.swift in Sources */ = {isa = PBXBuildFile; fileRef = E36A10AAB04A4E5683AE4B1269CB55E5 /* Repeat.swift */; };
+ F6DE98FB2098E3B5B7615FF5FDFE306A /* RxCocoaObjCRuntimeError+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C895F323C80D99491E20AB3A88797A3B /* RxCocoaObjCRuntimeError+Extensions.swift */; };
+ F7BD7BECE29FB3419524A0D164C9F43F /* UIActivityIndicatorView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCD4BE4C69C97611CDD16209D2A26860 /* UIActivityIndicatorView+Rx.swift */; };
+ F7EFEF5679DD9DF9EBCFF6578BE49FA0 /* InfiniteSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC509A14DB241C28206B889097C413B9 /* InfiniteSequence.swift */; };
+ F8C423BF8821B72D24686FEA562733A8 /* UITextView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCDB67B12D350E3712C3713A5DDC3AC1 /* UITextView+Rx.swift */; };
+ F8E7AA6F959A6D6B8DB65C5F6D44388E /* ObservableConvertibleType+SharedSequence.swift in Sources */ = {isa = PBXBuildFile; fileRef = F08D070993EE189DEDBE2E8283769ECA /* ObservableConvertibleType+SharedSequence.swift */; };
+ FA253AC265EDACA7B86680AC62340985 /* TakeWhile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B8B3247A709B4FD22813E354E88EC39 /* TakeWhile.swift */; };
+ FA46C6FB94B7CA84EAA05F67F2C43762 /* UISearchController+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9613FBA8885E8CDF0C27E2941C96A0BB /* UISearchController+Rx.swift */; };
+ FAB534525B9EA54B097DA8CD8E0BEC56 /* PublishSubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F11A7D0074CE30A7AB58FD1A7200979 /* PublishSubject.swift */; };
+ FBEE54B193FDF37E1B786DA47B3DB098 /* TailRecursiveSink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41CD03D4537993C97D5E596580296103 /* TailRecursiveSink.swift */; };
+ FC2E222A7AEA3DE73F21DE6984814C41 /* NSObject+Rx+RawRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83ECFEBCF63AD537C7DEAF180BC8E0E8 /* NSObject+Rx+RawRepresentable.swift */; };
+ FC9C041BD469A2A9A6217F7C3704ADAB /* Driver+Subscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19DDBF45DE47B160F7AA4FDBEF06DACC /* Driver+Subscription.swift */; };
+ FD21FEB5C3FE29950613F9A99491B723 /* BinaryDisposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80F462850F0C496E63D68311F38EB7B0 /* BinaryDisposable.swift */; };
+ FDEC0DDC235B4C3005565D39740E8183 /* Sink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E550FA6BA79CDA1CCCD9FCB9D6E4E6C /* Sink.swift */; };
+ FF824085592FCA110E19CCE569A99EAE /* Just.swift in Sources */ = {isa = PBXBuildFile; fileRef = B36737DB51F1433B35E27DAAADB90905 /* Just.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
- 7A59EA3B6E12321FD6DB829EA8F42F42 /* PBXContainerItemProxy */ = {
+ 03049E43A3F87053D3119C8267AE04FB /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */;
proxyType = 1;
- remoteGlobalIDString = 402EBD6070F177670CD20F26A5CB58BC;
- remoteInfo = RxSwift;
+ remoteGlobalIDString = CB4A3212CE222664E222C962519D604B;
+ remoteInfo = RxCocoa;
};
- 8F40DEC3F6744894271C630614C19039 /* PBXContainerItemProxy */ = {
+ 25FD2DDB690168D174CD0CC5A5230362 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */;
proxyType = 1;
- remoteGlobalIDString = 46F8D42C1E9780D15104E1B62753218F;
- remoteInfo = RxCocoa;
+ remoteGlobalIDString = 6111906DD6556E6699AC0D1C05078A02;
+ remoteInfo = RxSwift;
};
- F617D0BDD720063910D36DFF582CC31B /* PBXContainerItemProxy */ = {
+ 6393888B492465F2D50047FFA427087D /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */;
proxyType = 1;
- remoteGlobalIDString = 402EBD6070F177670CD20F26A5CB58BC;
+ remoteGlobalIDString = 6111906DD6556E6699AC0D1C05078A02;
remoteInfo = RxSwift;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
- 00053BD5230150E958799E47A48EA895 /* Deferred.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Deferred.swift; path = RxSwift/Observables/Implementations/Deferred.swift; sourceTree = ""; };
- 00ED64DA988B533B84EB169AFCED363E /* WithLatestFrom.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = WithLatestFrom.swift; path = RxSwift/Observables/Implementations/WithLatestFrom.swift; sourceTree = ""; };
+ 001721082AD1820BF14628A28649996E /* Bag.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Bag.swift; path = Platform/DataStructures/Bag.swift; sourceTree = ""; };
+ 00243578A2429FC5E1FFE03292FAFF64 /* StartWith.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StartWith.swift; path = RxSwift/Observables/Implementations/StartWith.swift; sourceTree = ""; };
+ 006A85CAF9C458F13EBCC787756720A2 /* InfiniteSequence.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = InfiniteSequence.swift; path = Platform/DataStructures/InfiniteSequence.swift; sourceTree = ""; };
0158974CA472DE568A4D35AE3DABD751 /* Pods-PokedexGo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-PokedexGo.release.xcconfig"; sourceTree = ""; };
- 023474758DA44A2BFAF627F30F635E6B /* PriorityQueue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PriorityQueue.swift; path = RxSwift/DataStructures/PriorityQueue.swift; sourceTree = ""; };
- 02811E0858D470F34B739A6BFD2056F3 /* ObserveOn.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ObserveOn.swift; path = RxSwift/Observables/Implementations/ObserveOn.swift; sourceTree = ""; };
- 0291CC41E092EBFDF54D42B02E6424D3 /* Driver+Operators+arity.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Driver+Operators+arity.swift"; path = "RxCocoa/Common/CocoaUnits/Driver/Driver+Operators+arity.swift"; sourceTree = ""; };
- 03A4D1610491EEC726F17C86B0EEADB0 /* UIViewController+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIViewController+Rx.swift"; path = "RxCocoa/iOS/UIViewController+Rx.swift"; sourceTree = ""; };
- 0691E2AF4F4BC07A24EC93D184A3FDEB /* Observable+Concurrency.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Observable+Concurrency.swift"; path = "RxSwift/Observables/Observable+Concurrency.swift"; sourceTree = ""; };
- 07938BBC6989A110F1642C7C78A2A03A /* RxTableViewDataSourceType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTableViewDataSourceType.swift; path = RxCocoa/iOS/Protocols/RxTableViewDataSourceType.swift; sourceTree = ""; };
- 08999F9E91C67F502F2B31AB37B21F34 /* Driver+Subscription.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Driver+Subscription.swift"; path = "RxCocoa/Common/CocoaUnits/Driver/Driver+Subscription.swift"; sourceTree = ""; };
+ 01DBF7C725D0BA477B3AA3A94377F2C9 /* _RXObjCRuntime.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _RXObjCRuntime.h; path = RxCocoa/Runtime/include/_RXObjCRuntime.h; sourceTree = ""; };
+ 02229AFE0B4BCF0FFE5A1F61A6A3E6E3 /* UIStepper+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIStepper+Rx.swift"; path = "RxCocoa/iOS/UIStepper+Rx.swift"; sourceTree = ""; };
+ 0261DA91C20FBC3AFF3A0D05B073CBA7 /* RxCollectionViewDataSourceType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxCollectionViewDataSourceType.swift; path = RxCocoa/iOS/Protocols/RxCollectionViewDataSourceType.swift; sourceTree = ""; };
+ 02E3FD64DE9F3F7935D3A66FC3A660AD /* Merge.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Merge.swift; path = RxSwift/Observables/Implementations/Merge.swift; sourceTree = ""; };
+ 0390599D2CE39A885EAF2242027BEDFB /* Platform.Darwin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Platform.Darwin.swift; path = Platform/Platform.Darwin.swift; sourceTree = ""; };
+ 04627568BE8263B246C8542E44BEB84E /* Disposables.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Disposables.swift; path = RxSwift/Disposables/Disposables.swift; sourceTree = ""; };
+ 05154EFEAF12E5BBAE9E13E095EDFAEA /* RxCollectionViewDataSourceProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxCollectionViewDataSourceProxy.swift; path = RxCocoa/iOS/Proxies/RxCollectionViewDataSourceProxy.swift; sourceTree = ""; };
+ 054F1DF36495EC9708AF0BFF1889B1B1 /* TextInput.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TextInput.swift; path = RxCocoa/Common/TextInput.swift; sourceTree = ""; };
+ 0563A182248FB9D6E2EE2A227B4278CB /* DelaySubscription.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DelaySubscription.swift; path = RxSwift/Observables/Implementations/DelaySubscription.swift; sourceTree = ""; };
+ 06AA53BF1102449A2CF3379F0B8C89C7 /* Filter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Filter.swift; path = RxSwift/Observables/Implementations/Filter.swift; sourceTree = ""; };
+ 0949D3D804F8DA073BC481DA1ACA5DFE /* KVORepresentable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KVORepresentable.swift; path = RxCocoa/Foundation/KVORepresentable.swift; sourceTree = ""; };
0A383D28A120663F29BAD0538E848E8B /* Pods-PokedexGo-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-PokedexGo-acknowledgements.plist"; sourceTree = ""; };
- 0AED7DC8C3D8A832530DA381920BFB08 /* SubscribeOn.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SubscribeOn.swift; path = RxSwift/Observables/Implementations/SubscribeOn.swift; sourceTree = ""; };
- 0B365A38BCEEABC88B67EA39D80A861F /* ConcurrentMainScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConcurrentMainScheduler.swift; path = RxSwift/Schedulers/ConcurrentMainScheduler.swift; sourceTree = ""; };
- 0D255DFA39931004E6FBAE8524E21D29 /* Debug.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Debug.swift; path = RxSwift/Observables/Implementations/Debug.swift; sourceTree = ""; };
- 0D7F8AC7906D8F3573813543E119E9C2 /* SerialDispatchQueueScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SerialDispatchQueueScheduler.swift; path = RxSwift/Schedulers/SerialDispatchQueueScheduler.swift; sourceTree = ""; };
- 0DE82875BF092ABF63F0129F1D66C342 /* _RXDelegateProxy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = _RXDelegateProxy.m; path = RxCocoa/Common/_RXDelegateProxy.m; sourceTree = ""; };
+ 0A4169BB7B76EC937D94F6BEF9FB9E0B /* VirtualTimeScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = VirtualTimeScheduler.swift; path = RxSwift/Schedulers/VirtualTimeScheduler.swift; sourceTree = ""; };
+ 0A652EC57C21EEA7396AB93AEEBB70CC /* RxTextStorageDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTextStorageDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxTextStorageDelegateProxy.swift; sourceTree = ""; };
+ 0A746282E628E8F2A9EB17EE33CD0C91 /* TakeUntil.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TakeUntil.swift; path = RxSwift/Observables/Implementations/TakeUntil.swift; sourceTree = ""; };
+ 0B97480CAF8B38BAFCC58CA4C786FC9B /* UIPickerView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIPickerView+Rx.swift"; path = "RxCocoa/iOS/UIPickerView+Rx.swift"; sourceTree = ""; };
+ 0C0C11784D64D692E0050ED48F989D57 /* RxCocoa-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RxCocoa-prefix.pch"; sourceTree = ""; };
+ 0C4D8309F4A7F25A8EC6FE8843F5CCC0 /* NSTextStorage+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSTextStorage+Rx.swift"; path = "RxCocoa/iOS/NSTextStorage+Rx.swift"; sourceTree = ""; };
+ 0C79970530D93F05F8B7C9A8203921AE /* PriorityQueue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PriorityQueue.swift; path = Platform/DataStructures/PriorityQueue.swift; sourceTree = ""; };
+ 0DBADAF4942134897BCBFC9D3F0ECCCE /* ObserveOn.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ObserveOn.swift; path = RxSwift/Observables/Implementations/ObserveOn.swift; sourceTree = ""; };
+ 0DC7413C45CB819C77DBA74D1CE67334 /* BehaviorSubject.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BehaviorSubject.swift; path = RxSwift/Subjects/BehaviorSubject.swift; sourceTree = ""; };
+ 0DF9CCC07A8F8899DAA3468E098F34B2 /* SynchronizedOnType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SynchronizedOnType.swift; path = RxSwift/Concurrency/SynchronizedOnType.swift; sourceTree = ""; };
+ 0EF39FC951C6CC263EDFD7124E057FCF /* SubscriptionDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SubscriptionDisposable.swift; path = RxSwift/Disposables/SubscriptionDisposable.swift; sourceTree = ""; };
0F1EE5FBEBAD64A518D583451C6D84F8 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
- 1186161B975100A7DFC409B8C396D8B0 /* UITabBarItem+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UITabBarItem+Rx.swift"; path = "RxCocoa/iOS/UITabBarItem+Rx.swift"; sourceTree = ""; };
- 12D37A1D8E30A99C0CA998A5F87E2EB9 /* RxCocoa-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RxCocoa-prefix.pch"; sourceTree = ""; };
- 14BF84797953369156C57EB5452EBF9E /* TextInput.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TextInput.swift; path = RxCocoa/Common/TextInput.swift; sourceTree = ""; };
- 14C6018EB8ED3D2D4687001C575AFF19 /* RxTextStorageDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTextStorageDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxTextStorageDelegateProxy.swift; sourceTree = ""; };
- 15466AD4A01ACC05B816711C276C94B7 /* ObservableConvertibleType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ObservableConvertibleType.swift; path = RxSwift/ObservableConvertibleType.swift; sourceTree = ""; };
- 16BBBD04181474EAD0A97986ADBDE173 /* DispatchQueueSchedulerQOS.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DispatchQueueSchedulerQOS.swift; path = RxSwift/Schedulers/DispatchQueueSchedulerQOS.swift; sourceTree = ""; };
+ 0F6F79C0E9CA7600FB215083C59C7A24 /* SingleAssignmentDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SingleAssignmentDisposable.swift; path = RxSwift/Disposables/SingleAssignmentDisposable.swift; sourceTree = ""; };
+ 0F702A0D040E23B8F7C4A2B2D7BF3D6D /* Observable+Debug.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Observable+Debug.swift"; path = "RxSwift/Observables/Observable+Debug.swift"; sourceTree = ""; };
+ 11C615CBD6201F948CE3830F3EFABFA3 /* SynchronizedSubscribeType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SynchronizedSubscribeType.swift; path = RxSwift/Concurrency/SynchronizedSubscribeType.swift; sourceTree = ""; };
+ 122E690AFB6AC805905FAC5D63EE4098 /* CombineLatest.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CombineLatest.swift; path = RxSwift/Observables/Implementations/CombineLatest.swift; sourceTree = ""; };
+ 13E02371A6891FF6803B48F80CEB4A26 /* ControlTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ControlTarget.swift; path = RxCocoa/Common/ControlTarget.swift; sourceTree = ""; };
+ 1491FA56387C07FA701050A6BAB1217B /* ElementAt.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ElementAt.swift; path = RxSwift/Observables/Implementations/ElementAt.swift; sourceTree = ""; };
+ 14F32DA16234790E73FEEB15D52896DA /* Observable+Single.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Observable+Single.swift"; path = "RxSwift/Observables/Observable+Single.swift"; sourceTree = ""; };
17237AA00C6DE7CADBCBC1A37C8642C2 /* Pods-PokedexGo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-PokedexGo.debug.xcconfig"; sourceTree = ""; };
- 199CEC87F4AF077D9B4762389FF6570A /* KVOObservable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KVOObservable.swift; path = RxCocoa/Common/Observables/Implementations/KVOObservable.swift; sourceTree = ""; };
- 1A0B4A186840C963BFED5950C240F664 /* RxCocoa.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = RxCocoa.modulemap; sourceTree = ""; };
- 1A1611E18D67AF94FDC0B20D1CAF3A5F /* SynchronizedSubscribeType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SynchronizedSubscribeType.swift; path = RxSwift/Concurrency/SynchronizedSubscribeType.swift; sourceTree = ""; };
- 1A47F6ED70808C18751C82FE05C97E84 /* RxCocoa.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RxCocoa.h; path = RxCocoa/RxCocoa.h; sourceTree = ""; };
- 1BD6B800FB60FC0B73E545E9998902FA /* _RX.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = _RX.m; path = RxCocoa/Common/_RX.m; sourceTree = ""; };
- 1E41312BC41502D9EC683B790A5DEC59 /* RefCount.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RefCount.swift; path = RxSwift/Observables/Implementations/RefCount.swift; sourceTree = ""; };
- 1EC5D0239E634C375CA320C1CA5F9FDF /* TakeLast.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TakeLast.swift; path = RxSwift/Observables/Implementations/TakeLast.swift; sourceTree = ""; };
- 23966E1D2B24C6547A2B15D92C5671D0 /* Variable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Variable.swift; path = RxSwift/Subjects/Variable.swift; sourceTree = ""; };
- 24189EB6F723B40C817F8408B893EB7B /* ImmediateSchedulerType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImmediateSchedulerType.swift; path = RxSwift/ImmediateSchedulerType.swift; sourceTree = ""; };
- 24EDBAF23688A76BA859735A2C8F3194 /* Just.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Just.swift; path = RxSwift/Observables/Implementations/Just.swift; sourceTree = ""; };
- 257340FD101A7D19D51F5261F0468333 /* SynchronizedOnType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SynchronizedOnType.swift; path = RxSwift/Concurrency/SynchronizedOnType.swift; sourceTree = ""; };
- 27AC0F00E0539EE6BB3CA625F08F2A21 /* Reduce.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Reduce.swift; path = RxSwift/Observables/Implementations/Reduce.swift; sourceTree = ""; };
- 286DB0BF724E24E942AE4449F63394D1 /* ControlProperty+Driver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ControlProperty+Driver.swift"; path = "RxCocoa/Common/CocoaUnits/Driver/ControlProperty+Driver.swift"; sourceTree = ""; };
- 2D8B5E655F870573D98C16B1C6D1D89E /* Scan.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Scan.swift; path = RxSwift/Observables/Implementations/Scan.swift; sourceTree = ""; };
- 2FE39B9E067C4AFC9544CBF93C985681 /* UIDatePicker+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIDatePicker+Rx.swift"; path = "RxCocoa/iOS/UIDatePicker+Rx.swift"; sourceTree = ""; };
- 3193F1228BF29C5E2A301B4B72B7980E /* ScheduledItemType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ScheduledItemType.swift; path = RxSwift/Schedulers/Internal/ScheduledItemType.swift; sourceTree = ""; };
- 32070195AC7FF295DC13483699433136 /* RxSearchControllerDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxSearchControllerDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxSearchControllerDelegateProxy.swift; sourceTree = ""; };
- 322CA81233C08A654C0E044DCDC6F33D /* UIBarButtonItem+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIBarButtonItem+Rx.swift"; path = "RxCocoa/iOS/UIBarButtonItem+Rx.swift"; sourceTree = ""; };
- 32F23A0961AAA6C01A1397AD90EDA9AA /* ConnectableObservable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConnectableObservable.swift; path = RxSwift/Observables/Implementations/ConnectableObservable.swift; sourceTree = ""; };
- 3355C93B63CA5FE5B47101DF7E77B25F /* UIImageView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIImageView+Rx.swift"; path = "RxCocoa/iOS/UIImageView+Rx.swift"; sourceTree = ""; };
- 357DF1CCC5063151569BCAC8BF4E9C6D /* MainScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MainScheduler.swift; path = RxSwift/Schedulers/MainScheduler.swift; sourceTree = ""; };
- 35BCDAFC104DCC94AF1FE83D7487AA10 /* Reactive.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Reactive.swift; path = RxCocoa/Common/Reactive.swift; sourceTree = ""; };
- 360DB4FE725B14D1B4A919CAE6C07BD0 /* ControlProperty.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ControlProperty.swift; path = RxCocoa/Common/CocoaUnits/ControlProperty.swift; sourceTree = ""; };
- 363274368317697F561BB2ED8F6AB66A /* NSObject+Rx+KVORepresentable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "NSObject+Rx+KVORepresentable.swift"; path = "RxCocoa/Common/Observables/NSObject+Rx+KVORepresentable.swift"; sourceTree = ""; };
- 366E4D0AB9A75F2A5712473C8D3EAE38 /* KVORepresentable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KVORepresentable.swift; path = RxCocoa/Common/KVORepresentable.swift; sourceTree = ""; };
- 3777004EB16505CA6386B7D9FDBD7ED7 /* Observable+Debug.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Observable+Debug.swift"; path = "RxSwift/Observables/Observable+Debug.swift"; sourceTree = ""; };
- 37B3D6613A18DC598DA7ABCA1D9CED33 /* AnyObserver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AnyObserver.swift; path = RxSwift/AnyObserver.swift; sourceTree = ""; };
- 383F17D9EBD7C4F32343FBA6C5743F68 /* ScheduledItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ScheduledItem.swift; path = RxSwift/Schedulers/Internal/ScheduledItem.swift; sourceTree = ""; };
+ 17FAD3C510F874695845F53E92CDEFCE /* HistoricalScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HistoricalScheduler.swift; path = RxSwift/Schedulers/HistoricalScheduler.swift; sourceTree = ""; };
+ 187761E03C1F7B58183B7320406658AE /* Never.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Never.swift; path = RxSwift/Observables/Implementations/Never.swift; sourceTree = ""; };
+ 19DDBF45DE47B160F7AA4FDBEF06DACC /* Driver+Subscription.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Driver+Subscription.swift"; path = "RxCocoa/CocoaUnits/Driver/Driver+Subscription.swift"; sourceTree = ""; };
+ 1A6B4401BAE249952C98F64BBC95B2F2 /* RxTableViewDataSourceProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTableViewDataSourceProxy.swift; path = RxCocoa/iOS/Proxies/RxTableViewDataSourceProxy.swift; sourceTree = ""; };
+ 1A72650E19D579EB5CDDC6E40B590B11 /* SkipWhile.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SkipWhile.swift; path = RxSwift/Observables/Implementations/SkipWhile.swift; sourceTree = ""; };
+ 1C5D30C37343EEFCC746F2C0DAE0E218 /* _RXDelegateProxy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _RXDelegateProxy.h; path = RxCocoa/Runtime/include/_RXDelegateProxy.h; sourceTree = ""; };
+ 1D0F791088E9C7CC17CC8E64A0BCF99D /* ControlProperty.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ControlProperty.swift; path = RxCocoa/CocoaUnits/ControlProperty.swift; sourceTree = ""; };
+ 20184E13B8706FF2BEC9F6F5162F5287 /* ImmediateSchedulerType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImmediateSchedulerType.swift; path = RxSwift/ImmediateSchedulerType.swift; sourceTree = ""; };
+ 2087DF11C7599522350EA04DE6B4156E /* RxCocoa.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = RxCocoa.modulemap; sourceTree = ""; };
+ 22954F1D4615BBFF718FD64924CADC93 /* BooleanDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BooleanDisposable.swift; path = RxSwift/Disposables/BooleanDisposable.swift; sourceTree = ""; };
+ 24241E179BF63060B757331E8BD99D63 /* Generate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Generate.swift; path = RxSwift/Observables/Implementations/Generate.swift; sourceTree = ""; };
+ 250DB34FC592CA01F9AC40F5B72D1E4E /* DispatchQueueConfiguration.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DispatchQueueConfiguration.swift; path = RxSwift/Schedulers/Internal/DispatchQueueConfiguration.swift; sourceTree = ""; };
+ 26CF7CCE8663939B828C53DF2B9BA2B4 /* Do.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Do.swift; path = RxSwift/Observables/Implementations/Do.swift; sourceTree = ""; };
+ 275C278EB8ECC1D443F42A7648BE8554 /* RxSwift-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "RxSwift-dummy.m"; sourceTree = ""; };
+ 2836FC17C9639B40E5BE53E2A461D59D /* ConnectableObservable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConnectableObservable.swift; path = RxSwift/Observables/Implementations/ConnectableObservable.swift; sourceTree = ""; };
+ 29639B573EB1412C4230E3B09B9ECAC5 /* ObserveOnSerialDispatchQueue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ObserveOnSerialDispatchQueue.swift; path = RxSwift/Observables/Implementations/ObserveOnSerialDispatchQueue.swift; sourceTree = ""; };
+ 29B44F83E55B949CDDD1F0AFEAEC880E /* Platform.Darwin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Platform.Darwin.swift; path = Platform/Platform.Darwin.swift; sourceTree = ""; };
+ 2A1A0CB1F9C1205703FF5508B7DEEDC6 /* UITableView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UITableView+Rx.swift"; path = "RxCocoa/iOS/UITableView+Rx.swift"; sourceTree = ""; };
+ 2B619CE407B9403711BDFBAEE67207A9 /* InvocableType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = InvocableType.swift; path = RxSwift/Schedulers/Internal/InvocableType.swift; sourceTree = ""; };
+ 2B983B555CBEC50516E21B9835EBA92E /* RxMutableBox.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxMutableBox.swift; path = RxSwift/RxMutableBox.swift; sourceTree = ""; };
+ 2BD37F2E2DCDC1316E634A329394F90C /* Lock.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Lock.swift; path = RxSwift/Concurrency/Lock.swift; sourceTree = ""; };
+ 2CA4CF3BFBE7871ADCF8FBBE747810FE /* RxSwift-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RxSwift-umbrella.h"; sourceTree = ""; };
+ 2D3967211EDE74A259D45C68D0919CCD /* RxSearchControllerDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxSearchControllerDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxSearchControllerDelegateProxy.swift; sourceTree = ""; };
+ 2E3E5238F35763575B4EA04D71B648D1 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ 2E550FA6BA79CDA1CCCD9FCB9D6E4E6C /* Sink.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Sink.swift; path = RxSwift/Observables/Implementations/Sink.swift; sourceTree = ""; };
+ 2FAD8B62333EE46C5A33F9FE50E5918A /* UIDatePicker+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIDatePicker+Rx.swift"; path = "RxCocoa/iOS/UIDatePicker+Rx.swift"; sourceTree = ""; };
+ 30D2A54F9FD3E9B455E0BC2E62C15FA3 /* Delay.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Delay.swift; path = RxSwift/Observables/Implementations/Delay.swift; sourceTree = ""; };
+ 30DFCE2B63D2C2FE3331E73B770B4903 /* ObservableType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ObservableType.swift; path = RxSwift/ObservableType.swift; sourceTree = ""; };
+ 30F24BBC537B71BDBC5816F0B5117B87 /* DispatchQueue+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DispatchQueue+Extensions.swift"; path = "Platform/DispatchQueue+Extensions.swift"; sourceTree = ""; };
+ 310E2059CCB59758D74FA623B7341F35 /* Cancelable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Cancelable.swift; path = RxSwift/Cancelable.swift; sourceTree = ""; };
+ 313763C6108D9C46316D32780D3A5ED1 /* _RX.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _RX.h; path = RxCocoa/Runtime/include/_RX.h; sourceTree = ""; };
+ 313873C00506CBE738D855EED5608303 /* SharedSequence+Operators.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "SharedSequence+Operators.swift"; path = "RxCocoa/CocoaUnits/SharedSequence/SharedSequence+Operators.swift"; sourceTree = ""; };
+ 323235124BDF04A1A2262894B9B69BF0 /* SynchronizedUnsubscribeType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SynchronizedUnsubscribeType.swift; path = RxSwift/Concurrency/SynchronizedUnsubscribeType.swift; sourceTree = ""; };
+ 32ECE316C2C08F2FBD9CD6146C162FE8 /* ToArray.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ToArray.swift; path = RxSwift/Observables/Implementations/ToArray.swift; sourceTree = ""; };
+ 3379A9C5DF632BB854582CE0439F9A48 /* Observable+Bind.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Observable+Bind.swift"; path = "RxCocoa/Common/Observable+Bind.swift"; sourceTree = ""; };
+ 33E24CBC32BF736F401E2C0002F4C163 /* Debunce.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Debunce.swift; path = RxSwift/Observables/Implementations/Debunce.swift; sourceTree = ""; };
+ 34CAF15FDB134CCB47A9BE558BA936CE /* ControlProperty+Driver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ControlProperty+Driver.swift"; path = "RxCocoa/CocoaUnits/Driver/ControlProperty+Driver.swift"; sourceTree = ""; };
+ 35A28FA391DB06D29D19DA4447AD37CA /* CombineLatest+Collection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "CombineLatest+Collection.swift"; path = "RxSwift/Observables/Implementations/CombineLatest+Collection.swift"; sourceTree = ""; };
+ 35DBF02092FEBD822B83924EB54C422A /* Zip+arity.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Zip+arity.swift"; path = "RxSwift/Observables/Implementations/Zip+arity.swift"; sourceTree = ""; };
+ 368C2CCC6A55F4D761B07A4A01E238F8 /* MainScheduler.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MainScheduler.swift; path = RxSwift/Schedulers/MainScheduler.swift; sourceTree = ""; };
+ 3887B94073C7C1FFAEA8E2F5181F29E3 /* NopDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NopDisposable.swift; path = RxSwift/Disposables/NopDisposable.swift; sourceTree = ""; };
397ED6A120A7323FEFFD443352B8A3B8 /* RxSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RxSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
- 3A111DDC4C1EB87CD4BE69AB57654306 /* Observable+Multiple.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Observable+Multiple.swift"; path = "RxSwift/Observables/Observable+Multiple.swift"; sourceTree = ""; };
- 3ADEF916724C3CD33414826B3075629D /* SingleAssignmentDisposable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SingleAssignmentDisposable.swift; path = RxSwift/Disposables/SingleAssignmentDisposable.swift; sourceTree = ""; };
- 3B4B0240401064916F34863D58160922 /* Catch.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Catch.swift; path = RxSwift/Observables/Implementations/Catch.swift; sourceTree = ""; };
- 3C72E0D48DA28CC03E4EC00234F52265 /* Pods-PokedexGo.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-PokedexGo.modulemap"; sourceTree = ""; };
- 3D2E6375EF514E682DD5E099DEEA3C10 /* DisposeBase.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DisposeBase.swift; path = RxSwift/Disposables/DisposeBase.swift; sourceTree = ""; };
- 3E9940D9817166477856DE65094A6260 /* PublishSubject.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PublishSubject.swift; path = RxSwift/Subjects/PublishSubject.swift; sourceTree = ""; };
- 3F083B32C768C775786BB21ECF548208 /* DeallocObservable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DeallocObservable.swift; path = RxCocoa/Common/Observables/Implementations/DeallocObservable.swift; sourceTree = ""; };
- 3F3B2427854E0EBD6D65C83D0820471B /* TailRecursiveSink.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TailRecursiveSink.swift; path = RxSwift/Observers/TailRecursiveSink.swift; sourceTree = ""; };
- 40AAB2FCC33C7D3618DF8098E641D159 /* Window.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Window.swift; path = RxSwift/Observables/Implementations/Window.swift; sourceTree = ""; };
- 4331958ADDFBB46E5D9FAAE5F90CFFCA /* Take.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Take.swift; path = RxSwift/Observables/Implementations/Take.swift; sourceTree = ""; };
- 438E2DC43570497DBE921AEB89518230 /* UISlider+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UISlider+Rx.swift"; path = "RxCocoa/iOS/UISlider+Rx.swift"; sourceTree = ""; };
- 43FC3978A8C9F39C7800B21748B1C0EF /* DistinctUntilChanged.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DistinctUntilChanged.swift; path = RxSwift/Observables/Implementations/DistinctUntilChanged.swift; sourceTree = ""; };
- 45B87E1492D431B8BA1E5AEB616A1AB4 /* Map.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Map.swift; path = RxSwift/Observables/Implementations/Map.swift; sourceTree = ""; };
- 4706890E176FBF3A8D3F02AC3051B9CC /* UISearchBar+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UISearchBar+Rx.swift"; path = "RxCocoa/iOS/UISearchBar+Rx.swift"; sourceTree = ""; };
- 4742034066CBC30A03A7231BA909C2B8 /* ControlTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ControlTarget.swift; path = RxCocoa/Common/Observables/Implementations/ControlTarget.swift; sourceTree = ""; };
- 47C615A0C1C7CB0D93B1B59AAE7AE2FF /* RxTabBarDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxTabBarDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxTabBarDelegateProxy.swift; sourceTree = ""; };
+ 3A84C7DDCCB01DD68DB69FDFAF2A317D /* RxCocoa-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RxCocoa-umbrella.h"; sourceTree = ""; };
+ 3B00D7B6E0CBFE12E1D5A6C30B939190 /* String+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+Rx.swift"; path = "RxSwift/Extensions/String+Rx.swift"; sourceTree = ""; };
+ 3B8B3247A709B4FD22813E354E88EC39 /* TakeWhile.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TakeWhile.swift; path = RxSwift/Observables/Implementations/TakeWhile.swift; sourceTree = ""; };
+ 3C2907A619D445EBAC4FE4C582FFBFC6 /* LockOwnerType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LockOwnerType.swift; path = RxSwift/Concurrency/LockOwnerType.swift; sourceTree = ""; };
+ 3C72E0D48DA28CC03E4EC00234F52265 /* Pods-PokedexGo.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = "Pods-PokedexGo.modulemap"; sourceTree = ""; };
+ 3DE5921D384D083F148002565A98CA7D /* Observable+Concurrency.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Observable+Concurrency.swift"; path = "RxSwift/Observables/Observable+Concurrency.swift"; sourceTree = ""; };
+ 3E36B0DA3408346FB92A93AB6C45E069 /* RxSearchBarDelegateProxy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RxSearchBarDelegateProxy.swift; path = RxCocoa/iOS/Proxies/RxSearchBarDelegateProxy.swift; sourceTree = ""; };
+ 3F204260242C3B57DA94787B81F9A379 /* DisposeBase.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DisposeBase.swift; path = RxSwift/Disposables/DisposeBase.swift; sourceTree = ""; };
+ 40B18BDB18A0F71D3408DC5B3D9CAB9C /* RxSwift.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = RxSwift.modulemap; sourceTree = ""; };
+ 41C211BF6B589CAD8CA0808923658DA3 /* Driver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Driver.swift; path = RxCocoa/CocoaUnits/Driver/Driver.swift; sourceTree = ""; };
+ 41CD03D4537993C97D5E596580296103 /* TailRecursiveSink.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TailRecursiveSink.swift; path = RxSwift/Observers/TailRecursiveSink.swift; sourceTree = ""; };
+ 420ED71D6CB2021AB9A4176B03D0C320 /* UIImageView+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIImageView+Rx.swift"; path = "RxCocoa/iOS/UIImageView+Rx.swift"; sourceTree = ""; };
+ 4488DC730219AA10C54CA340A3D5E405 /* UITextField+Rx.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UITextField+Rx.swift"; path = "RxCocoa/iOS/UITextField+Rx.swift"; sourceTree = ""; };
+ 4610BE88BD9A69E7311E15CCA3C9C30D /* HistoricalSchedulerTimeConverter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HistoricalSchedulerTimeConverter.swift; path = RxSwift/Schedulers/HistoricalSchedulerTimeConverter.swift; sourceTree = ""; };
+ 46529E285EEFBC21FADDCE1616A0D778 /* VirtualTimeConverterType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = VirtualTimeConverterType.swift; path = RxSwift/Schedulers/VirtualTimeConverterType.swift; sourceTree = "