diff --git a/.gitignore b/.gitignore
index 4e432c2..f13fd72 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,11 @@
+.DS_Store
+# If Xcode is setup to use a local derived data folder (recommended), ignore it
+DerivedData
+
+# Ignore xcodeproj because we codegenerate them
+*.xcodeproj
+# Ignore Info.plist because we codegen that, too
Info.plist
+
+# SwiftPM
+.build
diff --git a/04-tdd-in-the-real-world/0-start/.gitignore b/04-tdd-in-the-real-world/0-start/.gitignore
deleted file mode 100644
index 0f22386..0000000
--- a/04-tdd-in-the-real-world/0-start/.gitignore
+++ /dev/null
@@ -1,32 +0,0 @@
-#### joe made this: https://goel.io/joe
-
-#####=== Swift ===#####
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# CocoaPods
-#
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
-#
-# Pods/
-
-*.xcodeproj
diff --git a/04-tdd-in-the-real-world/0-start/Albertos.xcodeproj/project.xcworkspace/xcuserdata/gio.xcuserdatad/UserInterfaceState.xcuserstate b/04-tdd-in-the-real-world/0-start/Albertos.xcodeproj/project.xcworkspace/xcuserdata/gio.xcuserdatad/UserInterfaceState.xcuserstate
new file mode 100644
index 0000000..1437865
Binary files /dev/null and b/04-tdd-in-the-real-world/0-start/Albertos.xcodeproj/project.xcworkspace/xcuserdata/gio.xcuserdatad/UserInterfaceState.xcuserstate differ
diff --git a/04-tdd-in-the-real-world/0-start/Albertos.xcodeproj/xcuserdata/gio.xcuserdatad/xcschemes/xcschememanagement.plist b/04-tdd-in-the-real-world/0-start/Albertos.xcodeproj/xcuserdata/gio.xcuserdatad/xcschemes/xcschememanagement.plist
new file mode 100644
index 0000000..cc1a1fa
--- /dev/null
+++ b/04-tdd-in-the-real-world/0-start/Albertos.xcodeproj/xcuserdata/gio.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -0,0 +1,27 @@
+
+
+
+
+ SchemeUserState
+
+ Albertos.xcscheme_^#shared#^_
+
+ orderHint
+ 0
+
+
+ SuppressBuildableAutocreation
+
+ 33D869CEA8CD44DF60039E52
+
+ primary
+
+
+ B5F9F9D2250AEB2D2EE0494B
+
+ primary
+
+
+
+
+
diff --git a/04-tdd-in-the-real-world/1-end/.gitignore b/04-tdd-in-the-real-world/1-end/.gitignore
deleted file mode 100644
index 0f22386..0000000
--- a/04-tdd-in-the-real-world/1-end/.gitignore
+++ /dev/null
@@ -1,32 +0,0 @@
-#### joe made this: https://goel.io/joe
-
-#####=== Swift ===#####
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# CocoaPods
-#
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
-#
-# Pods/
-
-*.xcodeproj
diff --git a/04-tdd-in-the-real-world/1-end/Albertos.xcodeproj/project.pbxproj b/04-tdd-in-the-real-world/1-end/Albertos.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..d51362e
--- /dev/null
+++ b/04-tdd-in-the-real-world/1-end/Albertos.xcodeproj/project.pbxproj
@@ -0,0 +1,408 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 54;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 09ACA86E7D21F75667DFE0DD /* MenuItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E51B5F284ED8D04D444E045A /* MenuItem.swift */; };
+ 25E8CB41017E048190FCD053 /* Menu+Dummy.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8947C2D6FD62F24954413BF /* Menu+Dummy.swift */; };
+ 9CC30446EF46FE0263FC1016 /* Collection+Safe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AB92569F1F7C921D2EEAF36 /* Collection+Safe.swift */; };
+ 9D334FC1DB465C7F0B3BB3F7 /* MenuSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED56EEE9C2A95C8D940BE49B /* MenuSection.swift */; };
+ A432A71EDCF4DC54058A564E /* MenuGroupingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E8BD1E021C1238B66D6697D /* MenuGroupingTests.swift */; };
+ AAD605E22BB4D10BF3F39DA8 /* AlbertosApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = E231812A9BEA82FE13B6DDE3 /* AlbertosApp.swift */; };
+ C5EE5943ADB1EA4D1CE728EE /* MenuGrouping.swift in Sources */ = {isa = PBXBuildFile; fileRef = F89281C54BD39EEAB6CD33A7 /* MenuGrouping.swift */; };
+ F28A0F3222BF3EAF2CDA01FE /* MenuList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38E678AF65BE5E3636E405C7 /* MenuList.swift */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 059BD3039F2CCB1DD9C2B900 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = E8B17C8ABC8471E4224D1C39 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B5F9F9D2250AEB2D2EE0494B;
+ remoteInfo = Albertos;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ 38E678AF65BE5E3636E405C7 /* MenuList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuList.swift; sourceTree = ""; };
+ 6AB92569F1F7C921D2EEAF36 /* Collection+Safe.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Collection+Safe.swift"; sourceTree = ""; };
+ 823EEDCB67B487000A05DB62 /* Albertos.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = Albertos.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 9E8BD1E021C1238B66D6697D /* MenuGroupingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuGroupingTests.swift; sourceTree = ""; };
+ A8947C2D6FD62F24954413BF /* Menu+Dummy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Menu+Dummy.swift"; sourceTree = ""; };
+ BDF4B76EC90E0DB5458F8146 /* AlbertosTests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = AlbertosTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ E231812A9BEA82FE13B6DDE3 /* AlbertosApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbertosApp.swift; sourceTree = ""; };
+ E51B5F284ED8D04D444E045A /* MenuItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItem.swift; sourceTree = ""; };
+ E5C5903BDB22A99A4B3DC3C8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; };
+ ED56EEE9C2A95C8D940BE49B /* MenuSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuSection.swift; sourceTree = ""; };
+ F89281C54BD39EEAB6CD33A7 /* MenuGrouping.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuGrouping.swift; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXGroup section */
+ 6587589555E08BBEB63089E1 /* Sources */ = {
+ isa = PBXGroup;
+ children = (
+ 6AB92569F1F7C921D2EEAF36 /* Collection+Safe.swift */,
+ );
+ name = Sources;
+ path = ../../Packages/CollectionSafe/Sources;
+ sourceTree = "";
+ };
+ 8B609BB40A5421BBA31F3D3B /* AlbertosTests */ = {
+ isa = PBXGroup;
+ children = (
+ 9E8BD1E021C1238B66D6697D /* MenuGroupingTests.swift */,
+ );
+ path = AlbertosTests;
+ sourceTree = "";
+ };
+ 8D972551E420DEE0F670E89F /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ E231812A9BEA82FE13B6DDE3 /* AlbertosApp.swift */,
+ E5C5903BDB22A99A4B3DC3C8 /* Info.plist */,
+ A8947C2D6FD62F24954413BF /* Menu+Dummy.swift */,
+ F89281C54BD39EEAB6CD33A7 /* MenuGrouping.swift */,
+ E51B5F284ED8D04D444E045A /* MenuItem.swift */,
+ 38E678AF65BE5E3636E405C7 /* MenuList.swift */,
+ ED56EEE9C2A95C8D940BE49B /* MenuSection.swift */,
+ );
+ path = Albertos;
+ sourceTree = "";
+ };
+ 92B90574F9FA63884D9D7BBF = {
+ isa = PBXGroup;
+ children = (
+ 8D972551E420DEE0F670E89F /* Albertos */,
+ 8B609BB40A5421BBA31F3D3B /* AlbertosTests */,
+ 6587589555E08BBEB63089E1 /* Sources */,
+ A0D81A2A2581F3DF42D52538 /* Products */,
+ );
+ sourceTree = "";
+ };
+ A0D81A2A2581F3DF42D52538 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 823EEDCB67B487000A05DB62 /* Albertos.app */,
+ BDF4B76EC90E0DB5458F8146 /* AlbertosTests.xctest */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 33D869CEA8CD44DF60039E52 /* AlbertosTests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = F6A1BAA7BD8B12026072190E /* Build configuration list for PBXNativeTarget "AlbertosTests" */;
+ buildPhases = (
+ C099BFE9ACD985A8EDF284EA /* Sources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ C21F4B58454F5DE5FB4E056C /* PBXTargetDependency */,
+ );
+ name = AlbertosTests;
+ productName = AlbertosTests;
+ productReference = BDF4B76EC90E0DB5458F8146 /* AlbertosTests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+ B5F9F9D2250AEB2D2EE0494B /* Albertos */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 15021ED4CD768AB692CDEF6F /* Build configuration list for PBXNativeTarget "Albertos" */;
+ buildPhases = (
+ 2B3D01A98BE73618C91FF57C /* Sources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = Albertos;
+ productName = Albertos;
+ productReference = 823EEDCB67B487000A05DB62 /* Albertos.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ E8B17C8ABC8471E4224D1C39 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ BuildIndependentTargetsInParallel = YES;
+ LastUpgradeCheck = 1430;
+ TargetAttributes = {
+ };
+ };
+ buildConfigurationList = 04A0F0432ABD7A4B9292FF90 /* Build configuration list for PBXProject "Albertos" */;
+ compatibilityVersion = "Xcode 14.0";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ Base,
+ en,
+ );
+ mainGroup = 92B90574F9FA63884D9D7BBF;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ B5F9F9D2250AEB2D2EE0494B /* Albertos */,
+ 33D869CEA8CD44DF60039E52 /* AlbertosTests */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 2B3D01A98BE73618C91FF57C /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AAD605E22BB4D10BF3F39DA8 /* AlbertosApp.swift in Sources */,
+ 25E8CB41017E048190FCD053 /* Menu+Dummy.swift in Sources */,
+ C5EE5943ADB1EA4D1CE728EE /* MenuGrouping.swift in Sources */,
+ 09ACA86E7D21F75667DFE0DD /* MenuItem.swift in Sources */,
+ F28A0F3222BF3EAF2CDA01FE /* MenuList.swift in Sources */,
+ 9D334FC1DB465C7F0B3BB3F7 /* MenuSection.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ C099BFE9ACD985A8EDF284EA /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 9CC30446EF46FE0263FC1016 /* Collection+Safe.swift in Sources */,
+ A432A71EDCF4DC54058A564E /* MenuGroupingTests.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ C21F4B58454F5DE5FB4E056C /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B5F9F9D2250AEB2D2EE0494B /* Albertos */;
+ targetProxy = 059BD3039F2CCB1DD9C2B900 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+ 068E7B265A85A0D164E026DA /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CODE_SIGNING_ALLOWED = NO;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.mokacoding.Albertos.AlbertosTests;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Albertos.app/Albertos";
+ };
+ name = Release;
+ };
+ 1D797AB11DACDB9E4B218C54 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CODE_SIGNING_ALLOWED = NO;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.mokacoding.Albertos.AlbertosTests;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Albertos.app/Albertos";
+ };
+ name = Debug;
+ };
+ 60C5F61655CE71EFE9017DDE /* 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_ENABLE_OBJC_WEAK = 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_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ 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;
+ 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;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = iphoneos;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Release;
+ };
+ 924F1451F334BAAEFDFDAD7C /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ INFOPLIST_FILE = Albertos/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.mokacoding.Albertos.Albertos;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+ D6F337C2184F1D0A465FC2BA /* 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_ENABLE_OBJC_WEAK = 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_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ 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;
+ 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 = (
+ "$(inherited)",
+ "DEBUG=1",
+ );
+ 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;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = iphoneos;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Debug;
+ };
+ EC39A2F770A854AABF6204BC /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ INFOPLIST_FILE = Albertos/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.mokacoding.Albertos.Albertos;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 04A0F0432ABD7A4B9292FF90 /* Build configuration list for PBXProject "Albertos" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ D6F337C2184F1D0A465FC2BA /* Debug */,
+ 60C5F61655CE71EFE9017DDE /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Debug;
+ };
+ 15021ED4CD768AB692CDEF6F /* Build configuration list for PBXNativeTarget "Albertos" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ EC39A2F770A854AABF6204BC /* Debug */,
+ 924F1451F334BAAEFDFDAD7C /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Debug;
+ };
+ F6A1BAA7BD8B12026072190E /* Build configuration list for PBXNativeTarget "AlbertosTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1D797AB11DACDB9E4B218C54 /* Debug */,
+ 068E7B265A85A0D164E026DA /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Debug;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = E8B17C8ABC8471E4224D1C39 /* Project object */;
+}
diff --git a/04-tdd-in-the-real-world/1-end/Albertos.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/04-tdd-in-the-real-world/1-end/Albertos.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/04-tdd-in-the-real-world/1-end/Albertos.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/04-tdd-in-the-real-world/1-end/Albertos.xcodeproj/project.xcworkspace/xcuserdata/gio.xcuserdatad/UserInterfaceState.xcuserstate b/04-tdd-in-the-real-world/1-end/Albertos.xcodeproj/project.xcworkspace/xcuserdata/gio.xcuserdatad/UserInterfaceState.xcuserstate
new file mode 100644
index 0000000..34e74e4
Binary files /dev/null and b/04-tdd-in-the-real-world/1-end/Albertos.xcodeproj/project.xcworkspace/xcuserdata/gio.xcuserdatad/UserInterfaceState.xcuserstate differ
diff --git a/04-tdd-in-the-real-world/1-end/Albertos.xcodeproj/xcshareddata/xcschemes/Albertos.xcscheme b/04-tdd-in-the-real-world/1-end/Albertos.xcodeproj/xcshareddata/xcschemes/Albertos.xcscheme
new file mode 100644
index 0000000..625bb4c
--- /dev/null
+++ b/04-tdd-in-the-real-world/1-end/Albertos.xcodeproj/xcshareddata/xcschemes/Albertos.xcscheme
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/04-tdd-in-the-real-world/1-end/Albertos.xcodeproj/xcuserdata/gio.xcuserdatad/xcschemes/xcschememanagement.plist b/04-tdd-in-the-real-world/1-end/Albertos.xcodeproj/xcuserdata/gio.xcuserdatad/xcschemes/xcschememanagement.plist
new file mode 100644
index 0000000..4ed026f
--- /dev/null
+++ b/04-tdd-in-the-real-world/1-end/Albertos.xcodeproj/xcuserdata/gio.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -0,0 +1,14 @@
+
+
+
+
+ SchemeUserState
+
+ Albertos.xcscheme_^#shared#^_
+
+ orderHint
+ 0
+
+
+
+
diff --git a/05-fixtures/.gitignore b/05-fixtures/.gitignore
deleted file mode 100644
index 4640ebb..0000000
--- a/05-fixtures/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.xcodeproj
diff --git a/05-fixtures/0-start/.gitignore b/05-fixtures/0-start/.gitignore
deleted file mode 100644
index 0f22386..0000000
--- a/05-fixtures/0-start/.gitignore
+++ /dev/null
@@ -1,32 +0,0 @@
-#### joe made this: https://goel.io/joe
-
-#####=== Swift ===#####
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# CocoaPods
-#
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
-#
-# Pods/
-
-*.xcodeproj
diff --git a/05-fixtures/1-end/.gitignore b/05-fixtures/1-end/.gitignore
deleted file mode 100644
index 0f22386..0000000
--- a/05-fixtures/1-end/.gitignore
+++ /dev/null
@@ -1,32 +0,0 @@
-#### joe made this: https://goel.io/joe
-
-#####=== Swift ===#####
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# CocoaPods
-#
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
-#
-# Pods/
-
-*.xcodeproj
diff --git a/05-fixtures/1-end/Albertos.xcodeproj/project.xcworkspace/xcuserdata/gio.xcuserdatad/UserInterfaceState.xcuserstate b/05-fixtures/1-end/Albertos.xcodeproj/project.xcworkspace/xcuserdata/gio.xcuserdatad/UserInterfaceState.xcuserstate
new file mode 100644
index 0000000..fa57a87
Binary files /dev/null and b/05-fixtures/1-end/Albertos.xcodeproj/project.xcworkspace/xcuserdata/gio.xcuserdatad/UserInterfaceState.xcuserstate differ
diff --git a/06-testing-static-swiftui-views/.gitignore b/06-testing-static-swiftui-views/.gitignore
deleted file mode 100644
index 4640ebb..0000000
--- a/06-testing-static-swiftui-views/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.xcodeproj
diff --git a/06-testing-static-swiftui-views/0-start/.gitignore b/06-testing-static-swiftui-views/0-start/.gitignore
deleted file mode 100644
index f5ee019..0000000
--- a/06-testing-static-swiftui-views/0-start/.gitignore
+++ /dev/null
@@ -1,31 +0,0 @@
-#### joe made this: https://goel.io/joe
-
-#####=== Swift ===#####
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# CocoaPods
-#
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
-#
-# Pods/
-
diff --git a/06-testing-static-swiftui-views/1-end/.gitignore b/06-testing-static-swiftui-views/1-end/.gitignore
deleted file mode 100644
index f5ee019..0000000
--- a/06-testing-static-swiftui-views/1-end/.gitignore
+++ /dev/null
@@ -1,31 +0,0 @@
-#### joe made this: https://goel.io/joe
-
-#####=== Swift ===#####
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# CocoaPods
-#
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
-#
-# Pods/
-
diff --git a/06-testing-static-swiftui-views/1-end/Albertos.xcodeproj/project.xcworkspace/xcuserdata/gio.xcuserdatad/UserInterfaceState.xcuserstate b/06-testing-static-swiftui-views/1-end/Albertos.xcodeproj/project.xcworkspace/xcuserdata/gio.xcuserdatad/UserInterfaceState.xcuserstate
new file mode 100644
index 0000000..5c0a465
Binary files /dev/null and b/06-testing-static-swiftui-views/1-end/Albertos.xcodeproj/project.xcworkspace/xcuserdata/gio.xcuserdatad/UserInterfaceState.xcuserstate differ
diff --git a/07-testing-dynamic-swiftui-views/.gitignore b/07-testing-dynamic-swiftui-views/.gitignore
deleted file mode 100644
index 4640ebb..0000000
--- a/07-testing-dynamic-swiftui-views/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.xcodeproj
diff --git a/07-testing-dynamic-swiftui-views/0-start/.gitignore b/07-testing-dynamic-swiftui-views/0-start/.gitignore
deleted file mode 100644
index f5ee019..0000000
--- a/07-testing-dynamic-swiftui-views/0-start/.gitignore
+++ /dev/null
@@ -1,31 +0,0 @@
-#### joe made this: https://goel.io/joe
-
-#####=== Swift ===#####
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# CocoaPods
-#
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
-#
-# Pods/
-
diff --git a/07-testing-dynamic-swiftui-views/1-end/.gitignore b/07-testing-dynamic-swiftui-views/1-end/.gitignore
deleted file mode 100644
index f5ee019..0000000
--- a/07-testing-dynamic-swiftui-views/1-end/.gitignore
+++ /dev/null
@@ -1,31 +0,0 @@
-#### joe made this: https://goel.io/joe
-
-#####=== Swift ===#####
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# CocoaPods
-#
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
-#
-# Pods/
-
diff --git a/08-stub/.gitignore b/08-stub/.gitignore
deleted file mode 100644
index 4640ebb..0000000
--- a/08-stub/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.xcodeproj
diff --git a/08-stub/0-start/.gitignore b/08-stub/0-start/.gitignore
deleted file mode 100644
index f5ee019..0000000
--- a/08-stub/0-start/.gitignore
+++ /dev/null
@@ -1,31 +0,0 @@
-#### joe made this: https://goel.io/joe
-
-#####=== Swift ===#####
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# CocoaPods
-#
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
-#
-# Pods/
-
diff --git a/08-stub/1-end/.gitignore b/08-stub/1-end/.gitignore
deleted file mode 100644
index f5ee019..0000000
--- a/08-stub/1-end/.gitignore
+++ /dev/null
@@ -1,31 +0,0 @@
-#### joe made this: https://goel.io/joe
-
-#####=== Swift ===#####
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# CocoaPods
-#
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
-#
-# Pods/
-
diff --git a/09-json-decoding/.gitignore b/09-json-decoding/.gitignore
deleted file mode 100644
index 4640ebb..0000000
--- a/09-json-decoding/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.xcodeproj
diff --git a/09-json-decoding/0-start/.gitignore b/09-json-decoding/0-start/.gitignore
deleted file mode 100644
index f5ee019..0000000
--- a/09-json-decoding/0-start/.gitignore
+++ /dev/null
@@ -1,31 +0,0 @@
-#### joe made this: https://goel.io/joe
-
-#####=== Swift ===#####
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# CocoaPods
-#
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
-#
-# Pods/
-
diff --git a/09-json-decoding/1-end/.gitignore b/09-json-decoding/1-end/.gitignore
deleted file mode 100644
index f5ee019..0000000
--- a/09-json-decoding/1-end/.gitignore
+++ /dev/null
@@ -1,31 +0,0 @@
-#### joe made this: https://goel.io/joe
-
-#####=== Swift ===#####
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# CocoaPods
-#
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
-#
-# Pods/
-
diff --git a/10-networking/.gitignore b/10-networking/.gitignore
deleted file mode 100644
index 4640ebb..0000000
--- a/10-networking/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.xcodeproj
diff --git a/10-networking/0-start/.gitignore b/10-networking/0-start/.gitignore
deleted file mode 100644
index f5ee019..0000000
--- a/10-networking/0-start/.gitignore
+++ /dev/null
@@ -1,31 +0,0 @@
-#### joe made this: https://goel.io/joe
-
-#####=== Swift ===#####
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# CocoaPods
-#
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
-#
-# Pods/
-
diff --git a/10-networking/1-end/.gitignore b/10-networking/1-end/.gitignore
deleted file mode 100644
index f5ee019..0000000
--- a/10-networking/1-end/.gitignore
+++ /dev/null
@@ -1,31 +0,0 @@
-#### joe made this: https://goel.io/joe
-
-#####=== Swift ===#####
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# CocoaPods
-#
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
-#
-# Pods/
-
diff --git a/11-dependency-injection-with-environment-object/.gitignore b/11-dependency-injection-with-environment-object/.gitignore
deleted file mode 100644
index 4640ebb..0000000
--- a/11-dependency-injection-with-environment-object/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.xcodeproj
diff --git a/11-dependency-injection-with-environment-object/0-start/.gitignore b/11-dependency-injection-with-environment-object/0-start/.gitignore
deleted file mode 100644
index f5ee019..0000000
--- a/11-dependency-injection-with-environment-object/0-start/.gitignore
+++ /dev/null
@@ -1,31 +0,0 @@
-#### joe made this: https://goel.io/joe
-
-#####=== Swift ===#####
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# CocoaPods
-#
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
-#
-# Pods/
-
diff --git a/11-dependency-injection-with-environment-object/1-end/.gitignore b/11-dependency-injection-with-environment-object/1-end/.gitignore
deleted file mode 100644
index f5ee019..0000000
--- a/11-dependency-injection-with-environment-object/1-end/.gitignore
+++ /dev/null
@@ -1,31 +0,0 @@
-#### joe made this: https://goel.io/joe
-
-#####=== Swift ===#####
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# CocoaPods
-#
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
-#
-# Pods/
-
diff --git a/12-spy/.gitignore b/12-spy/.gitignore
deleted file mode 100644
index 4640ebb..0000000
--- a/12-spy/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.xcodeproj
diff --git a/12-spy/0-start/.gitignore b/12-spy/0-start/.gitignore
deleted file mode 100644
index f5ee019..0000000
--- a/12-spy/0-start/.gitignore
+++ /dev/null
@@ -1,31 +0,0 @@
-#### joe made this: https://goel.io/joe
-
-#####=== Swift ===#####
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# CocoaPods
-#
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
-#
-# Pods/
-
diff --git a/12-spy/1-end/.gitignore b/12-spy/1-end/.gitignore
deleted file mode 100644
index f5ee019..0000000
--- a/12-spy/1-end/.gitignore
+++ /dev/null
@@ -1,31 +0,0 @@
-#### joe made this: https://goel.io/joe
-
-#####=== Swift ===#####
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# CocoaPods
-#
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
-#
-# Pods/
-
diff --git a/13-testing-view-presentation/.gitignore b/13-testing-view-presentation/.gitignore
deleted file mode 100644
index 4640ebb..0000000
--- a/13-testing-view-presentation/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.xcodeproj
diff --git a/13-testing-view-presentation/0-start/.gitignore b/13-testing-view-presentation/0-start/.gitignore
deleted file mode 100644
index f5ee019..0000000
--- a/13-testing-view-presentation/0-start/.gitignore
+++ /dev/null
@@ -1,31 +0,0 @@
-#### joe made this: https://goel.io/joe
-
-#####=== Swift ===#####
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# CocoaPods
-#
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
-#
-# Pods/
-
diff --git a/13-testing-view-presentation/1-end/.gitignore b/13-testing-view-presentation/1-end/.gitignore
deleted file mode 100644
index f5ee019..0000000
--- a/13-testing-view-presentation/1-end/.gitignore
+++ /dev/null
@@ -1,31 +0,0 @@
-#### joe made this: https://goel.io/joe
-
-#####=== Swift ===#####
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# CocoaPods
-#
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
-#
-# Pods/
-
diff --git a/14-fixing-bugs-and-changing-code/.gitignore b/14-fixing-bugs-and-changing-code/.gitignore
deleted file mode 100644
index 4640ebb..0000000
--- a/14-fixing-bugs-and-changing-code/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.xcodeproj
diff --git a/14-fixing-bugs-and-changing-code/0-start/.gitignore b/14-fixing-bugs-and-changing-code/0-start/.gitignore
deleted file mode 100644
index f5ee019..0000000
--- a/14-fixing-bugs-and-changing-code/0-start/.gitignore
+++ /dev/null
@@ -1,31 +0,0 @@
-#### joe made this: https://goel.io/joe
-
-#####=== Swift ===#####
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# CocoaPods
-#
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
-#
-# Pods/
-
diff --git a/14-fixing-bugs-and-changing-code/1-end/.gitignore b/14-fixing-bugs-and-changing-code/1-end/.gitignore
deleted file mode 100644
index f5ee019..0000000
--- a/14-fixing-bugs-and-changing-code/1-end/.gitignore
+++ /dev/null
@@ -1,31 +0,0 @@
-#### joe made this: https://goel.io/joe
-
-#####=== Swift ===#####
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# CocoaPods
-#
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
-#
-# Pods/
-
diff --git a/15-fake-and-dummy/0-start/.gitignore b/15-fake-and-dummy/0-start/.gitignore
deleted file mode 100644
index 0f22386..0000000
--- a/15-fake-and-dummy/0-start/.gitignore
+++ /dev/null
@@ -1,32 +0,0 @@
-#### joe made this: https://goel.io/joe
-
-#####=== Swift ===#####
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# CocoaPods
-#
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
-#
-# Pods/
-
-*.xcodeproj
diff --git a/15-fake-and-dummy/0-start/Albertos.xcodeproj/project.pbxproj b/15-fake-and-dummy/0-start/Albertos.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..67a907e
--- /dev/null
+++ b/15-fake-and-dummy/0-start/Albertos.xcodeproj/project.pbxproj
@@ -0,0 +1,807 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 54;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 05F9CCF5DBBF99661E2674CD /* TestError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7415549C09C4274D8CCFCC77 /* TestError.swift */; };
+ 09ACA86E7D21F75667DFE0DD /* MenuItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E51B5F284ED8D04D444E045A /* MenuItem.swift */; };
+ 13387CFB26245EF8240C7A98 /* Order.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA8381D5EC52AEE8AD62901C /* Order.swift */; };
+ 142E55512BCC01F76E6619BE /* OrderDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2F6ABED8B7DE5C3B2201BFE /* OrderDetail.swift */; };
+ 191B255739C03540FAC7AED9 /* HippoAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = A1C7645975C081584B83D893 /* HippoAnalytics */; };
+ 226EEC8949476F310DD280D6 /* MenuItemDetail.ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DACB11387FDF655295A1EF5D /* MenuItemDetail.ViewModel.swift */; };
+ 24D42A189DD7783620BA9E71 /* MenuItem+Fixture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44F03178E9C863DACBC1814D /* MenuItem+Fixture.swift */; };
+ 25094AC33CCA4B5C9C22191F /* MenuFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA4292931534001B9214FC05 /* MenuFetcher.swift */; };
+ 2AA2150DDE3809E58743BD24 /* Order+HippoPayments.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EEB98A8D526FF61E06E97BE /* Order+HippoPayments.swift */; };
+ 2F918E0E8AD9FA1C52728236 /* URLSession+NetworkFetching.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CAC3002AC30D0DF4E5423A /* URLSession+NetworkFetching.swift */; };
+ 306A3E4B181122000CE510B5 /* HippoPayments in Frameworks */ = {isa = PBXBuildFile; productRef = E4DA341A663094C9B76ED975 /* HippoPayments */; };
+ 3E7AAFE5A8859BD805675B9A /* menu_item.json in Resources */ = {isa = PBXBuildFile; fileRef = D2424D0270A102DE67834630 /* menu_item.json */; };
+ 417B645EA8ABA9FD43A555DB /* OrderDetail.ViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0AAF8C46351787636819C4A /* OrderDetail.ViewModelTests.swift */; };
+ 418E360A5081788F4DCCEFB3 /* MenuRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCF95E9CB8962AFFF16D3FB9 /* MenuRow.swift */; };
+ 4EA49FA5AF515BE2921D520C /* MenuList.ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD4253D513637E0AAE27D6CF /* MenuList.ViewModel.swift */; };
+ 5354C38AA669CF9AF2973EA1 /* PaymentProcessingSpy.swift in Sources */ = {isa = PBXBuildFile; fileRef = D738530778704B5210E4A047 /* PaymentProcessingSpy.swift */; };
+ 5725BB9CC15E6A1FB9049F96 /* MenuItemTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0468A7C221FFC8B3BF0FA860 /* MenuItemTests.swift */; };
+ 5FF1F997B94105D2F8EE0162 /* MenuItemDetail.ViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 249B815756D66665262AEC0B /* MenuItemDetail.ViewModelTests.swift */; };
+ 649034BA985AB6A4C370FC4D /* MenuList.ViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59517D51C93F603F806005F5 /* MenuList.ViewModelTests.swift */; };
+ 6DA8821E769C21FD671732D3 /* PaymentProcessing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09723CD3E04C59D8931C539A /* PaymentProcessing.swift */; };
+ 780C4AC5BA073670CDF0C802 /* Color+Custom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23FAD24A78C9DA66DB9AF326 /* Color+Custom.swift */; };
+ 7C8488112F6CE8FD02FAD6E2 /* NetworkFetching.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9607928D2AE1C03FAC536A7A /* NetworkFetching.swift */; };
+ 7F479ECCACF640E0803676C3 /* MenuSection+Fixture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E930A2AB025AD0FBFFD28F6 /* MenuSection+Fixture.swift */; };
+ 82A227C7A37E3AD03FB346CD /* NetworkFetchingStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0904894B8407027E56A5C8C7 /* NetworkFetchingStub.swift */; };
+ 8CCEF233827037043C3CE766 /* Alert.ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F33AFCF39D65227624637B /* Alert.ViewModel.swift */; };
+ 9236A4B1D0CC219B8F23CBB1 /* OrderController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3B4BF35CD95A0E4AB3A54A3 /* OrderController.swift */; };
+ 933814BD4D1718D1ED9F669E /* MenuItemDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB25E45EE54DF3CD4374444F /* MenuItemDetail.swift */; };
+ 9CC30446EF46FE0263FC1016 /* Collection+Safe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AB92569F1F7C921D2EEAF36 /* Collection+Safe.swift */; };
+ 9D334FC1DB465C7F0B3BB3F7 /* MenuSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED56EEE9C2A95C8D940BE49B /* MenuSection.swift */; };
+ A140E52779DF1652541302F3 /* XCTestCase+Timeouts.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC4A09108CE16DBEA1BDC308 /* XCTestCase+Timeouts.swift */; };
+ A17BE57B0365DC289250E618 /* OrderButtonViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC5570E9468FD135453788B /* OrderButtonViewModelTests.swift */; };
+ A432A71EDCF4DC54058A564E /* MenuGroupingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E8BD1E021C1238B66D6697D /* MenuGroupingTests.swift */; };
+ A7D49EF97B36875A6B0215F8 /* MenuRow.ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FADB2F629C4815BE8ACA7FA7 /* MenuRow.ViewModel.swift */; };
+ A804D47930989A18364D1947 /* OrderControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B03E53B8DB9C8D11A3D01AA /* OrderControllerTests.swift */; };
+ AAD605E22BB4D10BF3F39DA8 /* AlbertosApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = E231812A9BEA82FE13B6DDE3 /* AlbertosApp.swift */; };
+ B3F8BD304D4C17EFD37A3F45 /* OrderDetail.ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EF87C1C7736BAD96EF36D48 /* OrderDetail.ViewModel.swift */; };
+ B4E3F2714E137147C9853A22 /* MenuRow.ViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 183E499D41745D441197920F /* MenuRow.ViewModelTests.swift */; };
+ BAB9DEE0C2BC90EA6E785B1F /* PaymentProcessingProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2131B9C900C82687F26D7897 /* PaymentProcessingProxy.swift */; };
+ C5EE5943ADB1EA4D1CE728EE /* MenuGrouping.swift in Sources */ = {isa = PBXBuildFile; fileRef = F89281C54BD39EEAB6CD33A7 /* MenuGrouping.swift */; };
+ D33843A1F41E697E457450B0 /* MenuItem+JSONFixture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EA77FDE9A4729980574BE69 /* MenuItem+JSONFixture.swift */; };
+ D8B61B7ADE287BC0654C8FBA /* PaymentProcessingStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 896FE3F619AFADE5CA8AE7AD /* PaymentProcessingStub.swift */; };
+ DAB59D18F337A03FFD259E0D /* MenuItemAlternateJSONTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D067494480000423A7D3541 /* MenuItemAlternateJSONTests.swift */; };
+ DDD52EC5E0B3BD1387E23A84 /* OrderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0475EBBA92E1E7795EB38A94 /* OrderTests.swift */; };
+ E55D459EF4C1A10CA14B2EDA /* MenuFetchingStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBDF4DFEF1B2F09792BA6D00 /* MenuFetchingStub.swift */; };
+ E5CB4631359F984486744922 /* MenuFetcherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15393DB4B0DD911EA59F80B4 /* MenuFetcherTests.swift */; };
+ EB1718A2B7AEA1093BB6A61F /* HippoPaymentsProcessor+PaymentProcessing.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB1DE85828E344BA72C97E96 /* HippoPaymentsProcessor+PaymentProcessing.swift */; };
+ F28A0F3222BF3EAF2CDA01FE /* MenuList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38E678AF65BE5E3636E405C7 /* MenuList.swift */; };
+ F7EC63727BB23F3A58EEF9B4 /* OrderButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8D8E9C4F9C83E8473793F47 /* OrderButton.swift */; };
+ FB761F5059AB45B17E2DF213 /* XCTestCase+JSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A1553886918E52BC11CC3DC /* XCTestCase+JSON.swift */; };
+ FD786266CA046DB84D08178E /* OrderButton.ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FA55EAF42B38DA7CE36726 /* OrderButton.ViewModel.swift */; };
+ FF7E3946FA9D5B74CBF5D8C2 /* MenuFetching.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C29236D8792EE571561C6C1 /* MenuFetching.swift */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 059BD3039F2CCB1DD9C2B900 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = E8B17C8ABC8471E4224D1C39 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B5F9F9D2250AEB2D2EE0494B;
+ remoteInfo = Albertos;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ 0468A7C221FFC8B3BF0FA860 /* MenuItemTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItemTests.swift; sourceTree = ""; };
+ 0475EBBA92E1E7795EB38A94 /* OrderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderTests.swift; sourceTree = ""; };
+ 0904894B8407027E56A5C8C7 /* NetworkFetchingStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkFetchingStub.swift; sourceTree = ""; };
+ 09723CD3E04C59D8931C539A /* PaymentProcessing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentProcessing.swift; sourceTree = ""; };
+ 0E930A2AB025AD0FBFFD28F6 /* MenuSection+Fixture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MenuSection+Fixture.swift"; sourceTree = ""; };
+ 15393DB4B0DD911EA59F80B4 /* MenuFetcherTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuFetcherTests.swift; sourceTree = ""; };
+ 183E499D41745D441197920F /* MenuRow.ViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuRow.ViewModelTests.swift; sourceTree = ""; };
+ 2131B9C900C82687F26D7897 /* PaymentProcessingProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentProcessingProxy.swift; sourceTree = ""; };
+ 23FAD24A78C9DA66DB9AF326 /* Color+Custom.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+Custom.swift"; sourceTree = ""; };
+ 249B815756D66665262AEC0B /* MenuItemDetail.ViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItemDetail.ViewModelTests.swift; sourceTree = ""; };
+ 2C29236D8792EE571561C6C1 /* MenuFetching.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuFetching.swift; sourceTree = ""; };
+ 2EEB98A8D526FF61E06E97BE /* Order+HippoPayments.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Order+HippoPayments.swift"; sourceTree = ""; };
+ 38E678AF65BE5E3636E405C7 /* MenuList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuList.swift; sourceTree = ""; };
+ 3EA77FDE9A4729980574BE69 /* MenuItem+JSONFixture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MenuItem+JSONFixture.swift"; sourceTree = ""; };
+ 44F03178E9C863DACBC1814D /* MenuItem+Fixture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MenuItem+Fixture.swift"; sourceTree = ""; };
+ 59517D51C93F603F806005F5 /* MenuList.ViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuList.ViewModelTests.swift; sourceTree = ""; };
+ 6AB92569F1F7C921D2EEAF36 /* Collection+Safe.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Collection+Safe.swift"; sourceTree = ""; };
+ 6B03E53B8DB9C8D11A3D01AA /* OrderControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderControllerTests.swift; sourceTree = ""; };
+ 72CC3E84F3456ED561DBFCAB /* HippoAnalytics */ = {isa = PBXFileReference; lastKnownFileType = folder; name = HippoAnalytics; path = ../../Packages/HippoAnalytics; sourceTree = SOURCE_ROOT; };
+ 7415549C09C4274D8CCFCC77 /* TestError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestError.swift; sourceTree = ""; };
+ 7A1553886918E52BC11CC3DC /* XCTestCase+JSON.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "XCTestCase+JSON.swift"; sourceTree = ""; };
+ 7D067494480000423A7D3541 /* MenuItemAlternateJSONTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItemAlternateJSONTests.swift; sourceTree = ""; };
+ 7D5D23DD07D469C771E0CCD7 /* HippoPayments */ = {isa = PBXFileReference; lastKnownFileType = folder; name = HippoPayments; path = ../../Packages/HippoPayments; sourceTree = SOURCE_ROOT; };
+ 7EF87C1C7736BAD96EF36D48 /* OrderDetail.ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderDetail.ViewModel.swift; sourceTree = ""; };
+ 823EEDCB67B487000A05DB62 /* Albertos.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = Albertos.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 83FA55EAF42B38DA7CE36726 /* OrderButton.ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderButton.ViewModel.swift; sourceTree = ""; };
+ 896FE3F619AFADE5CA8AE7AD /* PaymentProcessingStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentProcessingStub.swift; sourceTree = ""; };
+ 9607928D2AE1C03FAC536A7A /* NetworkFetching.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkFetching.swift; sourceTree = ""; };
+ 9E8BD1E021C1238B66D6697D /* MenuGroupingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuGroupingTests.swift; sourceTree = ""; };
+ A5CAC3002AC30D0DF4E5423A /* URLSession+NetworkFetching.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URLSession+NetworkFetching.swift"; sourceTree = ""; };
+ AB25E45EE54DF3CD4374444F /* MenuItemDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItemDetail.swift; sourceTree = ""; };
+ B0AAF8C46351787636819C4A /* OrderDetail.ViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderDetail.ViewModelTests.swift; sourceTree = ""; };
+ BBDF4DFEF1B2F09792BA6D00 /* MenuFetchingStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuFetchingStub.swift; sourceTree = ""; };
+ BCF95E9CB8962AFFF16D3FB9 /* MenuRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuRow.swift; sourceTree = ""; };
+ BD4253D513637E0AAE27D6CF /* MenuList.ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuList.ViewModel.swift; sourceTree = ""; };
+ BDF4B76EC90E0DB5458F8146 /* AlbertosTests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = AlbertosTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ CC4A09108CE16DBEA1BDC308 /* XCTestCase+Timeouts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "XCTestCase+Timeouts.swift"; sourceTree = ""; };
+ CEC5570E9468FD135453788B /* OrderButtonViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderButtonViewModelTests.swift; sourceTree = ""; };
+ D2424D0270A102DE67834630 /* menu_item.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = menu_item.json; sourceTree = ""; };
+ D3B4BF35CD95A0E4AB3A54A3 /* OrderController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderController.swift; sourceTree = ""; };
+ D738530778704B5210E4A047 /* PaymentProcessingSpy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentProcessingSpy.swift; sourceTree = ""; };
+ D7F33AFCF39D65227624637B /* Alert.ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Alert.ViewModel.swift; sourceTree = ""; };
+ DACB11387FDF655295A1EF5D /* MenuItemDetail.ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItemDetail.ViewModel.swift; sourceTree = ""; };
+ E231812A9BEA82FE13B6DDE3 /* AlbertosApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbertosApp.swift; sourceTree = ""; };
+ E2F6ABED8B7DE5C3B2201BFE /* OrderDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderDetail.swift; sourceTree = ""; };
+ E51B5F284ED8D04D444E045A /* MenuItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItem.swift; sourceTree = ""; };
+ E5C5903BDB22A99A4B3DC3C8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; };
+ E8D8E9C4F9C83E8473793F47 /* OrderButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderButton.swift; sourceTree = ""; };
+ ED56EEE9C2A95C8D940BE49B /* MenuSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuSection.swift; sourceTree = ""; };
+ F89281C54BD39EEAB6CD33A7 /* MenuGrouping.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuGrouping.swift; sourceTree = ""; };
+ FA4292931534001B9214FC05 /* MenuFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuFetcher.swift; sourceTree = ""; };
+ FA8381D5EC52AEE8AD62901C /* Order.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Order.swift; sourceTree = ""; };
+ FADB2F629C4815BE8ACA7FA7 /* MenuRow.ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuRow.ViewModel.swift; sourceTree = ""; };
+ FB1DE85828E344BA72C97E96 /* HippoPaymentsProcessor+PaymentProcessing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HippoPaymentsProcessor+PaymentProcessing.swift"; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 976EEC1F85DA654336D7815E /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 306A3E4B181122000CE510B5 /* HippoPayments in Frameworks */,
+ 191B255739C03540FAC7AED9 /* HippoAnalytics in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 0560AD3424758048A3A433C9 /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ BD4253D513637E0AAE27D6CF /* MenuList.ViewModel.swift */,
+ );
+ name = Albertos;
+ path = "../../08-stub/1-end/Albertos";
+ sourceTree = "";
+ };
+ 0BB75D973EA16C8867DCD068 /* AlbertosTests */ = {
+ isa = PBXGroup;
+ children = (
+ 249B815756D66665262AEC0B /* MenuItemDetail.ViewModelTests.swift */,
+ );
+ name = AlbertosTests;
+ path = "../../11-dependency-injection-with-environment-object/1-end/AlbertosTests";
+ sourceTree = "";
+ };
+ 1089370477C43CD0924C27EA /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ E51B5F284ED8D04D444E045A /* MenuItem.swift */,
+ );
+ name = Albertos;
+ path = "../../09-json-decoding/1-end/Albertos";
+ sourceTree = "";
+ };
+ 115342909CD1A0EAF4A3125B /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ 23FAD24A78C9DA66DB9AF326 /* Color+Custom.swift */,
+ );
+ name = Albertos;
+ path = "../../11-dependency-injection-with-environment-object/0-start/Albertos";
+ sourceTree = "";
+ };
+ 18550B0B0155037E0CA4A33D /* AlbertosTests */ = {
+ isa = PBXGroup;
+ children = (
+ 896FE3F619AFADE5CA8AE7AD /* PaymentProcessingStub.swift */,
+ CC4A09108CE16DBEA1BDC308 /* XCTestCase+Timeouts.swift */,
+ );
+ name = AlbertosTests;
+ path = "../../13-testing-view-presentation/1-end/AlbertosTests";
+ sourceTree = "";
+ };
+ 23ACB16B0E88DB238D562E90 /* AlbertosTests */ = {
+ isa = PBXGroup;
+ children = (
+ 6B03E53B8DB9C8D11A3D01AA /* OrderControllerTests.swift */,
+ );
+ name = AlbertosTests;
+ path = "../../11-dependency-injection-with-environment-object/0-start/AlbertosTests";
+ sourceTree = "";
+ };
+ 5A34B853AF420876FC374AE1 /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ AB25E45EE54DF3CD4374444F /* MenuItemDetail.swift */,
+ DACB11387FDF655295A1EF5D /* MenuItemDetail.ViewModel.swift */,
+ 38E678AF65BE5E3636E405C7 /* MenuList.swift */,
+ );
+ name = Albertos;
+ path = "../../11-dependency-injection-with-environment-object/1-end/Albertos";
+ sourceTree = "";
+ };
+ 5AA9638FB37A04075FDB6BBF /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ 83FA55EAF42B38DA7CE36726 /* OrderButton.ViewModel.swift */,
+ );
+ name = Albertos;
+ path = "../../12-spy/0-start/Albertos";
+ sourceTree = "";
+ };
+ 610DFD9158304B0567C4C959 /* AlbertosTests */ = {
+ isa = PBXGroup;
+ children = (
+ BBDF4DFEF1B2F09792BA6D00 /* MenuFetchingStub.swift */,
+ 7415549C09C4274D8CCFCC77 /* TestError.swift */,
+ );
+ name = AlbertosTests;
+ path = "../../08-stub/1-end/AlbertosTests";
+ sourceTree = "";
+ };
+ 623D63D3705EE89055A94C12 /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ 2C29236D8792EE571561C6C1 /* MenuFetching.swift */,
+ );
+ name = Albertos;
+ path = "../../07-testing-dynamic-swiftui-views/1-end/Albertos";
+ sourceTree = "";
+ };
+ 6587589555E08BBEB63089E1 /* Sources */ = {
+ isa = PBXGroup;
+ children = (
+ 6AB92569F1F7C921D2EEAF36 /* Collection+Safe.swift */,
+ );
+ name = Sources;
+ path = ../../Packages/CollectionSafe/Sources;
+ sourceTree = "";
+ };
+ 802824DAE2FE5EA864A24B56 /* AlbertosTests */ = {
+ isa = PBXGroup;
+ children = (
+ 15393DB4B0DD911EA59F80B4 /* MenuFetcherTests.swift */,
+ 59517D51C93F603F806005F5 /* MenuList.ViewModelTests.swift */,
+ 0904894B8407027E56A5C8C7 /* NetworkFetchingStub.swift */,
+ );
+ name = AlbertosTests;
+ path = "../../10-networking/1-end/AlbertosTests";
+ sourceTree = "";
+ };
+ 814F0849D627BA240B0F8D84 /* AlbertosTests */ = {
+ isa = PBXGroup;
+ children = (
+ 0475EBBA92E1E7795EB38A94 /* OrderTests.swift */,
+ D738530778704B5210E4A047 /* PaymentProcessingSpy.swift */,
+ );
+ name = AlbertosTests;
+ path = "../../12-spy/1-end/AlbertosTests";
+ sourceTree = "";
+ };
+ 8B609BB40A5421BBA31F3D3B /* AlbertosTests */ = {
+ isa = PBXGroup;
+ children = (
+ 9E8BD1E021C1238B66D6697D /* MenuGroupingTests.swift */,
+ 44F03178E9C863DACBC1814D /* MenuItem+Fixture.swift */,
+ 0E930A2AB025AD0FBFFD28F6 /* MenuSection+Fixture.swift */,
+ );
+ name = AlbertosTests;
+ path = "../../06-testing-static-swiftui-views/1-end/AlbertosTests";
+ sourceTree = "";
+ };
+ 8D972551E420DEE0F670E89F /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ F89281C54BD39EEAB6CD33A7 /* MenuGrouping.swift */,
+ );
+ name = Albertos;
+ path = "../../04-tdd-in-the-real-world/1-end/Albertos";
+ sourceTree = "";
+ };
+ 92B90574F9FA63884D9D7BBF = {
+ isa = PBXGroup;
+ children = (
+ 8D972551E420DEE0F670E89F /* Albertos */,
+ D9B63447692F960F19829F9B /* Albertos */,
+ 623D63D3705EE89055A94C12 /* Albertos */,
+ 0560AD3424758048A3A433C9 /* Albertos */,
+ 1089370477C43CD0924C27EA /* Albertos */,
+ DD3B74CA50EB6E5F084850EF /* Albertos */,
+ 115342909CD1A0EAF4A3125B /* Albertos */,
+ 5A34B853AF420876FC374AE1 /* Albertos */,
+ 5AA9638FB37A04075FDB6BBF /* Albertos */,
+ C8FA1DB4707A86998BDD3F99 /* Albertos */,
+ B95C2AEA9DF45D24D635ACED /* Albertos */,
+ E8AB92E07081D049054B3882 /* Albertos */,
+ 8B609BB40A5421BBA31F3D3B /* AlbertosTests */,
+ 610DFD9158304B0567C4C959 /* AlbertosTests */,
+ DB59F414D6282A4AE9C2F693 /* AlbertosTests */,
+ 802824DAE2FE5EA864A24B56 /* AlbertosTests */,
+ 23ACB16B0E88DB238D562E90 /* AlbertosTests */,
+ 0BB75D973EA16C8867DCD068 /* AlbertosTests */,
+ CDFD277F86A3D3C05F8490C5 /* AlbertosTests */,
+ 814F0849D627BA240B0F8D84 /* AlbertosTests */,
+ 18550B0B0155037E0CA4A33D /* AlbertosTests */,
+ F7E9F479AC9C201D2C8ABE24 /* AlbertosTests */,
+ D298843BDFC7FEE66A144DE6 /* Packages */,
+ 6587589555E08BBEB63089E1 /* Sources */,
+ A0D81A2A2581F3DF42D52538 /* Products */,
+ );
+ sourceTree = "";
+ };
+ A0D81A2A2581F3DF42D52538 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 823EEDCB67B487000A05DB62 /* Albertos.app */,
+ BDF4B76EC90E0DB5458F8146 /* AlbertosTests.xctest */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ B95C2AEA9DF45D24D635ACED /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ D7F33AFCF39D65227624637B /* Alert.ViewModel.swift */,
+ E8D8E9C4F9C83E8473793F47 /* OrderButton.swift */,
+ E2F6ABED8B7DE5C3B2201BFE /* OrderDetail.swift */,
+ );
+ name = Albertos;
+ path = "../../13-testing-view-presentation/1-end/Albertos";
+ sourceTree = "";
+ };
+ C8FA1DB4707A86998BDD3F99 /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ E231812A9BEA82FE13B6DDE3 /* AlbertosApp.swift */,
+ FB1DE85828E344BA72C97E96 /* HippoPaymentsProcessor+PaymentProcessing.swift */,
+ FA8381D5EC52AEE8AD62901C /* Order.swift */,
+ 2EEB98A8D526FF61E06E97BE /* Order+HippoPayments.swift */,
+ 09723CD3E04C59D8931C539A /* PaymentProcessing.swift */,
+ 2131B9C900C82687F26D7897 /* PaymentProcessingProxy.swift */,
+ );
+ name = Albertos;
+ path = "../../12-spy/1-end/Albertos";
+ sourceTree = "";
+ };
+ CDFD277F86A3D3C05F8490C5 /* AlbertosTests */ = {
+ isa = PBXGroup;
+ children = (
+ CEC5570E9468FD135453788B /* OrderButtonViewModelTests.swift */,
+ );
+ name = AlbertosTests;
+ path = "../../12-spy/0-start/AlbertosTests";
+ sourceTree = "";
+ };
+ D298843BDFC7FEE66A144DE6 /* Packages */ = {
+ isa = PBXGroup;
+ children = (
+ 72CC3E84F3456ED561DBFCAB /* HippoAnalytics */,
+ 7D5D23DD07D469C771E0CCD7 /* HippoPayments */,
+ );
+ name = Packages;
+ sourceTree = "";
+ };
+ D9B63447692F960F19829F9B /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ BCF95E9CB8962AFFF16D3FB9 /* MenuRow.swift */,
+ ED56EEE9C2A95C8D940BE49B /* MenuSection.swift */,
+ );
+ name = Albertos;
+ path = "../../06-testing-static-swiftui-views/1-end/Albertos";
+ sourceTree = "";
+ };
+ DB59F414D6282A4AE9C2F693 /* AlbertosTests */ = {
+ isa = PBXGroup;
+ children = (
+ D2424D0270A102DE67834630 /* menu_item.json */,
+ 3EA77FDE9A4729980574BE69 /* MenuItem+JSONFixture.swift */,
+ 7D067494480000423A7D3541 /* MenuItemAlternateJSONTests.swift */,
+ 0468A7C221FFC8B3BF0FA860 /* MenuItemTests.swift */,
+ 7A1553886918E52BC11CC3DC /* XCTestCase+JSON.swift */,
+ );
+ name = AlbertosTests;
+ path = "../../09-json-decoding/1-end/AlbertosTests";
+ sourceTree = "";
+ };
+ DD3B74CA50EB6E5F084850EF /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ FA4292931534001B9214FC05 /* MenuFetcher.swift */,
+ 9607928D2AE1C03FAC536A7A /* NetworkFetching.swift */,
+ A5CAC3002AC30D0DF4E5423A /* URLSession+NetworkFetching.swift */,
+ );
+ name = Albertos;
+ path = "../../10-networking/1-end/Albertos";
+ sourceTree = "";
+ };
+ E8AB92E07081D049054B3882 /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ E5C5903BDB22A99A4B3DC3C8 /* Info.plist */,
+ FADB2F629C4815BE8ACA7FA7 /* MenuRow.ViewModel.swift */,
+ D3B4BF35CD95A0E4AB3A54A3 /* OrderController.swift */,
+ 7EF87C1C7736BAD96EF36D48 /* OrderDetail.ViewModel.swift */,
+ );
+ name = Albertos;
+ path = "../../14-fixing-bugs-and-changing-code/1-end/Albertos";
+ sourceTree = "";
+ };
+ F7E9F479AC9C201D2C8ABE24 /* AlbertosTests */ = {
+ isa = PBXGroup;
+ children = (
+ 183E499D41745D441197920F /* MenuRow.ViewModelTests.swift */,
+ B0AAF8C46351787636819C4A /* OrderDetail.ViewModelTests.swift */,
+ );
+ name = AlbertosTests;
+ path = "../../14-fixing-bugs-and-changing-code/1-end/AlbertosTests";
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 33D869CEA8CD44DF60039E52 /* AlbertosTests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = F6A1BAA7BD8B12026072190E /* Build configuration list for PBXNativeTarget "AlbertosTests" */;
+ buildPhases = (
+ C099BFE9ACD985A8EDF284EA /* Sources */,
+ 4D9ABFE10A474D5655D092BE /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ C21F4B58454F5DE5FB4E056C /* PBXTargetDependency */,
+ );
+ name = AlbertosTests;
+ productName = AlbertosTests;
+ productReference = BDF4B76EC90E0DB5458F8146 /* AlbertosTests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+ B5F9F9D2250AEB2D2EE0494B /* Albertos */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 15021ED4CD768AB692CDEF6F /* Build configuration list for PBXNativeTarget "Albertos" */;
+ buildPhases = (
+ 2B3D01A98BE73618C91FF57C /* Sources */,
+ 976EEC1F85DA654336D7815E /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = Albertos;
+ packageProductDependencies = (
+ E4DA341A663094C9B76ED975 /* HippoPayments */,
+ A1C7645975C081584B83D893 /* HippoAnalytics */,
+ );
+ productName = Albertos;
+ productReference = 823EEDCB67B487000A05DB62 /* Albertos.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ E8B17C8ABC8471E4224D1C39 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ BuildIndependentTargetsInParallel = YES;
+ LastUpgradeCheck = 1430;
+ TargetAttributes = {
+ };
+ };
+ buildConfigurationList = 04A0F0432ABD7A4B9292FF90 /* Build configuration list for PBXProject "Albertos" */;
+ compatibilityVersion = "Xcode 14.0";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ Base,
+ en,
+ );
+ mainGroup = 92B90574F9FA63884D9D7BBF;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ B5F9F9D2250AEB2D2EE0494B /* Albertos */,
+ 33D869CEA8CD44DF60039E52 /* AlbertosTests */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 4D9ABFE10A474D5655D092BE /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 3E7AAFE5A8859BD805675B9A /* menu_item.json in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 2B3D01A98BE73618C91FF57C /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AAD605E22BB4D10BF3F39DA8 /* AlbertosApp.swift in Sources */,
+ 8CCEF233827037043C3CE766 /* Alert.ViewModel.swift in Sources */,
+ 780C4AC5BA073670CDF0C802 /* Color+Custom.swift in Sources */,
+ EB1718A2B7AEA1093BB6A61F /* HippoPaymentsProcessor+PaymentProcessing.swift in Sources */,
+ 25094AC33CCA4B5C9C22191F /* MenuFetcher.swift in Sources */,
+ FF7E3946FA9D5B74CBF5D8C2 /* MenuFetching.swift in Sources */,
+ C5EE5943ADB1EA4D1CE728EE /* MenuGrouping.swift in Sources */,
+ 09ACA86E7D21F75667DFE0DD /* MenuItem.swift in Sources */,
+ 226EEC8949476F310DD280D6 /* MenuItemDetail.ViewModel.swift in Sources */,
+ 933814BD4D1718D1ED9F669E /* MenuItemDetail.swift in Sources */,
+ 4EA49FA5AF515BE2921D520C /* MenuList.ViewModel.swift in Sources */,
+ F28A0F3222BF3EAF2CDA01FE /* MenuList.swift in Sources */,
+ A7D49EF97B36875A6B0215F8 /* MenuRow.ViewModel.swift in Sources */,
+ 418E360A5081788F4DCCEFB3 /* MenuRow.swift in Sources */,
+ 9D334FC1DB465C7F0B3BB3F7 /* MenuSection.swift in Sources */,
+ 7C8488112F6CE8FD02FAD6E2 /* NetworkFetching.swift in Sources */,
+ 2AA2150DDE3809E58743BD24 /* Order+HippoPayments.swift in Sources */,
+ 13387CFB26245EF8240C7A98 /* Order.swift in Sources */,
+ FD786266CA046DB84D08178E /* OrderButton.ViewModel.swift in Sources */,
+ F7EC63727BB23F3A58EEF9B4 /* OrderButton.swift in Sources */,
+ 9236A4B1D0CC219B8F23CBB1 /* OrderController.swift in Sources */,
+ B3F8BD304D4C17EFD37A3F45 /* OrderDetail.ViewModel.swift in Sources */,
+ 142E55512BCC01F76E6619BE /* OrderDetail.swift in Sources */,
+ 6DA8821E769C21FD671732D3 /* PaymentProcessing.swift in Sources */,
+ BAB9DEE0C2BC90EA6E785B1F /* PaymentProcessingProxy.swift in Sources */,
+ 2F918E0E8AD9FA1C52728236 /* URLSession+NetworkFetching.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ C099BFE9ACD985A8EDF284EA /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 9CC30446EF46FE0263FC1016 /* Collection+Safe.swift in Sources */,
+ E5CB4631359F984486744922 /* MenuFetcherTests.swift in Sources */,
+ E55D459EF4C1A10CA14B2EDA /* MenuFetchingStub.swift in Sources */,
+ A432A71EDCF4DC54058A564E /* MenuGroupingTests.swift in Sources */,
+ 24D42A189DD7783620BA9E71 /* MenuItem+Fixture.swift in Sources */,
+ D33843A1F41E697E457450B0 /* MenuItem+JSONFixture.swift in Sources */,
+ DAB59D18F337A03FFD259E0D /* MenuItemAlternateJSONTests.swift in Sources */,
+ 5FF1F997B94105D2F8EE0162 /* MenuItemDetail.ViewModelTests.swift in Sources */,
+ 5725BB9CC15E6A1FB9049F96 /* MenuItemTests.swift in Sources */,
+ 649034BA985AB6A4C370FC4D /* MenuList.ViewModelTests.swift in Sources */,
+ B4E3F2714E137147C9853A22 /* MenuRow.ViewModelTests.swift in Sources */,
+ 7F479ECCACF640E0803676C3 /* MenuSection+Fixture.swift in Sources */,
+ 82A227C7A37E3AD03FB346CD /* NetworkFetchingStub.swift in Sources */,
+ A17BE57B0365DC289250E618 /* OrderButtonViewModelTests.swift in Sources */,
+ A804D47930989A18364D1947 /* OrderControllerTests.swift in Sources */,
+ 417B645EA8ABA9FD43A555DB /* OrderDetail.ViewModelTests.swift in Sources */,
+ DDD52EC5E0B3BD1387E23A84 /* OrderTests.swift in Sources */,
+ 5354C38AA669CF9AF2973EA1 /* PaymentProcessingSpy.swift in Sources */,
+ D8B61B7ADE287BC0654C8FBA /* PaymentProcessingStub.swift in Sources */,
+ 05F9CCF5DBBF99661E2674CD /* TestError.swift in Sources */,
+ FB761F5059AB45B17E2DF213 /* XCTestCase+JSON.swift in Sources */,
+ A140E52779DF1652541302F3 /* XCTestCase+Timeouts.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ C21F4B58454F5DE5FB4E056C /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B5F9F9D2250AEB2D2EE0494B /* Albertos */;
+ targetProxy = 059BD3039F2CCB1DD9C2B900 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+ 068E7B265A85A0D164E026DA /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CODE_SIGNING_ALLOWED = NO;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.mokacoding.Albertos.AlbertosTests;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Albertos.app/Albertos";
+ };
+ name = Release;
+ };
+ 1D797AB11DACDB9E4B218C54 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CODE_SIGNING_ALLOWED = NO;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.mokacoding.Albertos.AlbertosTests;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Albertos.app/Albertos";
+ };
+ name = Debug;
+ };
+ 60C5F61655CE71EFE9017DDE /* 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_ENABLE_OBJC_WEAK = 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_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ 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;
+ 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;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = iphoneos;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Release;
+ };
+ 924F1451F334BAAEFDFDAD7C /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ INFOPLIST_FILE = "../../14-fixing-bugs-and-changing-code/1-end/Albertos/Info.plist";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.mokacoding.Albertos.Albertos;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+ D6F337C2184F1D0A465FC2BA /* 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_ENABLE_OBJC_WEAK = 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_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ 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;
+ 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 = (
+ "$(inherited)",
+ "DEBUG=1",
+ );
+ 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;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = iphoneos;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Debug;
+ };
+ EC39A2F770A854AABF6204BC /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ INFOPLIST_FILE = "../../14-fixing-bugs-and-changing-code/1-end/Albertos/Info.plist";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.mokacoding.Albertos.Albertos;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 04A0F0432ABD7A4B9292FF90 /* Build configuration list for PBXProject "Albertos" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ D6F337C2184F1D0A465FC2BA /* Debug */,
+ 60C5F61655CE71EFE9017DDE /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Debug;
+ };
+ 15021ED4CD768AB692CDEF6F /* Build configuration list for PBXNativeTarget "Albertos" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ EC39A2F770A854AABF6204BC /* Debug */,
+ 924F1451F334BAAEFDFDAD7C /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Debug;
+ };
+ F6A1BAA7BD8B12026072190E /* Build configuration list for PBXNativeTarget "AlbertosTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1D797AB11DACDB9E4B218C54 /* Debug */,
+ 068E7B265A85A0D164E026DA /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Debug;
+ };
+/* End XCConfigurationList section */
+
+/* Begin XCSwiftPackageProductDependency section */
+ A1C7645975C081584B83D893 /* HippoAnalytics */ = {
+ isa = XCSwiftPackageProductDependency;
+ productName = HippoAnalytics;
+ };
+ E4DA341A663094C9B76ED975 /* HippoPayments */ = {
+ isa = XCSwiftPackageProductDependency;
+ productName = HippoPayments;
+ };
+/* End XCSwiftPackageProductDependency section */
+ };
+ rootObject = E8B17C8ABC8471E4224D1C39 /* Project object */;
+}
diff --git a/15-fake-and-dummy/0-start/Albertos.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/15-fake-and-dummy/0-start/Albertos.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/15-fake-and-dummy/0-start/Albertos.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/15-fake-and-dummy/0-start/Albertos.xcodeproj/xcshareddata/xcschemes/Albertos.xcscheme b/15-fake-and-dummy/0-start/Albertos.xcodeproj/xcshareddata/xcschemes/Albertos.xcscheme
new file mode 100644
index 0000000..625bb4c
--- /dev/null
+++ b/15-fake-and-dummy/0-start/Albertos.xcodeproj/xcshareddata/xcschemes/Albertos.xcscheme
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/15-fake-and-dummy/1-end/.gitignore b/15-fake-and-dummy/1-end/.gitignore
deleted file mode 100644
index 0f22386..0000000
--- a/15-fake-and-dummy/1-end/.gitignore
+++ /dev/null
@@ -1,32 +0,0 @@
-#### joe made this: https://goel.io/joe
-
-#####=== Swift ===#####
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# CocoaPods
-#
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
-#
-# Pods/
-
-*.xcodeproj
diff --git a/15-fake-and-dummy/1-end/Albertos.xcodeproj/project.pbxproj b/15-fake-and-dummy/1-end/Albertos.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..ba4a663
--- /dev/null
+++ b/15-fake-and-dummy/1-end/Albertos.xcodeproj/project.pbxproj
@@ -0,0 +1,803 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 54;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 05F9CCF5DBBF99661E2674CD /* TestError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7415549C09C4274D8CCFCC77 /* TestError.swift */; };
+ 09ACA86E7D21F75667DFE0DD /* MenuItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E51B5F284ED8D04D444E045A /* MenuItem.swift */; };
+ 13387CFB26245EF8240C7A98 /* Order.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA8381D5EC52AEE8AD62901C /* Order.swift */; };
+ 142E55512BCC01F76E6619BE /* OrderDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2F6ABED8B7DE5C3B2201BFE /* OrderDetail.swift */; };
+ 191B255739C03540FAC7AED9 /* HippoAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = A1C7645975C081584B83D893 /* HippoAnalytics */; };
+ 226EEC8949476F310DD280D6 /* MenuItemDetail.ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DACB11387FDF655295A1EF5D /* MenuItemDetail.ViewModel.swift */; };
+ 24D42A189DD7783620BA9E71 /* MenuItem+Fixture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44F03178E9C863DACBC1814D /* MenuItem+Fixture.swift */; };
+ 25094AC33CCA4B5C9C22191F /* MenuFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA4292931534001B9214FC05 /* MenuFetcher.swift */; };
+ 2AA2150DDE3809E58743BD24 /* Order+HippoPayments.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EEB98A8D526FF61E06E97BE /* Order+HippoPayments.swift */; };
+ 2CE5477919484069C04F4DB8 /* UserDefaults+OrderStoring.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8374C25DD012A1F6AAFC0FC3 /* UserDefaults+OrderStoring.swift */; };
+ 2F918E0E8AD9FA1C52728236 /* URLSession+NetworkFetching.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CAC3002AC30D0DF4E5423A /* URLSession+NetworkFetching.swift */; };
+ 306A3E4B181122000CE510B5 /* HippoPayments in Frameworks */ = {isa = PBXBuildFile; productRef = E4DA341A663094C9B76ED975 /* HippoPayments */; };
+ 3E7AAFE5A8859BD805675B9A /* menu_item.json in Resources */ = {isa = PBXBuildFile; fileRef = D2424D0270A102DE67834630 /* menu_item.json */; };
+ 417B645EA8ABA9FD43A555DB /* OrderDetail.ViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0AAF8C46351787636819C4A /* OrderDetail.ViewModelTests.swift */; };
+ 418E360A5081788F4DCCEFB3 /* MenuRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCF95E9CB8962AFFF16D3FB9 /* MenuRow.swift */; };
+ 4723B6368E44839B144C6763 /* OrderStoring.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D9869FEAEED2E853728663B /* OrderStoring.swift */; };
+ 4EA49FA5AF515BE2921D520C /* MenuList.ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD4253D513637E0AAE27D6CF /* MenuList.ViewModel.swift */; };
+ 5354C38AA669CF9AF2973EA1 /* PaymentProcessingSpy.swift in Sources */ = {isa = PBXBuildFile; fileRef = D738530778704B5210E4A047 /* PaymentProcessingSpy.swift */; };
+ 5725BB9CC15E6A1FB9049F96 /* MenuItemTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0468A7C221FFC8B3BF0FA860 /* MenuItemTests.swift */; };
+ 5ED86F4FF8C7DE0E71C461B1 /* OrderStoringFake.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14553FF9D06453DF0E5EF514 /* OrderStoringFake.swift */; };
+ 5FF1F997B94105D2F8EE0162 /* MenuItemDetail.ViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 249B815756D66665262AEC0B /* MenuItemDetail.ViewModelTests.swift */; };
+ 649034BA985AB6A4C370FC4D /* MenuList.ViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59517D51C93F603F806005F5 /* MenuList.ViewModelTests.swift */; };
+ 6DA8821E769C21FD671732D3 /* PaymentProcessing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09723CD3E04C59D8931C539A /* PaymentProcessing.swift */; };
+ 780C4AC5BA073670CDF0C802 /* Color+Custom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23FAD24A78C9DA66DB9AF326 /* Color+Custom.swift */; };
+ 7C8488112F6CE8FD02FAD6E2 /* NetworkFetching.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9607928D2AE1C03FAC536A7A /* NetworkFetching.swift */; };
+ 7F479ECCACF640E0803676C3 /* MenuSection+Fixture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E930A2AB025AD0FBFFD28F6 /* MenuSection+Fixture.swift */; };
+ 82A227C7A37E3AD03FB346CD /* NetworkFetchingStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0904894B8407027E56A5C8C7 /* NetworkFetchingStub.swift */; };
+ 82F3DCE56B57C47611121CA6 /* PaymentProcessingDummy.swift in Sources */ = {isa = PBXBuildFile; fileRef = D155D69389A6A4AA5FCF55BA /* PaymentProcessingDummy.swift */; };
+ 8CCEF233827037043C3CE766 /* Alert.ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7F33AFCF39D65227624637B /* Alert.ViewModel.swift */; };
+ 9236A4B1D0CC219B8F23CBB1 /* OrderController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3B4BF35CD95A0E4AB3A54A3 /* OrderController.swift */; };
+ 933814BD4D1718D1ED9F669E /* MenuItemDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB25E45EE54DF3CD4374444F /* MenuItemDetail.swift */; };
+ 9CC30446EF46FE0263FC1016 /* Collection+Safe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AB92569F1F7C921D2EEAF36 /* Collection+Safe.swift */; };
+ 9D334FC1DB465C7F0B3BB3F7 /* MenuSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED56EEE9C2A95C8D940BE49B /* MenuSection.swift */; };
+ A140E52779DF1652541302F3 /* XCTestCase+Timeouts.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC4A09108CE16DBEA1BDC308 /* XCTestCase+Timeouts.swift */; };
+ A17BE57B0365DC289250E618 /* OrderButtonViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC5570E9468FD135453788B /* OrderButtonViewModelTests.swift */; };
+ A432A71EDCF4DC54058A564E /* MenuGroupingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E8BD1E021C1238B66D6697D /* MenuGroupingTests.swift */; };
+ A7D49EF97B36875A6B0215F8 /* MenuRow.ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FADB2F629C4815BE8ACA7FA7 /* MenuRow.ViewModel.swift */; };
+ A804D47930989A18364D1947 /* OrderControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B03E53B8DB9C8D11A3D01AA /* OrderControllerTests.swift */; };
+ AAD605E22BB4D10BF3F39DA8 /* AlbertosApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = E231812A9BEA82FE13B6DDE3 /* AlbertosApp.swift */; };
+ B3F8BD304D4C17EFD37A3F45 /* OrderDetail.ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EF87C1C7736BAD96EF36D48 /* OrderDetail.ViewModel.swift */; };
+ B4E3F2714E137147C9853A22 /* MenuRow.ViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 183E499D41745D441197920F /* MenuRow.ViewModelTests.swift */; };
+ BAB9DEE0C2BC90EA6E785B1F /* PaymentProcessingProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2131B9C900C82687F26D7897 /* PaymentProcessingProxy.swift */; };
+ C5EE5943ADB1EA4D1CE728EE /* MenuGrouping.swift in Sources */ = {isa = PBXBuildFile; fileRef = F89281C54BD39EEAB6CD33A7 /* MenuGrouping.swift */; };
+ D33843A1F41E697E457450B0 /* MenuItem+JSONFixture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EA77FDE9A4729980574BE69 /* MenuItem+JSONFixture.swift */; };
+ D8B61B7ADE287BC0654C8FBA /* PaymentProcessingStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 896FE3F619AFADE5CA8AE7AD /* PaymentProcessingStub.swift */; };
+ DAB59D18F337A03FFD259E0D /* MenuItemAlternateJSONTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D067494480000423A7D3541 /* MenuItemAlternateJSONTests.swift */; };
+ DDD52EC5E0B3BD1387E23A84 /* OrderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0475EBBA92E1E7795EB38A94 /* OrderTests.swift */; };
+ E55D459EF4C1A10CA14B2EDA /* MenuFetchingStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBDF4DFEF1B2F09792BA6D00 /* MenuFetchingStub.swift */; };
+ E5CB4631359F984486744922 /* MenuFetcherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15393DB4B0DD911EA59F80B4 /* MenuFetcherTests.swift */; };
+ EB1718A2B7AEA1093BB6A61F /* HippoPaymentsProcessor+PaymentProcessing.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB1DE85828E344BA72C97E96 /* HippoPaymentsProcessor+PaymentProcessing.swift */; };
+ F28A0F3222BF3EAF2CDA01FE /* MenuList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38E678AF65BE5E3636E405C7 /* MenuList.swift */; };
+ F7EC63727BB23F3A58EEF9B4 /* OrderButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8D8E9C4F9C83E8473793F47 /* OrderButton.swift */; };
+ FB761F5059AB45B17E2DF213 /* XCTestCase+JSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A1553886918E52BC11CC3DC /* XCTestCase+JSON.swift */; };
+ FD786266CA046DB84D08178E /* OrderButton.ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FA55EAF42B38DA7CE36726 /* OrderButton.ViewModel.swift */; };
+ FF7E3946FA9D5B74CBF5D8C2 /* MenuFetching.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C29236D8792EE571561C6C1 /* MenuFetching.swift */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 059BD3039F2CCB1DD9C2B900 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = E8B17C8ABC8471E4224D1C39 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B5F9F9D2250AEB2D2EE0494B;
+ remoteInfo = Albertos;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ 0468A7C221FFC8B3BF0FA860 /* MenuItemTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItemTests.swift; sourceTree = ""; };
+ 0475EBBA92E1E7795EB38A94 /* OrderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderTests.swift; sourceTree = ""; };
+ 0904894B8407027E56A5C8C7 /* NetworkFetchingStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkFetchingStub.swift; sourceTree = ""; };
+ 09723CD3E04C59D8931C539A /* PaymentProcessing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentProcessing.swift; sourceTree = ""; };
+ 0E930A2AB025AD0FBFFD28F6 /* MenuSection+Fixture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MenuSection+Fixture.swift"; sourceTree = ""; };
+ 14553FF9D06453DF0E5EF514 /* OrderStoringFake.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderStoringFake.swift; sourceTree = ""; };
+ 15393DB4B0DD911EA59F80B4 /* MenuFetcherTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuFetcherTests.swift; sourceTree = ""; };
+ 183E499D41745D441197920F /* MenuRow.ViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuRow.ViewModelTests.swift; sourceTree = ""; };
+ 2131B9C900C82687F26D7897 /* PaymentProcessingProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentProcessingProxy.swift; sourceTree = ""; };
+ 23FAD24A78C9DA66DB9AF326 /* Color+Custom.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+Custom.swift"; sourceTree = ""; };
+ 249B815756D66665262AEC0B /* MenuItemDetail.ViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItemDetail.ViewModelTests.swift; sourceTree = ""; };
+ 2C29236D8792EE571561C6C1 /* MenuFetching.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuFetching.swift; sourceTree = ""; };
+ 2EEB98A8D526FF61E06E97BE /* Order+HippoPayments.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Order+HippoPayments.swift"; sourceTree = ""; };
+ 38E678AF65BE5E3636E405C7 /* MenuList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuList.swift; sourceTree = ""; };
+ 3EA77FDE9A4729980574BE69 /* MenuItem+JSONFixture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MenuItem+JSONFixture.swift"; sourceTree = ""; };
+ 44F03178E9C863DACBC1814D /* MenuItem+Fixture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MenuItem+Fixture.swift"; sourceTree = ""; };
+ 59517D51C93F603F806005F5 /* MenuList.ViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuList.ViewModelTests.swift; sourceTree = ""; };
+ 6AB92569F1F7C921D2EEAF36 /* Collection+Safe.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Collection+Safe.swift"; sourceTree = ""; };
+ 6B03E53B8DB9C8D11A3D01AA /* OrderControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderControllerTests.swift; sourceTree = ""; };
+ 6D9869FEAEED2E853728663B /* OrderStoring.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderStoring.swift; sourceTree = ""; };
+ 72CC3E84F3456ED561DBFCAB /* HippoAnalytics */ = {isa = PBXFileReference; lastKnownFileType = folder; name = HippoAnalytics; path = ../../Packages/HippoAnalytics; sourceTree = SOURCE_ROOT; };
+ 7415549C09C4274D8CCFCC77 /* TestError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestError.swift; sourceTree = ""; };
+ 7A1553886918E52BC11CC3DC /* XCTestCase+JSON.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "XCTestCase+JSON.swift"; sourceTree = ""; };
+ 7D067494480000423A7D3541 /* MenuItemAlternateJSONTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItemAlternateJSONTests.swift; sourceTree = ""; };
+ 7D5D23DD07D469C771E0CCD7 /* HippoPayments */ = {isa = PBXFileReference; lastKnownFileType = folder; name = HippoPayments; path = ../../Packages/HippoPayments; sourceTree = SOURCE_ROOT; };
+ 7EF87C1C7736BAD96EF36D48 /* OrderDetail.ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderDetail.ViewModel.swift; sourceTree = ""; };
+ 823EEDCB67B487000A05DB62 /* Albertos.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = Albertos.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 8374C25DD012A1F6AAFC0FC3 /* UserDefaults+OrderStoring.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserDefaults+OrderStoring.swift"; sourceTree = ""; };
+ 83FA55EAF42B38DA7CE36726 /* OrderButton.ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderButton.ViewModel.swift; sourceTree = ""; };
+ 896FE3F619AFADE5CA8AE7AD /* PaymentProcessingStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentProcessingStub.swift; sourceTree = ""; };
+ 9607928D2AE1C03FAC536A7A /* NetworkFetching.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkFetching.swift; sourceTree = ""; };
+ 9E8BD1E021C1238B66D6697D /* MenuGroupingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuGroupingTests.swift; sourceTree = ""; };
+ A5CAC3002AC30D0DF4E5423A /* URLSession+NetworkFetching.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URLSession+NetworkFetching.swift"; sourceTree = ""; };
+ AB25E45EE54DF3CD4374444F /* MenuItemDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItemDetail.swift; sourceTree = ""; };
+ B0AAF8C46351787636819C4A /* OrderDetail.ViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderDetail.ViewModelTests.swift; sourceTree = ""; };
+ BBDF4DFEF1B2F09792BA6D00 /* MenuFetchingStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuFetchingStub.swift; sourceTree = ""; };
+ BCF95E9CB8962AFFF16D3FB9 /* MenuRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuRow.swift; sourceTree = ""; };
+ BD4253D513637E0AAE27D6CF /* MenuList.ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuList.ViewModel.swift; sourceTree = ""; };
+ BDF4B76EC90E0DB5458F8146 /* AlbertosTests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = AlbertosTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ CC4A09108CE16DBEA1BDC308 /* XCTestCase+Timeouts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "XCTestCase+Timeouts.swift"; sourceTree = ""; };
+ CEC5570E9468FD135453788B /* OrderButtonViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderButtonViewModelTests.swift; sourceTree = ""; };
+ D155D69389A6A4AA5FCF55BA /* PaymentProcessingDummy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentProcessingDummy.swift; sourceTree = ""; };
+ D2424D0270A102DE67834630 /* menu_item.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = menu_item.json; sourceTree = ""; };
+ D3B4BF35CD95A0E4AB3A54A3 /* OrderController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderController.swift; sourceTree = ""; };
+ D738530778704B5210E4A047 /* PaymentProcessingSpy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentProcessingSpy.swift; sourceTree = ""; };
+ D7F33AFCF39D65227624637B /* Alert.ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Alert.ViewModel.swift; sourceTree = ""; };
+ DACB11387FDF655295A1EF5D /* MenuItemDetail.ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItemDetail.ViewModel.swift; sourceTree = ""; };
+ E231812A9BEA82FE13B6DDE3 /* AlbertosApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbertosApp.swift; sourceTree = ""; };
+ E2F6ABED8B7DE5C3B2201BFE /* OrderDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderDetail.swift; sourceTree = ""; };
+ E51B5F284ED8D04D444E045A /* MenuItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItem.swift; sourceTree = ""; };
+ E5C5903BDB22A99A4B3DC3C8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; };
+ E8D8E9C4F9C83E8473793F47 /* OrderButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderButton.swift; sourceTree = ""; };
+ ED56EEE9C2A95C8D940BE49B /* MenuSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuSection.swift; sourceTree = ""; };
+ F89281C54BD39EEAB6CD33A7 /* MenuGrouping.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuGrouping.swift; sourceTree = ""; };
+ FA4292931534001B9214FC05 /* MenuFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuFetcher.swift; sourceTree = ""; };
+ FA8381D5EC52AEE8AD62901C /* Order.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Order.swift; sourceTree = ""; };
+ FADB2F629C4815BE8ACA7FA7 /* MenuRow.ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuRow.ViewModel.swift; sourceTree = ""; };
+ FB1DE85828E344BA72C97E96 /* HippoPaymentsProcessor+PaymentProcessing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HippoPaymentsProcessor+PaymentProcessing.swift"; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 976EEC1F85DA654336D7815E /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 306A3E4B181122000CE510B5 /* HippoPayments in Frameworks */,
+ 191B255739C03540FAC7AED9 /* HippoAnalytics in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 0560AD3424758048A3A433C9 /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ 2C29236D8792EE571561C6C1 /* MenuFetching.swift */,
+ );
+ name = Albertos;
+ path = "../../07-testing-dynamic-swiftui-views/1-end/Albertos";
+ sourceTree = "";
+ };
+ 0BB75D973EA16C8867DCD068 /* AlbertosTests */ = {
+ isa = PBXGroup;
+ children = (
+ 0475EBBA92E1E7795EB38A94 /* OrderTests.swift */,
+ D738530778704B5210E4A047 /* PaymentProcessingSpy.swift */,
+ );
+ name = AlbertosTests;
+ path = "../../12-spy/1-end/AlbertosTests";
+ sourceTree = "";
+ };
+ 1089370477C43CD0924C27EA /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ BD4253D513637E0AAE27D6CF /* MenuList.ViewModel.swift */,
+ );
+ name = Albertos;
+ path = "../../08-stub/1-end/Albertos";
+ sourceTree = "";
+ };
+ 115342909CD1A0EAF4A3125B /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ 23FAD24A78C9DA66DB9AF326 /* Color+Custom.swift */,
+ );
+ name = Albertos;
+ path = "../../11-dependency-injection-with-environment-object/0-start/Albertos";
+ sourceTree = "";
+ };
+ 23ACB16B0E88DB238D562E90 /* AlbertosTests */ = {
+ isa = PBXGroup;
+ children = (
+ 15393DB4B0DD911EA59F80B4 /* MenuFetcherTests.swift */,
+ 59517D51C93F603F806005F5 /* MenuList.ViewModelTests.swift */,
+ 0904894B8407027E56A5C8C7 /* NetworkFetchingStub.swift */,
+ );
+ name = AlbertosTests;
+ path = "../../10-networking/1-end/AlbertosTests";
+ sourceTree = "";
+ };
+ 5A34B853AF420876FC374AE1 /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ AB25E45EE54DF3CD4374444F /* MenuItemDetail.swift */,
+ DACB11387FDF655295A1EF5D /* MenuItemDetail.ViewModel.swift */,
+ );
+ name = Albertos;
+ path = "../../11-dependency-injection-with-environment-object/1-end/Albertos";
+ sourceTree = "";
+ };
+ 5AA9638FB37A04075FDB6BBF /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ 83FA55EAF42B38DA7CE36726 /* OrderButton.ViewModel.swift */,
+ );
+ name = Albertos;
+ path = "../../12-spy/0-start/Albertos";
+ sourceTree = "";
+ };
+ 610DFD9158304B0567C4C959 /* AlbertosTests */ = {
+ isa = PBXGroup;
+ children = (
+ 9E8BD1E021C1238B66D6697D /* MenuGroupingTests.swift */,
+ 44F03178E9C863DACBC1814D /* MenuItem+Fixture.swift */,
+ 0E930A2AB025AD0FBFFD28F6 /* MenuSection+Fixture.swift */,
+ );
+ name = AlbertosTests;
+ path = "../../06-testing-static-swiftui-views/1-end/AlbertosTests";
+ sourceTree = "";
+ };
+ 623D63D3705EE89055A94C12 /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ BCF95E9CB8962AFFF16D3FB9 /* MenuRow.swift */,
+ ED56EEE9C2A95C8D940BE49B /* MenuSection.swift */,
+ );
+ name = Albertos;
+ path = "../../06-testing-static-swiftui-views/1-end/Albertos";
+ sourceTree = "";
+ };
+ 6587589555E08BBEB63089E1 /* Sources */ = {
+ isa = PBXGroup;
+ children = (
+ 6AB92569F1F7C921D2EEAF36 /* Collection+Safe.swift */,
+ );
+ name = Sources;
+ path = ../../Packages/CollectionSafe/Sources;
+ sourceTree = "";
+ };
+ 802824DAE2FE5EA864A24B56 /* AlbertosTests */ = {
+ isa = PBXGroup;
+ children = (
+ D2424D0270A102DE67834630 /* menu_item.json */,
+ 3EA77FDE9A4729980574BE69 /* MenuItem+JSONFixture.swift */,
+ 7D067494480000423A7D3541 /* MenuItemAlternateJSONTests.swift */,
+ 0468A7C221FFC8B3BF0FA860 /* MenuItemTests.swift */,
+ 7A1553886918E52BC11CC3DC /* XCTestCase+JSON.swift */,
+ );
+ name = AlbertosTests;
+ path = "../../09-json-decoding/1-end/AlbertosTests";
+ sourceTree = "";
+ };
+ 814F0849D627BA240B0F8D84 /* AlbertosTests */ = {
+ isa = PBXGroup;
+ children = (
+ 183E499D41745D441197920F /* MenuRow.ViewModelTests.swift */,
+ );
+ name = AlbertosTests;
+ path = "../../14-fixing-bugs-and-changing-code/1-end/AlbertosTests";
+ sourceTree = "";
+ };
+ 8B609BB40A5421BBA31F3D3B /* AlbertosTests */ = {
+ isa = PBXGroup;
+ children = (
+ 249B815756D66665262AEC0B /* MenuItemDetail.ViewModelTests.swift */,
+ CEC5570E9468FD135453788B /* OrderButtonViewModelTests.swift */,
+ 6B03E53B8DB9C8D11A3D01AA /* OrderControllerTests.swift */,
+ B0AAF8C46351787636819C4A /* OrderDetail.ViewModelTests.swift */,
+ 14553FF9D06453DF0E5EF514 /* OrderStoringFake.swift */,
+ D155D69389A6A4AA5FCF55BA /* PaymentProcessingDummy.swift */,
+ );
+ path = AlbertosTests;
+ sourceTree = "";
+ };
+ 8D972551E420DEE0F670E89F /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ E5C5903BDB22A99A4B3DC3C8 /* Info.plist */,
+ E51B5F284ED8D04D444E045A /* MenuItem.swift */,
+ 38E678AF65BE5E3636E405C7 /* MenuList.swift */,
+ FA8381D5EC52AEE8AD62901C /* Order.swift */,
+ D3B4BF35CD95A0E4AB3A54A3 /* OrderController.swift */,
+ 6D9869FEAEED2E853728663B /* OrderStoring.swift */,
+ 8374C25DD012A1F6AAFC0FC3 /* UserDefaults+OrderStoring.swift */,
+ );
+ path = Albertos;
+ sourceTree = "";
+ };
+ 92B90574F9FA63884D9D7BBF = {
+ isa = PBXGroup;
+ children = (
+ 8D972551E420DEE0F670E89F /* Albertos */,
+ D9B63447692F960F19829F9B /* Albertos */,
+ 623D63D3705EE89055A94C12 /* Albertos */,
+ 0560AD3424758048A3A433C9 /* Albertos */,
+ 1089370477C43CD0924C27EA /* Albertos */,
+ DD3B74CA50EB6E5F084850EF /* Albertos */,
+ 115342909CD1A0EAF4A3125B /* Albertos */,
+ 5A34B853AF420876FC374AE1 /* Albertos */,
+ 5AA9638FB37A04075FDB6BBF /* Albertos */,
+ C8FA1DB4707A86998BDD3F99 /* Albertos */,
+ B95C2AEA9DF45D24D635ACED /* Albertos */,
+ E8AB92E07081D049054B3882 /* Albertos */,
+ 8B609BB40A5421BBA31F3D3B /* AlbertosTests */,
+ 610DFD9158304B0567C4C959 /* AlbertosTests */,
+ DB59F414D6282A4AE9C2F693 /* AlbertosTests */,
+ 802824DAE2FE5EA864A24B56 /* AlbertosTests */,
+ 23ACB16B0E88DB238D562E90 /* AlbertosTests */,
+ 0BB75D973EA16C8867DCD068 /* AlbertosTests */,
+ CDFD277F86A3D3C05F8490C5 /* AlbertosTests */,
+ 814F0849D627BA240B0F8D84 /* AlbertosTests */,
+ D298843BDFC7FEE66A144DE6 /* Packages */,
+ 6587589555E08BBEB63089E1 /* Sources */,
+ A0D81A2A2581F3DF42D52538 /* Products */,
+ );
+ sourceTree = "";
+ };
+ A0D81A2A2581F3DF42D52538 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 823EEDCB67B487000A05DB62 /* Albertos.app */,
+ BDF4B76EC90E0DB5458F8146 /* AlbertosTests.xctest */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ B95C2AEA9DF45D24D635ACED /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ D7F33AFCF39D65227624637B /* Alert.ViewModel.swift */,
+ E8D8E9C4F9C83E8473793F47 /* OrderButton.swift */,
+ E2F6ABED8B7DE5C3B2201BFE /* OrderDetail.swift */,
+ );
+ name = Albertos;
+ path = "../../13-testing-view-presentation/1-end/Albertos";
+ sourceTree = "";
+ };
+ C8FA1DB4707A86998BDD3F99 /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ E231812A9BEA82FE13B6DDE3 /* AlbertosApp.swift */,
+ FB1DE85828E344BA72C97E96 /* HippoPaymentsProcessor+PaymentProcessing.swift */,
+ 2EEB98A8D526FF61E06E97BE /* Order+HippoPayments.swift */,
+ 09723CD3E04C59D8931C539A /* PaymentProcessing.swift */,
+ 2131B9C900C82687F26D7897 /* PaymentProcessingProxy.swift */,
+ );
+ name = Albertos;
+ path = "../../12-spy/1-end/Albertos";
+ sourceTree = "";
+ };
+ CDFD277F86A3D3C05F8490C5 /* AlbertosTests */ = {
+ isa = PBXGroup;
+ children = (
+ 896FE3F619AFADE5CA8AE7AD /* PaymentProcessingStub.swift */,
+ CC4A09108CE16DBEA1BDC308 /* XCTestCase+Timeouts.swift */,
+ );
+ name = AlbertosTests;
+ path = "../../13-testing-view-presentation/1-end/AlbertosTests";
+ sourceTree = "";
+ };
+ D298843BDFC7FEE66A144DE6 /* Packages */ = {
+ isa = PBXGroup;
+ children = (
+ 72CC3E84F3456ED561DBFCAB /* HippoAnalytics */,
+ 7D5D23DD07D469C771E0CCD7 /* HippoPayments */,
+ );
+ name = Packages;
+ sourceTree = "";
+ };
+ D9B63447692F960F19829F9B /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ F89281C54BD39EEAB6CD33A7 /* MenuGrouping.swift */,
+ );
+ name = Albertos;
+ path = "../../04-tdd-in-the-real-world/1-end/Albertos";
+ sourceTree = "";
+ };
+ DB59F414D6282A4AE9C2F693 /* AlbertosTests */ = {
+ isa = PBXGroup;
+ children = (
+ BBDF4DFEF1B2F09792BA6D00 /* MenuFetchingStub.swift */,
+ 7415549C09C4274D8CCFCC77 /* TestError.swift */,
+ );
+ name = AlbertosTests;
+ path = "../../08-stub/1-end/AlbertosTests";
+ sourceTree = "";
+ };
+ DD3B74CA50EB6E5F084850EF /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ FA4292931534001B9214FC05 /* MenuFetcher.swift */,
+ 9607928D2AE1C03FAC536A7A /* NetworkFetching.swift */,
+ A5CAC3002AC30D0DF4E5423A /* URLSession+NetworkFetching.swift */,
+ );
+ name = Albertos;
+ path = "../../10-networking/1-end/Albertos";
+ sourceTree = "";
+ };
+ E8AB92E07081D049054B3882 /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ FADB2F629C4815BE8ACA7FA7 /* MenuRow.ViewModel.swift */,
+ 7EF87C1C7736BAD96EF36D48 /* OrderDetail.ViewModel.swift */,
+ );
+ name = Albertos;
+ path = "../../14-fixing-bugs-and-changing-code/1-end/Albertos";
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 33D869CEA8CD44DF60039E52 /* AlbertosTests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = F6A1BAA7BD8B12026072190E /* Build configuration list for PBXNativeTarget "AlbertosTests" */;
+ buildPhases = (
+ C099BFE9ACD985A8EDF284EA /* Sources */,
+ 4D9ABFE10A474D5655D092BE /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ C21F4B58454F5DE5FB4E056C /* PBXTargetDependency */,
+ );
+ name = AlbertosTests;
+ productName = AlbertosTests;
+ productReference = BDF4B76EC90E0DB5458F8146 /* AlbertosTests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+ B5F9F9D2250AEB2D2EE0494B /* Albertos */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 15021ED4CD768AB692CDEF6F /* Build configuration list for PBXNativeTarget "Albertos" */;
+ buildPhases = (
+ 2B3D01A98BE73618C91FF57C /* Sources */,
+ 976EEC1F85DA654336D7815E /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = Albertos;
+ packageProductDependencies = (
+ E4DA341A663094C9B76ED975 /* HippoPayments */,
+ A1C7645975C081584B83D893 /* HippoAnalytics */,
+ );
+ productName = Albertos;
+ productReference = 823EEDCB67B487000A05DB62 /* Albertos.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ E8B17C8ABC8471E4224D1C39 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ BuildIndependentTargetsInParallel = YES;
+ LastUpgradeCheck = 1430;
+ TargetAttributes = {
+ };
+ };
+ buildConfigurationList = 04A0F0432ABD7A4B9292FF90 /* Build configuration list for PBXProject "Albertos" */;
+ compatibilityVersion = "Xcode 14.0";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ Base,
+ en,
+ );
+ mainGroup = 92B90574F9FA63884D9D7BBF;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ B5F9F9D2250AEB2D2EE0494B /* Albertos */,
+ 33D869CEA8CD44DF60039E52 /* AlbertosTests */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 4D9ABFE10A474D5655D092BE /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 3E7AAFE5A8859BD805675B9A /* menu_item.json in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 2B3D01A98BE73618C91FF57C /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AAD605E22BB4D10BF3F39DA8 /* AlbertosApp.swift in Sources */,
+ 8CCEF233827037043C3CE766 /* Alert.ViewModel.swift in Sources */,
+ 780C4AC5BA073670CDF0C802 /* Color+Custom.swift in Sources */,
+ EB1718A2B7AEA1093BB6A61F /* HippoPaymentsProcessor+PaymentProcessing.swift in Sources */,
+ 25094AC33CCA4B5C9C22191F /* MenuFetcher.swift in Sources */,
+ FF7E3946FA9D5B74CBF5D8C2 /* MenuFetching.swift in Sources */,
+ C5EE5943ADB1EA4D1CE728EE /* MenuGrouping.swift in Sources */,
+ 09ACA86E7D21F75667DFE0DD /* MenuItem.swift in Sources */,
+ 226EEC8949476F310DD280D6 /* MenuItemDetail.ViewModel.swift in Sources */,
+ 933814BD4D1718D1ED9F669E /* MenuItemDetail.swift in Sources */,
+ 4EA49FA5AF515BE2921D520C /* MenuList.ViewModel.swift in Sources */,
+ F28A0F3222BF3EAF2CDA01FE /* MenuList.swift in Sources */,
+ A7D49EF97B36875A6B0215F8 /* MenuRow.ViewModel.swift in Sources */,
+ 418E360A5081788F4DCCEFB3 /* MenuRow.swift in Sources */,
+ 9D334FC1DB465C7F0B3BB3F7 /* MenuSection.swift in Sources */,
+ 7C8488112F6CE8FD02FAD6E2 /* NetworkFetching.swift in Sources */,
+ 2AA2150DDE3809E58743BD24 /* Order+HippoPayments.swift in Sources */,
+ 13387CFB26245EF8240C7A98 /* Order.swift in Sources */,
+ FD786266CA046DB84D08178E /* OrderButton.ViewModel.swift in Sources */,
+ F7EC63727BB23F3A58EEF9B4 /* OrderButton.swift in Sources */,
+ 9236A4B1D0CC219B8F23CBB1 /* OrderController.swift in Sources */,
+ B3F8BD304D4C17EFD37A3F45 /* OrderDetail.ViewModel.swift in Sources */,
+ 142E55512BCC01F76E6619BE /* OrderDetail.swift in Sources */,
+ 4723B6368E44839B144C6763 /* OrderStoring.swift in Sources */,
+ 6DA8821E769C21FD671732D3 /* PaymentProcessing.swift in Sources */,
+ BAB9DEE0C2BC90EA6E785B1F /* PaymentProcessingProxy.swift in Sources */,
+ 2F918E0E8AD9FA1C52728236 /* URLSession+NetworkFetching.swift in Sources */,
+ 2CE5477919484069C04F4DB8 /* UserDefaults+OrderStoring.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ C099BFE9ACD985A8EDF284EA /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 9CC30446EF46FE0263FC1016 /* Collection+Safe.swift in Sources */,
+ E5CB4631359F984486744922 /* MenuFetcherTests.swift in Sources */,
+ E55D459EF4C1A10CA14B2EDA /* MenuFetchingStub.swift in Sources */,
+ A432A71EDCF4DC54058A564E /* MenuGroupingTests.swift in Sources */,
+ 24D42A189DD7783620BA9E71 /* MenuItem+Fixture.swift in Sources */,
+ D33843A1F41E697E457450B0 /* MenuItem+JSONFixture.swift in Sources */,
+ DAB59D18F337A03FFD259E0D /* MenuItemAlternateJSONTests.swift in Sources */,
+ 5FF1F997B94105D2F8EE0162 /* MenuItemDetail.ViewModelTests.swift in Sources */,
+ 5725BB9CC15E6A1FB9049F96 /* MenuItemTests.swift in Sources */,
+ 649034BA985AB6A4C370FC4D /* MenuList.ViewModelTests.swift in Sources */,
+ B4E3F2714E137147C9853A22 /* MenuRow.ViewModelTests.swift in Sources */,
+ 7F479ECCACF640E0803676C3 /* MenuSection+Fixture.swift in Sources */,
+ 82A227C7A37E3AD03FB346CD /* NetworkFetchingStub.swift in Sources */,
+ A17BE57B0365DC289250E618 /* OrderButtonViewModelTests.swift in Sources */,
+ A804D47930989A18364D1947 /* OrderControllerTests.swift in Sources */,
+ 417B645EA8ABA9FD43A555DB /* OrderDetail.ViewModelTests.swift in Sources */,
+ 5ED86F4FF8C7DE0E71C461B1 /* OrderStoringFake.swift in Sources */,
+ DDD52EC5E0B3BD1387E23A84 /* OrderTests.swift in Sources */,
+ 82F3DCE56B57C47611121CA6 /* PaymentProcessingDummy.swift in Sources */,
+ 5354C38AA669CF9AF2973EA1 /* PaymentProcessingSpy.swift in Sources */,
+ D8B61B7ADE287BC0654C8FBA /* PaymentProcessingStub.swift in Sources */,
+ 05F9CCF5DBBF99661E2674CD /* TestError.swift in Sources */,
+ FB761F5059AB45B17E2DF213 /* XCTestCase+JSON.swift in Sources */,
+ A140E52779DF1652541302F3 /* XCTestCase+Timeouts.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ C21F4B58454F5DE5FB4E056C /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B5F9F9D2250AEB2D2EE0494B /* Albertos */;
+ targetProxy = 059BD3039F2CCB1DD9C2B900 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+ 068E7B265A85A0D164E026DA /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CODE_SIGNING_ALLOWED = NO;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.mokacoding.Albertos.AlbertosTests;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Albertos.app/Albertos";
+ };
+ name = Release;
+ };
+ 1D797AB11DACDB9E4B218C54 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CODE_SIGNING_ALLOWED = NO;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.mokacoding.Albertos.AlbertosTests;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Albertos.app/Albertos";
+ };
+ name = Debug;
+ };
+ 60C5F61655CE71EFE9017DDE /* 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_ENABLE_OBJC_WEAK = 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_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ 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;
+ 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;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = iphoneos;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Release;
+ };
+ 924F1451F334BAAEFDFDAD7C /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ INFOPLIST_FILE = Albertos/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.mokacoding.Albertos.Albertos;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+ D6F337C2184F1D0A465FC2BA /* 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_ENABLE_OBJC_WEAK = 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_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ 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;
+ 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 = (
+ "$(inherited)",
+ "DEBUG=1",
+ );
+ 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;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = iphoneos;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ };
+ name = Debug;
+ };
+ EC39A2F770A854AABF6204BC /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ INFOPLIST_FILE = Albertos/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.mokacoding.Albertos.Albertos;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 04A0F0432ABD7A4B9292FF90 /* Build configuration list for PBXProject "Albertos" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ D6F337C2184F1D0A465FC2BA /* Debug */,
+ 60C5F61655CE71EFE9017DDE /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Debug;
+ };
+ 15021ED4CD768AB692CDEF6F /* Build configuration list for PBXNativeTarget "Albertos" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ EC39A2F770A854AABF6204BC /* Debug */,
+ 924F1451F334BAAEFDFDAD7C /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Debug;
+ };
+ F6A1BAA7BD8B12026072190E /* Build configuration list for PBXNativeTarget "AlbertosTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1D797AB11DACDB9E4B218C54 /* Debug */,
+ 068E7B265A85A0D164E026DA /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Debug;
+ };
+/* End XCConfigurationList section */
+
+/* Begin XCSwiftPackageProductDependency section */
+ A1C7645975C081584B83D893 /* HippoAnalytics */ = {
+ isa = XCSwiftPackageProductDependency;
+ productName = HippoAnalytics;
+ };
+ E4DA341A663094C9B76ED975 /* HippoPayments */ = {
+ isa = XCSwiftPackageProductDependency;
+ productName = HippoPayments;
+ };
+/* End XCSwiftPackageProductDependency section */
+ };
+ rootObject = E8B17C8ABC8471E4224D1C39 /* Project object */;
+}
diff --git a/15-fake-and-dummy/1-end/Albertos.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/15-fake-and-dummy/1-end/Albertos.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/15-fake-and-dummy/1-end/Albertos.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/15-fake-and-dummy/1-end/Albertos.xcodeproj/project.xcworkspace/xcuserdata/gio.xcuserdatad/UserInterfaceState.xcuserstate b/15-fake-and-dummy/1-end/Albertos.xcodeproj/project.xcworkspace/xcuserdata/gio.xcuserdatad/UserInterfaceState.xcuserstate
new file mode 100644
index 0000000..3e43443
Binary files /dev/null and b/15-fake-and-dummy/1-end/Albertos.xcodeproj/project.xcworkspace/xcuserdata/gio.xcuserdatad/UserInterfaceState.xcuserstate differ
diff --git a/15-fake-and-dummy/1-end/Albertos.xcodeproj/xcshareddata/xcschemes/Albertos.xcscheme b/15-fake-and-dummy/1-end/Albertos.xcodeproj/xcshareddata/xcschemes/Albertos.xcscheme
new file mode 100644
index 0000000..625bb4c
--- /dev/null
+++ b/15-fake-and-dummy/1-end/Albertos.xcodeproj/xcshareddata/xcschemes/Albertos.xcscheme
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/15-fake-and-dummy/1-end/Albertos.xcodeproj/xcuserdata/gio.xcuserdatad/xcschemes/xcschememanagement.plist b/15-fake-and-dummy/1-end/Albertos.xcodeproj/xcuserdata/gio.xcuserdatad/xcschemes/xcschememanagement.plist
new file mode 100644
index 0000000..86089fb
--- /dev/null
+++ b/15-fake-and-dummy/1-end/Albertos.xcodeproj/xcuserdata/gio.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -0,0 +1,24 @@
+
+
+
+
+ SchemeUserState
+
+ Albertos.xcscheme_^#shared#^_
+
+ orderHint
+ 0
+
+ HippoAnalytics.xcscheme_^#shared#^_
+
+ orderHint
+ 1
+
+ HippoPayments.xcscheme_^#shared#^_
+
+ orderHint
+ 2
+
+
+
+
diff --git a/17-appendix-b-nimble-only/.gitignore b/17-appendix-b-nimble-only/.gitignore
deleted file mode 100644
index 0f22386..0000000
--- a/17-appendix-b-nimble-only/.gitignore
+++ /dev/null
@@ -1,32 +0,0 @@
-#### joe made this: https://goel.io/joe
-
-#####=== Swift ===#####
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# CocoaPods
-#
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
-#
-# Pods/
-
-*.xcodeproj
diff --git a/18-appendix-b-quick-and-nimble/.gitignore b/18-appendix-b-quick-and-nimble/.gitignore
deleted file mode 100644
index 0f22386..0000000
--- a/18-appendix-b-quick-and-nimble/.gitignore
+++ /dev/null
@@ -1,32 +0,0 @@
-#### joe made this: https://goel.io/joe
-
-#####=== Swift ===#####
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# CocoaPods
-#
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
-#
-# Pods/
-
-*.xcodeproj
diff --git a/19-appendix-c-uikit/.gitignore b/19-appendix-c-uikit/.gitignore
deleted file mode 100644
index 0f22386..0000000
--- a/19-appendix-c-uikit/.gitignore
+++ /dev/null
@@ -1,32 +0,0 @@
-#### joe made this: https://goel.io/joe
-
-#####=== Swift ===#####
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-
-# CocoaPods
-#
-# We recommend against adding the Pods directory to your .gitignore. However
-# you should judge for yourself, the pros and cons are mentioned at:
-# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
-#
-# Pods/
-
-*.xcodeproj
diff --git a/19-appendix-c-uikit/Albertos.xcodeproj/project.pbxproj b/19-appendix-c-uikit/Albertos.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..0ebf74c
--- /dev/null
+++ b/19-appendix-c-uikit/Albertos.xcodeproj/project.pbxproj
@@ -0,0 +1,863 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 54;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 04C378BF8E1E01A319707838 /* Collection+Safe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AB92569F1F7C921D2EEAF36 /* Collection+Safe.swift */; };
+ 05F9CCF5DBBF99661E2674CD /* TestError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7415549C09C4274D8CCFCC77 /* TestError.swift */; };
+ 09ACA86E7D21F75667DFE0DD /* MenuItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E51B5F284ED8D04D444E045A /* MenuItem.swift */; };
+ 0A6E7E283A595F21FBEB04DE /* AppCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98DD8EC578114A25574829BF /* AppCoordinatorTests.swift */; };
+ 13387CFB26245EF8240C7A98 /* Order.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA8381D5EC52AEE8AD62901C /* Order.swift */; };
+ 191B255739C03540FAC7AED9 /* HippoAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = A1C7645975C081584B83D893 /* HippoAnalytics */; };
+ 21CAEB263BFD3D7B6F0D4F08 /* OrderDetailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBF5FFF3921ABEBD8A67232A /* OrderDetailViewModel.swift */; };
+ 24D42A189DD7783620BA9E71 /* MenuItem+Fixture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44F03178E9C863DACBC1814D /* MenuItem+Fixture.swift */; };
+ 25094AC33CCA4B5C9C22191F /* MenuFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA4292931534001B9214FC05 /* MenuFetcher.swift */; };
+ 29101E13108C884C459526CD /* MenuItemDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60FDCBD1DF45F7EE65A66691 /* MenuItemDetailViewController.swift */; };
+ 2AA2150DDE3809E58743BD24 /* Order+HippoPayments.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EEB98A8D526FF61E06E97BE /* Order+HippoPayments.swift */; };
+ 2ADAE45912459DFF5FFF1304 /* Nimble in Frameworks */ = {isa = PBXBuildFile; productRef = 34F8A6BCB50934E2E744EBE9 /* Nimble */; };
+ 2CE5477919484069C04F4DB8 /* UserDefaults+OrderStoring.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8374C25DD012A1F6AAFC0FC3 /* UserDefaults+OrderStoring.swift */; };
+ 2ED641F33327266A500061F7 /* MeunListTableViewDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CCD1ACEEEA7F71C336D8C2D /* MeunListTableViewDelegateTests.swift */; };
+ 2F918E0E8AD9FA1C52728236 /* URLSession+NetworkFetching.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5CAC3002AC30D0DF4E5423A /* URLSession+NetworkFetching.swift */; };
+ 306A3E4B181122000CE510B5 /* HippoPayments in Frameworks */ = {isa = PBXBuildFile; productRef = E4DA341A663094C9B76ED975 /* HippoPayments */; };
+ 363CBC894DBF689F25A4ED16 /* UIFont+Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 858EE294EEF02D5B6DCF1BF3 /* UIFont+Utils.swift */; };
+ 3E7AAFE5A8859BD805675B9A /* menu_item.json in Resources */ = {isa = PBXBuildFile; fileRef = D2424D0270A102DE67834630 /* menu_item.json */; };
+ 417B645EA8ABA9FD43A555DB /* OrderDetail.ViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0AAF8C46351787636819C4A /* OrderDetail.ViewModelTests.swift */; };
+ 420337AB5BAB9429B22E27CE /* AlertViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04BB2C4BE59959A3DEAE67B3 /* AlertViewModel.swift */; };
+ 43E91F57C7F85EE9A82599DC /* MenuItemDetailViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C12289A0D103BC85248ADD /* MenuItemDetailViewTests.swift */; };
+ 451A7E0A42CFBCBF25629AB3 /* MenuItemDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E9A053961EA4012DC82365E /* MenuItemDetailView.swift */; };
+ 4723B6368E44839B144C6763 /* OrderStoring.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D9869FEAEED2E853728663B /* OrderStoring.swift */; };
+ 4B2E7EC070E04ABFCE2C8D26 /* MenuItemDetailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9C73A5583A97A45A668E83D /* MenuItemDetailViewModel.swift */; };
+ 5354C38AA669CF9AF2973EA1 /* PaymentProcessingSpy.swift in Sources */ = {isa = PBXBuildFile; fileRef = D738530778704B5210E4A047 /* PaymentProcessingSpy.swift */; };
+ 5725BB9CC15E6A1FB9049F96 /* MenuItemTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0468A7C221FFC8B3BF0FA860 /* MenuItemTests.swift */; };
+ 5ED86F4FF8C7DE0E71C461B1 /* OrderStoringFake.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14553FF9D06453DF0E5EF514 /* OrderStoringFake.swift */; };
+ 5FE042375496A008C5ADC64D /* MenuListTableViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B722D06B4B39F344FD4A81D8 /* MenuListTableViewDelegate.swift */; };
+ 5FF1F997B94105D2F8EE0162 /* MenuItemDetail.ViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 249B815756D66665262AEC0B /* MenuItemDetail.ViewModelTests.swift */; };
+ 649034BA985AB6A4C370FC4D /* MenuList.ViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59517D51C93F603F806005F5 /* MenuList.ViewModelTests.swift */; };
+ 6DA8821E769C21FD671732D3 /* PaymentProcessing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09723CD3E04C59D8931C539A /* PaymentProcessing.swift */; };
+ 70323886C0C07B8479B4DB19 /* OrderDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75037602ABE320D3619E5B75 /* OrderDetailViewController.swift */; };
+ 727185695D29ECAFF9D5ABD0 /* MenuRowViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EA6323757FC15B622B0B86D /* MenuRowViewModel.swift */; };
+ 72DDE0D9D1F25D443BB10C1A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2C507EDE6836AB38573A45D /* AppDelegate.swift */; };
+ 7B32439B4ACE34E580BBF496 /* MenuListTableViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37C4B92FD364569E573412DA /* MenuListTableViewDataSource.swift */; };
+ 7C8488112F6CE8FD02FAD6E2 /* NetworkFetching.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9607928D2AE1C03FAC536A7A /* NetworkFetching.swift */; };
+ 7E6263654C074E5D5C21FD8B /* MenuItemDetailViewControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C761A4EBCBCD18DAD5C8D69 /* MenuItemDetailViewControllerTests.swift */; };
+ 7F479ECCACF640E0803676C3 /* MenuSection+Fixture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E930A2AB025AD0FBFFD28F6 /* MenuSection+Fixture.swift */; };
+ 82A227C7A37E3AD03FB346CD /* NetworkFetchingStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0904894B8407027E56A5C8C7 /* NetworkFetchingStub.swift */; };
+ 82F3DCE56B57C47611121CA6 /* PaymentProcessingDummy.swift in Sources */ = {isa = PBXBuildFile; fileRef = D155D69389A6A4AA5FCF55BA /* PaymentProcessingDummy.swift */; };
+ 882BFA2C9C53B919DBFEE08D /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD50FC921D1FB3B658D8847C /* SceneDelegate.swift */; };
+ 8DCED4000A587EA928537850 /* MenuListTableViewDataSourceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD74F497CC0C6AE7F2938A20 /* MenuListTableViewDataSourceTests.swift */; };
+ 9236A4B1D0CC219B8F23CBB1 /* OrderController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3B4BF35CD95A0E4AB3A54A3 /* OrderController.swift */; };
+ 93EBC3F7932F03B8C184DAB0 /* MenuListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8011D4D40A9961373BF7E42 /* MenuListViewController.swift */; };
+ 9BEE4D8C5A515780B2DA5FE6 /* UIView+AutoLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB649B4BFE20C170B935EA8D /* UIView+AutoLayout.swift */; };
+ 9CC30446EF46FE0263FC1016 /* Collection+Safe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AB92569F1F7C921D2EEAF36 /* Collection+Safe.swift */; };
+ 9D334FC1DB465C7F0B3BB3F7 /* MenuSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED56EEE9C2A95C8D940BE49B /* MenuSection.swift */; };
+ 9FF9DD6FA84C81164D4B71D0 /* UIButton+BigButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = E83C07B61990FC0EDF9A52E8 /* UIButton+BigButtonStyle.swift */; };
+ A140E52779DF1652541302F3 /* XCTestCase+Timeouts.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC4A09108CE16DBEA1BDC308 /* XCTestCase+Timeouts.swift */; };
+ A17BE57B0365DC289250E618 /* OrderButtonViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC5570E9468FD135453788B /* OrderButtonViewModelTests.swift */; };
+ A432A71EDCF4DC54058A564E /* MenuGroupingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E8BD1E021C1238B66D6697D /* MenuGroupingTests.swift */; };
+ A804D47930989A18364D1947 /* OrderControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B03E53B8DB9C8D11A3D01AA /* OrderControllerTests.swift */; };
+ AF9FF4A099156E882C5358A9 /* UIColor+Custom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EAB46D6E7F1ABF93B8F33E9 /* UIColor+Custom.swift */; };
+ B36547A03718CCC9ED9A8FE2 /* AppCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10EB1E9E60AE99753C358562 /* AppCoordinator.swift */; };
+ B4E3F2714E137147C9853A22 /* MenuRow.ViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 183E499D41745D441197920F /* MenuRow.ViewModelTests.swift */; };
+ B8E9D4EB24784E24EEE1DCB9 /* MenuListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63C615DC155947C2ADA0D58A /* MenuListViewModel.swift */; };
+ C34F443201A8C842CDD10D3D /* SceneDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D70605F6CEC33D2238D93E /* SceneDelegateTests.swift */; };
+ C5EE5943ADB1EA4D1CE728EE /* MenuGrouping.swift in Sources */ = {isa = PBXBuildFile; fileRef = F89281C54BD39EEAB6CD33A7 /* MenuGrouping.swift */; };
+ CDCA5B8F5EB3FED804BF6A04 /* UITableViewFooterLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8159A5688255D31E3CDB372 /* UITableViewFooterLabel.swift */; };
+ D33843A1F41E697E457450B0 /* MenuItem+JSONFixture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EA77FDE9A4729980574BE69 /* MenuItem+JSONFixture.swift */; };
+ D8B61B7ADE287BC0654C8FBA /* PaymentProcessingStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 896FE3F619AFADE5CA8AE7AD /* PaymentProcessingStub.swift */; };
+ DAB59D18F337A03FFD259E0D /* MenuItemAlternateJSONTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D067494480000423A7D3541 /* MenuItemAlternateJSONTests.swift */; };
+ DB5612B7B536AF211EF7ABA3 /* MenuListViewControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2239C164CC6A4E6C640F555B /* MenuListViewControllerTests.swift */; };
+ DDD52EC5E0B3BD1387E23A84 /* OrderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0475EBBA92E1E7795EB38A94 /* OrderTests.swift */; };
+ E55D459EF4C1A10CA14B2EDA /* MenuFetchingStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBDF4DFEF1B2F09792BA6D00 /* MenuFetchingStub.swift */; };
+ E5CB4631359F984486744922 /* MenuFetcherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15393DB4B0DD911EA59F80B4 /* MenuFetcherTests.swift */; };
+ EABF936007EFF66CCC51D4DA /* UIViewControllerPresenting.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE19930A67D49607DD71C381 /* UIViewControllerPresenting.swift */; };
+ EB1718A2B7AEA1093BB6A61F /* HippoPaymentsProcessor+PaymentProcessing.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB1DE85828E344BA72C97E96 /* HippoPaymentsProcessor+PaymentProcessing.swift */; };
+ F28A0F3222BF3EAF2CDA01FE /* MenuList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38E678AF65BE5E3636E405C7 /* MenuList.swift */; };
+ FB761F5059AB45B17E2DF213 /* XCTestCase+JSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A1553886918E52BC11CC3DC /* XCTestCase+JSON.swift */; };
+ FD786266CA046DB84D08178E /* OrderButton.ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83FA55EAF42B38DA7CE36726 /* OrderButton.ViewModel.swift */; };
+ FF7E3946FA9D5B74CBF5D8C2 /* MenuFetching.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C29236D8792EE571561C6C1 /* MenuFetching.swift */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 059BD3039F2CCB1DD9C2B900 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = E8B17C8ABC8471E4224D1C39 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B5F9F9D2250AEB2D2EE0494B;
+ remoteInfo = Albertos;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ 0468A7C221FFC8B3BF0FA860 /* MenuItemTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItemTests.swift; sourceTree = ""; };
+ 0475EBBA92E1E7795EB38A94 /* OrderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderTests.swift; sourceTree = ""; };
+ 04BB2C4BE59959A3DEAE67B3 /* AlertViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertViewModel.swift; sourceTree = ""; };
+ 0904894B8407027E56A5C8C7 /* NetworkFetchingStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkFetchingStub.swift; sourceTree = ""; };
+ 09723CD3E04C59D8931C539A /* PaymentProcessing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentProcessing.swift; sourceTree = ""; };
+ 0E930A2AB025AD0FBFFD28F6 /* MenuSection+Fixture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MenuSection+Fixture.swift"; sourceTree = ""; };
+ 0EA6323757FC15B622B0B86D /* MenuRowViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuRowViewModel.swift; sourceTree = ""; };
+ 0EAB46D6E7F1ABF93B8F33E9 /* UIColor+Custom.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Custom.swift"; sourceTree = ""; };
+ 10EB1E9E60AE99753C358562 /* AppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCoordinator.swift; sourceTree = ""; };
+ 14553FF9D06453DF0E5EF514 /* OrderStoringFake.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderStoringFake.swift; sourceTree = ""; };
+ 15393DB4B0DD911EA59F80B4 /* MenuFetcherTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuFetcherTests.swift; sourceTree = ""; };
+ 183E499D41745D441197920F /* MenuRow.ViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuRow.ViewModelTests.swift; sourceTree = ""; };
+ 1C761A4EBCBCD18DAD5C8D69 /* MenuItemDetailViewControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItemDetailViewControllerTests.swift; sourceTree = ""; };
+ 2239C164CC6A4E6C640F555B /* MenuListViewControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuListViewControllerTests.swift; sourceTree = ""; };
+ 249B815756D66665262AEC0B /* MenuItemDetail.ViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItemDetail.ViewModelTests.swift; sourceTree = ""; };
+ 2C29236D8792EE571561C6C1 /* MenuFetching.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuFetching.swift; sourceTree = ""; };
+ 2EEB98A8D526FF61E06E97BE /* Order+HippoPayments.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Order+HippoPayments.swift"; sourceTree = ""; };
+ 37C4B92FD364569E573412DA /* MenuListTableViewDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuListTableViewDataSource.swift; sourceTree = ""; };
+ 38E678AF65BE5E3636E405C7 /* MenuList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuList.swift; sourceTree = ""; };
+ 3E9A053961EA4012DC82365E /* MenuItemDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItemDetailView.swift; sourceTree = ""; };
+ 3EA77FDE9A4729980574BE69 /* MenuItem+JSONFixture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MenuItem+JSONFixture.swift"; sourceTree = ""; };
+ 43D70605F6CEC33D2238D93E /* SceneDelegateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegateTests.swift; sourceTree = ""; };
+ 44F03178E9C863DACBC1814D /* MenuItem+Fixture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MenuItem+Fixture.swift"; sourceTree = ""; };
+ 59517D51C93F603F806005F5 /* MenuList.ViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuList.ViewModelTests.swift; sourceTree = ""; };
+ 60FDCBD1DF45F7EE65A66691 /* MenuItemDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItemDetailViewController.swift; sourceTree = ""; };
+ 63C615DC155947C2ADA0D58A /* MenuListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuListViewModel.swift; sourceTree = ""; };
+ 6AB92569F1F7C921D2EEAF36 /* Collection+Safe.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Collection+Safe.swift"; sourceTree = ""; };
+ 6B03E53B8DB9C8D11A3D01AA /* OrderControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderControllerTests.swift; sourceTree = ""; };
+ 6D9869FEAEED2E853728663B /* OrderStoring.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderStoring.swift; sourceTree = ""; };
+ 72CC3E84F3456ED561DBFCAB /* HippoAnalytics */ = {isa = PBXFileReference; lastKnownFileType = folder; name = HippoAnalytics; path = ../Packages/HippoAnalytics; sourceTree = SOURCE_ROOT; };
+ 7415549C09C4274D8CCFCC77 /* TestError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestError.swift; sourceTree = ""; };
+ 75037602ABE320D3619E5B75 /* OrderDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderDetailViewController.swift; sourceTree = ""; };
+ 7A1553886918E52BC11CC3DC /* XCTestCase+JSON.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "XCTestCase+JSON.swift"; sourceTree = ""; };
+ 7D067494480000423A7D3541 /* MenuItemAlternateJSONTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItemAlternateJSONTests.swift; sourceTree = ""; };
+ 7D5D23DD07D469C771E0CCD7 /* HippoPayments */ = {isa = PBXFileReference; lastKnownFileType = folder; name = HippoPayments; path = ../Packages/HippoPayments; sourceTree = SOURCE_ROOT; };
+ 823EEDCB67B487000A05DB62 /* Albertos.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = Albertos.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 8374C25DD012A1F6AAFC0FC3 /* UserDefaults+OrderStoring.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserDefaults+OrderStoring.swift"; sourceTree = ""; };
+ 83FA55EAF42B38DA7CE36726 /* OrderButton.ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderButton.ViewModel.swift; sourceTree = ""; };
+ 858EE294EEF02D5B6DCF1BF3 /* UIFont+Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIFont+Utils.swift"; sourceTree = ""; };
+ 896FE3F619AFADE5CA8AE7AD /* PaymentProcessingStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentProcessingStub.swift; sourceTree = ""; };
+ 94C12289A0D103BC85248ADD /* MenuItemDetailViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItemDetailViewTests.swift; sourceTree = ""; };
+ 9607928D2AE1C03FAC536A7A /* NetworkFetching.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkFetching.swift; sourceTree = ""; };
+ 98DD8EC578114A25574829BF /* AppCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCoordinatorTests.swift; sourceTree = ""; };
+ 9CCD1ACEEEA7F71C336D8C2D /* MeunListTableViewDelegateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeunListTableViewDelegateTests.swift; sourceTree = ""; };
+ 9E8BD1E021C1238B66D6697D /* MenuGroupingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuGroupingTests.swift; sourceTree = ""; };
+ A5CAC3002AC30D0DF4E5423A /* URLSession+NetworkFetching.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URLSession+NetworkFetching.swift"; sourceTree = ""; };
+ A8011D4D40A9961373BF7E42 /* MenuListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuListViewController.swift; sourceTree = ""; };
+ A9C73A5583A97A45A668E83D /* MenuItemDetailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItemDetailViewModel.swift; sourceTree = ""; };
+ AD74F497CC0C6AE7F2938A20 /* MenuListTableViewDataSourceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuListTableViewDataSourceTests.swift; sourceTree = ""; };
+ B0AAF8C46351787636819C4A /* OrderDetail.ViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderDetail.ViewModelTests.swift; sourceTree = ""; };
+ B2C507EDE6836AB38573A45D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ B722D06B4B39F344FD4A81D8 /* MenuListTableViewDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuListTableViewDelegate.swift; sourceTree = ""; };
+ B8159A5688255D31E3CDB372 /* UITableViewFooterLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITableViewFooterLabel.swift; sourceTree = ""; };
+ BBDF4DFEF1B2F09792BA6D00 /* MenuFetchingStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuFetchingStub.swift; sourceTree = ""; };
+ BD50FC921D1FB3B658D8847C /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; };
+ BDF4B76EC90E0DB5458F8146 /* AlbertosTests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = AlbertosTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ BE19930A67D49607DD71C381 /* UIViewControllerPresenting.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewControllerPresenting.swift; sourceTree = ""; };
+ CC4A09108CE16DBEA1BDC308 /* XCTestCase+Timeouts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "XCTestCase+Timeouts.swift"; sourceTree = ""; };
+ CEC5570E9468FD135453788B /* OrderButtonViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderButtonViewModelTests.swift; sourceTree = ""; };
+ D155D69389A6A4AA5FCF55BA /* PaymentProcessingDummy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentProcessingDummy.swift; sourceTree = ""; };
+ D2424D0270A102DE67834630 /* menu_item.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = menu_item.json; sourceTree = ""; };
+ D3B4BF35CD95A0E4AB3A54A3 /* OrderController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderController.swift; sourceTree = ""; };
+ D738530778704B5210E4A047 /* PaymentProcessingSpy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentProcessingSpy.swift; sourceTree = ""; };
+ E51B5F284ED8D04D444E045A /* MenuItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItem.swift; sourceTree = ""; };
+ E83C07B61990FC0EDF9A52E8 /* UIButton+BigButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIButton+BigButtonStyle.swift"; sourceTree = ""; };
+ EBF5FFF3921ABEBD8A67232A /* OrderDetailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderDetailViewModel.swift; sourceTree = ""; };
+ ED56EEE9C2A95C8D940BE49B /* MenuSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuSection.swift; sourceTree = ""; };
+ F89281C54BD39EEAB6CD33A7 /* MenuGrouping.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuGrouping.swift; sourceTree = ""; };
+ FA4292931534001B9214FC05 /* MenuFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuFetcher.swift; sourceTree = ""; };
+ FA8381D5EC52AEE8AD62901C /* Order.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Order.swift; sourceTree = ""; };
+ FB1DE85828E344BA72C97E96 /* HippoPaymentsProcessor+PaymentProcessing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HippoPaymentsProcessor+PaymentProcessing.swift"; sourceTree = ""; };
+ FB649B4BFE20C170B935EA8D /* UIView+AutoLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+AutoLayout.swift"; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 825B7E4C853101B0641DDE14 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 2ADAE45912459DFF5FFF1304 /* Nimble in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 976EEC1F85DA654336D7815E /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 306A3E4B181122000CE510B5 /* HippoPayments in Frameworks */,
+ 191B255739C03540FAC7AED9 /* HippoAnalytics in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 0560AD3424758048A3A433C9 /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ 2C29236D8792EE571561C6C1 /* MenuFetching.swift */,
+ );
+ name = Albertos;
+ path = "../07-testing-dynamic-swiftui-views/1-end/Albertos";
+ sourceTree = "";
+ };
+ 0BB75D973EA16C8867DCD068 /* AlbertosTests */ = {
+ isa = PBXGroup;
+ children = (
+ D738530778704B5210E4A047 /* PaymentProcessingSpy.swift */,
+ );
+ name = AlbertosTests;
+ path = "../12-spy/1-end/AlbertosTests";
+ sourceTree = "";
+ };
+ 1089370477C43CD0924C27EA /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ FA4292931534001B9214FC05 /* MenuFetcher.swift */,
+ 9607928D2AE1C03FAC536A7A /* NetworkFetching.swift */,
+ A5CAC3002AC30D0DF4E5423A /* URLSession+NetworkFetching.swift */,
+ );
+ name = Albertos;
+ path = "../10-networking/1-end/Albertos";
+ sourceTree = "";
+ };
+ 115342909CD1A0EAF4A3125B /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ E51B5F284ED8D04D444E045A /* MenuItem.swift */,
+ 38E678AF65BE5E3636E405C7 /* MenuList.swift */,
+ FA8381D5EC52AEE8AD62901C /* Order.swift */,
+ D3B4BF35CD95A0E4AB3A54A3 /* OrderController.swift */,
+ 6D9869FEAEED2E853728663B /* OrderStoring.swift */,
+ 8374C25DD012A1F6AAFC0FC3 /* UserDefaults+OrderStoring.swift */,
+ );
+ name = Albertos;
+ path = "../15-fake-and-dummy/1-end/Albertos";
+ sourceTree = "";
+ };
+ 23ACB16B0E88DB238D562E90 /* AlbertosTests */ = {
+ isa = PBXGroup;
+ children = (
+ 0904894B8407027E56A5C8C7 /* NetworkFetchingStub.swift */,
+ );
+ name = AlbertosTests;
+ path = "../10-networking/1-end/AlbertosTests";
+ sourceTree = "";
+ };
+ 610DFD9158304B0567C4C959 /* AlbertosTests */ = {
+ isa = PBXGroup;
+ children = (
+ 44F03178E9C863DACBC1814D /* MenuItem+Fixture.swift */,
+ 0E930A2AB025AD0FBFFD28F6 /* MenuSection+Fixture.swift */,
+ );
+ name = AlbertosTests;
+ path = "../06-testing-static-swiftui-views/1-end/AlbertosTests";
+ sourceTree = "";
+ };
+ 623D63D3705EE89055A94C12 /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ ED56EEE9C2A95C8D940BE49B /* MenuSection.swift */,
+ );
+ name = Albertos;
+ path = "../06-testing-static-swiftui-views/1-end/Albertos";
+ sourceTree = "";
+ };
+ 6587589555E08BBEB63089E1 /* Sources */ = {
+ isa = PBXGroup;
+ children = (
+ 6AB92569F1F7C921D2EEAF36 /* Collection+Safe.swift */,
+ );
+ name = Sources;
+ path = ../Packages/CollectionSafe/Sources;
+ sourceTree = "";
+ };
+ 802824DAE2FE5EA864A24B56 /* AlbertosTests */ = {
+ isa = PBXGroup;
+ children = (
+ D2424D0270A102DE67834630 /* menu_item.json */,
+ 3EA77FDE9A4729980574BE69 /* MenuItem+JSONFixture.swift */,
+ 7A1553886918E52BC11CC3DC /* XCTestCase+JSON.swift */,
+ );
+ name = AlbertosTests;
+ path = "../09-json-decoding/1-end/AlbertosTests";
+ sourceTree = "";
+ };
+ 814F0849D627BA240B0F8D84 /* AlbertosTests */ = {
+ isa = PBXGroup;
+ children = (
+ 14553FF9D06453DF0E5EF514 /* OrderStoringFake.swift */,
+ D155D69389A6A4AA5FCF55BA /* PaymentProcessingDummy.swift */,
+ );
+ name = AlbertosTests;
+ path = "../15-fake-and-dummy/1-end/AlbertosTests";
+ sourceTree = "";
+ };
+ 8B609BB40A5421BBA31F3D3B /* AlbertosTests */ = {
+ isa = PBXGroup;
+ children = (
+ 98DD8EC578114A25574829BF /* AppCoordinatorTests.swift */,
+ 15393DB4B0DD911EA59F80B4 /* MenuFetcherTests.swift */,
+ 9E8BD1E021C1238B66D6697D /* MenuGroupingTests.swift */,
+ 7D067494480000423A7D3541 /* MenuItemAlternateJSONTests.swift */,
+ 249B815756D66665262AEC0B /* MenuItemDetail.ViewModelTests.swift */,
+ 1C761A4EBCBCD18DAD5C8D69 /* MenuItemDetailViewControllerTests.swift */,
+ 94C12289A0D103BC85248ADD /* MenuItemDetailViewTests.swift */,
+ 0468A7C221FFC8B3BF0FA860 /* MenuItemTests.swift */,
+ 59517D51C93F603F806005F5 /* MenuList.ViewModelTests.swift */,
+ AD74F497CC0C6AE7F2938A20 /* MenuListTableViewDataSourceTests.swift */,
+ 2239C164CC6A4E6C640F555B /* MenuListViewControllerTests.swift */,
+ 183E499D41745D441197920F /* MenuRow.ViewModelTests.swift */,
+ 9CCD1ACEEEA7F71C336D8C2D /* MeunListTableViewDelegateTests.swift */,
+ CEC5570E9468FD135453788B /* OrderButtonViewModelTests.swift */,
+ 6B03E53B8DB9C8D11A3D01AA /* OrderControllerTests.swift */,
+ B0AAF8C46351787636819C4A /* OrderDetail.ViewModelTests.swift */,
+ 0475EBBA92E1E7795EB38A94 /* OrderTests.swift */,
+ 43D70605F6CEC33D2238D93E /* SceneDelegateTests.swift */,
+ );
+ path = AlbertosTests;
+ sourceTree = "";
+ };
+ 8D972551E420DEE0F670E89F /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ 04BB2C4BE59959A3DEAE67B3 /* AlertViewModel.swift */,
+ 10EB1E9E60AE99753C358562 /* AppCoordinator.swift */,
+ B2C507EDE6836AB38573A45D /* AppDelegate.swift */,
+ 3E9A053961EA4012DC82365E /* MenuItemDetailView.swift */,
+ 60FDCBD1DF45F7EE65A66691 /* MenuItemDetailViewController.swift */,
+ A9C73A5583A97A45A668E83D /* MenuItemDetailViewModel.swift */,
+ 37C4B92FD364569E573412DA /* MenuListTableViewDataSource.swift */,
+ B722D06B4B39F344FD4A81D8 /* MenuListTableViewDelegate.swift */,
+ A8011D4D40A9961373BF7E42 /* MenuListViewController.swift */,
+ 63C615DC155947C2ADA0D58A /* MenuListViewModel.swift */,
+ 0EA6323757FC15B622B0B86D /* MenuRowViewModel.swift */,
+ 2EEB98A8D526FF61E06E97BE /* Order+HippoPayments.swift */,
+ 83FA55EAF42B38DA7CE36726 /* OrderButton.ViewModel.swift */,
+ 75037602ABE320D3619E5B75 /* OrderDetailViewController.swift */,
+ EBF5FFF3921ABEBD8A67232A /* OrderDetailViewModel.swift */,
+ BD50FC921D1FB3B658D8847C /* SceneDelegate.swift */,
+ E83C07B61990FC0EDF9A52E8 /* UIButton+BigButtonStyle.swift */,
+ 0EAB46D6E7F1ABF93B8F33E9 /* UIColor+Custom.swift */,
+ 858EE294EEF02D5B6DCF1BF3 /* UIFont+Utils.swift */,
+ B8159A5688255D31E3CDB372 /* UITableViewFooterLabel.swift */,
+ FB649B4BFE20C170B935EA8D /* UIView+AutoLayout.swift */,
+ BE19930A67D49607DD71C381 /* UIViewControllerPresenting.swift */,
+ );
+ path = Albertos;
+ sourceTree = "";
+ };
+ 92B90574F9FA63884D9D7BBF = {
+ isa = PBXGroup;
+ children = (
+ 8D972551E420DEE0F670E89F /* Albertos */,
+ D9B63447692F960F19829F9B /* Albertos */,
+ 623D63D3705EE89055A94C12 /* Albertos */,
+ 0560AD3424758048A3A433C9 /* Albertos */,
+ 1089370477C43CD0924C27EA /* Albertos */,
+ DD3B74CA50EB6E5F084850EF /* Albertos */,
+ 115342909CD1A0EAF4A3125B /* Albertos */,
+ 8B609BB40A5421BBA31F3D3B /* AlbertosTests */,
+ 610DFD9158304B0567C4C959 /* AlbertosTests */,
+ DB59F414D6282A4AE9C2F693 /* AlbertosTests */,
+ 802824DAE2FE5EA864A24B56 /* AlbertosTests */,
+ 23ACB16B0E88DB238D562E90 /* AlbertosTests */,
+ 0BB75D973EA16C8867DCD068 /* AlbertosTests */,
+ CDFD277F86A3D3C05F8490C5 /* AlbertosTests */,
+ 814F0849D627BA240B0F8D84 /* AlbertosTests */,
+ D298843BDFC7FEE66A144DE6 /* Packages */,
+ 6587589555E08BBEB63089E1 /* Sources */,
+ A0D81A2A2581F3DF42D52538 /* Products */,
+ );
+ sourceTree = "";
+ };
+ A0D81A2A2581F3DF42D52538 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 823EEDCB67B487000A05DB62 /* Albertos.app */,
+ BDF4B76EC90E0DB5458F8146 /* AlbertosTests.xctest */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ CDFD277F86A3D3C05F8490C5 /* AlbertosTests */ = {
+ isa = PBXGroup;
+ children = (
+ 896FE3F619AFADE5CA8AE7AD /* PaymentProcessingStub.swift */,
+ CC4A09108CE16DBEA1BDC308 /* XCTestCase+Timeouts.swift */,
+ );
+ name = AlbertosTests;
+ path = "../13-testing-view-presentation/1-end/AlbertosTests";
+ sourceTree = "";
+ };
+ D298843BDFC7FEE66A144DE6 /* Packages */ = {
+ isa = PBXGroup;
+ children = (
+ 72CC3E84F3456ED561DBFCAB /* HippoAnalytics */,
+ 7D5D23DD07D469C771E0CCD7 /* HippoPayments */,
+ );
+ name = Packages;
+ sourceTree = "";
+ };
+ D9B63447692F960F19829F9B /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ F89281C54BD39EEAB6CD33A7 /* MenuGrouping.swift */,
+ );
+ name = Albertos;
+ path = "../04-tdd-in-the-real-world/1-end/Albertos";
+ sourceTree = "";
+ };
+ DB59F414D6282A4AE9C2F693 /* AlbertosTests */ = {
+ isa = PBXGroup;
+ children = (
+ BBDF4DFEF1B2F09792BA6D00 /* MenuFetchingStub.swift */,
+ 7415549C09C4274D8CCFCC77 /* TestError.swift */,
+ );
+ name = AlbertosTests;
+ path = "../08-stub/1-end/AlbertosTests";
+ sourceTree = "";
+ };
+ DD3B74CA50EB6E5F084850EF /* Albertos */ = {
+ isa = PBXGroup;
+ children = (
+ FB1DE85828E344BA72C97E96 /* HippoPaymentsProcessor+PaymentProcessing.swift */,
+ 09723CD3E04C59D8931C539A /* PaymentProcessing.swift */,
+ );
+ name = Albertos;
+ path = "../12-spy/1-end/Albertos";
+ sourceTree = "