diff --git a/Detail/.DS_Store b/Detail/.DS_Store new file mode 100644 index 0000000..db501c7 Binary files /dev/null and b/Detail/.DS_Store differ diff --git a/Detail/Detail.xcodeproj/project.pbxproj b/Detail/Detail.xcodeproj/project.pbxproj new file mode 100644 index 0000000..73ee172 --- /dev/null +++ b/Detail/Detail.xcodeproj/project.pbxproj @@ -0,0 +1,381 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 484EE82521B9CA7F000DD56D /* FirebaseItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 484EE82321B9CA7E000DD56D /* FirebaseItem.swift */; }; + 484EE82621B9CA7F000DD56D /* Firebase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 484EE82421B9CA7F000DD56D /* Firebase.swift */; }; + 8E4DE798219C9EB200AFE381 /* Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E4DE797219C9EB200AFE381 /* Model.swift */; }; + 8E4DE79A219C9F3800AFE381 /* Person.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E4DE799219C9F3800AFE381 /* Person.swift */; }; + 8E4DE79C219CA16500AFE381 /* TableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E4DE79B219CA16500AFE381 /* TableViewController.swift */; }; + 8E4DE79E219CAA7700AFE381 /* ModelUpdateClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E4DE79D219CAA7700AFE381 /* ModelUpdateClient.swift */; }; + 8E9AA977219C92880012896B /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E9AA976219C92880012896B /* AppDelegate.swift */; }; + 8E9AA97C219C92880012896B /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8E9AA97A219C92880012896B /* Main.storyboard */; }; + 8E9AA97E219C928B0012896B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8E9AA97D219C928B0012896B /* Assets.xcassets */; }; + 8E9AA981219C928B0012896B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8E9AA97F219C928B0012896B /* LaunchScreen.storyboard */; }; + 8E9AA989219C92CB0012896B /* PersonCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E9AA988219C92CB0012896B /* PersonCell.swift */; }; + 8E9AA98B219C92D50012896B /* EntryCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E9AA98A219C92D50012896B /* EntryCell.swift */; }; + 8E9AA98D219C93100012896B /* PersonCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8E9AA98C219C93100012896B /* PersonCell.xib */; }; + 8E9AA98F219C93170012896B /* EntryCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8E9AA98E219C93170012896B /* EntryCell.xib */; }; + 8E9AA991219C9BDD0012896B /* DetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E9AA990219C9BDD0012896B /* DetailViewController.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 484EE82321B9CA7E000DD56D /* FirebaseItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FirebaseItem.swift; path = ../../FirebaseItem.swift; sourceTree = ""; }; + 484EE82421B9CA7F000DD56D /* Firebase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Firebase.swift; path = ../../Firebase.swift; sourceTree = ""; }; + 8E4DE797219C9EB200AFE381 /* Model.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Model.swift; sourceTree = ""; }; + 8E4DE799219C9F3800AFE381 /* Person.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Person.swift; sourceTree = ""; }; + 8E4DE79B219CA16500AFE381 /* TableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewController.swift; sourceTree = ""; }; + 8E4DE79D219CAA7700AFE381 /* ModelUpdateClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModelUpdateClient.swift; sourceTree = ""; }; + 8E9AA973219C92880012896B /* Detail.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Detail.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 8E9AA976219C92880012896B /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 8E9AA97B219C92880012896B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 8E9AA97D219C928B0012896B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 8E9AA980219C928B0012896B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 8E9AA982219C928B0012896B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 8E9AA988219C92CB0012896B /* PersonCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PersonCell.swift; sourceTree = ""; }; + 8E9AA98A219C92D50012896B /* EntryCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntryCell.swift; sourceTree = ""; }; + 8E9AA98C219C93100012896B /* PersonCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = PersonCell.xib; sourceTree = ""; }; + 8E9AA98E219C93170012896B /* EntryCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = EntryCell.xib; sourceTree = ""; }; + 8E9AA990219C9BDD0012896B /* DetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailViewController.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8E9AA970219C92880012896B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 8E9AA96A219C92880012896B = { + isa = PBXGroup; + children = ( + 8E9AA975219C92880012896B /* Detail */, + 8E9AA974219C92880012896B /* Products */, + ); + sourceTree = ""; + }; + 8E9AA974219C92880012896B /* Products */ = { + isa = PBXGroup; + children = ( + 8E9AA973219C92880012896B /* Detail.app */, + ); + name = Products; + sourceTree = ""; + }; + 8E9AA975219C92880012896B /* Detail */ = { + isa = PBXGroup; + children = ( + 8E9AA976219C92880012896B /* AppDelegate.swift */, + 484EE82421B9CA7F000DD56D /* Firebase.swift */, + 484EE82321B9CA7E000DD56D /* FirebaseItem.swift */, + 8E9AA988219C92CB0012896B /* PersonCell.swift */, + 8E9AA98C219C93100012896B /* PersonCell.xib */, + 8E9AA98A219C92D50012896B /* EntryCell.swift */, + 8E9AA98E219C93170012896B /* EntryCell.xib */, + 8E9AA990219C9BDD0012896B /* DetailViewController.swift */, + 8E4DE79B219CA16500AFE381 /* TableViewController.swift */, + 8E4DE797219C9EB200AFE381 /* Model.swift */, + 8E4DE79D219CAA7700AFE381 /* ModelUpdateClient.swift */, + 8E4DE799219C9F3800AFE381 /* Person.swift */, + 8E9AA97A219C92880012896B /* Main.storyboard */, + 8E9AA97D219C928B0012896B /* Assets.xcassets */, + 8E9AA97F219C928B0012896B /* LaunchScreen.storyboard */, + 8E9AA982219C928B0012896B /* Info.plist */, + ); + path = Detail; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 8E9AA972219C92880012896B /* Detail */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8E9AA985219C928B0012896B /* Build configuration list for PBXNativeTarget "Detail" */; + buildPhases = ( + 8E9AA96F219C92880012896B /* Sources */, + 8E9AA970219C92880012896B /* Frameworks */, + 8E9AA971219C92880012896B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Detail; + productName = Detail; + productReference = 8E9AA973219C92880012896B /* Detail.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 8E9AA96B219C92880012896B /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1010; + LastUpgradeCheck = 1010; + ORGANIZATIONNAME = "Erica Sadun"; + TargetAttributes = { + 8E9AA972219C92880012896B = { + CreatedOnToolsVersion = 10.1; + }; + }; + }; + buildConfigurationList = 8E9AA96E219C92880012896B /* Build configuration list for PBXProject "Detail" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 8E9AA96A219C92880012896B; + productRefGroup = 8E9AA974219C92880012896B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 8E9AA972219C92880012896B /* Detail */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8E9AA971219C92880012896B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8E9AA981219C928B0012896B /* LaunchScreen.storyboard in Resources */, + 8E9AA97E219C928B0012896B /* Assets.xcassets in Resources */, + 8E9AA98F219C93170012896B /* EntryCell.xib in Resources */, + 8E9AA98D219C93100012896B /* PersonCell.xib in Resources */, + 8E9AA97C219C92880012896B /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8E9AA96F219C92880012896B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 484EE82621B9CA7F000DD56D /* Firebase.swift in Sources */, + 8E4DE79A219C9F3800AFE381 /* Person.swift in Sources */, + 8E4DE79C219CA16500AFE381 /* TableViewController.swift in Sources */, + 8E4DE798219C9EB200AFE381 /* Model.swift in Sources */, + 484EE82521B9CA7F000DD56D /* FirebaseItem.swift in Sources */, + 8E9AA989219C92CB0012896B /* PersonCell.swift in Sources */, + 8E9AA98B219C92D50012896B /* EntryCell.swift in Sources */, + 8E4DE79E219CAA7700AFE381 /* ModelUpdateClient.swift in Sources */, + 8E9AA977219C92880012896B /* AppDelegate.swift in Sources */, + 8E9AA991219C9BDD0012896B /* DetailViewController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 8E9AA97A219C92880012896B /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 8E9AA97B219C92880012896B /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 8E9AA97F219C928B0012896B /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 8E9AA980219C928B0012896B /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 8E9AA983219C928B0012896B /* 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_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 8E9AA984219C928B0012896B /* 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_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 8E9AA986219C928B0012896B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 2W4DVPEQ39; + INFOPLIST_FILE = Detail/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.sadun.Detail; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 8E9AA987219C928B0012896B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 2W4DVPEQ39; + INFOPLIST_FILE = Detail/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.sadun.Detail; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 8E9AA96E219C92880012896B /* Build configuration list for PBXProject "Detail" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8E9AA983219C928B0012896B /* Debug */, + 8E9AA984219C928B0012896B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8E9AA985219C928B0012896B /* Build configuration list for PBXNativeTarget "Detail" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8E9AA986219C928B0012896B /* Debug */, + 8E9AA987219C928B0012896B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 8E9AA96B219C92880012896B /* Project object */; +} diff --git a/Detail/Detail.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Detail/Detail.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..50d85f8 --- /dev/null +++ b/Detail/Detail.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Detail/Detail.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Detail/Detail.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Detail/Detail.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Detail/Detail.xcodeproj/project.xcworkspace/xcuserdata/ericasadun.xcuserdatad/UserInterfaceState.xcuserstate b/Detail/Detail.xcodeproj/project.xcworkspace/xcuserdata/ericasadun.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..1dcbe09 Binary files /dev/null and b/Detail/Detail.xcodeproj/project.xcworkspace/xcuserdata/ericasadun.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/Detail/Detail.xcodeproj/project.xcworkspace/xcuserdata/lambda_school_loaner_34.xcuserdatad/UserInterfaceState.xcuserstate b/Detail/Detail.xcodeproj/project.xcworkspace/xcuserdata/lambda_school_loaner_34.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..15bdc0a Binary files /dev/null and b/Detail/Detail.xcodeproj/project.xcworkspace/xcuserdata/lambda_school_loaner_34.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/Detail/Detail.xcodeproj/xcuserdata/ericasadun.xcuserdatad/xcschemes/xcschememanagement.plist b/Detail/Detail.xcodeproj/xcuserdata/ericasadun.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..37d3e97 --- /dev/null +++ b/Detail/Detail.xcodeproj/xcuserdata/ericasadun.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + Detail.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/Detail/Detail.xcodeproj/xcuserdata/lambda_school_loaner_34.xcuserdatad/xcschemes/xcschememanagement.plist b/Detail/Detail.xcodeproj/xcuserdata/lambda_school_loaner_34.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..37d3e97 --- /dev/null +++ b/Detail/Detail.xcodeproj/xcuserdata/lambda_school_loaner_34.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + Detail.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/Detail/Detail/AppDelegate.swift b/Detail/Detail/AppDelegate.swift new file mode 100644 index 0000000..31619e2 --- /dev/null +++ b/Detail/Detail/AppDelegate.swift @@ -0,0 +1,10 @@ +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + return true + } +} diff --git a/Detail/Detail/Assets.xcassets/AppIcon.appiconset/Contents.json b/Detail/Detail/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/Detail/Detail/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Detail/Detail/Assets.xcassets/Contents.json b/Detail/Detail/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Detail/Detail/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Detail/Detail/Base.lproj/LaunchScreen.storyboard b/Detail/Detail/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..bfa3612 --- /dev/null +++ b/Detail/Detail/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Detail/Detail/Base.lproj/Main.storyboard b/Detail/Detail/Base.lproj/Main.storyboard new file mode 100644 index 0000000..6a9891d --- /dev/null +++ b/Detail/Detail/Base.lproj/Main.storyboard @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Detail/Detail/DetailViewController.swift b/Detail/Detail/DetailViewController.swift new file mode 100644 index 0000000..43f80bb --- /dev/null +++ b/Detail/Detail/DetailViewController.swift @@ -0,0 +1,26 @@ +import UIKit + +class DetailViewController: UIViewController { + var person: Person? + + @IBOutlet weak var nameField: UITextField! + @IBOutlet weak var cohortField: UITextField! + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + guard let person = person else { return } + nameField.text = person.name + cohortField.text = person.cohort + } + + @IBAction func save(_ sender: Any) { + guard let person = person else { return } + guard let name = nameField.text, !name.isEmpty else { return } + person.name = name + person.cohort = cohortField.text ?? "" + Model.shared.add(person: person, completion: {}) + + navigationController?.popViewController(animated: true) + } +} diff --git a/Detail/Detail/EntryCell.swift b/Detail/Detail/EntryCell.swift new file mode 100644 index 0000000..cb625cb --- /dev/null +++ b/Detail/Detail/EntryCell.swift @@ -0,0 +1,18 @@ +import UIKit + +class EntryCell: UITableViewCell { + static let reuseIdentifier = "entry cell" + + @IBOutlet weak var nameField: UITextField! + + @IBOutlet weak var cohortField: UITextField! + + @IBAction func add(_ sender: Any) { + guard let name = nameField.text, !name.isEmpty else { return } + let cohort = cohortField.text ?? "" + let person = Person(name: name, cohort: cohort) + Model.shared.add(person: person, completion: {}) + nameField.text = nil + cohortField.text = nil + } +} diff --git a/Detail/Detail/EntryCell.xib b/Detail/Detail/EntryCell.xib new file mode 100644 index 0000000..52c04e8 --- /dev/null +++ b/Detail/Detail/EntryCell.xib @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Detail/Detail/Info.plist b/Detail/Detail/Info.plist new file mode 100644 index 0000000..16be3b6 --- /dev/null +++ b/Detail/Detail/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Detail/Detail/Model.swift b/Detail/Detail/Model.swift new file mode 100644 index 0000000..eb450b7 --- /dev/null +++ b/Detail/Detail/Model.swift @@ -0,0 +1,55 @@ +import Foundation + +class Model { + static let shared = Model() + private init() {} + var delegate: ModelUpdateClient? + + var persons: [Person] = [] + + func count() -> Int { + return persons.count + } + + func person(forIndex index: Int) -> Person { + return persons[index] + } + + func add(person: Person, completion: @escaping () -> Void) { + persons.append(person) + + Firebase.save(item: person) { success in + guard success else { return } + DispatchQueue.main.async { completion() } + } + delegate?.modelDidUpdate() + } + + func deletePerson(at indexPath: IndexPath, completion: @escaping () -> Void) { + let person = persons[indexPath.row] + //in local model + persons.remove(at: indexPath.row) + + //in firebase + Firebase.delete(item: person) { success in + guard success else { return } + DispatchQueue.main.async { completion() } + } + // delegate?.modelDidUpdate() + + } + + func updatePerson(for person: Person, completion: @escaping () -> Void) { + //in local model + //update without the index path, updating in detail so no indexPath + //let person = persons[indexPath.row] + + //in firebase + Firebase.save(item: person) { success in + guard success else { return } + DispatchQueue.main.async { completion() } + } + //delegate?.modelDidUpdate() + + } +} diff --git a/Detail/Detail/ModelUpdateClient.swift b/Detail/Detail/ModelUpdateClient.swift new file mode 100644 index 0000000..6268cd4 --- /dev/null +++ b/Detail/Detail/ModelUpdateClient.swift @@ -0,0 +1,5 @@ +import Foundation + +protocol ModelUpdateClient { + func modelDidUpdate() +} diff --git a/Detail/Detail/Person.swift b/Detail/Detail/Person.swift new file mode 100644 index 0000000..fedddaa --- /dev/null +++ b/Detail/Detail/Person.swift @@ -0,0 +1,13 @@ +import Foundation + +class Person: Codable, FirebaseItem { + + var name: String + var cohort: String + var recordIdentifier = "" + + + init(name: String, cohort: String) { + (self.name, self.cohort) = (name, cohort) + } +} diff --git a/Detail/Detail/PersonCell.swift b/Detail/Detail/PersonCell.swift new file mode 100644 index 0000000..57762b0 --- /dev/null +++ b/Detail/Detail/PersonCell.swift @@ -0,0 +1,8 @@ +import UIKit + +class PersonCell: UITableViewCell { + static let reuseIdentifier = "person cell" + + @IBOutlet weak var nameLabel: UILabel! + @IBOutlet weak var cohortLabel: UILabel! +} diff --git a/Detail/Detail/PersonCell.xib b/Detail/Detail/PersonCell.xib new file mode 100644 index 0000000..c536c7c --- /dev/null +++ b/Detail/Detail/PersonCell.xib @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Detail/Detail/TableViewController.swift b/Detail/Detail/TableViewController.swift new file mode 100644 index 0000000..131e52c --- /dev/null +++ b/Detail/Detail/TableViewController.swift @@ -0,0 +1,86 @@ +import UIKit + +class TableViewController: UITableViewController, ModelUpdateClient { + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + Firebase.fetchRecords { persons in + if let persons = persons { + Model.shared.persons = persons + + DispatchQueue.main.async { + self.tableView.reloadData() + + } + } + } + } + + override func numberOfSections(in tableView: UITableView) -> Int { + return 2 + } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + switch section { + case 0: + return 1 + case 1: + return Model.shared.count() + default: + fatalError("Illegal section") + } + } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + if indexPath.section == 0 { + // handle the single entry cell + // return it + guard let cell = tableView.dequeueReusableCell(withIdentifier: EntryCell.reuseIdentifier, for: indexPath) as? EntryCell + else { fatalError("Unable to dequeue entry cell") } + + cell.nameField.text = "" // Coder paranoia + cell.cohortField.text = "" + + return cell + } + + // do anything related to person cell + guard let cell = tableView.dequeueReusableCell(withIdentifier: PersonCell.reuseIdentifier, for: indexPath) as? PersonCell + else { fatalError("Unable to dequeue person cell") } + + let person = Model.shared.person(forIndex: indexPath.row) + cell.nameLabel.text = person.name + cell.cohortLabel.text = person.cohort + return cell + } + + override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { + + guard editingStyle == .delete else { return } + + // FIXME: Delete an item, update Firebase, update model, and reload data + Model.shared.deletePerson(at: indexPath) { + self.tableView.reloadData() + } + } + + + override func viewDidLoad() { + super.viewDidLoad() + Model.shared.delegate = self + } + + func modelDidUpdate() { + tableView.reloadData() + } + + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + guard let indexPath = tableView.indexPathForSelectedRow + else { return } + guard let destination = segue.destination as? DetailViewController + else { return } + + destination.person = Model.shared.person(forIndex: indexPath.row) + } +} diff --git a/Firebase.swift b/Firebase.swift index d1f857c..d7922df 100644 --- a/Firebase.swift +++ b/Firebase.swift @@ -10,7 +10,7 @@ import Foundation class Firebase { - static var baseURL: URL! { return URL(string: "https://put-and-post.firebaseio.com/") } + static var baseURL: URL! { return URL(string: "https://detail-firebase.firebaseio.com/") } static func requestURL(_ method: String, for recordIdentifier: String = "unknownid") -> URL { switch method { diff --git a/Questions.rtf b/Questions.rtf new file mode 100644 index 0000000..32f3b32 --- /dev/null +++ b/Questions.rtf @@ -0,0 +1,64 @@ +{\rtf1\ansi\ansicpg1252\cocoartf1671 +{\fonttbl\f0\fnil\fcharset0 HelveticaNeue;} +{\colortbl;\red255\green255\blue255;\red27\green31\blue34;\red255\green255\blue255;} +{\*\expandedcolortbl;;\cssrgb\c14118\c16078\c18039;\cssrgb\c100000\c100000\c100000;} +\margl1440\margr1440\vieww15480\viewh7960\viewkind0 +\deftab720 +\pard\tx720\pardeftab720\sl360\partightenfactor0 + +\f0\fs32 \cf2 \cb3 \expnd0\expndtw0\kerning0 +\outl0\strokewidth0 \strokec2 1. What is a RESTful interface? \ +It is an application program interface(API) that uses HTTP requests to GET, PUT, POST, and DELETE data.\ +\ +2. When do you use it? \ +You use it when you need to use one of the HTTP methods.\ +\ +3. What are its characteristics?\ +GET-This allows you to get data\ +PUT -This allows you to revise data\ +POST -This allows you to create something\ +DELETE -This is where you want something removed\ +\cb1 \ +\cb3 4. What is the difference between POST and PUT?\ +POST- Every time you post something you will see it. It is something you create. Visually it\'92s like seeing a post on an app or website. You can post something and you will see it visually. \ +PUT- It is more behind the scenes. You can make a revision. Or do something several times using PUT and you may or may not see it.\ +\cb1 \ +\cb3 5. How does the record ID work in Firebase? \ +They are a combination of a timestamp and something else. The timestamp ensure they are ordered chronologically and the something else give an ID that is unique so that multiple people can be creating and push IDs at the same time.\ +\ +6. Why does it take two steps to save a record (first POST then PUT) in our app? \ +Post requests that the server accepts whatever is being enclosed and requested.\ +Put takes the requests of whatever is enclosed and is asked to store it\ +\ +7. Why does the FirebaseItem protocol even exist?\ +It allows for HTTP syntax to pass messages from your app server to the client.\ +\cb1 \ +\cb3 8. Explain what a generic type is and what advantages it offers.\ +A generic type is when \'93<\'93, \'94>\'94, \'93T\'94, \'93U\'94 is used in the naming convention. If we declare that the function takes a generic element we can use that generic element in multiple parts.\ +\cb1 \ +\cb3 9. What does a URLRequest do? \ +It is asking for the web address.\ +\ +10. When do you need one and when can you just use a URL?\ +You need a URL Request when you are getting information from a web site like if you were getting data from an api. You can use just the URL when you are using firebase\ +\cb1 \ +\cb3 11. What is the role of a URL session? \ +It is where you are fetching data through data tasks and using do catch block.\ +\ +12. How does it work?\ +It works by decoding information through try and also catching errors.\ +\cb1 \ +\cb3 13. What are completion handlers? \ +These allow you to order things and allows you to code when you want things to execute\ +\ +14. Why use completion handlers? \ +It allows you to run the function in a specific order\ +\ +15. What advantages do they provide?\ +You can pass along information out of a function through a completion handler\ +\cb1 \ +\cb3 16. Explain at least three strategies that promote code reuse that we used in today's project\ +-1 The firebase files were untouched and we were able to just use them in different projects\ +-2 Evidently you can refactor a project and still have it work using the firebase files\ +-3 When using the HTTP methods you can pretty much copy and paste those lines of code because they will always have the same function.\cb1 \ +} \ No newline at end of file