diff --git a/week01/mission/Megabox_week1/Megabox.xcodeproj/project.pbxproj b/week01/mission/Megabox_week1/Megabox.xcodeproj/project.pbxproj new file mode 100644 index 0000000..f84334a --- /dev/null +++ b/week01/mission/Megabox_week1/Megabox.xcodeproj/project.pbxproj @@ -0,0 +1,555 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 77; + objects = { + +/* Begin PBXContainerItemProxy section */ + E49AC74E2E7E85D200FA6D6D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E49AC7382E7E85CE00FA6D6D /* Project object */; + proxyType = 1; + remoteGlobalIDString = E49AC73F2E7E85CE00FA6D6D; + remoteInfo = Megabox; + }; + E49AC7582E7E85D200FA6D6D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E49AC7382E7E85CE00FA6D6D /* Project object */; + proxyType = 1; + remoteGlobalIDString = E49AC73F2E7E85CE00FA6D6D; + remoteInfo = Megabox; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + E49AC7402E7E85CE00FA6D6D /* Megabox.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Megabox.app; sourceTree = BUILT_PRODUCTS_DIR; }; + E49AC74D2E7E85D200FA6D6D /* MegaboxTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MegaboxTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + E49AC7572E7E85D200FA6D6D /* MegaboxUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MegaboxUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + E49AC7422E7E85CE00FA6D6D /* Megabox */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = Megabox; + sourceTree = ""; + }; + E49AC7502E7E85D200FA6D6D /* MegaboxTests */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = MegaboxTests; + sourceTree = ""; + }; + E49AC75A2E7E85D200FA6D6D /* MegaboxUITests */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = MegaboxUITests; + sourceTree = ""; + }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + E49AC73D2E7E85CE00FA6D6D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E49AC74A2E7E85D200FA6D6D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E49AC7542E7E85D200FA6D6D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + E49AC7372E7E85CE00FA6D6D = { + isa = PBXGroup; + children = ( + E49AC7422E7E85CE00FA6D6D /* Megabox */, + E49AC7502E7E85D200FA6D6D /* MegaboxTests */, + E49AC75A2E7E85D200FA6D6D /* MegaboxUITests */, + E49AC7412E7E85CE00FA6D6D /* Products */, + ); + sourceTree = ""; + }; + E49AC7412E7E85CE00FA6D6D /* Products */ = { + isa = PBXGroup; + children = ( + E49AC7402E7E85CE00FA6D6D /* Megabox.app */, + E49AC74D2E7E85D200FA6D6D /* MegaboxTests.xctest */, + E49AC7572E7E85D200FA6D6D /* MegaboxUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + E49AC73F2E7E85CE00FA6D6D /* Megabox */ = { + isa = PBXNativeTarget; + buildConfigurationList = E49AC7612E7E85D200FA6D6D /* Build configuration list for PBXNativeTarget "Megabox" */; + buildPhases = ( + E49AC73C2E7E85CE00FA6D6D /* Sources */, + E49AC73D2E7E85CE00FA6D6D /* Frameworks */, + E49AC73E2E7E85CE00FA6D6D /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + E49AC7422E7E85CE00FA6D6D /* Megabox */, + ); + name = Megabox; + packageProductDependencies = ( + ); + productName = Megabox; + productReference = E49AC7402E7E85CE00FA6D6D /* Megabox.app */; + productType = "com.apple.product-type.application"; + }; + E49AC74C2E7E85D200FA6D6D /* MegaboxTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = E49AC7642E7E85D200FA6D6D /* Build configuration list for PBXNativeTarget "MegaboxTests" */; + buildPhases = ( + E49AC7492E7E85D200FA6D6D /* Sources */, + E49AC74A2E7E85D200FA6D6D /* Frameworks */, + E49AC74B2E7E85D200FA6D6D /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + E49AC74F2E7E85D200FA6D6D /* PBXTargetDependency */, + ); + fileSystemSynchronizedGroups = ( + E49AC7502E7E85D200FA6D6D /* MegaboxTests */, + ); + name = MegaboxTests; + packageProductDependencies = ( + ); + productName = MegaboxTests; + productReference = E49AC74D2E7E85D200FA6D6D /* MegaboxTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + E49AC7562E7E85D200FA6D6D /* MegaboxUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = E49AC7672E7E85D200FA6D6D /* Build configuration list for PBXNativeTarget "MegaboxUITests" */; + buildPhases = ( + E49AC7532E7E85D200FA6D6D /* Sources */, + E49AC7542E7E85D200FA6D6D /* Frameworks */, + E49AC7552E7E85D200FA6D6D /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + E49AC7592E7E85D200FA6D6D /* PBXTargetDependency */, + ); + fileSystemSynchronizedGroups = ( + E49AC75A2E7E85D200FA6D6D /* MegaboxUITests */, + ); + name = MegaboxUITests; + packageProductDependencies = ( + ); + productName = MegaboxUITests; + productReference = E49AC7572E7E85D200FA6D6D /* MegaboxUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + E49AC7382E7E85CE00FA6D6D /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1640; + LastUpgradeCheck = 1640; + TargetAttributes = { + E49AC73F2E7E85CE00FA6D6D = { + CreatedOnToolsVersion = 16.4; + }; + E49AC74C2E7E85D200FA6D6D = { + CreatedOnToolsVersion = 16.4; + TestTargetID = E49AC73F2E7E85CE00FA6D6D; + }; + E49AC7562E7E85D200FA6D6D = { + CreatedOnToolsVersion = 16.4; + TestTargetID = E49AC73F2E7E85CE00FA6D6D; + }; + }; + }; + buildConfigurationList = E49AC73B2E7E85CE00FA6D6D /* Build configuration list for PBXProject "Megabox" */; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = E49AC7372E7E85CE00FA6D6D; + minimizedProjectReferenceProxies = 1; + preferredProjectObjectVersion = 77; + productRefGroup = E49AC7412E7E85CE00FA6D6D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + E49AC73F2E7E85CE00FA6D6D /* Megabox */, + E49AC74C2E7E85D200FA6D6D /* MegaboxTests */, + E49AC7562E7E85D200FA6D6D /* MegaboxUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + E49AC73E2E7E85CE00FA6D6D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E49AC74B2E7E85D200FA6D6D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E49AC7552E7E85D200FA6D6D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + E49AC73C2E7E85CE00FA6D6D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E49AC7492E7E85D200FA6D6D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E49AC7532E7E85D200FA6D6D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + E49AC74F2E7E85D200FA6D6D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = E49AC73F2E7E85CE00FA6D6D /* Megabox */; + targetProxy = E49AC74E2E7E85D200FA6D6D /* PBXContainerItemProxy */; + }; + E49AC7592E7E85D200FA6D6D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = E49AC73F2E7E85CE00FA6D6D /* Megabox */; + targetProxy = E49AC7582E7E85D200FA6D6D /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + E49AC75F2E7E85D200FA6D6D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + 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; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + 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 = 18.5; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + E49AC7602E7E85D200FA6D6D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + 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; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + 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 = 18.5; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + E49AC7622E7E85D200FA6D6D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.woojin.Megabox; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + E49AC7632E7E85D200FA6D6D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.woojin.Megabox; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + E49AC7652E7E85D200FA6D6D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.5; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.woojin.MegaboxTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Megabox.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Megabox"; + }; + name = Debug; + }; + E49AC7662E7E85D200FA6D6D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.5; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.woojin.MegaboxTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Megabox.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Megabox"; + }; + name = Release; + }; + E49AC7682E7E85D200FA6D6D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.woojin.MegaboxUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = Megabox; + }; + name = Debug; + }; + E49AC7692E7E85D200FA6D6D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.woojin.MegaboxUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = Megabox; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + E49AC73B2E7E85CE00FA6D6D /* Build configuration list for PBXProject "Megabox" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E49AC75F2E7E85D200FA6D6D /* Debug */, + E49AC7602E7E85D200FA6D6D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E49AC7612E7E85D200FA6D6D /* Build configuration list for PBXNativeTarget "Megabox" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E49AC7622E7E85D200FA6D6D /* Debug */, + E49AC7632E7E85D200FA6D6D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E49AC7642E7E85D200FA6D6D /* Build configuration list for PBXNativeTarget "MegaboxTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E49AC7652E7E85D200FA6D6D /* Debug */, + E49AC7662E7E85D200FA6D6D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E49AC7672E7E85D200FA6D6D /* Build configuration list for PBXNativeTarget "MegaboxUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E49AC7682E7E85D200FA6D6D /* Debug */, + E49AC7692E7E85D200FA6D6D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = E49AC7382E7E85CE00FA6D6D /* Project object */; +} diff --git a/week01/mission/Megabox_week1/Megabox.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/week01/mission/Megabox_week1/Megabox.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/week01/mission/Megabox_week1/Megabox.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/week01/mission/Megabox_week1/Megabox.xcodeproj/project.xcworkspace/xcuserdata/wj_intelmac.xcuserdatad/UserInterfaceState.xcuserstate b/week01/mission/Megabox_week1/Megabox.xcodeproj/project.xcworkspace/xcuserdata/wj_intelmac.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..9173363 Binary files /dev/null and b/week01/mission/Megabox_week1/Megabox.xcodeproj/project.xcworkspace/xcuserdata/wj_intelmac.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/week01/mission/Megabox_week1/Megabox.xcodeproj/xcuserdata/wj_intelmac.xcuserdatad/xcschemes/xcschememanagement.plist b/week01/mission/Megabox_week1/Megabox.xcodeproj/xcuserdata/wj_intelmac.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..6ccbb59 --- /dev/null +++ b/week01/mission/Megabox_week1/Megabox.xcodeproj/xcuserdata/wj_intelmac.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + Megabox.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/week01/mission/Megabox_week1/Megabox/Assets.xcassets/AccentColor.colorset/Contents.json b/week01/mission/Megabox_week1/Megabox/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/week01/mission/Megabox_week1/Megabox/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week01/mission/Megabox_week1/Megabox/Assets.xcassets/AppIcon.appiconset/Contents.json b/week01/mission/Megabox_week1/Megabox/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..2305880 --- /dev/null +++ b/week01/mission/Megabox_week1/Megabox/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,35 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "tinted" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week01/mission/Megabox_week1/Megabox/Assets.xcassets/Contents.json b/week01/mission/Megabox_week1/Megabox/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/week01/mission/Megabox_week1/Megabox/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week01/mission/Megabox_week1/Megabox/Assets.xcassets/apple.imageset/Contents.json b/week01/mission/Megabox_week1/Megabox/Assets.xcassets/apple.imageset/Contents.json new file mode 100644 index 0000000..0975940 --- /dev/null +++ b/week01/mission/Megabox_week1/Megabox/Assets.xcassets/apple.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "apple.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week01/mission/Megabox_week1/Megabox/Assets.xcassets/apple.imageset/apple.pdf b/week01/mission/Megabox_week1/Megabox/Assets.xcassets/apple.imageset/apple.pdf new file mode 100644 index 0000000..909af30 Binary files /dev/null and b/week01/mission/Megabox_week1/Megabox/Assets.xcassets/apple.imageset/apple.pdf differ diff --git a/week01/mission/Megabox_week1/Megabox/Assets.xcassets/kakao.imageset/Contents.json b/week01/mission/Megabox_week1/Megabox/Assets.xcassets/kakao.imageset/Contents.json new file mode 100644 index 0000000..2ff1237 --- /dev/null +++ b/week01/mission/Megabox_week1/Megabox/Assets.xcassets/kakao.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "kakao.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week01/mission/Megabox_week1/Megabox/Assets.xcassets/kakao.imageset/kakao.pdf b/week01/mission/Megabox_week1/Megabox/Assets.xcassets/kakao.imageset/kakao.pdf new file mode 100644 index 0000000..9f17f2b Binary files /dev/null and b/week01/mission/Megabox_week1/Megabox/Assets.xcassets/kakao.imageset/kakao.pdf differ diff --git a/week01/mission/Megabox_week1/Megabox/Assets.xcassets/megabox_logo.imageset/Contents.json b/week01/mission/Megabox_week1/Megabox/Assets.xcassets/megabox_logo.imageset/Contents.json new file mode 100644 index 0000000..9999a13 --- /dev/null +++ b/week01/mission/Megabox_week1/Megabox/Assets.xcassets/megabox_logo.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "megabox_logo.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week01/mission/Megabox_week1/Megabox/Assets.xcassets/megabox_logo.imageset/megabox_logo.pdf b/week01/mission/Megabox_week1/Megabox/Assets.xcassets/megabox_logo.imageset/megabox_logo.pdf new file mode 100644 index 0000000..88b2939 Binary files /dev/null and b/week01/mission/Megabox_week1/Megabox/Assets.xcassets/megabox_logo.imageset/megabox_logo.pdf differ diff --git a/week01/mission/Megabox_week1/Megabox/Assets.xcassets/naver.imageset/Contents.json b/week01/mission/Megabox_week1/Megabox/Assets.xcassets/naver.imageset/Contents.json new file mode 100644 index 0000000..59d595e --- /dev/null +++ b/week01/mission/Megabox_week1/Megabox/Assets.xcassets/naver.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "naver.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week01/mission/Megabox_week1/Megabox/Assets.xcassets/naver.imageset/naver.pdf b/week01/mission/Megabox_week1/Megabox/Assets.xcassets/naver.imageset/naver.pdf new file mode 100644 index 0000000..ebde8f5 Binary files /dev/null and b/week01/mission/Megabox_week1/Megabox/Assets.xcassets/naver.imageset/naver.pdf differ diff --git a/week01/mission/Megabox_week1/Megabox/Assets.xcassets/umc_image.imageset/Contents.json b/week01/mission/Megabox_week1/Megabox/Assets.xcassets/umc_image.imageset/Contents.json new file mode 100644 index 0000000..a6310e5 --- /dev/null +++ b/week01/mission/Megabox_week1/Megabox/Assets.xcassets/umc_image.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "umc_image.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week01/mission/Megabox_week1/Megabox/Assets.xcassets/umc_image.imageset/umc_image.png b/week01/mission/Megabox_week1/Megabox/Assets.xcassets/umc_image.imageset/umc_image.png new file mode 100644 index 0000000..47c6104 Binary files /dev/null and b/week01/mission/Megabox_week1/Megabox/Assets.xcassets/umc_image.imageset/umc_image.png differ diff --git a/week01/mission/Megabox_week1/Megabox/LoginView.swift b/week01/mission/Megabox_week1/Megabox/LoginView.swift new file mode 100644 index 0000000..2a4a6ac --- /dev/null +++ b/week01/mission/Megabox_week1/Megabox/LoginView.swift @@ -0,0 +1,93 @@ +import SwiftUI + + +struct LoginView: View { + + var body: some View { + VStack{ + //Part1 - 로그인 글씨 + Text("로그인").font(.PretendardSemiBold24).foregroundColor(.black) + Spacer(minLength: 44) + + //Part2 - 로그인 영역 + VStack{ + VStack(spacing: 40){ //Part2.1 - id,pw + //id + VStack(alignment: .leading, spacing: 6) { + Text("아이디").font(.PretendardMedium16).foregroundColor(.gray03) + Rectangle().frame(height: 1).foregroundColor(.gray02) + } + + //pw + VStack(alignment: .leading, spacing: 6) { + Text("비밀번호").font(.PretendardMedium16).foregroundColor(.gray03) + Rectangle().frame(height: 1).foregroundColor(.gray02) + } + } + Spacer(minLength: 75) + + VStack{ //2.2 - Login Button & 회원가입 + Button(action: {}) { + Text("로그인").font(.PretendardBold18).foregroundColor(.white) + .frame(maxWidth: .infinity, minHeight: 54) + .background(RoundedRectangle(cornerRadius: 12).fill(Color.purple04)) + } + .shadow(color: .black.opacity(0.25),radius: 12, x: 0, y: 8) + // 회원가입 + Text("회원가입").font(.PretendardMedium13).foregroundColor(.gray04) + } + Spacer(minLength: 17) + + HStack{ //2.3 아이콘 3개 넣기 + Spacer().frame(width: 71) // 왼쪽 여백 + + Image("naver") + .resizable() + .scaledToFit() + .frame(width: 40, height: 40) + + Spacer() // 네이버 ↔ 카카오 자동 간격 + + Image("kakao") + .resizable() + .scaledToFit() + .frame(width: 40, height: 40) + + Spacer() // 카카오 ↔ 애플 자동 간격 + + Image("apple") + .resizable() + .scaledToFit() + .frame(width: 40, height: 40) + + Spacer().frame(width: 71) // 오른쪽 여백 + + } + .frame(maxWidth: .infinity) // 부모 기준으로 꽉 차게 + + } + .frame(height: 323) // ← 여기서 전체 VStack 높이를 323pt로 고정 + Spacer(minLength: 17) + + // Part3 - 하단 사진 (이게 과제 요구사항) + Image("umc_image").resizable().scaledToFill().frame(width: 408, height: 266) + + //수정한 버전 이게 더 이쁘게 나옴 + /*Image("umc_image") + .resizable() + .scaledToFit() // 비율 유지하면서 가로에 맞춤 + .frame(maxWidth: .infinity) // 부모 너비 기준으로 채움 + .frame(height: 266) // 높이 고정 + .padding(.horizontal, 16) // ← 여기서 여백 적용 + */ + + + } + + .padding(.horizontal, 16) // ← 여기서 좌우 16pt 여백 적용 + } +} + +#Preview { + LoginView() +} diff --git a/week01/mission/Megabox_week1/Megabox/MegaboxApp.swift b/week01/mission/Megabox_week1/Megabox/MegaboxApp.swift new file mode 100644 index 0000000..9ba8350 --- /dev/null +++ b/week01/mission/Megabox_week1/Megabox/MegaboxApp.swift @@ -0,0 +1,17 @@ +// +// MegaboxApp.swift +// Megabox +// +// Created by 최우진 on 9/20/25. +// + +import SwiftUI + +@main +struct MegaboxApp: App { + var body: some Scene { + WindowGroup { + LoginView() + } + } +} diff --git a/week01/mission/Megabox_week1/Megabox/SplashView.swift b/week01/mission/Megabox_week1/Megabox/SplashView.swift new file mode 100644 index 0000000..bd95bf2 --- /dev/null +++ b/week01/mission/Megabox_week1/Megabox/SplashView.swift @@ -0,0 +1,15 @@ +import SwiftUI + +struct SplashView: View { + var body: some View { + VStack{ + Spacer() + Image("megabox_logo").resizable().scaledToFit().frame(width: 249, height: 84) + Spacer() + } + } +} + +#Preview { + SplashView() +} diff --git a/week01/mission/Megabox_week1/Megabox/color.swift b/week01/mission/Megabox_week1/Megabox/color.swift new file mode 100644 index 0000000..ee92204 --- /dev/null +++ b/week01/mission/Megabox_week1/Megabox/color.swift @@ -0,0 +1,62 @@ +// +// color.swift +// Megabox +// +// Created by 최우진 on 9/20/25. +// + +import Foundation +import SwiftUI + +extension Color { + // 1) 이니셜라이저를 Color.swift로 옮기고, 팔레트보다 위에 둡니다. + init(hex: UInt, alpha: Double = 1.0) { + self.init(.sRGB, + red: Double((hex >> 16) & 0xFF) / 255.0, + green: Double((hex >> 8) & 0xFF) / 255.0, + blue: Double( hex & 0xFF) / 255.0, + opacity: alpha) + } + + // 2) 팔레트 정의 + // Blue + static let blue00 = Color(hex: 0xE5EAFA as UInt) + static let blue01 = Color(hex: 0xFFFFFF as UInt) + static let blue02 = Color(hex: 0xE3E9F5 as UInt) + static let blue03 = Color(hex: 0x8AAAD6 as UInt) + static let blue04 = Color(hex: 0x6C94C3 as UInt) + static let blue05 = Color(hex: 0x5C85B9 as UInt) + static let blue06 = Color(hex: 0x466F9E as UInt) + static let blue07 = Color(hex: 0x2F567F as UInt) + static let blue08 = Color(hex: 0x1E3C60 as UInt) + static let blue09 = Color(hex: 0x132847 as UInt) + + // Purple + static let purple00 = Color(hex: 0xF5E8FF as UInt) + static let purple01 = Color(hex: 0xE4C8FF as UInt) + static let purple02 = Color(hex: 0xC49CFF as UInt) + static let purple03 = Color(hex: 0x9C6EFF as UInt) + static let purple04 = Color(hex: 0x6F2CFF as UInt) // 버튼 색 + static let purple05 = Color(hex: 0x5C23CC as UInt) + static let purple06 = Color(hex: 0x491A99 as UInt) + static let purple07 = Color(hex: 0x371266 as UInt) + static let purple08 = Color(hex: 0x240933 as UInt) + static let purple09 = Color(hex: 0x1A0020 as UInt) + + // Grey + static let gray00 = Color(hex: 0xF8F9FA as UInt) + static let gray01 = Color(hex: 0xF1F3F5 as UInt) + static let gray02 = Color(hex: 0xE5E5EA as UInt) + static let gray03 = Color(hex: 0xD1D5DB as UInt) + static let gray04 = Color(hex: 0x9CA3AF as UInt) + static let gray05 = Color(hex: 0x6B7280 as UInt) + static let gray06 = Color(hex: 0x4B5563 as UInt) + static let gray07 = Color(hex: 0x374151 as UInt) + static let gray08 = Color(hex: 0x1F2937 as UInt) + static let gray09 = Color(hex: 0x111827 as UInt) + + // White / Black (토큰) + static let White = Color.white + static let Black = Color.black +} + diff --git a/week01/mission/Megabox_week1/Megabox/resource/Fonts/Fonts.swift b/week01/mission/Megabox_week1/Megabox/resource/Fonts/Fonts.swift new file mode 100644 index 0000000..eb400a6 --- /dev/null +++ b/week01/mission/Megabox_week1/Megabox/resource/Fonts/Fonts.swift @@ -0,0 +1,152 @@ +// +// Fonts.swift +// Week1_Practice +// +// Created by 최우진 on 9/20/25. +// + +import Foundation +import SwiftUI + +extension Font { + enum Pretend { + case extraBold + case bold + case semibold + case medium + case regular + case light + + var value: String { + switch self { + case .extraBold: + return "Pretendard-ExtraBold" + case .bold: + return "Pretendard-Bold" + case .semibold: + return "Pretendard-SemiBold" + case .medium: + return "Pretendard-Medium" + case .regular: + return "Pretendard-Regular" + case .light: + return "Pretendard-Light" + } + } + } + + static func pretend(type: Pretend, size: CGFloat) -> Font { + return .custom(type.value, size: size) + } + + static var PretendardBold30: Font { + return .pretend(type: .bold, size: 30) + } + + // 새로 추가한 스타일 + static var PretendardRegular16: Font { + return .pretend(type: .regular, size: 16) + } + + static var PretendardBold24: Font { + return .pretend(type: .bold, size: 24) + } + + static var PretendardSemiBold18: Font { + return .pretend(type: .semibold, size: 18) + } + + static var PretendardLight16: Font { + return .pretend(type: .light, size: 16) + } + + // Bold + static var PretendardBold18: Font { + return .pretend(type: .bold, size: 18) + } + + static var PretendardBold22: Font { + return .pretend(type: .bold, size: 22) + } + + // SemiBold + static var PretendardSemiBold38: Font { + return .pretend(type: .semibold, size: 38) + } + + static var PretendardSemiBold24: Font { + return .pretend(type: .semibold, size: 24) + } + + static var PretendardSemiBold16: Font { + return .pretend(type: .semibold, size: 16) + } + + static var PretendardSemiBold14: Font { + return .pretend(type: .semibold, size: 14) + } + + static var PretendardSemiBold13: Font { + return .pretend(type: .semibold, size: 13) + } + + static var PretendardSemiBold12: Font { + return .pretend(type: .semibold, size: 12) + } + + // Regular + static var PretendardRegular20: Font { + return .pretend(type: .regular, size: 20) + } + + static var PretendardRegular18: Font { + return .pretend(type: .regular, size: 18) + } + + static var PretendardRegular13: Font { + return .pretend(type: .regular, size: 13) + } + + static var PretendardRegular12: Font { + return .pretend(type: .regular, size: 12) + } + + static var PretendardRegular9: Font { + return .pretend(type: .regular, size: 9) + } + + // Medium + static var PretendardMedium18: Font { + return .pretend(type: .medium, size: 18) + } + + static var PretendardMedium16: Font { + return .pretend(type: .medium, size: 16) + } + + static var PretendardMedium14: Font { + return .pretend(type: .medium, size: 14) + } + + static var PretendardMedium13: Font { + return .pretend(type: .medium, size: 13) + } + + static var PretendardMedium10: Font { + return .pretend(type: .medium, size: 10) + } + + static var PretendardMedium8: Font { + return .pretend(type: .medium, size: 8) + } + + // Light + static var PretendardLight14: Font { + return .pretend(type: .light, size: 14) + } + + // ExtraBold + static var PretendardExtraBold24: Font { + return .pretend(type: .extraBold, size: 24) + } +} diff --git a/week01/mission/Megabox_week1/Megabox/resource/Fonts/Pretendard-Black.otf b/week01/mission/Megabox_week1/Megabox/resource/Fonts/Pretendard-Black.otf new file mode 100644 index 0000000..a0d849e Binary files /dev/null and b/week01/mission/Megabox_week1/Megabox/resource/Fonts/Pretendard-Black.otf differ diff --git a/week01/mission/Megabox_week1/Megabox/resource/Fonts/Pretendard-Bold.otf b/week01/mission/Megabox_week1/Megabox/resource/Fonts/Pretendard-Bold.otf new file mode 100644 index 0000000..8e5e30a Binary files /dev/null and b/week01/mission/Megabox_week1/Megabox/resource/Fonts/Pretendard-Bold.otf differ diff --git a/week01/mission/Megabox_week1/Megabox/resource/Fonts/Pretendard-ExtraBold.otf b/week01/mission/Megabox_week1/Megabox/resource/Fonts/Pretendard-ExtraBold.otf new file mode 100644 index 0000000..388f3ca Binary files /dev/null and b/week01/mission/Megabox_week1/Megabox/resource/Fonts/Pretendard-ExtraBold.otf differ diff --git a/week01/mission/Megabox_week1/Megabox/resource/Fonts/Pretendard-ExtraLight.otf b/week01/mission/Megabox_week1/Megabox/resource/Fonts/Pretendard-ExtraLight.otf new file mode 100644 index 0000000..40c8b69 Binary files /dev/null and b/week01/mission/Megabox_week1/Megabox/resource/Fonts/Pretendard-ExtraLight.otf differ diff --git a/week01/mission/Megabox_week1/Megabox/resource/Fonts/Pretendard-Light.otf b/week01/mission/Megabox_week1/Megabox/resource/Fonts/Pretendard-Light.otf new file mode 100644 index 0000000..228679e Binary files /dev/null and b/week01/mission/Megabox_week1/Megabox/resource/Fonts/Pretendard-Light.otf differ diff --git a/week01/mission/Megabox_week1/Megabox/resource/Fonts/Pretendard-Medium.otf b/week01/mission/Megabox_week1/Megabox/resource/Fonts/Pretendard-Medium.otf new file mode 100644 index 0000000..0575069 Binary files /dev/null and b/week01/mission/Megabox_week1/Megabox/resource/Fonts/Pretendard-Medium.otf differ diff --git a/week01/mission/Megabox_week1/Megabox/resource/Fonts/Pretendard-Regular.otf b/week01/mission/Megabox_week1/Megabox/resource/Fonts/Pretendard-Regular.otf new file mode 100644 index 0000000..08bf4cf Binary files /dev/null and b/week01/mission/Megabox_week1/Megabox/resource/Fonts/Pretendard-Regular.otf differ diff --git a/week01/mission/Megabox_week1/Megabox/resource/Fonts/Pretendard-SemiBold.otf b/week01/mission/Megabox_week1/Megabox/resource/Fonts/Pretendard-SemiBold.otf new file mode 100644 index 0000000..e7e36ab Binary files /dev/null and b/week01/mission/Megabox_week1/Megabox/resource/Fonts/Pretendard-SemiBold.otf differ diff --git a/week01/mission/Megabox_week1/Megabox/resource/Fonts/Pretendard-Thin.otf b/week01/mission/Megabox_week1/Megabox/resource/Fonts/Pretendard-Thin.otf new file mode 100644 index 0000000..77e792d Binary files /dev/null and b/week01/mission/Megabox_week1/Megabox/resource/Fonts/Pretendard-Thin.otf differ diff --git a/week01/mission/Megabox_week1/MegaboxTests/MegaboxTests.swift b/week01/mission/Megabox_week1/MegaboxTests/MegaboxTests.swift new file mode 100644 index 0000000..c31796e --- /dev/null +++ b/week01/mission/Megabox_week1/MegaboxTests/MegaboxTests.swift @@ -0,0 +1,17 @@ +// +// MegaboxTests.swift +// MegaboxTests +// +// Created by 최우진 on 9/20/25. +// + +import Testing +@testable import Megabox + +struct MegaboxTests { + + @Test func example() async throws { + // Write your test here and use APIs like `#expect(...)` to check expected conditions. + } + +} diff --git a/week01/mission/Megabox_week1/MegaboxUITests/MegaboxUITests.swift b/week01/mission/Megabox_week1/MegaboxUITests/MegaboxUITests.swift new file mode 100644 index 0000000..2707644 --- /dev/null +++ b/week01/mission/Megabox_week1/MegaboxUITests/MegaboxUITests.swift @@ -0,0 +1,41 @@ +// +// MegaboxUITests.swift +// MegaboxUITests +// +// Created by 최우진 on 9/20/25. +// + +import XCTest + +final class MegaboxUITests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + @MainActor + func testExample() throws { + // UI tests must launch the application that they test. + let app = XCUIApplication() + app.launch() + + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + @MainActor + func testLaunchPerformance() throws { + // This measures how long it takes to launch your application. + measure(metrics: [XCTApplicationLaunchMetric()]) { + XCUIApplication().launch() + } + } +} diff --git a/week01/mission/Megabox_week1/MegaboxUITests/MegaboxUITestsLaunchTests.swift b/week01/mission/Megabox_week1/MegaboxUITests/MegaboxUITestsLaunchTests.swift new file mode 100644 index 0000000..12e3051 --- /dev/null +++ b/week01/mission/Megabox_week1/MegaboxUITests/MegaboxUITestsLaunchTests.swift @@ -0,0 +1,33 @@ +// +// MegaboxUITestsLaunchTests.swift +// MegaboxUITests +// +// Created by 최우진 on 9/20/25. +// + +import XCTest + +final class MegaboxUITestsLaunchTests: XCTestCase { + + override class var runsForEachTargetApplicationUIConfiguration: Bool { + true + } + + override func setUpWithError() throws { + continueAfterFailure = false + } + + @MainActor + func testLaunch() throws { + let app = XCUIApplication() + app.launch() + + // Insert steps here to perform after app launch but before taking a screenshot, + // such as logging into a test account or navigating somewhere in the app + + let attachment = XCTAttachment(screenshot: app.screenshot()) + attachment.name = "Launch Screen" + attachment.lifetime = .keepAlways + add(attachment) + } +} diff --git a/week02/mission/Week2_Megabox/Megabox_2.xcodeproj/project.pbxproj b/week02/mission/Week2_Megabox/Megabox_2.xcodeproj/project.pbxproj new file mode 100644 index 0000000..5afd53c --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2.xcodeproj/project.pbxproj @@ -0,0 +1,557 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 77; + objects = { + +/* Begin PBXContainerItemProxy section */ + 9390FBEF2E85C22F00A35604 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 9390FBD62E85C22D00A35604 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 9390FBDD2E85C22D00A35604; + remoteInfo = Megabox_2; + }; + 9390FBF92E85C22F00A35604 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 9390FBD62E85C22D00A35604 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 9390FBDD2E85C22D00A35604; + remoteInfo = Megabox_2; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 9390FBDE2E85C22D00A35604 /* Megabox_2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Megabox_2.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 9390FBEE2E85C22F00A35604 /* Megabox_2Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Megabox_2Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 9390FBF82E85C22F00A35604 /* Megabox_2UITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Megabox_2UITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + 9390FBE02E85C22D00A35604 /* Megabox_2 */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = Megabox_2; + sourceTree = ""; + }; + 9390FBF12E85C22F00A35604 /* Megabox_2Tests */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = Megabox_2Tests; + sourceTree = ""; + }; + 9390FBFB2E85C22F00A35604 /* Megabox_2UITests */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = Megabox_2UITests; + sourceTree = ""; + }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + 9390FBDB2E85C22D00A35604 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9390FBEB2E85C22F00A35604 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9390FBF52E85C22F00A35604 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9390FBD52E85C22D00A35604 = { + isa = PBXGroup; + children = ( + 9390FBE02E85C22D00A35604 /* Megabox_2 */, + 9390FBF12E85C22F00A35604 /* Megabox_2Tests */, + 9390FBFB2E85C22F00A35604 /* Megabox_2UITests */, + 9390FBDF2E85C22D00A35604 /* Products */, + ); + sourceTree = ""; + }; + 9390FBDF2E85C22D00A35604 /* Products */ = { + isa = PBXGroup; + children = ( + 9390FBDE2E85C22D00A35604 /* Megabox_2.app */, + 9390FBEE2E85C22F00A35604 /* Megabox_2Tests.xctest */, + 9390FBF82E85C22F00A35604 /* Megabox_2UITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 9390FBDD2E85C22D00A35604 /* Megabox_2 */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9390FC022E85C22F00A35604 /* Build configuration list for PBXNativeTarget "Megabox_2" */; + buildPhases = ( + 9390FBDA2E85C22D00A35604 /* Sources */, + 9390FBDB2E85C22D00A35604 /* Frameworks */, + 9390FBDC2E85C22D00A35604 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + 9390FBE02E85C22D00A35604 /* Megabox_2 */, + ); + name = Megabox_2; + packageProductDependencies = ( + ); + productName = Megabox_2; + productReference = 9390FBDE2E85C22D00A35604 /* Megabox_2.app */; + productType = "com.apple.product-type.application"; + }; + 9390FBED2E85C22F00A35604 /* Megabox_2Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9390FC052E85C22F00A35604 /* Build configuration list for PBXNativeTarget "Megabox_2Tests" */; + buildPhases = ( + 9390FBEA2E85C22F00A35604 /* Sources */, + 9390FBEB2E85C22F00A35604 /* Frameworks */, + 9390FBEC2E85C22F00A35604 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 9390FBF02E85C22F00A35604 /* PBXTargetDependency */, + ); + fileSystemSynchronizedGroups = ( + 9390FBF12E85C22F00A35604 /* Megabox_2Tests */, + ); + name = Megabox_2Tests; + packageProductDependencies = ( + ); + productName = Megabox_2Tests; + productReference = 9390FBEE2E85C22F00A35604 /* Megabox_2Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 9390FBF72E85C22F00A35604 /* Megabox_2UITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9390FC082E85C22F00A35604 /* Build configuration list for PBXNativeTarget "Megabox_2UITests" */; + buildPhases = ( + 9390FBF42E85C22F00A35604 /* Sources */, + 9390FBF52E85C22F00A35604 /* Frameworks */, + 9390FBF62E85C22F00A35604 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 9390FBFA2E85C22F00A35604 /* PBXTargetDependency */, + ); + fileSystemSynchronizedGroups = ( + 9390FBFB2E85C22F00A35604 /* Megabox_2UITests */, + ); + name = Megabox_2UITests; + packageProductDependencies = ( + ); + productName = Megabox_2UITests; + productReference = 9390FBF82E85C22F00A35604 /* Megabox_2UITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 9390FBD62E85C22D00A35604 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1620; + LastUpgradeCheck = 1620; + TargetAttributes = { + 9390FBDD2E85C22D00A35604 = { + CreatedOnToolsVersion = 16.2; + }; + 9390FBED2E85C22F00A35604 = { + CreatedOnToolsVersion = 16.2; + TestTargetID = 9390FBDD2E85C22D00A35604; + }; + 9390FBF72E85C22F00A35604 = { + CreatedOnToolsVersion = 16.2; + TestTargetID = 9390FBDD2E85C22D00A35604; + }; + }; + }; + buildConfigurationList = 9390FBD92E85C22D00A35604 /* Build configuration list for PBXProject "Megabox_2" */; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 9390FBD52E85C22D00A35604; + minimizedProjectReferenceProxies = 1; + preferredProjectObjectVersion = 77; + productRefGroup = 9390FBDF2E85C22D00A35604 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 9390FBDD2E85C22D00A35604 /* Megabox_2 */, + 9390FBED2E85C22F00A35604 /* Megabox_2Tests */, + 9390FBF72E85C22F00A35604 /* Megabox_2UITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 9390FBDC2E85C22D00A35604 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9390FBEC2E85C22F00A35604 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9390FBF62E85C22F00A35604 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 9390FBDA2E85C22D00A35604 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9390FBEA2E85C22F00A35604 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9390FBF42E85C22F00A35604 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 9390FBF02E85C22F00A35604 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 9390FBDD2E85C22D00A35604 /* Megabox_2 */; + targetProxy = 9390FBEF2E85C22F00A35604 /* PBXContainerItemProxy */; + }; + 9390FBFA2E85C22F00A35604 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 9390FBDD2E85C22D00A35604 /* Megabox_2 */; + targetProxy = 9390FBF92E85C22F00A35604 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 9390FC002E85C22F00A35604 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + 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; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + 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 = 18.2; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 9390FC012E85C22F00A35604 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + 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; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + 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 = 18.2; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 9390FC032E85C22F00A35604 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"Megabox_2/Preview Content\""; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "woojin.Megabox-2"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 9390FC042E85C22F00A35604 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"Megabox_2/Preview Content\""; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "woojin.Megabox-2"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 9390FC062E85C22F00A35604 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.2; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "woojin.Megabox-2Tests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Megabox_2.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Megabox_2"; + }; + name = Debug; + }; + 9390FC072E85C22F00A35604 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.2; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "woojin.Megabox-2Tests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Megabox_2.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Megabox_2"; + }; + name = Release; + }; + 9390FC092E85C22F00A35604 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "woojin.Megabox-2UITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = Megabox_2; + }; + name = Debug; + }; + 9390FC0A2E85C22F00A35604 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "woojin.Megabox-2UITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = Megabox_2; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 9390FBD92E85C22D00A35604 /* Build configuration list for PBXProject "Megabox_2" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9390FC002E85C22F00A35604 /* Debug */, + 9390FC012E85C22F00A35604 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 9390FC022E85C22F00A35604 /* Build configuration list for PBXNativeTarget "Megabox_2" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9390FC032E85C22F00A35604 /* Debug */, + 9390FC042E85C22F00A35604 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 9390FC052E85C22F00A35604 /* Build configuration list for PBXNativeTarget "Megabox_2Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9390FC062E85C22F00A35604 /* Debug */, + 9390FC072E85C22F00A35604 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 9390FC082E85C22F00A35604 /* Build configuration list for PBXNativeTarget "Megabox_2UITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9390FC092E85C22F00A35604 /* Debug */, + 9390FC0A2E85C22F00A35604 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 9390FBD62E85C22D00A35604 /* Project object */; +} diff --git a/week02/mission/Week2_Megabox/Megabox_2.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/week02/mission/Week2_Megabox/Megabox_2.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/week02/mission/Week2_Megabox/Megabox_2.xcodeproj/project.xcworkspace/xcuserdata/ujin.xcuserdatad/UserInterfaceState.xcuserstate b/week02/mission/Week2_Megabox/Megabox_2.xcodeproj/project.xcworkspace/xcuserdata/ujin.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..e0a39e0 Binary files /dev/null and b/week02/mission/Week2_Megabox/Megabox_2.xcodeproj/project.xcworkspace/xcuserdata/ujin.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/week02/mission/Week2_Megabox/Megabox_2.xcodeproj/xcuserdata/ujin.xcuserdatad/xcschemes/xcschememanagement.plist b/week02/mission/Week2_Megabox/Megabox_2.xcodeproj/xcuserdata/ujin.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..6853619 --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2.xcodeproj/xcuserdata/ujin.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + Megabox_2.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/AccentColor.colorset/Contents.json b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/AppIcon.appiconset/Contents.json b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..2305880 --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,35 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "tinted" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/Contents.json b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/apple.imageset/Contents.json b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/apple.imageset/Contents.json new file mode 100644 index 0000000..0975940 --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/apple.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "apple.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/apple.imageset/apple.pdf b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/apple.imageset/apple.pdf new file mode 100644 index 0000000..909af30 Binary files /dev/null and b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/apple.imageset/apple.pdf differ diff --git a/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/background.imageset/Contents.json b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/background.imageset/Contents.json new file mode 100644 index 0000000..7e26126 --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/background.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "background.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/background.imageset/background.pdf b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/background.imageset/background.pdf new file mode 100644 index 0000000..e2c0ebe Binary files /dev/null and b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/background.imageset/background.pdf differ diff --git a/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/cinema.imageset/Contents.json b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/cinema.imageset/Contents.json new file mode 100644 index 0000000..430a6e5 --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/cinema.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "cinema.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/cinema.imageset/cinema.pdf b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/cinema.imageset/cinema.pdf new file mode 100644 index 0000000..d76a452 Binary files /dev/null and b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/cinema.imageset/cinema.pdf differ diff --git a/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/clock.imageset/Contents.json b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/clock.imageset/Contents.json new file mode 100644 index 0000000..bd6a149 --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/clock.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "clock.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/clock.imageset/clock.png b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/clock.imageset/clock.png new file mode 100644 index 0000000..6e662a5 Binary files /dev/null and b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/clock.imageset/clock.png differ diff --git a/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/film-reel.imageset/Contents.json b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/film-reel.imageset/Contents.json new file mode 100644 index 0000000..c1aba9f --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/film-reel.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "film-reel.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/film-reel.imageset/film-reel.pdf b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/film-reel.imageset/film-reel.pdf new file mode 100644 index 0000000..9d4ba17 Binary files /dev/null and b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/film-reel.imageset/film-reel.pdf differ diff --git a/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/kakao.imageset/Contents.json b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/kakao.imageset/Contents.json new file mode 100644 index 0000000..2ff1237 --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/kakao.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "kakao.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/kakao.imageset/kakao.pdf b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/kakao.imageset/kakao.pdf new file mode 100644 index 0000000..9f17f2b Binary files /dev/null and b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/kakao.imageset/kakao.pdf differ diff --git a/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/map.imageset/Contents.json b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/map.imageset/Contents.json new file mode 100644 index 0000000..60ad78a --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/map.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "map.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/map.imageset/map.pdf b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/map.imageset/map.pdf new file mode 100644 index 0000000..9bc07f2 Binary files /dev/null and b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/map.imageset/map.pdf differ diff --git a/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/megabox_logo.imageset/Contents.json b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/megabox_logo.imageset/Contents.json new file mode 100644 index 0000000..9999a13 --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/megabox_logo.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "megabox_logo.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/megabox_logo.imageset/megabox_logo.pdf b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/megabox_logo.imageset/megabox_logo.pdf new file mode 100644 index 0000000..88b2939 Binary files /dev/null and b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/megabox_logo.imageset/megabox_logo.pdf differ diff --git a/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/naver.imageset/Contents.json b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/naver.imageset/Contents.json new file mode 100644 index 0000000..59d595e --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/naver.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "naver.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/naver.imageset/naver.pdf b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/naver.imageset/naver.pdf new file mode 100644 index 0000000..ebde8f5 Binary files /dev/null and b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/naver.imageset/naver.pdf differ diff --git a/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/sofa.imageset/Contents.json b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/sofa.imageset/Contents.json new file mode 100644 index 0000000..7867b3b --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/sofa.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "sofa.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/sofa.imageset/sofa.pdf b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/sofa.imageset/sofa.pdf new file mode 100644 index 0000000..a7bfd92 Binary files /dev/null and b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/sofa.imageset/sofa.pdf differ diff --git a/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/umc_image.imageset/Contents.json b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/umc_image.imageset/Contents.json new file mode 100644 index 0000000..a6310e5 --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/umc_image.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "umc_image.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/umc_image.imageset/umc_image.png b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/umc_image.imageset/umc_image.png new file mode 100644 index 0000000..47c6104 Binary files /dev/null and b/week02/mission/Week2_Megabox/Megabox_2/Assets.xcassets/umc_image.imageset/umc_image.png differ diff --git a/week02/mission/Week2_Megabox/Megabox_2/ContentView.swift b/week02/mission/Week2_Megabox/Megabox_2/ContentView.swift new file mode 100644 index 0000000..a65b078 --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2/ContentView.swift @@ -0,0 +1,24 @@ +// +// ContentView.swift +// Megabox_2 +// +// Created by 최우진 on 9/26/25. +// + +import SwiftUI + +struct ContentView: View { + var body: some View { + VStack { + Image(systemName: "globe") + .imageScale(.large) + .foregroundStyle(.tint) + Text("Hello, world!") + } + .padding() + } +} + +#Preview { + ContentView() +} diff --git a/week02/mission/Week2_Megabox/Megabox_2/LoginModel.swift b/week02/mission/Week2_Megabox/Megabox_2/LoginModel.swift new file mode 100644 index 0000000..c035007 --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2/LoginModel.swift @@ -0,0 +1,15 @@ +// +// LoginModel.swift +// Megabox +// +// Created by 최우진 on 9/25/25. +// + +// LoginModel.swift + +import Foundation + +struct LoginModel { + var id: String = "" + var pwd: String = "" +} diff --git a/week02/mission/Week2_Megabox/Megabox_2/LoginView.swift b/week02/mission/Week2_Megabox/Megabox_2/LoginView.swift new file mode 100644 index 0000000..9aeb0ec --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2/LoginView.swift @@ -0,0 +1,114 @@ +import SwiftUI + + +struct LoginView: View { + @State private var viewModel = LoginViewModel() + @AppStorage("savedId") private var savedId: String = "" + @AppStorage("savedPassword") private var savedPassword: String = "" + + var body: some View { + NavigationStack { + VStack{ + //Part1 - 로그인 글씨 + Text("로그인").font(.PretendardSemiBold24).foregroundColor(.black) + Spacer(minLength: 44) + + //Part2 - 로그인 영역 + VStack{ + VStack(spacing: 40){ //Part2.1 - id,pw + //id + VStack(alignment: .leading, spacing: 6) { + TextField("아이디", text: $viewModel.id).font(.PretendardMedium16).foregroundColor(.gray03) + Rectangle().frame(height: 1).foregroundColor(.gray02) + } + + //pw + VStack(alignment: .leading, spacing: 6) { + SecureField("비밀번호", text: $viewModel.pwd).font(.PretendardMedium16).foregroundColor(.gray03) + Rectangle().frame(height: 1).foregroundColor(.gray02) + } + } + Spacer(minLength: 75) + + VStack{ //2.2 - Login Button & 회원가입 + // Button(action: { + // savedId = viewModel.id + // savedPassword = viewModel.pwd + // }) { + // Text("로그인").font(.PretendardBold18).foregroundColor(.white) + // .frame(maxWidth: .infinity, minHeight: 54) + // .background(RoundedRectangle(cornerRadius: 12).fill(Color.purple04)) + // } + // .shadow(color: .black.opacity(0.25),radius: 12, x: 0, y: 8) + NavigationLink(destination: MemberInfoView()) { + // 버튼의 '모양'은 그대로 유지 + Text("로그인") + .font(.PretendardBold18) + .foregroundColor(.white) + .frame(maxWidth: .infinity, minHeight: 54) + .background(RoundedRectangle(cornerRadius: 12).fill(Color.purple04)) + } + .shadow(color: .black.opacity(0.25), radius: 12, x: 0, y: 8) + // 버튼을 누르는 '동작'은 .simultaneousGesture로 실행 + .simultaneousGesture(TapGesture().onEnded { + savedId = viewModel.id + savedPassword = viewModel.pwd + }) + // 회원가입 + Text("회원가입").font(.PretendardMedium13).foregroundColor(.gray04) + } + Spacer(minLength: 17) + + HStack{ //2.3 아이콘 3개 넣기 + Spacer().frame(width: 71) // 왼쪽 여백 + + Image("naver") + .resizable() + .scaledToFit() + .frame(width: 40, height: 40) + + Spacer() // 네이버 ↔ 카카오 자동 간격 + + Image("kakao") + .resizable() + .scaledToFit() + .frame(width: 40, height: 40) + + Spacer() // 카카오 ↔ 애플 자동 간격 + + Image("apple") + .resizable() + .scaledToFit() + .frame(width: 40, height: 40) + + Spacer().frame(width: 71) // 오른쪽 여백 + + } + .frame(maxWidth: .infinity) // 부모 기준으로 꽉 차게 + + } + .frame(height: 323) // ← 여기서 전체 VStack 높이를 323pt로 고정 + Spacer(minLength: 17) + + // Part3 - 하단 사진 (이게 과제 요구사항) + Image("umc_image").resizable().scaledToFill().frame(width: 408, height: 266) + + //수정한 버전 이게 더 이쁘게 나옴 + /*Image("umc_image") + .resizable() + .scaledToFit() // 비율 유지하면서 가로에 맞춤 + .frame(maxWidth: .infinity) // 부모 너비 기준으로 채움 + .frame(height: 266) // 높이 고정 + .padding(.horizontal, 16) // ← 여기서 여백 적용 + */ + + + } + .padding(.horizontal, 16) // ← 여기서 좌우 16pt 여백 적용 + } + } +} + +#Preview { + LoginView() +} diff --git a/week02/mission/Week2_Megabox/Megabox_2/LoginViewModel.swift b/week02/mission/Week2_Megabox/Megabox_2/LoginViewModel.swift new file mode 100644 index 0000000..9e12630 --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2/LoginViewModel.swift @@ -0,0 +1,27 @@ +// +// LoginViewModel.swift +// Megabox +// +// Created by 최우진 on 9/25/25. +// + +// LoginViewModel.swift + +import Foundation +import Observation + + +@Observable //전역으로 사용할 수 있도록 설정 +class LoginViewModel { + var loginModel = LoginModel() + + var id: String { + get { loginModel.id } + set { loginModel.id = newValue } + } + + var pwd: String { + get { loginModel.pwd } + set { loginModel.pwd = newValue } + } +} diff --git a/week02/mission/Week2_Megabox/Megabox_2/Megabox_2App.swift b/week02/mission/Week2_Megabox/Megabox_2/Megabox_2App.swift new file mode 100644 index 0000000..580318c --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2/Megabox_2App.swift @@ -0,0 +1,29 @@ +// +// Megabox_2App.swift +// Megabox_2 +// +// Created by 최우진 on 9/26/25. +// + +import SwiftUI + +@main +struct MegaboxApp: App { + @State private var showLogin = true + + var body: some Scene { + WindowGroup { + if showLogin { + SplashView() + .onAppear { + DispatchQueue.main.asyncAfter(deadline: .now() + 2) { + showLogin = false + } + } + } + else { + LoginView() + } + } + } +} diff --git a/week02/mission/Week2_Megabox/Megabox_2/MemberInfoManagementView.swift b/week02/mission/Week2_Megabox/Megabox_2/MemberInfoManagementView.swift new file mode 100644 index 0000000..2b3749c --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2/MemberInfoManagementView.swift @@ -0,0 +1,99 @@ +// +// MemberInfoManagementView.swift +// Megabox_2 +// +// Created by 최우진 on 9/26/25. +// + +import SwiftUI + +struct MemberInfoManagementView: View { + // 커스텀 뒤로가기 버튼을 위한 환경 변수 + @Environment(\.dismiss) var dismiss + + // AppStorage 변수 선언 + @AppStorage("savedId") private var savedId: String = "jwlee010523" + @AppStorage("userName") private var userName: String = "최우진" + + // TextField의 입력을 실시간으로 받기 위한 @State 변수 + @State private var nameInput: String = "" + + var body: some View { + // 1. 가장 큰 VStack + VStack(spacing: 53) { + + // 2. 상단 네비게이션 바 (HStack) + HStack(spacing:0) { + // 커스텀 뒤로가기 버튼 + Button(action: { + dismiss() // 이 버튼을 누르면 이전 화면으로 돌아갑니다. + }) { + Image(systemName: "arrow.left") + .foregroundColor(.black) + } + + Spacer() + + Text("회원정보 관리") + .font(.PretendardMedium16) + + Spacer() + } + + + + // 3. 기본정보 파트 (VStack) + VStack(alignment: .leading, spacing: 26) { + Text("기본정보") + .font(.PretendardBold18) + + // 아이디 (Text 처리) + VStack(alignment: .leading, spacing: 3) { + Text(savedId) + .foregroundColor(.black).font(.PretendardMedium18) + Divider().background(Color.gray02) + } + + // 이름 (TextField + 변경 버튼) + VStack(alignment: .leading, spacing: 3) { + HStack { + TextField("이름", text: $nameInput).font(.PretendardMedium18) + + // 이름 변경 버튼 + Button(action: { + // TextField에 입력된 값을 AppStorage에 저장 + userName = nameInput + + }) { + ZStack { + // 1. 배경 레이어 + RoundedRectangle(cornerRadius: 16) + .stroke(Color.gray03, lineWidth: 1) + + // 2. 상단 레이어 + Text("변경") + .font(.PretendardMedium10) + .foregroundColor(.gray03) + }.frame(width: 60, height: 28) + } + } + Divider().background(Color.gray02) + } + } + + Spacer() + } + .padding(.horizontal,16) // 전체적인 좌우 여백 + .navigationBarBackButtonHidden(true) // SwiftUI의 기본 뒤로가기 버튼 숨기기 + .onAppear { + // 이 화면이 나타날 때, AppStorage에 저장된 이름을 TextField에 미리 채우도록 설정 + nameInput = userName + } + } +} + +#Preview { + NavigationStack { + MemberInfoManagementView() + } +} diff --git a/week02/mission/Week2_Megabox/Megabox_2/MemberInfoView.swift b/week02/mission/Week2_Megabox/Megabox_2/MemberInfoView.swift new file mode 100644 index 0000000..8e0b16d --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2/MemberInfoView.swift @@ -0,0 +1,183 @@ +import SwiftUI + +struct MemberInfoView: View { + // 로그인 뷰에서 저장한 아이디를 가져옵니다. + @AppStorage("savedId") private var savedId: String = "" + @AppStorage("userName") private var userName: String = "최우진" + + var body: some View { + NavigationStack { //회원정보 View로 가도록 + VStack(spacing: 33) { + HStack(alignment: .top) { + // 이름과 포인트를 담는 왼쪽 VStack + VStack(alignment: .leading, spacing: 0) { + HStack(spacing:5) { + Text(userName) + .font(.PretendardBold24) + .fontWeight(.bold) + ZStack { + RoundedRectangle(cornerRadius: 6) + .fill(Color(red: 48/255, green: 209/255, blue: 201/255)) + Text("WELCOME") + .font(.PretendardMedium14) + .fontWeight(.bold) + .foregroundColor(.white) + } + .frame(width: 81, height: 25) + } + HStack(spacing: 9) { + Text("멤버십 포인트") + .font(.footnote) + .foregroundColor(.gray) + Text("500P") + .font(.footnote) + .fontWeight(.semibold) + } + } + Spacer() + // 회원정보 버튼 + NavigationLink(destination: MemberInfoManagementView()) { + VStack { + Text("회원정보") + .font(.PretendardSemiBold14) + .foregroundColor(.white) + } + .padding(.vertical, 4) + .frame(width: 72, height: 28) + .background(Color.gray07) + .cornerRadius(16) + } + } + VStack { + HStack(spacing : 3) { + Text("클럽 멤버십") + .font(.PretendardSemiBold16) + .foregroundColor(.white) + + Image(systemName: "chevron.right") + .font(.system(size: 14, weight: .semibold)) // 아이콘 크기/굵기 조절 + .foregroundColor(.white.opacity(0.8)) + + Spacer() + } + } + .frame(maxWidth: .infinity) + .padding(.vertical, 12) // 상하 패딩 12pt (높이를 46pt로 만듦) + .padding(.horizontal,8) + .background( + LinearGradient( + gradient: Gradient(colors: [ + Color(red: 0.67, green: 0.55, blue: 1), + Color(red: 0.56, green: 0.68, blue: 0.95), + Color(red: 0.36, green: 0.8, blue: 0.93) + ]), + //그라데이션 만들기 + startPoint: .leading, + endPoint: .trailing + ) + ) + .cornerRadius(8) + + ZStack { + // 배경과 테두리 + RoundedRectangle(cornerRadius: 8) + .fill(Color.white) + .stroke(Color.gray02, lineWidth: 1) + + + HStack (spacing: 43){ + VStack(spacing: 9) { + Text("쿠폰") + .font(.PretendardSemiBold16) + .foregroundColor(.gray02) + Text("2") + .font(.PretendardSemiBold18) + .foregroundColor(.black) + } + .frame(maxWidth: .infinity) + + Divider().frame(height: 31) + + VStack(spacing: 9) { + Text("스토어 교환권") + .font(.PretendardSemiBold16) + .foregroundColor(.gray02) + Text("0") + .font(.PretendardSemiBold18) + .foregroundColor(.black) + } + .frame(maxWidth: .infinity) + + Divider().frame(height: 31) + + VStack(spacing: 9) { + Text("모바일 티켓") + .font(.PretendardSemiBold16) + .foregroundColor(.gray02) + Text("0") + .font(.PretendardSemiBold18) + .foregroundColor(.black) + } + .frame(maxWidth: .infinity) + } + .padding(.vertical, 12) + .padding(.horizontal, 24) + } + .frame(height: 76) + + HStack(alignment: .top, spacing: 16) { + VStack(spacing: 12) { + Image("film-reel") + .resizable() + .scaledToFit() + .frame(height: 36) + Text("영화별예매") + .font(.PretendardMedium16) + } + .frame(maxWidth: .infinity) + + VStack(spacing: 12) { + Image("map") + .resizable() + .scaledToFit() + .frame(height: 36) + Text("극장별예매") + .font(.PretendardMedium16) + } + .frame(maxWidth: .infinity) + + VStack(spacing: 12) { + Image("sofa") + .resizable() + .scaledToFit() + .frame(height: 36) + Text("특별관예매") + .font(.PretendardMedium16) + } + .frame(maxWidth: .infinity) + + VStack(spacing: 12) { + Image("cinema") + .resizable() + .scaledToFit() + .frame(height: 36) + Text("모바일오더") + .font(.PretendardMedium16) + } + .frame(maxWidth: .infinity) + + } + + Spacer() + } + .padding(.horizontal, 24) // ← 여기서 전체 좌우 16pt 여백 줌 + .padding(.vertical, 95) + .background(Color(uiColor: .white)) // 전체 배경색 + } + .navigationBarBackButtonHidden(true) + } +} + +#Preview { + MemberInfoView() +} diff --git a/week02/mission/Week2_Megabox/Megabox_2/Preview Content/Preview Assets.xcassets/Contents.json b/week02/mission/Week2_Megabox/Megabox_2/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week02/mission/Week2_Megabox/Megabox_2/SplashView.swift b/week02/mission/Week2_Megabox/Megabox_2/SplashView.swift new file mode 100644 index 0000000..bd95bf2 --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2/SplashView.swift @@ -0,0 +1,15 @@ +import SwiftUI + +struct SplashView: View { + var body: some View { + VStack{ + Spacer() + Image("megabox_logo").resizable().scaledToFit().frame(width: 249, height: 84) + Spacer() + } + } +} + +#Preview { + SplashView() +} diff --git a/week02/mission/Week2_Megabox/Megabox_2/color.swift b/week02/mission/Week2_Megabox/Megabox_2/color.swift new file mode 100644 index 0000000..ee92204 --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2/color.swift @@ -0,0 +1,62 @@ +// +// color.swift +// Megabox +// +// Created by 최우진 on 9/20/25. +// + +import Foundation +import SwiftUI + +extension Color { + // 1) 이니셜라이저를 Color.swift로 옮기고, 팔레트보다 위에 둡니다. + init(hex: UInt, alpha: Double = 1.0) { + self.init(.sRGB, + red: Double((hex >> 16) & 0xFF) / 255.0, + green: Double((hex >> 8) & 0xFF) / 255.0, + blue: Double( hex & 0xFF) / 255.0, + opacity: alpha) + } + + // 2) 팔레트 정의 + // Blue + static let blue00 = Color(hex: 0xE5EAFA as UInt) + static let blue01 = Color(hex: 0xFFFFFF as UInt) + static let blue02 = Color(hex: 0xE3E9F5 as UInt) + static let blue03 = Color(hex: 0x8AAAD6 as UInt) + static let blue04 = Color(hex: 0x6C94C3 as UInt) + static let blue05 = Color(hex: 0x5C85B9 as UInt) + static let blue06 = Color(hex: 0x466F9E as UInt) + static let blue07 = Color(hex: 0x2F567F as UInt) + static let blue08 = Color(hex: 0x1E3C60 as UInt) + static let blue09 = Color(hex: 0x132847 as UInt) + + // Purple + static let purple00 = Color(hex: 0xF5E8FF as UInt) + static let purple01 = Color(hex: 0xE4C8FF as UInt) + static let purple02 = Color(hex: 0xC49CFF as UInt) + static let purple03 = Color(hex: 0x9C6EFF as UInt) + static let purple04 = Color(hex: 0x6F2CFF as UInt) // 버튼 색 + static let purple05 = Color(hex: 0x5C23CC as UInt) + static let purple06 = Color(hex: 0x491A99 as UInt) + static let purple07 = Color(hex: 0x371266 as UInt) + static let purple08 = Color(hex: 0x240933 as UInt) + static let purple09 = Color(hex: 0x1A0020 as UInt) + + // Grey + static let gray00 = Color(hex: 0xF8F9FA as UInt) + static let gray01 = Color(hex: 0xF1F3F5 as UInt) + static let gray02 = Color(hex: 0xE5E5EA as UInt) + static let gray03 = Color(hex: 0xD1D5DB as UInt) + static let gray04 = Color(hex: 0x9CA3AF as UInt) + static let gray05 = Color(hex: 0x6B7280 as UInt) + static let gray06 = Color(hex: 0x4B5563 as UInt) + static let gray07 = Color(hex: 0x374151 as UInt) + static let gray08 = Color(hex: 0x1F2937 as UInt) + static let gray09 = Color(hex: 0x111827 as UInt) + + // White / Black (토큰) + static let White = Color.white + static let Black = Color.black +} + diff --git a/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Fonts.swift b/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Fonts.swift new file mode 100644 index 0000000..eb400a6 --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Fonts.swift @@ -0,0 +1,152 @@ +// +// Fonts.swift +// Week1_Practice +// +// Created by 최우진 on 9/20/25. +// + +import Foundation +import SwiftUI + +extension Font { + enum Pretend { + case extraBold + case bold + case semibold + case medium + case regular + case light + + var value: String { + switch self { + case .extraBold: + return "Pretendard-ExtraBold" + case .bold: + return "Pretendard-Bold" + case .semibold: + return "Pretendard-SemiBold" + case .medium: + return "Pretendard-Medium" + case .regular: + return "Pretendard-Regular" + case .light: + return "Pretendard-Light" + } + } + } + + static func pretend(type: Pretend, size: CGFloat) -> Font { + return .custom(type.value, size: size) + } + + static var PretendardBold30: Font { + return .pretend(type: .bold, size: 30) + } + + // 새로 추가한 스타일 + static var PretendardRegular16: Font { + return .pretend(type: .regular, size: 16) + } + + static var PretendardBold24: Font { + return .pretend(type: .bold, size: 24) + } + + static var PretendardSemiBold18: Font { + return .pretend(type: .semibold, size: 18) + } + + static var PretendardLight16: Font { + return .pretend(type: .light, size: 16) + } + + // Bold + static var PretendardBold18: Font { + return .pretend(type: .bold, size: 18) + } + + static var PretendardBold22: Font { + return .pretend(type: .bold, size: 22) + } + + // SemiBold + static var PretendardSemiBold38: Font { + return .pretend(type: .semibold, size: 38) + } + + static var PretendardSemiBold24: Font { + return .pretend(type: .semibold, size: 24) + } + + static var PretendardSemiBold16: Font { + return .pretend(type: .semibold, size: 16) + } + + static var PretendardSemiBold14: Font { + return .pretend(type: .semibold, size: 14) + } + + static var PretendardSemiBold13: Font { + return .pretend(type: .semibold, size: 13) + } + + static var PretendardSemiBold12: Font { + return .pretend(type: .semibold, size: 12) + } + + // Regular + static var PretendardRegular20: Font { + return .pretend(type: .regular, size: 20) + } + + static var PretendardRegular18: Font { + return .pretend(type: .regular, size: 18) + } + + static var PretendardRegular13: Font { + return .pretend(type: .regular, size: 13) + } + + static var PretendardRegular12: Font { + return .pretend(type: .regular, size: 12) + } + + static var PretendardRegular9: Font { + return .pretend(type: .regular, size: 9) + } + + // Medium + static var PretendardMedium18: Font { + return .pretend(type: .medium, size: 18) + } + + static var PretendardMedium16: Font { + return .pretend(type: .medium, size: 16) + } + + static var PretendardMedium14: Font { + return .pretend(type: .medium, size: 14) + } + + static var PretendardMedium13: Font { + return .pretend(type: .medium, size: 13) + } + + static var PretendardMedium10: Font { + return .pretend(type: .medium, size: 10) + } + + static var PretendardMedium8: Font { + return .pretend(type: .medium, size: 8) + } + + // Light + static var PretendardLight14: Font { + return .pretend(type: .light, size: 14) + } + + // ExtraBold + static var PretendardExtraBold24: Font { + return .pretend(type: .extraBold, size: 24) + } +} diff --git a/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Pretendard-Black.otf b/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Pretendard-Black.otf new file mode 100644 index 0000000..a0d849e Binary files /dev/null and b/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Pretendard-Black.otf differ diff --git a/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Pretendard-Bold.otf b/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Pretendard-Bold.otf new file mode 100644 index 0000000..8e5e30a Binary files /dev/null and b/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Pretendard-Bold.otf differ diff --git a/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Pretendard-ExtraBold.otf b/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Pretendard-ExtraBold.otf new file mode 100644 index 0000000..388f3ca Binary files /dev/null and b/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Pretendard-ExtraBold.otf differ diff --git a/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Pretendard-ExtraLight.otf b/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Pretendard-ExtraLight.otf new file mode 100644 index 0000000..40c8b69 Binary files /dev/null and b/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Pretendard-ExtraLight.otf differ diff --git a/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Pretendard-Light.otf b/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Pretendard-Light.otf new file mode 100644 index 0000000..228679e Binary files /dev/null and b/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Pretendard-Light.otf differ diff --git a/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Pretendard-Medium.otf b/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Pretendard-Medium.otf new file mode 100644 index 0000000..0575069 Binary files /dev/null and b/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Pretendard-Medium.otf differ diff --git a/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Pretendard-Regular.otf b/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Pretendard-Regular.otf new file mode 100644 index 0000000..08bf4cf Binary files /dev/null and b/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Pretendard-Regular.otf differ diff --git a/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Pretendard-SemiBold.otf b/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Pretendard-SemiBold.otf new file mode 100644 index 0000000..e7e36ab Binary files /dev/null and b/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Pretendard-SemiBold.otf differ diff --git a/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Pretendard-Thin.otf b/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Pretendard-Thin.otf new file mode 100644 index 0000000..77e792d Binary files /dev/null and b/week02/mission/Week2_Megabox/Megabox_2/resource/Fonts/Pretendard-Thin.otf differ diff --git a/week02/mission/Week2_Megabox/Megabox_2Tests/Megabox_2Tests.swift b/week02/mission/Week2_Megabox/Megabox_2Tests/Megabox_2Tests.swift new file mode 100644 index 0000000..7c6aa7a --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2Tests/Megabox_2Tests.swift @@ -0,0 +1,17 @@ +// +// Megabox_2Tests.swift +// Megabox_2Tests +// +// Created by 최우진 on 9/26/25. +// + +import Testing +@testable import Megabox_2 + +struct Megabox_2Tests { + + @Test func example() async throws { + // Write your test here and use APIs like `#expect(...)` to check expected conditions. + } + +} diff --git a/week02/mission/Week2_Megabox/Megabox_2UITests/Megabox_2UITests.swift b/week02/mission/Week2_Megabox/Megabox_2UITests/Megabox_2UITests.swift new file mode 100644 index 0000000..aaac992 --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2UITests/Megabox_2UITests.swift @@ -0,0 +1,43 @@ +// +// Megabox_2UITests.swift +// Megabox_2UITests +// +// Created by 최우진 on 9/26/25. +// + +import XCTest + +final class Megabox_2UITests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + @MainActor + func testExample() throws { + // UI tests must launch the application that they test. + let app = XCUIApplication() + app.launch() + + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + @MainActor + func testLaunchPerformance() throws { + if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) { + // This measures how long it takes to launch your application. + measure(metrics: [XCTApplicationLaunchMetric()]) { + XCUIApplication().launch() + } + } + } +} diff --git a/week02/mission/Week2_Megabox/Megabox_2UITests/Megabox_2UITestsLaunchTests.swift b/week02/mission/Week2_Megabox/Megabox_2UITests/Megabox_2UITestsLaunchTests.swift new file mode 100644 index 0000000..bcadde0 --- /dev/null +++ b/week02/mission/Week2_Megabox/Megabox_2UITests/Megabox_2UITestsLaunchTests.swift @@ -0,0 +1,33 @@ +// +// Megabox_2UITestsLaunchTests.swift +// Megabox_2UITests +// +// Created by 최우진 on 9/26/25. +// + +import XCTest + +final class Megabox_2UITestsLaunchTests: XCTestCase { + + override class var runsForEachTargetApplicationUIConfiguration: Bool { + true + } + + override func setUpWithError() throws { + continueAfterFailure = false + } + + @MainActor + func testLaunch() throws { + let app = XCUIApplication() + app.launch() + + // Insert steps here to perform after app launch but before taking a screenshot, + // such as logging into a test account or navigating somewhere in the app + + let attachment = XCTAttachment(screenshot: app.screenshot()) + attachment.name = "Launch Screen" + attachment.lifetime = .keepAlways + add(attachment) + } +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox.xcodeproj/project.pbxproj b/week03/mission/Week3_Magabox/Week3_Magabox.xcodeproj/project.pbxproj new file mode 100644 index 0000000..4aad055 --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox.xcodeproj/project.pbxproj @@ -0,0 +1,555 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 77; + objects = { + +/* Begin PBXContainerItemProxy section */ + E4AFDB9C2E8D8D5E0064D682 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E4AFDB862E8D8D5A0064D682 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E4AFDB8D2E8D8D5A0064D682; + remoteInfo = Week3_Magabox; + }; + E4AFDBA62E8D8D5E0064D682 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E4AFDB862E8D8D5A0064D682 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E4AFDB8D2E8D8D5A0064D682; + remoteInfo = Week3_Magabox; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + E4AFDB8E2E8D8D5A0064D682 /* Week3_Magabox.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Week3_Magabox.app; sourceTree = BUILT_PRODUCTS_DIR; }; + E4AFDB9B2E8D8D5E0064D682 /* Week3_MagaboxTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Week3_MagaboxTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + E4AFDBA52E8D8D5E0064D682 /* Week3_MagaboxUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Week3_MagaboxUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + E4AFDB902E8D8D5A0064D682 /* Week3_Magabox */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = Week3_Magabox; + sourceTree = ""; + }; + E4AFDB9E2E8D8D5E0064D682 /* Week3_MagaboxTests */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = Week3_MagaboxTests; + sourceTree = ""; + }; + E4AFDBA82E8D8D5E0064D682 /* Week3_MagaboxUITests */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = Week3_MagaboxUITests; + sourceTree = ""; + }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + E4AFDB8B2E8D8D5A0064D682 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E4AFDB982E8D8D5E0064D682 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E4AFDBA22E8D8D5E0064D682 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + E4AFDB852E8D8D5A0064D682 = { + isa = PBXGroup; + children = ( + E4AFDB902E8D8D5A0064D682 /* Week3_Magabox */, + E4AFDB9E2E8D8D5E0064D682 /* Week3_MagaboxTests */, + E4AFDBA82E8D8D5E0064D682 /* Week3_MagaboxUITests */, + E4AFDB8F2E8D8D5A0064D682 /* Products */, + ); + sourceTree = ""; + }; + E4AFDB8F2E8D8D5A0064D682 /* Products */ = { + isa = PBXGroup; + children = ( + E4AFDB8E2E8D8D5A0064D682 /* Week3_Magabox.app */, + E4AFDB9B2E8D8D5E0064D682 /* Week3_MagaboxTests.xctest */, + E4AFDBA52E8D8D5E0064D682 /* Week3_MagaboxUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + E4AFDB8D2E8D8D5A0064D682 /* Week3_Magabox */ = { + isa = PBXNativeTarget; + buildConfigurationList = E4AFDBAF2E8D8D5F0064D682 /* Build configuration list for PBXNativeTarget "Week3_Magabox" */; + buildPhases = ( + E4AFDB8A2E8D8D5A0064D682 /* Sources */, + E4AFDB8B2E8D8D5A0064D682 /* Frameworks */, + E4AFDB8C2E8D8D5A0064D682 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + E4AFDB902E8D8D5A0064D682 /* Week3_Magabox */, + ); + name = Week3_Magabox; + packageProductDependencies = ( + ); + productName = Week3_Magabox; + productReference = E4AFDB8E2E8D8D5A0064D682 /* Week3_Magabox.app */; + productType = "com.apple.product-type.application"; + }; + E4AFDB9A2E8D8D5E0064D682 /* Week3_MagaboxTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = E4AFDBB22E8D8D5F0064D682 /* Build configuration list for PBXNativeTarget "Week3_MagaboxTests" */; + buildPhases = ( + E4AFDB972E8D8D5E0064D682 /* Sources */, + E4AFDB982E8D8D5E0064D682 /* Frameworks */, + E4AFDB992E8D8D5E0064D682 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + E4AFDB9D2E8D8D5E0064D682 /* PBXTargetDependency */, + ); + fileSystemSynchronizedGroups = ( + E4AFDB9E2E8D8D5E0064D682 /* Week3_MagaboxTests */, + ); + name = Week3_MagaboxTests; + packageProductDependencies = ( + ); + productName = Week3_MagaboxTests; + productReference = E4AFDB9B2E8D8D5E0064D682 /* Week3_MagaboxTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + E4AFDBA42E8D8D5E0064D682 /* Week3_MagaboxUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = E4AFDBB52E8D8D5F0064D682 /* Build configuration list for PBXNativeTarget "Week3_MagaboxUITests" */; + buildPhases = ( + E4AFDBA12E8D8D5E0064D682 /* Sources */, + E4AFDBA22E8D8D5E0064D682 /* Frameworks */, + E4AFDBA32E8D8D5E0064D682 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + E4AFDBA72E8D8D5E0064D682 /* PBXTargetDependency */, + ); + fileSystemSynchronizedGroups = ( + E4AFDBA82E8D8D5E0064D682 /* Week3_MagaboxUITests */, + ); + name = Week3_MagaboxUITests; + packageProductDependencies = ( + ); + productName = Week3_MagaboxUITests; + productReference = E4AFDBA52E8D8D5E0064D682 /* Week3_MagaboxUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + E4AFDB862E8D8D5A0064D682 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1640; + LastUpgradeCheck = 1640; + TargetAttributes = { + E4AFDB8D2E8D8D5A0064D682 = { + CreatedOnToolsVersion = 16.4; + }; + E4AFDB9A2E8D8D5E0064D682 = { + CreatedOnToolsVersion = 16.4; + TestTargetID = E4AFDB8D2E8D8D5A0064D682; + }; + E4AFDBA42E8D8D5E0064D682 = { + CreatedOnToolsVersion = 16.4; + TestTargetID = E4AFDB8D2E8D8D5A0064D682; + }; + }; + }; + buildConfigurationList = E4AFDB892E8D8D5A0064D682 /* Build configuration list for PBXProject "Week3_Magabox" */; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = E4AFDB852E8D8D5A0064D682; + minimizedProjectReferenceProxies = 1; + preferredProjectObjectVersion = 77; + productRefGroup = E4AFDB8F2E8D8D5A0064D682 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + E4AFDB8D2E8D8D5A0064D682 /* Week3_Magabox */, + E4AFDB9A2E8D8D5E0064D682 /* Week3_MagaboxTests */, + E4AFDBA42E8D8D5E0064D682 /* Week3_MagaboxUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + E4AFDB8C2E8D8D5A0064D682 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E4AFDB992E8D8D5E0064D682 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E4AFDBA32E8D8D5E0064D682 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + E4AFDB8A2E8D8D5A0064D682 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E4AFDB972E8D8D5E0064D682 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E4AFDBA12E8D8D5E0064D682 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + E4AFDB9D2E8D8D5E0064D682 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = E4AFDB8D2E8D8D5A0064D682 /* Week3_Magabox */; + targetProxy = E4AFDB9C2E8D8D5E0064D682 /* PBXContainerItemProxy */; + }; + E4AFDBA72E8D8D5E0064D682 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = E4AFDB8D2E8D8D5A0064D682 /* Week3_Magabox */; + targetProxy = E4AFDBA62E8D8D5E0064D682 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + E4AFDBAD2E8D8D5F0064D682 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + 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; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + 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 = 18.5; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + E4AFDBAE2E8D8D5F0064D682 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + 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; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + 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 = 18.5; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + E4AFDBB02E8D8D5F0064D682 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.woojin.Week3-Magabox"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + E4AFDBB12E8D8D5F0064D682 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.woojin.Week3-Magabox"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + E4AFDBB32E8D8D5F0064D682 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.5; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.woojin.Week3-MagaboxTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Week3_Magabox.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Week3_Magabox"; + }; + name = Debug; + }; + E4AFDBB42E8D8D5F0064D682 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.5; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.woojin.Week3-MagaboxTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Week3_Magabox.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Week3_Magabox"; + }; + name = Release; + }; + E4AFDBB62E8D8D5F0064D682 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.woojin.Week3-MagaboxUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = Week3_Magabox; + }; + name = Debug; + }; + E4AFDBB72E8D8D5F0064D682 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.woojin.Week3-MagaboxUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = Week3_Magabox; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + E4AFDB892E8D8D5A0064D682 /* Build configuration list for PBXProject "Week3_Magabox" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E4AFDBAD2E8D8D5F0064D682 /* Debug */, + E4AFDBAE2E8D8D5F0064D682 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E4AFDBAF2E8D8D5F0064D682 /* Build configuration list for PBXNativeTarget "Week3_Magabox" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E4AFDBB02E8D8D5F0064D682 /* Debug */, + E4AFDBB12E8D8D5F0064D682 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E4AFDBB22E8D8D5F0064D682 /* Build configuration list for PBXNativeTarget "Week3_MagaboxTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E4AFDBB32E8D8D5F0064D682 /* Debug */, + E4AFDBB42E8D8D5F0064D682 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E4AFDBB52E8D8D5F0064D682 /* Build configuration list for PBXNativeTarget "Week3_MagaboxUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E4AFDBB62E8D8D5F0064D682 /* Debug */, + E4AFDBB72E8D8D5F0064D682 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = E4AFDB862E8D8D5A0064D682 /* Project object */; +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/week03/mission/Week3_Magabox/Week3_Magabox.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/week03/mission/Week3_Magabox/Week3_Magabox.xcodeproj/project.xcworkspace/xcuserdata/wj_intelmac.xcuserdatad/UserInterfaceState.xcuserstate b/week03/mission/Week3_Magabox/Week3_Magabox.xcodeproj/project.xcworkspace/xcuserdata/wj_intelmac.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..150a52f Binary files /dev/null and b/week03/mission/Week3_Magabox/Week3_Magabox.xcodeproj/project.xcworkspace/xcuserdata/wj_intelmac.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/week03/mission/Week3_Magabox/Week3_Magabox.xcodeproj/xcuserdata/wj_intelmac.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/week03/mission/Week3_Magabox/Week3_Magabox.xcodeproj/xcuserdata/wj_intelmac.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..e4f9e97 --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox.xcodeproj/xcuserdata/wj_intelmac.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,6 @@ + + + diff --git a/week03/mission/Week3_Magabox/Week3_Magabox.xcodeproj/xcuserdata/wj_intelmac.xcuserdatad/xcschemes/xcschememanagement.plist b/week03/mission/Week3_Magabox/Week3_Magabox.xcodeproj/xcuserdata/wj_intelmac.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..6e46924 --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox.xcodeproj/xcuserdata/wj_intelmac.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + Week3_Magabox.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/AccentColor.colorset/Contents.json b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/AppIcon.appiconset/Contents.json b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..2305880 --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,35 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "tinted" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/Contents.json b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/apple.imageset/Contents.json b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/apple.imageset/Contents.json new file mode 100644 index 0000000..0975940 --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/apple.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "apple.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/apple.imageset/apple.pdf b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/apple.imageset/apple.pdf new file mode 100644 index 0000000..909af30 Binary files /dev/null and b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/apple.imageset/apple.pdf differ diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/background.imageset/Contents.json b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/background.imageset/Contents.json new file mode 100644 index 0000000..7e26126 --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/background.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "background.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/background.imageset/background.pdf b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/background.imageset/background.pdf new file mode 100644 index 0000000..e2c0ebe Binary files /dev/null and b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/background.imageset/background.pdf differ diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/cinema.imageset/Contents.json b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/cinema.imageset/Contents.json new file mode 100644 index 0000000..430a6e5 --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/cinema.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "cinema.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/cinema.imageset/cinema.pdf b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/cinema.imageset/cinema.pdf new file mode 100644 index 0000000..d76a452 Binary files /dev/null and b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/cinema.imageset/cinema.pdf differ diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/clock.imageset/Contents.json b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/clock.imageset/Contents.json new file mode 100644 index 0000000..bd6a149 --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/clock.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "clock.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/clock.imageset/clock.png b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/clock.imageset/clock.png new file mode 100644 index 0000000..6e662a5 Binary files /dev/null and b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/clock.imageset/clock.png differ diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/f1.imageset/Contents.json b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/f1.imageset/Contents.json new file mode 100644 index 0000000..dc40783 --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/f1.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "f1.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/f1.imageset/f1.pdf b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/f1.imageset/f1.pdf new file mode 100644 index 0000000..d1c6f76 Binary files /dev/null and b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/f1.imageset/f1.pdf differ diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/f1_header.imageset/Contents.json b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/f1_header.imageset/Contents.json new file mode 100644 index 0000000..aef409b --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/f1_header.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "f1_header.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/f1_header.imageset/f1_header.pdf b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/f1_header.imageset/f1_header.pdf new file mode 100644 index 0000000..c616447 Binary files /dev/null and b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/f1_header.imageset/f1_header.pdf differ diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/film-reel.imageset/Contents.json b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/film-reel.imageset/Contents.json new file mode 100644 index 0000000..c1aba9f --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/film-reel.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "film-reel.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/film-reel.imageset/film-reel.pdf b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/film-reel.imageset/film-reel.pdf new file mode 100644 index 0000000..9d4ba17 Binary files /dev/null and b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/film-reel.imageset/film-reel.pdf differ diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/image 1.imageset/Contents.json b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/image 1.imageset/Contents.json new file mode 100644 index 0000000..6a452fc --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/image 1.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "image 1.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/image 1.imageset/image 1.pdf b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/image 1.imageset/image 1.pdf new file mode 100644 index 0000000..417b2a5 Binary files /dev/null and b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/image 1.imageset/image 1.pdf differ diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/image 2.imageset/Contents.json b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/image 2.imageset/Contents.json new file mode 100644 index 0000000..dc4f61a --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/image 2.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "image 2.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/image 2.imageset/image 2.pdf b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/image 2.imageset/image 2.pdf new file mode 100644 index 0000000..477d48c Binary files /dev/null and b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/image 2.imageset/image 2.pdf differ diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/image 3.imageset/Contents.json b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/image 3.imageset/Contents.json new file mode 100644 index 0000000..6a452fc --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/image 3.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "image 1.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/image 3.imageset/image 1.pdf b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/image 3.imageset/image 1.pdf new file mode 100644 index 0000000..83b4fa6 Binary files /dev/null and b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/image 3.imageset/image 1.pdf differ diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/kakao.imageset/Contents.json b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/kakao.imageset/Contents.json new file mode 100644 index 0000000..2ff1237 --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/kakao.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "kakao.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/kakao.imageset/kakao.pdf b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/kakao.imageset/kakao.pdf new file mode 100644 index 0000000..9f17f2b Binary files /dev/null and b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/kakao.imageset/kakao.pdf differ diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/map.imageset/Contents.json b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/map.imageset/Contents.json new file mode 100644 index 0000000..60ad78a --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/map.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "map.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/map.imageset/map.pdf b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/map.imageset/map.pdf new file mode 100644 index 0000000..9bc07f2 Binary files /dev/null and b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/map.imageset/map.pdf differ diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/meboxLogo_home.imageset/Contents.json b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/meboxLogo_home.imageset/Contents.json new file mode 100644 index 0000000..7d8b28b --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/meboxLogo_home.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "meboxLogo_home.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/meboxLogo_home.imageset/meboxLogo_home.pdf b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/meboxLogo_home.imageset/meboxLogo_home.pdf new file mode 100644 index 0000000..8f2c502 Binary files /dev/null and b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/meboxLogo_home.imageset/meboxLogo_home.pdf differ diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/megabox_logo.imageset/Contents.json b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/megabox_logo.imageset/Contents.json new file mode 100644 index 0000000..9999a13 --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/megabox_logo.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "megabox_logo.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/megabox_logo.imageset/megabox_logo.pdf b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/megabox_logo.imageset/megabox_logo.pdf new file mode 100644 index 0000000..88b2939 Binary files /dev/null and b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/megabox_logo.imageset/megabox_logo.pdf differ diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/naver.imageset/Contents.json b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/naver.imageset/Contents.json new file mode 100644 index 0000000..59d595e --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/naver.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "naver.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/naver.imageset/naver.pdf b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/naver.imageset/naver.pdf new file mode 100644 index 0000000..ebde8f5 Binary files /dev/null and b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/naver.imageset/naver.pdf differ diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/sofa.imageset/Contents.json b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/sofa.imageset/Contents.json new file mode 100644 index 0000000..7867b3b --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/sofa.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "sofa.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/sofa.imageset/sofa.pdf b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/sofa.imageset/sofa.pdf new file mode 100644 index 0000000..a7bfd92 Binary files /dev/null and b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/sofa.imageset/sofa.pdf differ diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/umc_image.imageset/Contents.json b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/umc_image.imageset/Contents.json new file mode 100644 index 0000000..a6310e5 --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/umc_image.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "umc_image.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/umc_image.imageset/umc_image.png b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/umc_image.imageset/umc_image.png new file mode 100644 index 0000000..47c6104 Binary files /dev/null and b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/umc_image.imageset/umc_image.png differ diff --git "a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/\341\204\206\341\205\256\341\204\222\341\205\241\341\206\253\341\204\211\341\205\245\341\206\274.imageset/Contents.json" "b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/\341\204\206\341\205\256\341\204\222\341\205\241\341\206\253\341\204\211\341\205\245\341\206\274.imageset/Contents.json" new file mode 100644 index 0000000..3e06ca0 --- /dev/null +++ "b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/\341\204\206\341\205\256\341\204\222\341\205\241\341\206\253\341\204\211\341\205\245\341\206\274.imageset/Contents.json" @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "무한성.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/\341\204\206\341\205\256\341\204\222\341\205\241\341\206\253\341\204\211\341\205\245\341\206\274.imageset/\341\204\206\341\205\256\341\204\222\341\205\241\341\206\253\341\204\211\341\205\245\341\206\274.pdf" "b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/\341\204\206\341\205\256\341\204\222\341\205\241\341\206\253\341\204\211\341\205\245\341\206\274.imageset/\341\204\206\341\205\256\341\204\222\341\205\241\341\206\253\341\204\211\341\205\245\341\206\274.pdf" new file mode 100644 index 0000000..b0ab786 Binary files /dev/null and "b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/\341\204\206\341\205\256\341\204\222\341\205\241\341\206\253\341\204\211\341\205\245\341\206\274.imageset/\341\204\206\341\205\256\341\204\222\341\205\241\341\206\253\341\204\211\341\205\245\341\206\274.pdf" differ diff --git "a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/\341\204\213\341\205\245\341\204\215\341\205\245\341\206\257\341\204\211\341\205\256\341\204\200\341\205\241 \341\204\213\341\205\245\341\206\271\341\204\203\341\205\241.imageset/Contents.json" "b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/\341\204\213\341\205\245\341\204\215\341\205\245\341\206\257\341\204\211\341\205\256\341\204\200\341\205\241 \341\204\213\341\205\245\341\206\271\341\204\203\341\205\241.imageset/Contents.json" new file mode 100644 index 0000000..096181b --- /dev/null +++ "b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/\341\204\213\341\205\245\341\204\215\341\205\245\341\206\257\341\204\211\341\205\256\341\204\200\341\205\241 \341\204\213\341\205\245\341\206\271\341\204\203\341\205\241.imageset/Contents.json" @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "어쩔수가 없다.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/\341\204\213\341\205\245\341\204\215\341\205\245\341\206\257\341\204\211\341\205\256\341\204\200\341\205\241 \341\204\213\341\205\245\341\206\271\341\204\203\341\205\241.imageset/\341\204\213\341\205\245\341\204\215\341\205\245\341\206\257\341\204\211\341\205\256\341\204\200\341\205\241 \341\204\213\341\205\245\341\206\271\341\204\203\341\205\241.pdf" "b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/\341\204\213\341\205\245\341\204\215\341\205\245\341\206\257\341\204\211\341\205\256\341\204\200\341\205\241 \341\204\213\341\205\245\341\206\271\341\204\203\341\205\241.imageset/\341\204\213\341\205\245\341\204\215\341\205\245\341\206\257\341\204\211\341\205\256\341\204\200\341\205\241 \341\204\213\341\205\245\341\206\271\341\204\203\341\205\241.pdf" new file mode 100644 index 0000000..6c44435 Binary files /dev/null and "b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/\341\204\213\341\205\245\341\204\215\341\205\245\341\206\257\341\204\211\341\205\256\341\204\200\341\205\241 \341\204\213\341\205\245\341\206\271\341\204\203\341\205\241.imageset/\341\204\213\341\205\245\341\204\215\341\205\245\341\206\257\341\204\211\341\205\256\341\204\200\341\205\241 \341\204\213\341\205\245\341\206\271\341\204\203\341\205\241.pdf" differ diff --git "a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/\341\204\213\341\205\245\341\206\257\341\204\200\341\205\256\341\206\257.imageset/Contents.json" "b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/\341\204\213\341\205\245\341\206\257\341\204\200\341\205\256\341\206\257.imageset/Contents.json" new file mode 100644 index 0000000..aa5605c --- /dev/null +++ "b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/\341\204\213\341\205\245\341\206\257\341\204\200\341\205\256\341\206\257.imageset/Contents.json" @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "얼굴.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/\341\204\213\341\205\245\341\206\257\341\204\200\341\205\256\341\206\257.imageset/\341\204\213\341\205\245\341\206\257\341\204\200\341\205\256\341\206\257.pdf" "b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/\341\204\213\341\205\245\341\206\257\341\204\200\341\205\256\341\206\257.imageset/\341\204\213\341\205\245\341\206\257\341\204\200\341\205\256\341\206\257.pdf" new file mode 100644 index 0000000..4fa2a3f Binary files /dev/null and "b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/\341\204\213\341\205\245\341\206\257\341\204\200\341\205\256\341\206\257.imageset/\341\204\213\341\205\245\341\206\257\341\204\200\341\205\256\341\206\257.pdf" differ diff --git "a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/\341\204\214\341\205\242\341\204\200\341\205\242\341\204\207\341\205\251\341\206\274.imageset/Contents.json" "b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/\341\204\214\341\205\242\341\204\200\341\205\242\341\204\207\341\205\251\341\206\274.imageset/Contents.json" new file mode 100644 index 0000000..aad4da5 --- /dev/null +++ "b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/\341\204\214\341\205\242\341\204\200\341\205\242\341\204\207\341\205\251\341\206\274.imageset/Contents.json" @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "재개봉.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/\341\204\214\341\205\242\341\204\200\341\205\242\341\204\207\341\205\251\341\206\274.imageset/\341\204\214\341\205\242\341\204\200\341\205\242\341\204\207\341\205\251\341\206\274.pdf" "b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/\341\204\214\341\205\242\341\204\200\341\205\242\341\204\207\341\205\251\341\206\274.imageset/\341\204\214\341\205\242\341\204\200\341\205\242\341\204\207\341\205\251\341\206\274.pdf" new file mode 100644 index 0000000..0c7b350 Binary files /dev/null and "b/week03/mission/Week3_Magabox/Week3_Magabox/Assets.xcassets/\341\204\214\341\205\242\341\204\200\341\205\242\341\204\207\341\205\251\341\206\274.imageset/\341\204\214\341\205\242\341\204\200\341\205\242\341\204\207\341\205\251\341\206\274.pdf" differ diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/ContentView.swift b/week03/mission/Week3_Magabox/Week3_Magabox/ContentView.swift new file mode 100644 index 0000000..a65b078 --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/ContentView.swift @@ -0,0 +1,24 @@ +// +// ContentView.swift +// Megabox_2 +// +// Created by 최우진 on 9/26/25. +// + +import SwiftUI + +struct ContentView: View { + var body: some View { + VStack { + Image(systemName: "globe") + .imageScale(.large) + .foregroundStyle(.tint) + Text("Hello, world!") + } + .padding() + } +} + +#Preview { + ContentView() +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/HomeModel.swift b/week03/mission/Week3_Magabox/Week3_Magabox/HomeModel.swift new file mode 100644 index 0000000..05d29da --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/HomeModel.swift @@ -0,0 +1,51 @@ +// +// HomeModel.swift +// Week3_Magabox +// +// Created by 최우진 on 10/4/25. +// + +import Foundation + + +// 상단 텍스트 탭 +enum HomeTopTab: Int, CaseIterable { + case home, event, store, favorite + var title: String { + switch self { + case .home: return "홈" + case .event: return "이벤트" + case .store: return "스토어" + case .favorite: return "선호극장" + } + } +} + +// 칩(무비차트 / 상영예정) +enum MovieChip: Int { //case에 따라 String 값을 유동적으로 변경 가능 + case chart = 0 + case upcoming = 1 + + var title: String { + switch self { //case에 따라 String 값을 유동적으로 변경 가능 + case .chart: return "무비차트" + case .upcoming:return "상영예정" + } + } +} + +// 영화 데이터 모델 +// Identifiable은 고유 ID를 알리는 프로토컬이고 Hashable은 해시값으로 쓸 수 있도록 하는겨 +// 즉 Identifiable->foreach, Hashable->NavigationLink +struct Movie: Identifiable, Hashable { + let id = UUID() + let poster: String + let title: String + let audience: String + + let header: String + let subtitle: String? + let overview: String? + let ageRating: String? + let releaseDate: String? +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/HomeView.swift b/week03/mission/Week3_Magabox/Week3_Magabox/HomeView.swift new file mode 100644 index 0000000..0bd5e91 --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/HomeView.swift @@ -0,0 +1,442 @@ +// HomeView.swift +// Week3_Magabox +// +// Created by 최우진 on 10/2/25. +// + +import SwiftUI + +struct HomeView: View { + // 화면 상태 및 뷰 모델 + @StateObject private var vm = HomeViewModel() + @Namespace private var tabNS + + // 상세 화면의 상단 탭 상태 + private enum DetailTab { case info, reviews } + @State private var detailTab: DetailTab = .info + + // 내비게이션 뒤로가기 처리 + @Environment(\.dismiss) private var dismiss + + var body: some View { + + NavigationStack { + + // MARK: - 상단 영역 + 본문 + VStack(spacing: 9) { + + // MARK: 상단 헤더 + VStack(alignment: .leading, spacing: 12) { + + // 로고 + HStack(spacing: 0) { + Image("meboxLogo_home") + .resizable() + .scaledToFit() + .frame(width: 149, height: 30) + Spacer() + } + + // 상단 텍스트 탭 + HStack(spacing: 28) { + ForEach(HomeTopTab.allCases, id: \.self) { tab in + let selected = (vm.topTab == tab) + + Button { vm.selectTopTab(tab) } label: { + Text(tab.title) + .font(.custom("Pretendard", + size: 24, + relativeTo: .title3)) + .fontWeight(.semibold) + .foregroundStyle(selected ? Color.black : Color.gray04) + } + .buttonStyle(.plain) + } + } + } + + // MARK: 본문 스크롤 + ScrollView { + + // 칩(무비차트 / 상영예정) + HStack(spacing: 23) { + let chipWidth: CGFloat = 84 + let chipHeight: CGFloat = 38 + let chipRadius: CGFloat = 30 + + // 무비차트 + Button { vm.selectChip(.chart) } label: { + ZStack { + RoundedRectangle(cornerRadius: chipRadius, style: .continuous) + .fill(vm.chip == .chart ? Color.gray08 : Color.gray02) + Text(MovieChip.chart.title) + .font(.PretendardMedium14) + .foregroundColor(vm.chip == .chart ? .white : Color.gray04) + } + .frame(width: chipWidth, height: chipHeight) + } + .buttonStyle(.plain) + + // 상영예정 + Button { vm.selectChip(.upcoming) } label: { + ZStack { + RoundedRectangle(cornerRadius: chipRadius, style: .continuous) + .fill(vm.chip == .upcoming ? Color.gray08 : Color.gray02) + Text(MovieChip.upcoming.title) + .font(.PretendardMedium14) + .foregroundColor(vm.chip == .upcoming ? .white : Color.gray04) + } + .frame(width: chipWidth, height: chipHeight) + } + .buttonStyle(.plain) + + Spacer() + } + + // 섹션 묶음 + VStack(alignment: .leading, spacing: 37) { + + // 가로 스크롤 무비 카드 + ScrollView(.horizontal, showsIndicators: false) { + HStack(spacing: 24) { + ForEach(vm.displayedMovies) { movie in + VStack(alignment: .leading, spacing: 8) { + + // 포스터 → 상세 진입 + NavigationLink(value: movie) { + Image(movie.poster) + .resizable() + .scaledToFill() + .frame(width: 148, height: 212) + .clipShape(RoundedRectangle(cornerRadius: 12)) + .overlay( + RoundedRectangle(cornerRadius: 12) + .stroke(Color.black.opacity(0.06), lineWidth: 1) + ) + } + .buttonStyle(.plain) + + // 액션 버튼(예매/상영예정) + Button { /* TODO */ } label: { + Text(vm.chip == .chart ? "바로 예매" : "상영 예정") + .font(.PretendardMedium16) + .foregroundColor(.purple03) + .frame(width: 148, height: 36) + .overlay( + RoundedRectangle(cornerRadius: 14) + .stroke(Color.purple03, lineWidth: 1) + ) + } + .buttonStyle(.plain) + + // 타이틀/보조 텍스트 + VStack(alignment: .leading, spacing: 0) { + Text(movie.title) + .font(.PretendardBold22) + .foregroundColor(.primary) + .frame(width: 148, alignment: .leading) + .lineLimit(1) + + Text(movie.audience) + .font(.PretendardMedium18) + .foregroundStyle(.secondary) + .frame(width: 148, alignment: .leading) + } + } + } + } + } + .scrollIndicators(.hidden) + + // 무비피드 히어로(제목 + 배너) + VStack(alignment: .leading, spacing: 4) { + HStack { + Text("알고보면 더 재밌는 무비피드") + .font(.PretendardBold24) + Spacer() + Button {} label: { + Image(systemName: "arrow.right") + .font(.title3.weight(.semibold)) + .frame(width: 39, height: 39) + .background(.ultraThinMaterial) + .clipShape(Circle()) + } + .buttonStyle(.plain) + } + + Image("image 3") + .resizable() + .scaledToFill() + .frame(height: 221) + } + + // 추가 피드 2행 + VStack(spacing: 39) { + + // 1행 + HStack(alignment: .top, spacing: 0) { + Image("재개봉") + .resizable() + .scaledToFill() + .frame(width: 100, height: 100) + .clipShape(RoundedRectangle(cornerRadius: 14)) + + Spacer() + + VStack(alignment: .leading, spacing: 25) { + Text("9월, 메가박스의 영화들(1) - 명작들의 재개봉") + .frame(width: 285, alignment: .leading) + .font(.PretendardSemiBold18) + .foregroundColor(.black) + + Text("<모노노케 히메>, <퍼펙트 블루>") + .font(.PretendardSemiBold13) + .foregroundStyle(.secondary) + .lineLimit(1) + Spacer() + } + } + + // 2행 + HStack(alignment: .top, spacing: 0) { + Image("image 2") + .resizable() + .scaledToFill() + .frame(width: 100, height: 100) + .clipShape(RoundedRectangle(cornerRadius: 14)) + + Spacer() + + VStack(alignment: .leading, spacing: 25) { + Text("메가박스 오리지널 티켓 Re.37 <얼굴>") + .frame(width: 285, alignment: .leading) + .font(.PretendardSemiBold18) + .foregroundColor(.black) + .lineLimit(2) + + Text("영화 속 양극적인 감정의 대비") + .font(.PretendardSemiBold13) + .foregroundStyle(.secondary) + .lineLimit(1) + Spacer() + } + .frame(width: 285) + } + Spacer() + } + .padding(.bottom, 32) + } + .padding(.top, 8) + } + .scrollIndicators(.hidden) + } + .padding(.horizontal, 16) + + // MARK: - 하단 커스텀 탭 + .safeAreaInset(edge: .bottom) { + let tabItems: [(title: String, active: String, inactive: String)] = [ + ("홈", "house.fill", "house"), + ("바로 예매", "play.rectangle.fill", "play.rectangle"), + ("모바일 오더", "popcorn.fill", "popcorn"), + ("마이 페이지", "person.fill", "person") + ] + + HStack(spacing: 8) { + ForEach(Array(tabItems.enumerated()), id: \.offset) { i, item in + Button { + withAnimation(.spring(response: 0.35, dampingFraction: 0.85)) { + vm.bottomTabIndex = i + } + } label: { + ZStack { + if vm.bottomTabIndex == i { + RoundedRectangle(cornerRadius: 50, style: .continuous) + .fill(Color.white) + .matchedGeometryEffect(id: "TAB_BG", in: tabNS) + .shadow(color: .black.opacity(0.12), radius: 10, y: 4) + } + VStack(spacing: 6) { + Image(systemName: vm.bottomTabIndex == i ? item.active : item.inactive) + .font(.system(size: 20, weight: .semibold)) + .foregroundColor(.black.opacity(vm.bottomTabIndex == i ? 1 : 0.6)) + Text(item.title) + .font(.footnote.weight(.semibold)) + .foregroundStyle(vm.bottomTabIndex == i ? Color.black : Color.secondary) + .lineLimit(1) + } + .padding(.horizontal, 8) + } + .frame(height: 60) + .frame(maxWidth: .infinity) + } + .buttonStyle(.plain) + } + } + .padding(10) + .frame(width: 360, height: 68) + .background( + RoundedRectangle(cornerRadius: 28, style: .continuous) + .fill(.ultraThinMaterial) + .overlay( + RoundedRectangle(cornerRadius: 28, style: .continuous) + .stroke(Color.white.opacity(0.35), lineWidth: 0.5) + ) + .shadow(color: .black.opacity(0.08), radius: 18, y: 8) + ) + .padding(.horizontal, 12) + .padding(.bottom, 6) + } + + // MARK: - 상세 화면 (Movie 값 기반 라우팅) + .navigationDestination(for: Movie.self) { movie in + ScrollView { + VStack(alignment: .leading, spacing: 16) { + + // 상단 히어로 이미지 + let heroName = movie.header + ZStack(alignment: .bottom) { + Image(heroName) + .resizable() + .scaledToFill() + .frame(height: 248) + .clipped() + } + + // 타이틀/부제/개요 + VStack(spacing: 22) { + VStack(spacing: 9) { + VStack(spacing: 0) { + Text(movie.title) + .font(.PretendardBold22) + .multilineTextAlignment(.center) + + if let sub = movie.subtitle { + Text(sub) + .font(.PretendardSemiBold14) + .foregroundStyle(.secondary) + .multilineTextAlignment(.center) + } + } + + if let ov = movie.overview { + Text(ov) + .font(.PretendardSemiBold18) + .foregroundStyle(.secondary) + .lineSpacing(5) + .multilineTextAlignment(.leading) + } + } + .frame(maxWidth: .infinity, alignment: .center) + + // 상세/실관람평 탭 헤더 + VStack(spacing: 0) { + HStack { + Spacer() + Button { + withAnimation(.easeInOut(duration: 0.2)) { detailTab = .info } + } label: { + Text("상세 정보") + .font(.PretendardBold22) + .foregroundColor(detailTab == .info ? .primary : .secondary) + } + + Spacer() + Spacer() + + Button { + withAnimation(.easeInOut(duration: 0.2)) { detailTab = .reviews } + } label: { + Text("실관람평") + .font(.PretendardBold22) + .foregroundColor(detailTab == .reviews ? .primary : .secondary) + } + Spacer() + } + .padding(.vertical, 12) + + // 탭 언더라인 + GeometryReader { g in + ZStack(alignment: .leading) { + Rectangle() + .frame(height: 1) + .foregroundStyle(.quaternary) + + Rectangle() + .frame(width: g.size.width / 2, height: 2) + .foregroundColor(.black) + .offset(x: detailTab == .info ? 0 : g.size.width / 2, y: -0.5) + .animation(.easeInOut(duration: 0.2), value: detailTab) + } + } + .frame(height: 2) + } + + // 탭 컨텐츠 + Group { + if detailTab == .info { + // 상세 정보 + HStack(alignment: .top, spacing: 13) { + Image(movie.poster) + .resizable() + .frame(width: 100, height: 120) + VStack(alignment: .leading, spacing: 9) { + if let age = movie.ageRating { + Text(age) + .font(.PretendardSemiBold13) + .foregroundColor(.primary) + } + if let date = movie.releaseDate { + Text(date) + .font(.PretendardSemiBold13) + .foregroundStyle(.primary) + } + } + Spacer() + } + .frame(alignment: .top) + } else { + // 실관람평(플레이스홀더) + RoundedRectangle(cornerRadius: 12) + .stroke(Color.purple02, lineWidth: 1) + .frame(height: 141) + .overlay( + Text("등록된 관람평이 없어요 😌") + .font(.PretendardSemiBold18) + .foregroundStyle(.black) + ) + } + } + .padding(.horizontal, 16) + .animation(.easeInOut(duration: 0.15), value: detailTab) + } + } + .padding(.bottom, 24) + } + .navigationTitle(movie.title) + .navigationBarTitleDisplayMode(.inline) + .navigationBarBackButtonHidden(true) + .toolbar { + ToolbarItem(placement: .topBarLeading) { + Button { dismiss() } label: { + ZStack { + Circle() + .fill(.ultraThinMaterial) + .frame(width: 36, height: 36) + Image(systemName: "arrow.left") + .font(.system(size: 18, weight: .semibold)) + .foregroundColor(.black.opacity(0.85)) + } + .shadow(color: .black.opacity(0.12), radius: 6, y: 2) + } + .buttonStyle(.plain) + } + } + } + } + } +} + +// 미리보기 +#Preview { + HomeView() +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/HomeViewModel.swift b/week03/mission/Week3_Magabox/Week3_Magabox/HomeViewModel.swift new file mode 100644 index 0000000..8ccf2ad --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/HomeViewModel.swift @@ -0,0 +1,170 @@ +// +// HomeViewModel.swift +// Week3_Magabox +// +// Created by 최우진 on 10/4/25. +// + +import SwiftUI + +class HomeViewModel: ObservableObject { + + // 화면 상태 + @Published var topTab: HomeTopTab = .home + @Published var chip: MovieChip = .chart + @Published var bottomTabIndex: Int = 0 + + // 더미 데이터 (필요 시 네트워크 대체) + @Published private(set) var movies: [Movie] = [ + Movie( + poster: "어쩔수가 없다", + title: "어쩔수가 없다", + audience: "누적관객수 20만", + header: "어쩔수가 없다", + subtitle: "F1 : The Movie", + overview: + """ + 최고가 되지 못한 전설 VS 최고가 되고 싶은 루키 + + 한때 주목받는 유망주였지만 끔찍한 사고로 F1에서 우승하지 못하고 + 한순간에 추락한 드라이버 ‘숀·헤이스’(브래드 피트). + 그의 오랜 동료 ‘루벤 세르반테스’(하비에르 바르뎀)에게 + 레이싱 복귀를 제안받으며 최하위 팀 APGXP에 합류한다. + """, + ageRating: "12세 이상 관람가", + releaseDate: "2025.06.25 개봉" + ), + Movie( + poster: "무한성", + title: "극장판 귀멸의 칼날: 무한성 편", + audience: "누적관객수 1", + header: "무한성", + subtitle: "F1 : The Movie", + overview: + """ + 최고가 되지 못한 전설 VS 최고가 되고 싶은 루키 + 한때 주목받는 유망주였지만 끔찍한 사고로 F1에서 우승하지 못하고 + 한순간에 추락한 드라이버 ‘숀·헤이스’(브래드 피트). + 그의 오랜 동료 ‘루벤 세르반테스’(하비에르 바르뎀)에게 + 레이싱 복귀를 제안받으며 최하위 팀 APGXP에 합류한다. + """, + ageRating: "12세 이상 관람가", + releaseDate: "2025.06.25 개봉" + ), + Movie( + poster: "f1", + title: "F1 더 무비", + audience: "누적관객수 -", + header: "f1_header", // ← 상세 상단 히어로 이미지 + subtitle: "F1 : The Movie", + overview: + """ + 최고가 되지 못한 전설 VS 최고가 되고 싶은 루키 + + 한때 주목받는 유망주였지만 끔찍한 사고로 F1에서 우승하지 못하고 + 한순간에 추락한 드라이버 ‘숀·헤이스’(브래드 피트). + 그의 오랜 동료 ‘루벤 세르반테스’(하비에르 바르뎀)에게 + 레이싱 복귀를 제안받으며 최하위 팀 APGXP에 합류한다. + """, + ageRating: "12세 이상 관람가", + releaseDate: "2025.06.25 개봉" + ), + Movie( + poster: "image 1", + title: "얼굴", + audience: "누적관객수 -", + header: "image 1", + subtitle: "F1 : The Movie", + overview: + """ + 최고가 되지 못한 전설 VS 최고가 되고 싶은 루키 + 한때 주목받는 유망주였지만 끔찍한 사고로 F1에서 우승하지 못하고 + 한순간에 추락한 드라이버 ‘숀·헤이스’(브래드 피트). + 그의 오랜 동료 ‘루벤 세르반테스’(하비에르 바르뎀)에게 + 레이싱 복귀를 제안받으며 최하위 팀 APGXP에 합류한다. + """, + ageRating: "12세 이상 관람가", + releaseDate: "2025.06.25 개봉" + ), + Movie( + poster: "image 2", + title: "정글", + audience: "누적관객수 -", + header: "image 2", + subtitle: "F1 : The Movie", + overview: + """ + 최고가 되지 못한 전설 VS 최고가 되고 싶은 루키 + 한때 주목받는 유망주였지만 끔찍한 사고로 F1에서 우승하지 못하고 + 한순간에 추락한 드라이버 ‘숀·헤이스’(브래드 피트). + 그의 오랜 동료 ‘루벤 세르반테스’(하비에르 바르뎀)에게 + 레이싱 복귀를 제안받으며 최하위 팀 APGXP에 합류한다. + """, + ageRating: "12세 이상 관람가", + releaseDate: "2025.06.25 개봉" + ) + ] + + @Published private(set) var upcomingMovies: [Movie] = [ + Movie( + poster: "image 1", + title: "얼굴", + audience: "누적관객수 -", + header: "image 1", + subtitle: "F1 : The Movie", + overview: + """ + 최고가 되지 못한 전설 VS 최고가 되고 싶은 루키 + 한때 주목받는 유망주였지만 끔찍한 사고로 F1에서 우승하지 못하고 + 한순간에 추락한 드라이버 ‘숀·헤이스’(브래드 피트). + 그의 오랜 동료 ‘루벤 세르반테스’(하비에르 바르뎀)에게 + 레이싱 복귀를 제안받으며 최하위 팀 APGXP에 합류한다. + """, + ageRating: "12세 이상 관람가", + releaseDate: "2025.06.25 개봉" + ), + Movie( + poster: "image 2", + title: "정글", + audience: "누적관객수 -", + header: "image 2", + subtitle: "F1 : The Movie", + overview: + """ + 최고가 되지 못한 전설 VS 최고가 되고 싶은 루키 + 한때 주목받는 유망주였지만 끔찍한 사고로 F1에서 우승하지 못하고 + 한순간에 추락한 드라이버 ‘숀·헤이스’(브래드 피트). + 그의 오랜 동료 ‘루벤 세르반테스’(하비에르 바르뎀)에게 + 레이싱 복귀를 제안받으며 최하위 팀 APGXP에 합류한다. + """, + ageRating: "12세 이상 관람가", + releaseDate: "2025.06.25 개봉" + ), + Movie( + poster: "f1", + title: "F1 더 무비", + audience: "누적관객수 -", + header: "f1_header", // ← 상세 상단 히어로 이미지 + subtitle: "F1 : The Movie", + overview: + """ + 최고가 되지 못한 전설 VS 최고가 되고 싶은 루키 + 한때 주목받는 유망주였지만 끔찍한 사고로 F1에서 우승하지 못하고 + 한순간에 추락한 드라이버 ‘숀·헤이스’(브래드 피트). + 그의 오랜 동료 ‘루벤 세르반테스’(하비에르 바르뎀)에게 + 레이싱 복귀를 제안받으며 최하위 팀 APGXP에 합류한다. + """, + ageRating: "12세 이상 관람가", + releaseDate: "2025.06.25 개봉" + ) + ] + + // 현재 칩에 따른 노출 리스트 + var displayedMovies: [Movie] { + chip == .chart ? movies : upcomingMovies + } + + // 액션 헬퍼 (원하면 로깅/트래킹 추가) + func selectTopTab(_ tab: HomeTopTab) { topTab = tab } + func selectChip(_ chip: MovieChip) { self.chip = chip } +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/LoginModel.swift b/week03/mission/Week3_Magabox/Week3_Magabox/LoginModel.swift new file mode 100644 index 0000000..c035007 --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/LoginModel.swift @@ -0,0 +1,15 @@ +// +// LoginModel.swift +// Megabox +// +// Created by 최우진 on 9/25/25. +// + +// LoginModel.swift + +import Foundation + +struct LoginModel { + var id: String = "" + var pwd: String = "" +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/LoginView.swift b/week03/mission/Week3_Magabox/Week3_Magabox/LoginView.swift new file mode 100644 index 0000000..dc9099c --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/LoginView.swift @@ -0,0 +1,115 @@ +import SwiftUI + +struct LoginView: View { + // ViewModel: 아이디/비밀번호 입력을 보관 + @State private var viewModel = LoginViewModel() + // 로컬 저장 자격(예시용): 실제 앱에서는 보안 저장소로 대체 권장 + @AppStorage("savedId") private var savedId: String = "cwj1213" + @AppStorage("savedPassword") private var savedPassword: String = "1111" + + // 로그인 성공 시 화면 전환 트리거 + @State private var goHome = false + + var body: some View { + NavigationStack { + VStack { + // MARK: - 상단 타이틀 + Text("로그인") + .font(.PretendardSemiBold24) + .foregroundColor(.black) + Spacer(minLength: 44) + + // MARK: - 로그인 입력 영역 + VStack { + // 아이디 / 비밀번호 필드 + VStack(spacing: 40) { + // 아이디 + VStack(alignment: .leading, spacing: 6) { + TextField("아이디", text: $viewModel.id) + .font(.PretendardMedium16) + .foregroundColor(.gray03) + .textInputAutocapitalization(.never) + .autocorrectionDisabled(true) + Rectangle() + .frame(height: 1) + .foregroundColor(.gray02) + } + + // 비밀번호 + VStack(alignment: .leading, spacing: 6) { + SecureField("비밀번호", text: $viewModel.pwd) + .font(.PretendardMedium16) + .foregroundColor(.gray03) + Rectangle() + .frame(height: 1) + .foregroundColor(.gray02) + } + } + + Spacer(minLength: 75) + + // MARK: - 로그인 버튼 / 회원가입 + VStack { + // 로그인: 입력값이 저장값과 동일할 때만 goHome = true + Button { + if viewModel.id == savedId && viewModel.pwd == savedPassword { + goHome = true + } else { + // 불일치 시 추가 피드백(알림/토스트 등) 필요하면 여기서 처리 + } + } label: { + Text("로그인") + .font(.PretendardBold18) + .foregroundColor(.white) + .frame(maxWidth: .infinity, minHeight: 54) + .background( + RoundedRectangle(cornerRadius: 12) + .fill(Color.purple04) + ) + } + .shadow(color: .black.opacity(0.25), radius: 12, x: 0, y: 8) + + // 내비게이션: goHome == true일 때 HomeView로 푸시 + .navigationDestination(isPresented: $goHome) { + HomeView() + .navigationBarBackButtonHidden(true) + } + + // (플레이스홀더) 회원가입 링크 텍스트 + Text("회원가입") + .font(.PretendardMedium13) + .foregroundColor(.gray04) + } + + Spacer(minLength: 17) + + // MARK: - 소셜 아이콘 3종 + HStack { + Spacer().frame(width: 71) + Image("naver").resizable().scaledToFit().frame(width: 40, height: 40) + Spacer() + Image("kakao").resizable().scaledToFit().frame(width: 40, height: 40) + Spacer() + Image("apple").resizable().scaledToFit().frame(width: 40, height: 40) + Spacer().frame(width: 71) + } + .frame(maxWidth: .infinity) + } + .frame(height: 323) + + Spacer(minLength: 17) + + // MARK: - 하단 배너 이미지 + Image("umc_image") + .resizable() + .scaledToFill() + .frame(width: 408, height: 266) + } + .padding(.horizontal, 16) + } + } +} + +#Preview { + LoginView() +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/LoginViewModel.swift b/week03/mission/Week3_Magabox/Week3_Magabox/LoginViewModel.swift new file mode 100644 index 0000000..9e12630 --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/LoginViewModel.swift @@ -0,0 +1,27 @@ +// +// LoginViewModel.swift +// Megabox +// +// Created by 최우진 on 9/25/25. +// + +// LoginViewModel.swift + +import Foundation +import Observation + + +@Observable //전역으로 사용할 수 있도록 설정 +class LoginViewModel { + var loginModel = LoginModel() + + var id: String { + get { loginModel.id } + set { loginModel.id = newValue } + } + + var pwd: String { + get { loginModel.pwd } + set { loginModel.pwd = newValue } + } +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/MemberInfoManagementView.swift b/week03/mission/Week3_Magabox/Week3_Magabox/MemberInfoManagementView.swift new file mode 100644 index 0000000..57b24bf --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/MemberInfoManagementView.swift @@ -0,0 +1,100 @@ +// +// MemberInfoManagementView.swift +// Megabox_2 +// +// Created by 최우진 on 9/26/25. +// + +import SwiftUI + +struct MemberInfoManagementView: View { + // 커스텀 뒤로가기 버튼을 위한 환경 변수 + @Environment(\.dismiss) var dismiss + + // AppStorage 변수 선언 + @AppStorage("savedId") private var savedId: String = "cwj1213" + @AppStorage("savedPassword") private var savedPassword: String = "1111" + @AppStorage("userName") private var userName: String = "최우진" + + // TextField의 입력을 실시간으로 받기 위한 @State 변수 + @State private var nameInput: String = "" + + var body: some View { + // 1. 가장 큰 VStack + VStack(spacing: 53) { + + // 2. 상단 네비게이션 바 (HStack) + HStack(spacing:0) { + // 커스텀 뒤로가기 버튼 + Button(action: { + dismiss() // 이 버튼을 누르면 이전 화면으로 돌아갑니다. + }) { + Image(systemName: "arrow.left") + .foregroundColor(.black) + } + + Spacer() + + Text("회원정보 관리") + .font(.PretendardMedium16) + + Spacer() + } + + + + // 3. 기본정보 파트 (VStack) + VStack(alignment: .leading, spacing: 26) { + Text("기본정보") + .font(.PretendardBold18) + + // 아이디 (Text 처리) + VStack(alignment: .leading, spacing: 3) { + Text(savedId) + .foregroundColor(.black).font(.PretendardMedium18) + Divider().background(Color.gray02) + } + + // 이름 (TextField + 변경 버튼) + VStack(alignment: .leading, spacing: 3) { + HStack { + TextField("이름", text: $nameInput).font(.PretendardMedium18) + + // 이름 변경 버튼 + Button(action: { + // TextField에 입력된 값을 AppStorage에 저장 + userName = nameInput + + }) { + ZStack { + // 1. 배경 레이어 + RoundedRectangle(cornerRadius: 16) + .stroke(Color.gray03, lineWidth: 1) + + // 2. 상단 레이어 + Text("변경") + .font(.PretendardMedium10) + .foregroundColor(.gray03) + }.frame(width: 60, height: 28) + } + } + Divider().background(Color.gray02) + } + } + + Spacer() + } + .padding(.horizontal,16) // 전체적인 좌우 여백 + .navigationBarBackButtonHidden(true) // SwiftUI의 기본 뒤로가기 버튼 숨기기 + .onAppear { + // 이 화면이 나타날 때, AppStorage에 저장된 이름을 TextField에 미리 채우도록 설정 + nameInput = userName + } + } +} + +#Preview { + NavigationStack { + MemberInfoManagementView() + } +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/MemberInfoView.swift b/week03/mission/Week3_Magabox/Week3_Magabox/MemberInfoView.swift new file mode 100644 index 0000000..5eb6672 --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/MemberInfoView.swift @@ -0,0 +1,184 @@ +import SwiftUI + +struct MemberInfoView: View { + // 로그인 뷰에서 저장한 아이디를 가져옵니다. + @AppStorage("savedId") private var savedId: String = "cwj1213" + @AppStorage("savedPassword") private var savedPassword: String = "1111" + @AppStorage("userName") private var userName: String = "최우진" + + var body: some View { + NavigationStack { //회원정보 View로 가도록 + VStack(spacing: 33) { + HStack(alignment: .top) { + // 이름과 포인트를 담는 왼쪽 VStack + VStack(alignment: .leading, spacing: 0) { + HStack(spacing:5) { + Text(userName) + .font(.PretendardBold24) + .fontWeight(.bold) + ZStack { + RoundedRectangle(cornerRadius: 6) + .fill(Color(red: 48/255, green: 209/255, blue: 201/255)) + Text("WELCOME") + .font(.PretendardMedium14) + .fontWeight(.bold) + .foregroundColor(.white) + } + .frame(width: 81, height: 25) + } + HStack(spacing: 9) { + Text("멤버십 포인트") + .font(.footnote) + .foregroundColor(.gray) + Text("500P") + .font(.footnote) + .fontWeight(.semibold) + } + } + Spacer() + // 회원정보 버튼 + NavigationLink(destination: MemberInfoManagementView()) { + VStack { + Text("회원정보") + .font(.PretendardSemiBold14) + .foregroundColor(.white) + } + .padding(.vertical, 4) + .frame(width: 72, height: 28) + .background(Color.gray07) + .cornerRadius(16) + } + } + VStack { + HStack(spacing : 3) { + Text("클럽 멤버십") + .font(.PretendardSemiBold16) + .foregroundColor(.white) + + Image(systemName: "chevron.right") + .font(.system(size: 14, weight: .semibold)) // 아이콘 크기/굵기 조절 + .foregroundColor(.white.opacity(0.8)) + + Spacer() + } + } + .frame(maxWidth: .infinity) + .padding(.vertical, 12) // 상하 패딩 12pt (높이를 46pt로 만듦) + .padding(.horizontal,8) + .background( + LinearGradient( + gradient: Gradient(colors: [ + Color(red: 0.67, green: 0.55, blue: 1), + Color(red: 0.56, green: 0.68, blue: 0.95), + Color(red: 0.36, green: 0.8, blue: 0.93) + ]), + //그라데이션 만들기 + startPoint: .leading, + endPoint: .trailing + ) + ) + .cornerRadius(8) + + ZStack { + // 배경과 테두리 + RoundedRectangle(cornerRadius: 8) + .fill(Color.white) + .stroke(Color.gray02, lineWidth: 1) + + + HStack (spacing: 43){ + VStack(spacing: 9) { + Text("쿠폰") + .font(.PretendardSemiBold16) + .foregroundColor(.gray02) + Text("2") + .font(.PretendardSemiBold18) + .foregroundColor(.black) + } + .frame(maxWidth: .infinity) + + Divider().frame(height: 31) + + VStack(spacing: 9) { + Text("스토어 교환권") + .font(.PretendardSemiBold16) + .foregroundColor(.gray02) + Text("0") + .font(.PretendardSemiBold18) + .foregroundColor(.black) + } + .frame(maxWidth: .infinity) + + Divider().frame(height: 31) + + VStack(spacing: 9) { + Text("모바일 티켓") + .font(.PretendardSemiBold16) + .foregroundColor(.gray02) + Text("0") + .font(.PretendardSemiBold18) + .foregroundColor(.black) + } + .frame(maxWidth: .infinity) + } + .padding(.vertical, 12) + .padding(.horizontal, 24) + } + .frame(height: 76) + + HStack(alignment: .top, spacing: 16) { + VStack(spacing: 12) { + Image("film-reel") + .resizable() + .scaledToFit() + .frame(height: 36) + Text("영화별예매") + .font(.PretendardMedium16) + } + .frame(maxWidth: .infinity) + + VStack(spacing: 12) { + Image("map") + .resizable() + .scaledToFit() + .frame(height: 36) + Text("극장별예매") + .font(.PretendardMedium16) + } + .frame(maxWidth: .infinity) + + VStack(spacing: 12) { + Image("sofa") + .resizable() + .scaledToFit() + .frame(height: 36) + Text("특별관예매") + .font(.PretendardMedium16) + } + .frame(maxWidth: .infinity) + + VStack(spacing: 12) { + Image("cinema") + .resizable() + .scaledToFit() + .frame(height: 36) + Text("모바일오더") + .font(.PretendardMedium16) + } + .frame(maxWidth: .infinity) + + } + + Spacer() + } + .padding(.horizontal, 24) // ← 여기서 전체 좌우 16pt 여백 줌 + .padding(.vertical, 95) + .background(Color(uiColor: .white)) // 전체 배경색 + } + .navigationBarBackButtonHidden(true) + } +} + +#Preview { + MemberInfoView() +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/SplashView.swift b/week03/mission/Week3_Magabox/Week3_Magabox/SplashView.swift new file mode 100644 index 0000000..bd95bf2 --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/SplashView.swift @@ -0,0 +1,15 @@ +import SwiftUI + +struct SplashView: View { + var body: some View { + VStack{ + Spacer() + Image("megabox_logo").resizable().scaledToFit().frame(width: 249, height: 84) + Spacer() + } + } +} + +#Preview { + SplashView() +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/Week3_MagaboxApp.swift b/week03/mission/Week3_Magabox/Week3_Magabox/Week3_MagaboxApp.swift new file mode 100644 index 0000000..8b16c53 --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/Week3_MagaboxApp.swift @@ -0,0 +1,28 @@ +// +// Week3_MagaboxApp.swift +// Week3_Magabox +// +// Created by 최우진 on 10/2/25. +// +import SwiftUI + +@main +struct MegaboxApp: App { + @State private var showLogin = true + + var body: some Scene { + WindowGroup { + if showLogin { + SplashView() + .onAppear { + DispatchQueue.main.asyncAfter(deadline: .now() + 2) { + showLogin = false + } + } + } + else { + LoginView() + } + } + } +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/color.swift b/week03/mission/Week3_Magabox/Week3_Magabox/color.swift new file mode 100644 index 0000000..ee92204 --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/color.swift @@ -0,0 +1,62 @@ +// +// color.swift +// Megabox +// +// Created by 최우진 on 9/20/25. +// + +import Foundation +import SwiftUI + +extension Color { + // 1) 이니셜라이저를 Color.swift로 옮기고, 팔레트보다 위에 둡니다. + init(hex: UInt, alpha: Double = 1.0) { + self.init(.sRGB, + red: Double((hex >> 16) & 0xFF) / 255.0, + green: Double((hex >> 8) & 0xFF) / 255.0, + blue: Double( hex & 0xFF) / 255.0, + opacity: alpha) + } + + // 2) 팔레트 정의 + // Blue + static let blue00 = Color(hex: 0xE5EAFA as UInt) + static let blue01 = Color(hex: 0xFFFFFF as UInt) + static let blue02 = Color(hex: 0xE3E9F5 as UInt) + static let blue03 = Color(hex: 0x8AAAD6 as UInt) + static let blue04 = Color(hex: 0x6C94C3 as UInt) + static let blue05 = Color(hex: 0x5C85B9 as UInt) + static let blue06 = Color(hex: 0x466F9E as UInt) + static let blue07 = Color(hex: 0x2F567F as UInt) + static let blue08 = Color(hex: 0x1E3C60 as UInt) + static let blue09 = Color(hex: 0x132847 as UInt) + + // Purple + static let purple00 = Color(hex: 0xF5E8FF as UInt) + static let purple01 = Color(hex: 0xE4C8FF as UInt) + static let purple02 = Color(hex: 0xC49CFF as UInt) + static let purple03 = Color(hex: 0x9C6EFF as UInt) + static let purple04 = Color(hex: 0x6F2CFF as UInt) // 버튼 색 + static let purple05 = Color(hex: 0x5C23CC as UInt) + static let purple06 = Color(hex: 0x491A99 as UInt) + static let purple07 = Color(hex: 0x371266 as UInt) + static let purple08 = Color(hex: 0x240933 as UInt) + static let purple09 = Color(hex: 0x1A0020 as UInt) + + // Grey + static let gray00 = Color(hex: 0xF8F9FA as UInt) + static let gray01 = Color(hex: 0xF1F3F5 as UInt) + static let gray02 = Color(hex: 0xE5E5EA as UInt) + static let gray03 = Color(hex: 0xD1D5DB as UInt) + static let gray04 = Color(hex: 0x9CA3AF as UInt) + static let gray05 = Color(hex: 0x6B7280 as UInt) + static let gray06 = Color(hex: 0x4B5563 as UInt) + static let gray07 = Color(hex: 0x374151 as UInt) + static let gray08 = Color(hex: 0x1F2937 as UInt) + static let gray09 = Color(hex: 0x111827 as UInt) + + // White / Black (토큰) + static let White = Color.white + static let Black = Color.black +} + diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Fonts.swift b/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Fonts.swift new file mode 100644 index 0000000..eb400a6 --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Fonts.swift @@ -0,0 +1,152 @@ +// +// Fonts.swift +// Week1_Practice +// +// Created by 최우진 on 9/20/25. +// + +import Foundation +import SwiftUI + +extension Font { + enum Pretend { + case extraBold + case bold + case semibold + case medium + case regular + case light + + var value: String { + switch self { + case .extraBold: + return "Pretendard-ExtraBold" + case .bold: + return "Pretendard-Bold" + case .semibold: + return "Pretendard-SemiBold" + case .medium: + return "Pretendard-Medium" + case .regular: + return "Pretendard-Regular" + case .light: + return "Pretendard-Light" + } + } + } + + static func pretend(type: Pretend, size: CGFloat) -> Font { + return .custom(type.value, size: size) + } + + static var PretendardBold30: Font { + return .pretend(type: .bold, size: 30) + } + + // 새로 추가한 스타일 + static var PretendardRegular16: Font { + return .pretend(type: .regular, size: 16) + } + + static var PretendardBold24: Font { + return .pretend(type: .bold, size: 24) + } + + static var PretendardSemiBold18: Font { + return .pretend(type: .semibold, size: 18) + } + + static var PretendardLight16: Font { + return .pretend(type: .light, size: 16) + } + + // Bold + static var PretendardBold18: Font { + return .pretend(type: .bold, size: 18) + } + + static var PretendardBold22: Font { + return .pretend(type: .bold, size: 22) + } + + // SemiBold + static var PretendardSemiBold38: Font { + return .pretend(type: .semibold, size: 38) + } + + static var PretendardSemiBold24: Font { + return .pretend(type: .semibold, size: 24) + } + + static var PretendardSemiBold16: Font { + return .pretend(type: .semibold, size: 16) + } + + static var PretendardSemiBold14: Font { + return .pretend(type: .semibold, size: 14) + } + + static var PretendardSemiBold13: Font { + return .pretend(type: .semibold, size: 13) + } + + static var PretendardSemiBold12: Font { + return .pretend(type: .semibold, size: 12) + } + + // Regular + static var PretendardRegular20: Font { + return .pretend(type: .regular, size: 20) + } + + static var PretendardRegular18: Font { + return .pretend(type: .regular, size: 18) + } + + static var PretendardRegular13: Font { + return .pretend(type: .regular, size: 13) + } + + static var PretendardRegular12: Font { + return .pretend(type: .regular, size: 12) + } + + static var PretendardRegular9: Font { + return .pretend(type: .regular, size: 9) + } + + // Medium + static var PretendardMedium18: Font { + return .pretend(type: .medium, size: 18) + } + + static var PretendardMedium16: Font { + return .pretend(type: .medium, size: 16) + } + + static var PretendardMedium14: Font { + return .pretend(type: .medium, size: 14) + } + + static var PretendardMedium13: Font { + return .pretend(type: .medium, size: 13) + } + + static var PretendardMedium10: Font { + return .pretend(type: .medium, size: 10) + } + + static var PretendardMedium8: Font { + return .pretend(type: .medium, size: 8) + } + + // Light + static var PretendardLight14: Font { + return .pretend(type: .light, size: 14) + } + + // ExtraBold + static var PretendardExtraBold24: Font { + return .pretend(type: .extraBold, size: 24) + } +} diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Black.otf b/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Black.otf new file mode 100644 index 0000000..a0d849e Binary files /dev/null and b/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Black.otf differ diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Bold.otf b/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Bold.otf new file mode 100644 index 0000000..8e5e30a Binary files /dev/null and b/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Bold.otf differ diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Pretendard-ExtraBold.otf b/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Pretendard-ExtraBold.otf new file mode 100644 index 0000000..388f3ca Binary files /dev/null and b/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Pretendard-ExtraBold.otf differ diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Pretendard-ExtraLight.otf b/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Pretendard-ExtraLight.otf new file mode 100644 index 0000000..40c8b69 Binary files /dev/null and b/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Pretendard-ExtraLight.otf differ diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Light.otf b/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Light.otf new file mode 100644 index 0000000..228679e Binary files /dev/null and b/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Light.otf differ diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Medium.otf b/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Medium.otf new file mode 100644 index 0000000..0575069 Binary files /dev/null and b/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Medium.otf differ diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Regular.otf b/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Regular.otf new file mode 100644 index 0000000..08bf4cf Binary files /dev/null and b/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Regular.otf differ diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Pretendard-SemiBold.otf b/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Pretendard-SemiBold.otf new file mode 100644 index 0000000..e7e36ab Binary files /dev/null and b/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Pretendard-SemiBold.otf differ diff --git a/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Thin.otf b/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Thin.otf new file mode 100644 index 0000000..77e792d Binary files /dev/null and b/week03/mission/Week3_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Thin.otf differ diff --git a/week03/mission/Week3_Magabox/Week3_MagaboxTests/Week3_MagaboxTests.swift b/week03/mission/Week3_Magabox/Week3_MagaboxTests/Week3_MagaboxTests.swift new file mode 100644 index 0000000..f1493a8 --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_MagaboxTests/Week3_MagaboxTests.swift @@ -0,0 +1,17 @@ +// +// Week3_MagaboxTests.swift +// Week3_MagaboxTests +// +// Created by 최우진 on 10/2/25. +// + +import Testing +@testable import Week3_Magabox + +struct Week3_MagaboxTests { + + @Test func example() async throws { + // Write your test here and use APIs like `#expect(...)` to check expected conditions. + } + +} diff --git a/week03/mission/Week3_Magabox/Week3_MagaboxUITests/Week3_MagaboxUITests.swift b/week03/mission/Week3_Magabox/Week3_MagaboxUITests/Week3_MagaboxUITests.swift new file mode 100644 index 0000000..4245719 --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_MagaboxUITests/Week3_MagaboxUITests.swift @@ -0,0 +1,41 @@ +// +// Week3_MagaboxUITests.swift +// Week3_MagaboxUITests +// +// Created by 최우진 on 10/2/25. +// + +import XCTest + +final class Week3_MagaboxUITests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + @MainActor + func testExample() throws { + // UI tests must launch the application that they test. + let app = XCUIApplication() + app.launch() + + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + @MainActor + func testLaunchPerformance() throws { + // This measures how long it takes to launch your application. + measure(metrics: [XCTApplicationLaunchMetric()]) { + XCUIApplication().launch() + } + } +} diff --git a/week03/mission/Week3_Magabox/Week3_MagaboxUITests/Week3_MagaboxUITestsLaunchTests.swift b/week03/mission/Week3_Magabox/Week3_MagaboxUITests/Week3_MagaboxUITestsLaunchTests.swift new file mode 100644 index 0000000..dad038b --- /dev/null +++ b/week03/mission/Week3_Magabox/Week3_MagaboxUITests/Week3_MagaboxUITestsLaunchTests.swift @@ -0,0 +1,33 @@ +// +// Week3_MagaboxUITestsLaunchTests.swift +// Week3_MagaboxUITests +// +// Created by 최우진 on 10/2/25. +// + +import XCTest + +final class Week3_MagaboxUITestsLaunchTests: XCTestCase { + + override class var runsForEachTargetApplicationUIConfiguration: Bool { + true + } + + override func setUpWithError() throws { + continueAfterFailure = false + } + + @MainActor + func testLaunch() throws { + let app = XCUIApplication() + app.launch() + + // Insert steps here to perform after app launch but before taking a screenshot, + // such as logging into a test account or navigating somewhere in the app + + let attachment = XCTAttachment(screenshot: app.screenshot()) + attachment.name = "Launch Screen" + attachment.lifetime = .keepAlways + add(attachment) + } +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox.xcodeproj/project.pbxproj b/week04/mission/Week4_Magabox/Week3_Magabox.xcodeproj/project.pbxproj new file mode 100644 index 0000000..4aad055 --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox.xcodeproj/project.pbxproj @@ -0,0 +1,555 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 77; + objects = { + +/* Begin PBXContainerItemProxy section */ + E4AFDB9C2E8D8D5E0064D682 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E4AFDB862E8D8D5A0064D682 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E4AFDB8D2E8D8D5A0064D682; + remoteInfo = Week3_Magabox; + }; + E4AFDBA62E8D8D5E0064D682 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E4AFDB862E8D8D5A0064D682 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E4AFDB8D2E8D8D5A0064D682; + remoteInfo = Week3_Magabox; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + E4AFDB8E2E8D8D5A0064D682 /* Week3_Magabox.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Week3_Magabox.app; sourceTree = BUILT_PRODUCTS_DIR; }; + E4AFDB9B2E8D8D5E0064D682 /* Week3_MagaboxTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Week3_MagaboxTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + E4AFDBA52E8D8D5E0064D682 /* Week3_MagaboxUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Week3_MagaboxUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + E4AFDB902E8D8D5A0064D682 /* Week3_Magabox */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = Week3_Magabox; + sourceTree = ""; + }; + E4AFDB9E2E8D8D5E0064D682 /* Week3_MagaboxTests */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = Week3_MagaboxTests; + sourceTree = ""; + }; + E4AFDBA82E8D8D5E0064D682 /* Week3_MagaboxUITests */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = Week3_MagaboxUITests; + sourceTree = ""; + }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + E4AFDB8B2E8D8D5A0064D682 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E4AFDB982E8D8D5E0064D682 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E4AFDBA22E8D8D5E0064D682 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + E4AFDB852E8D8D5A0064D682 = { + isa = PBXGroup; + children = ( + E4AFDB902E8D8D5A0064D682 /* Week3_Magabox */, + E4AFDB9E2E8D8D5E0064D682 /* Week3_MagaboxTests */, + E4AFDBA82E8D8D5E0064D682 /* Week3_MagaboxUITests */, + E4AFDB8F2E8D8D5A0064D682 /* Products */, + ); + sourceTree = ""; + }; + E4AFDB8F2E8D8D5A0064D682 /* Products */ = { + isa = PBXGroup; + children = ( + E4AFDB8E2E8D8D5A0064D682 /* Week3_Magabox.app */, + E4AFDB9B2E8D8D5E0064D682 /* Week3_MagaboxTests.xctest */, + E4AFDBA52E8D8D5E0064D682 /* Week3_MagaboxUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + E4AFDB8D2E8D8D5A0064D682 /* Week3_Magabox */ = { + isa = PBXNativeTarget; + buildConfigurationList = E4AFDBAF2E8D8D5F0064D682 /* Build configuration list for PBXNativeTarget "Week3_Magabox" */; + buildPhases = ( + E4AFDB8A2E8D8D5A0064D682 /* Sources */, + E4AFDB8B2E8D8D5A0064D682 /* Frameworks */, + E4AFDB8C2E8D8D5A0064D682 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + E4AFDB902E8D8D5A0064D682 /* Week3_Magabox */, + ); + name = Week3_Magabox; + packageProductDependencies = ( + ); + productName = Week3_Magabox; + productReference = E4AFDB8E2E8D8D5A0064D682 /* Week3_Magabox.app */; + productType = "com.apple.product-type.application"; + }; + E4AFDB9A2E8D8D5E0064D682 /* Week3_MagaboxTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = E4AFDBB22E8D8D5F0064D682 /* Build configuration list for PBXNativeTarget "Week3_MagaboxTests" */; + buildPhases = ( + E4AFDB972E8D8D5E0064D682 /* Sources */, + E4AFDB982E8D8D5E0064D682 /* Frameworks */, + E4AFDB992E8D8D5E0064D682 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + E4AFDB9D2E8D8D5E0064D682 /* PBXTargetDependency */, + ); + fileSystemSynchronizedGroups = ( + E4AFDB9E2E8D8D5E0064D682 /* Week3_MagaboxTests */, + ); + name = Week3_MagaboxTests; + packageProductDependencies = ( + ); + productName = Week3_MagaboxTests; + productReference = E4AFDB9B2E8D8D5E0064D682 /* Week3_MagaboxTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + E4AFDBA42E8D8D5E0064D682 /* Week3_MagaboxUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = E4AFDBB52E8D8D5F0064D682 /* Build configuration list for PBXNativeTarget "Week3_MagaboxUITests" */; + buildPhases = ( + E4AFDBA12E8D8D5E0064D682 /* Sources */, + E4AFDBA22E8D8D5E0064D682 /* Frameworks */, + E4AFDBA32E8D8D5E0064D682 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + E4AFDBA72E8D8D5E0064D682 /* PBXTargetDependency */, + ); + fileSystemSynchronizedGroups = ( + E4AFDBA82E8D8D5E0064D682 /* Week3_MagaboxUITests */, + ); + name = Week3_MagaboxUITests; + packageProductDependencies = ( + ); + productName = Week3_MagaboxUITests; + productReference = E4AFDBA52E8D8D5E0064D682 /* Week3_MagaboxUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + E4AFDB862E8D8D5A0064D682 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1640; + LastUpgradeCheck = 1640; + TargetAttributes = { + E4AFDB8D2E8D8D5A0064D682 = { + CreatedOnToolsVersion = 16.4; + }; + E4AFDB9A2E8D8D5E0064D682 = { + CreatedOnToolsVersion = 16.4; + TestTargetID = E4AFDB8D2E8D8D5A0064D682; + }; + E4AFDBA42E8D8D5E0064D682 = { + CreatedOnToolsVersion = 16.4; + TestTargetID = E4AFDB8D2E8D8D5A0064D682; + }; + }; + }; + buildConfigurationList = E4AFDB892E8D8D5A0064D682 /* Build configuration list for PBXProject "Week3_Magabox" */; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = E4AFDB852E8D8D5A0064D682; + minimizedProjectReferenceProxies = 1; + preferredProjectObjectVersion = 77; + productRefGroup = E4AFDB8F2E8D8D5A0064D682 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + E4AFDB8D2E8D8D5A0064D682 /* Week3_Magabox */, + E4AFDB9A2E8D8D5E0064D682 /* Week3_MagaboxTests */, + E4AFDBA42E8D8D5E0064D682 /* Week3_MagaboxUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + E4AFDB8C2E8D8D5A0064D682 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E4AFDB992E8D8D5E0064D682 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E4AFDBA32E8D8D5E0064D682 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + E4AFDB8A2E8D8D5A0064D682 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E4AFDB972E8D8D5E0064D682 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E4AFDBA12E8D8D5E0064D682 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + E4AFDB9D2E8D8D5E0064D682 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = E4AFDB8D2E8D8D5A0064D682 /* Week3_Magabox */; + targetProxy = E4AFDB9C2E8D8D5E0064D682 /* PBXContainerItemProxy */; + }; + E4AFDBA72E8D8D5E0064D682 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = E4AFDB8D2E8D8D5A0064D682 /* Week3_Magabox */; + targetProxy = E4AFDBA62E8D8D5E0064D682 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + E4AFDBAD2E8D8D5F0064D682 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + 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; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + 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 = 18.5; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + E4AFDBAE2E8D8D5F0064D682 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + 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; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + 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 = 18.5; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + E4AFDBB02E8D8D5F0064D682 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.woojin.Week3-Magabox"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + E4AFDBB12E8D8D5F0064D682 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.woojin.Week3-Magabox"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + E4AFDBB32E8D8D5F0064D682 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.5; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.woojin.Week3-MagaboxTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Week3_Magabox.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Week3_Magabox"; + }; + name = Debug; + }; + E4AFDBB42E8D8D5F0064D682 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.5; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.woojin.Week3-MagaboxTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Week3_Magabox.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Week3_Magabox"; + }; + name = Release; + }; + E4AFDBB62E8D8D5F0064D682 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.woojin.Week3-MagaboxUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = Week3_Magabox; + }; + name = Debug; + }; + E4AFDBB72E8D8D5F0064D682 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.woojin.Week3-MagaboxUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = Week3_Magabox; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + E4AFDB892E8D8D5A0064D682 /* Build configuration list for PBXProject "Week3_Magabox" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E4AFDBAD2E8D8D5F0064D682 /* Debug */, + E4AFDBAE2E8D8D5F0064D682 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E4AFDBAF2E8D8D5F0064D682 /* Build configuration list for PBXNativeTarget "Week3_Magabox" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E4AFDBB02E8D8D5F0064D682 /* Debug */, + E4AFDBB12E8D8D5F0064D682 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E4AFDBB22E8D8D5F0064D682 /* Build configuration list for PBXNativeTarget "Week3_MagaboxTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E4AFDBB32E8D8D5F0064D682 /* Debug */, + E4AFDBB42E8D8D5F0064D682 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E4AFDBB52E8D8D5F0064D682 /* Build configuration list for PBXNativeTarget "Week3_MagaboxUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E4AFDBB62E8D8D5F0064D682 /* Debug */, + E4AFDBB72E8D8D5F0064D682 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = E4AFDB862E8D8D5A0064D682 /* Project object */; +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/week04/mission/Week4_Magabox/Week3_Magabox.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/week04/mission/Week4_Magabox/Week3_Magabox.xcodeproj/project.xcworkspace/xcuserdata/wj_intelmac.xcuserdatad/UserInterfaceState.xcuserstate b/week04/mission/Week4_Magabox/Week3_Magabox.xcodeproj/project.xcworkspace/xcuserdata/wj_intelmac.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..22a662b Binary files /dev/null and b/week04/mission/Week4_Magabox/Week3_Magabox.xcodeproj/project.xcworkspace/xcuserdata/wj_intelmac.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/week04/mission/Week4_Magabox/Week3_Magabox.xcodeproj/xcuserdata/wj_intelmac.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/week04/mission/Week4_Magabox/Week3_Magabox.xcodeproj/xcuserdata/wj_intelmac.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..e4f9e97 --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox.xcodeproj/xcuserdata/wj_intelmac.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,6 @@ + + + diff --git a/week04/mission/Week4_Magabox/Week3_Magabox.xcodeproj/xcuserdata/wj_intelmac.xcuserdatad/xcschemes/xcschememanagement.plist b/week04/mission/Week4_Magabox/Week3_Magabox.xcodeproj/xcuserdata/wj_intelmac.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..6e46924 --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox.xcodeproj/xcuserdata/wj_intelmac.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + Week3_Magabox.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/AccentColor.colorset/Contents.json b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/AppIcon.appiconset/Contents.json b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..2305880 --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,35 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "tinted" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/Contents.json b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/apple.imageset/Contents.json b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/apple.imageset/Contents.json new file mode 100644 index 0000000..0975940 --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/apple.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "apple.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/apple.imageset/apple.pdf b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/apple.imageset/apple.pdf new file mode 100644 index 0000000..909af30 Binary files /dev/null and b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/apple.imageset/apple.pdf differ diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/background.imageset/Contents.json b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/background.imageset/Contents.json new file mode 100644 index 0000000..7e26126 --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/background.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "background.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/background.imageset/background.pdf b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/background.imageset/background.pdf new file mode 100644 index 0000000..e2c0ebe Binary files /dev/null and b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/background.imageset/background.pdf differ diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/cinema.imageset/Contents.json b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/cinema.imageset/Contents.json new file mode 100644 index 0000000..430a6e5 --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/cinema.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "cinema.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/cinema.imageset/cinema.pdf b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/cinema.imageset/cinema.pdf new file mode 100644 index 0000000..d76a452 Binary files /dev/null and b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/cinema.imageset/cinema.pdf differ diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/clock.imageset/Contents.json b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/clock.imageset/Contents.json new file mode 100644 index 0000000..bd6a149 --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/clock.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "clock.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/clock.imageset/clock.png b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/clock.imageset/clock.png new file mode 100644 index 0000000..6e662a5 Binary files /dev/null and b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/clock.imageset/clock.png differ diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/f1.imageset/Contents.json b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/f1.imageset/Contents.json new file mode 100644 index 0000000..dc40783 --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/f1.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "f1.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/f1.imageset/f1.pdf b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/f1.imageset/f1.pdf new file mode 100644 index 0000000..d1c6f76 Binary files /dev/null and b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/f1.imageset/f1.pdf differ diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/f1_header.imageset/Contents.json b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/f1_header.imageset/Contents.json new file mode 100644 index 0000000..aef409b --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/f1_header.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "f1_header.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/f1_header.imageset/f1_header.pdf b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/f1_header.imageset/f1_header.pdf new file mode 100644 index 0000000..c616447 Binary files /dev/null and b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/f1_header.imageset/f1_header.pdf differ diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/film-reel.imageset/Contents.json b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/film-reel.imageset/Contents.json new file mode 100644 index 0000000..c1aba9f --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/film-reel.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "film-reel.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/film-reel.imageset/film-reel.pdf b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/film-reel.imageset/film-reel.pdf new file mode 100644 index 0000000..9d4ba17 Binary files /dev/null and b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/film-reel.imageset/film-reel.pdf differ diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/image 1.imageset/Contents.json b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/image 1.imageset/Contents.json new file mode 100644 index 0000000..6a452fc --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/image 1.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "image 1.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/image 1.imageset/image 1.pdf b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/image 1.imageset/image 1.pdf new file mode 100644 index 0000000..417b2a5 Binary files /dev/null and b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/image 1.imageset/image 1.pdf differ diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/image 2.imageset/Contents.json b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/image 2.imageset/Contents.json new file mode 100644 index 0000000..dc4f61a --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/image 2.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "image 2.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/image 2.imageset/image 2.pdf b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/image 2.imageset/image 2.pdf new file mode 100644 index 0000000..477d48c Binary files /dev/null and b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/image 2.imageset/image 2.pdf differ diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/image 3.imageset/Contents.json b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/image 3.imageset/Contents.json new file mode 100644 index 0000000..6a452fc --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/image 3.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "image 1.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/image 3.imageset/image 1.pdf b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/image 3.imageset/image 1.pdf new file mode 100644 index 0000000..83b4fa6 Binary files /dev/null and b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/image 3.imageset/image 1.pdf differ diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/kakao.imageset/Contents.json b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/kakao.imageset/Contents.json new file mode 100644 index 0000000..2ff1237 --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/kakao.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "kakao.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/kakao.imageset/kakao.pdf b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/kakao.imageset/kakao.pdf new file mode 100644 index 0000000..9f17f2b Binary files /dev/null and b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/kakao.imageset/kakao.pdf differ diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/map.imageset/Contents.json b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/map.imageset/Contents.json new file mode 100644 index 0000000..60ad78a --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/map.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "map.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/map.imageset/map.pdf b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/map.imageset/map.pdf new file mode 100644 index 0000000..9bc07f2 Binary files /dev/null and b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/map.imageset/map.pdf differ diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/meboxLogo_home.imageset/Contents.json b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/meboxLogo_home.imageset/Contents.json new file mode 100644 index 0000000..7d8b28b --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/meboxLogo_home.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "meboxLogo_home.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/meboxLogo_home.imageset/meboxLogo_home.pdf b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/meboxLogo_home.imageset/meboxLogo_home.pdf new file mode 100644 index 0000000..8f2c502 Binary files /dev/null and b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/meboxLogo_home.imageset/meboxLogo_home.pdf differ diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/megabox_logo.imageset/Contents.json b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/megabox_logo.imageset/Contents.json new file mode 100644 index 0000000..9999a13 --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/megabox_logo.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "megabox_logo.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/megabox_logo.imageset/megabox_logo.pdf b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/megabox_logo.imageset/megabox_logo.pdf new file mode 100644 index 0000000..88b2939 Binary files /dev/null and b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/megabox_logo.imageset/megabox_logo.pdf differ diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/naver.imageset/Contents.json b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/naver.imageset/Contents.json new file mode 100644 index 0000000..59d595e --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/naver.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "naver.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/naver.imageset/naver.pdf b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/naver.imageset/naver.pdf new file mode 100644 index 0000000..ebde8f5 Binary files /dev/null and b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/naver.imageset/naver.pdf differ diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/sofa.imageset/Contents.json b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/sofa.imageset/Contents.json new file mode 100644 index 0000000..7867b3b --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/sofa.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "sofa.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/sofa.imageset/sofa.pdf b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/sofa.imageset/sofa.pdf new file mode 100644 index 0000000..a7bfd92 Binary files /dev/null and b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/sofa.imageset/sofa.pdf differ diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/umc_image.imageset/Contents.json b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/umc_image.imageset/Contents.json new file mode 100644 index 0000000..a6310e5 --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/umc_image.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "umc_image.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/umc_image.imageset/umc_image.png b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/umc_image.imageset/umc_image.png new file mode 100644 index 0000000..47c6104 Binary files /dev/null and b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/umc_image.imageset/umc_image.png differ diff --git "a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/\341\204\206\341\205\256\341\204\222\341\205\241\341\206\253\341\204\211\341\205\245\341\206\274.imageset/Contents.json" "b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/\341\204\206\341\205\256\341\204\222\341\205\241\341\206\253\341\204\211\341\205\245\341\206\274.imageset/Contents.json" new file mode 100644 index 0000000..3e06ca0 --- /dev/null +++ "b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/\341\204\206\341\205\256\341\204\222\341\205\241\341\206\253\341\204\211\341\205\245\341\206\274.imageset/Contents.json" @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "무한성.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/\341\204\206\341\205\256\341\204\222\341\205\241\341\206\253\341\204\211\341\205\245\341\206\274.imageset/\341\204\206\341\205\256\341\204\222\341\205\241\341\206\253\341\204\211\341\205\245\341\206\274.pdf" "b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/\341\204\206\341\205\256\341\204\222\341\205\241\341\206\253\341\204\211\341\205\245\341\206\274.imageset/\341\204\206\341\205\256\341\204\222\341\205\241\341\206\253\341\204\211\341\205\245\341\206\274.pdf" new file mode 100644 index 0000000..b0ab786 Binary files /dev/null and "b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/\341\204\206\341\205\256\341\204\222\341\205\241\341\206\253\341\204\211\341\205\245\341\206\274.imageset/\341\204\206\341\205\256\341\204\222\341\205\241\341\206\253\341\204\211\341\205\245\341\206\274.pdf" differ diff --git "a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/\341\204\213\341\205\245\341\204\215\341\205\245\341\206\257\341\204\211\341\205\256\341\204\200\341\205\241 \341\204\213\341\205\245\341\206\271\341\204\203\341\205\241.imageset/Contents.json" "b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/\341\204\213\341\205\245\341\204\215\341\205\245\341\206\257\341\204\211\341\205\256\341\204\200\341\205\241 \341\204\213\341\205\245\341\206\271\341\204\203\341\205\241.imageset/Contents.json" new file mode 100644 index 0000000..096181b --- /dev/null +++ "b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/\341\204\213\341\205\245\341\204\215\341\205\245\341\206\257\341\204\211\341\205\256\341\204\200\341\205\241 \341\204\213\341\205\245\341\206\271\341\204\203\341\205\241.imageset/Contents.json" @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "어쩔수가 없다.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/\341\204\213\341\205\245\341\204\215\341\205\245\341\206\257\341\204\211\341\205\256\341\204\200\341\205\241 \341\204\213\341\205\245\341\206\271\341\204\203\341\205\241.imageset/\341\204\213\341\205\245\341\204\215\341\205\245\341\206\257\341\204\211\341\205\256\341\204\200\341\205\241 \341\204\213\341\205\245\341\206\271\341\204\203\341\205\241.pdf" "b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/\341\204\213\341\205\245\341\204\215\341\205\245\341\206\257\341\204\211\341\205\256\341\204\200\341\205\241 \341\204\213\341\205\245\341\206\271\341\204\203\341\205\241.imageset/\341\204\213\341\205\245\341\204\215\341\205\245\341\206\257\341\204\211\341\205\256\341\204\200\341\205\241 \341\204\213\341\205\245\341\206\271\341\204\203\341\205\241.pdf" new file mode 100644 index 0000000..6c44435 Binary files /dev/null and "b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/\341\204\213\341\205\245\341\204\215\341\205\245\341\206\257\341\204\211\341\205\256\341\204\200\341\205\241 \341\204\213\341\205\245\341\206\271\341\204\203\341\205\241.imageset/\341\204\213\341\205\245\341\204\215\341\205\245\341\206\257\341\204\211\341\205\256\341\204\200\341\205\241 \341\204\213\341\205\245\341\206\271\341\204\203\341\205\241.pdf" differ diff --git "a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/\341\204\213\341\205\245\341\206\257\341\204\200\341\205\256\341\206\257.imageset/Contents.json" "b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/\341\204\213\341\205\245\341\206\257\341\204\200\341\205\256\341\206\257.imageset/Contents.json" new file mode 100644 index 0000000..aa5605c --- /dev/null +++ "b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/\341\204\213\341\205\245\341\206\257\341\204\200\341\205\256\341\206\257.imageset/Contents.json" @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "얼굴.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/\341\204\213\341\205\245\341\206\257\341\204\200\341\205\256\341\206\257.imageset/\341\204\213\341\205\245\341\206\257\341\204\200\341\205\256\341\206\257.pdf" "b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/\341\204\213\341\205\245\341\206\257\341\204\200\341\205\256\341\206\257.imageset/\341\204\213\341\205\245\341\206\257\341\204\200\341\205\256\341\206\257.pdf" new file mode 100644 index 0000000..4fa2a3f Binary files /dev/null and "b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/\341\204\213\341\205\245\341\206\257\341\204\200\341\205\256\341\206\257.imageset/\341\204\213\341\205\245\341\206\257\341\204\200\341\205\256\341\206\257.pdf" differ diff --git "a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/\341\204\214\341\205\242\341\204\200\341\205\242\341\204\207\341\205\251\341\206\274.imageset/Contents.json" "b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/\341\204\214\341\205\242\341\204\200\341\205\242\341\204\207\341\205\251\341\206\274.imageset/Contents.json" new file mode 100644 index 0000000..aad4da5 --- /dev/null +++ "b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/\341\204\214\341\205\242\341\204\200\341\205\242\341\204\207\341\205\251\341\206\274.imageset/Contents.json" @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "재개봉.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/\341\204\214\341\205\242\341\204\200\341\205\242\341\204\207\341\205\251\341\206\274.imageset/\341\204\214\341\205\242\341\204\200\341\205\242\341\204\207\341\205\251\341\206\274.pdf" "b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/\341\204\214\341\205\242\341\204\200\341\205\242\341\204\207\341\205\251\341\206\274.imageset/\341\204\214\341\205\242\341\204\200\341\205\242\341\204\207\341\205\251\341\206\274.pdf" new file mode 100644 index 0000000..0c7b350 Binary files /dev/null and "b/week04/mission/Week4_Magabox/Week3_Magabox/Assets.xcassets/\341\204\214\341\205\242\341\204\200\341\205\242\341\204\207\341\205\251\341\206\274.imageset/\341\204\214\341\205\242\341\204\200\341\205\242\341\204\207\341\205\251\341\206\274.pdf" differ diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/ContentView.swift b/week04/mission/Week4_Magabox/Week3_Magabox/ContentView.swift new file mode 100644 index 0000000..a65b078 --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/ContentView.swift @@ -0,0 +1,24 @@ +// +// ContentView.swift +// Megabox_2 +// +// Created by 최우진 on 9/26/25. +// + +import SwiftUI + +struct ContentView: View { + var body: some View { + VStack { + Image(systemName: "globe") + .imageScale(.large) + .foregroundStyle(.tint) + Text("Hello, world!") + } + .padding() + } +} + +#Preview { + ContentView() +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/HomeModel.swift b/week04/mission/Week4_Magabox/Week3_Magabox/HomeModel.swift new file mode 100644 index 0000000..05d29da --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/HomeModel.swift @@ -0,0 +1,51 @@ +// +// HomeModel.swift +// Week3_Magabox +// +// Created by 최우진 on 10/4/25. +// + +import Foundation + + +// 상단 텍스트 탭 +enum HomeTopTab: Int, CaseIterable { + case home, event, store, favorite + var title: String { + switch self { + case .home: return "홈" + case .event: return "이벤트" + case .store: return "스토어" + case .favorite: return "선호극장" + } + } +} + +// 칩(무비차트 / 상영예정) +enum MovieChip: Int { //case에 따라 String 값을 유동적으로 변경 가능 + case chart = 0 + case upcoming = 1 + + var title: String { + switch self { //case에 따라 String 값을 유동적으로 변경 가능 + case .chart: return "무비차트" + case .upcoming:return "상영예정" + } + } +} + +// 영화 데이터 모델 +// Identifiable은 고유 ID를 알리는 프로토컬이고 Hashable은 해시값으로 쓸 수 있도록 하는겨 +// 즉 Identifiable->foreach, Hashable->NavigationLink +struct Movie: Identifiable, Hashable { + let id = UUID() + let poster: String + let title: String + let audience: String + + let header: String + let subtitle: String? + let overview: String? + let ageRating: String? + let releaseDate: String? +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/HomeView.swift b/week04/mission/Week4_Magabox/Week3_Magabox/HomeView.swift new file mode 100644 index 0000000..0bd5e91 --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/HomeView.swift @@ -0,0 +1,442 @@ +// HomeView.swift +// Week3_Magabox +// +// Created by 최우진 on 10/2/25. +// + +import SwiftUI + +struct HomeView: View { + // 화면 상태 및 뷰 모델 + @StateObject private var vm = HomeViewModel() + @Namespace private var tabNS + + // 상세 화면의 상단 탭 상태 + private enum DetailTab { case info, reviews } + @State private var detailTab: DetailTab = .info + + // 내비게이션 뒤로가기 처리 + @Environment(\.dismiss) private var dismiss + + var body: some View { + + NavigationStack { + + // MARK: - 상단 영역 + 본문 + VStack(spacing: 9) { + + // MARK: 상단 헤더 + VStack(alignment: .leading, spacing: 12) { + + // 로고 + HStack(spacing: 0) { + Image("meboxLogo_home") + .resizable() + .scaledToFit() + .frame(width: 149, height: 30) + Spacer() + } + + // 상단 텍스트 탭 + HStack(spacing: 28) { + ForEach(HomeTopTab.allCases, id: \.self) { tab in + let selected = (vm.topTab == tab) + + Button { vm.selectTopTab(tab) } label: { + Text(tab.title) + .font(.custom("Pretendard", + size: 24, + relativeTo: .title3)) + .fontWeight(.semibold) + .foregroundStyle(selected ? Color.black : Color.gray04) + } + .buttonStyle(.plain) + } + } + } + + // MARK: 본문 스크롤 + ScrollView { + + // 칩(무비차트 / 상영예정) + HStack(spacing: 23) { + let chipWidth: CGFloat = 84 + let chipHeight: CGFloat = 38 + let chipRadius: CGFloat = 30 + + // 무비차트 + Button { vm.selectChip(.chart) } label: { + ZStack { + RoundedRectangle(cornerRadius: chipRadius, style: .continuous) + .fill(vm.chip == .chart ? Color.gray08 : Color.gray02) + Text(MovieChip.chart.title) + .font(.PretendardMedium14) + .foregroundColor(vm.chip == .chart ? .white : Color.gray04) + } + .frame(width: chipWidth, height: chipHeight) + } + .buttonStyle(.plain) + + // 상영예정 + Button { vm.selectChip(.upcoming) } label: { + ZStack { + RoundedRectangle(cornerRadius: chipRadius, style: .continuous) + .fill(vm.chip == .upcoming ? Color.gray08 : Color.gray02) + Text(MovieChip.upcoming.title) + .font(.PretendardMedium14) + .foregroundColor(vm.chip == .upcoming ? .white : Color.gray04) + } + .frame(width: chipWidth, height: chipHeight) + } + .buttonStyle(.plain) + + Spacer() + } + + // 섹션 묶음 + VStack(alignment: .leading, spacing: 37) { + + // 가로 스크롤 무비 카드 + ScrollView(.horizontal, showsIndicators: false) { + HStack(spacing: 24) { + ForEach(vm.displayedMovies) { movie in + VStack(alignment: .leading, spacing: 8) { + + // 포스터 → 상세 진입 + NavigationLink(value: movie) { + Image(movie.poster) + .resizable() + .scaledToFill() + .frame(width: 148, height: 212) + .clipShape(RoundedRectangle(cornerRadius: 12)) + .overlay( + RoundedRectangle(cornerRadius: 12) + .stroke(Color.black.opacity(0.06), lineWidth: 1) + ) + } + .buttonStyle(.plain) + + // 액션 버튼(예매/상영예정) + Button { /* TODO */ } label: { + Text(vm.chip == .chart ? "바로 예매" : "상영 예정") + .font(.PretendardMedium16) + .foregroundColor(.purple03) + .frame(width: 148, height: 36) + .overlay( + RoundedRectangle(cornerRadius: 14) + .stroke(Color.purple03, lineWidth: 1) + ) + } + .buttonStyle(.plain) + + // 타이틀/보조 텍스트 + VStack(alignment: .leading, spacing: 0) { + Text(movie.title) + .font(.PretendardBold22) + .foregroundColor(.primary) + .frame(width: 148, alignment: .leading) + .lineLimit(1) + + Text(movie.audience) + .font(.PretendardMedium18) + .foregroundStyle(.secondary) + .frame(width: 148, alignment: .leading) + } + } + } + } + } + .scrollIndicators(.hidden) + + // 무비피드 히어로(제목 + 배너) + VStack(alignment: .leading, spacing: 4) { + HStack { + Text("알고보면 더 재밌는 무비피드") + .font(.PretendardBold24) + Spacer() + Button {} label: { + Image(systemName: "arrow.right") + .font(.title3.weight(.semibold)) + .frame(width: 39, height: 39) + .background(.ultraThinMaterial) + .clipShape(Circle()) + } + .buttonStyle(.plain) + } + + Image("image 3") + .resizable() + .scaledToFill() + .frame(height: 221) + } + + // 추가 피드 2행 + VStack(spacing: 39) { + + // 1행 + HStack(alignment: .top, spacing: 0) { + Image("재개봉") + .resizable() + .scaledToFill() + .frame(width: 100, height: 100) + .clipShape(RoundedRectangle(cornerRadius: 14)) + + Spacer() + + VStack(alignment: .leading, spacing: 25) { + Text("9월, 메가박스의 영화들(1) - 명작들의 재개봉") + .frame(width: 285, alignment: .leading) + .font(.PretendardSemiBold18) + .foregroundColor(.black) + + Text("<모노노케 히메>, <퍼펙트 블루>") + .font(.PretendardSemiBold13) + .foregroundStyle(.secondary) + .lineLimit(1) + Spacer() + } + } + + // 2행 + HStack(alignment: .top, spacing: 0) { + Image("image 2") + .resizable() + .scaledToFill() + .frame(width: 100, height: 100) + .clipShape(RoundedRectangle(cornerRadius: 14)) + + Spacer() + + VStack(alignment: .leading, spacing: 25) { + Text("메가박스 오리지널 티켓 Re.37 <얼굴>") + .frame(width: 285, alignment: .leading) + .font(.PretendardSemiBold18) + .foregroundColor(.black) + .lineLimit(2) + + Text("영화 속 양극적인 감정의 대비") + .font(.PretendardSemiBold13) + .foregroundStyle(.secondary) + .lineLimit(1) + Spacer() + } + .frame(width: 285) + } + Spacer() + } + .padding(.bottom, 32) + } + .padding(.top, 8) + } + .scrollIndicators(.hidden) + } + .padding(.horizontal, 16) + + // MARK: - 하단 커스텀 탭 + .safeAreaInset(edge: .bottom) { + let tabItems: [(title: String, active: String, inactive: String)] = [ + ("홈", "house.fill", "house"), + ("바로 예매", "play.rectangle.fill", "play.rectangle"), + ("모바일 오더", "popcorn.fill", "popcorn"), + ("마이 페이지", "person.fill", "person") + ] + + HStack(spacing: 8) { + ForEach(Array(tabItems.enumerated()), id: \.offset) { i, item in + Button { + withAnimation(.spring(response: 0.35, dampingFraction: 0.85)) { + vm.bottomTabIndex = i + } + } label: { + ZStack { + if vm.bottomTabIndex == i { + RoundedRectangle(cornerRadius: 50, style: .continuous) + .fill(Color.white) + .matchedGeometryEffect(id: "TAB_BG", in: tabNS) + .shadow(color: .black.opacity(0.12), radius: 10, y: 4) + } + VStack(spacing: 6) { + Image(systemName: vm.bottomTabIndex == i ? item.active : item.inactive) + .font(.system(size: 20, weight: .semibold)) + .foregroundColor(.black.opacity(vm.bottomTabIndex == i ? 1 : 0.6)) + Text(item.title) + .font(.footnote.weight(.semibold)) + .foregroundStyle(vm.bottomTabIndex == i ? Color.black : Color.secondary) + .lineLimit(1) + } + .padding(.horizontal, 8) + } + .frame(height: 60) + .frame(maxWidth: .infinity) + } + .buttonStyle(.plain) + } + } + .padding(10) + .frame(width: 360, height: 68) + .background( + RoundedRectangle(cornerRadius: 28, style: .continuous) + .fill(.ultraThinMaterial) + .overlay( + RoundedRectangle(cornerRadius: 28, style: .continuous) + .stroke(Color.white.opacity(0.35), lineWidth: 0.5) + ) + .shadow(color: .black.opacity(0.08), radius: 18, y: 8) + ) + .padding(.horizontal, 12) + .padding(.bottom, 6) + } + + // MARK: - 상세 화면 (Movie 값 기반 라우팅) + .navigationDestination(for: Movie.self) { movie in + ScrollView { + VStack(alignment: .leading, spacing: 16) { + + // 상단 히어로 이미지 + let heroName = movie.header + ZStack(alignment: .bottom) { + Image(heroName) + .resizable() + .scaledToFill() + .frame(height: 248) + .clipped() + } + + // 타이틀/부제/개요 + VStack(spacing: 22) { + VStack(spacing: 9) { + VStack(spacing: 0) { + Text(movie.title) + .font(.PretendardBold22) + .multilineTextAlignment(.center) + + if let sub = movie.subtitle { + Text(sub) + .font(.PretendardSemiBold14) + .foregroundStyle(.secondary) + .multilineTextAlignment(.center) + } + } + + if let ov = movie.overview { + Text(ov) + .font(.PretendardSemiBold18) + .foregroundStyle(.secondary) + .lineSpacing(5) + .multilineTextAlignment(.leading) + } + } + .frame(maxWidth: .infinity, alignment: .center) + + // 상세/실관람평 탭 헤더 + VStack(spacing: 0) { + HStack { + Spacer() + Button { + withAnimation(.easeInOut(duration: 0.2)) { detailTab = .info } + } label: { + Text("상세 정보") + .font(.PretendardBold22) + .foregroundColor(detailTab == .info ? .primary : .secondary) + } + + Spacer() + Spacer() + + Button { + withAnimation(.easeInOut(duration: 0.2)) { detailTab = .reviews } + } label: { + Text("실관람평") + .font(.PretendardBold22) + .foregroundColor(detailTab == .reviews ? .primary : .secondary) + } + Spacer() + } + .padding(.vertical, 12) + + // 탭 언더라인 + GeometryReader { g in + ZStack(alignment: .leading) { + Rectangle() + .frame(height: 1) + .foregroundStyle(.quaternary) + + Rectangle() + .frame(width: g.size.width / 2, height: 2) + .foregroundColor(.black) + .offset(x: detailTab == .info ? 0 : g.size.width / 2, y: -0.5) + .animation(.easeInOut(duration: 0.2), value: detailTab) + } + } + .frame(height: 2) + } + + // 탭 컨텐츠 + Group { + if detailTab == .info { + // 상세 정보 + HStack(alignment: .top, spacing: 13) { + Image(movie.poster) + .resizable() + .frame(width: 100, height: 120) + VStack(alignment: .leading, spacing: 9) { + if let age = movie.ageRating { + Text(age) + .font(.PretendardSemiBold13) + .foregroundColor(.primary) + } + if let date = movie.releaseDate { + Text(date) + .font(.PretendardSemiBold13) + .foregroundStyle(.primary) + } + } + Spacer() + } + .frame(alignment: .top) + } else { + // 실관람평(플레이스홀더) + RoundedRectangle(cornerRadius: 12) + .stroke(Color.purple02, lineWidth: 1) + .frame(height: 141) + .overlay( + Text("등록된 관람평이 없어요 😌") + .font(.PretendardSemiBold18) + .foregroundStyle(.black) + ) + } + } + .padding(.horizontal, 16) + .animation(.easeInOut(duration: 0.15), value: detailTab) + } + } + .padding(.bottom, 24) + } + .navigationTitle(movie.title) + .navigationBarTitleDisplayMode(.inline) + .navigationBarBackButtonHidden(true) + .toolbar { + ToolbarItem(placement: .topBarLeading) { + Button { dismiss() } label: { + ZStack { + Circle() + .fill(.ultraThinMaterial) + .frame(width: 36, height: 36) + Image(systemName: "arrow.left") + .font(.system(size: 18, weight: .semibold)) + .foregroundColor(.black.opacity(0.85)) + } + .shadow(color: .black.opacity(0.12), radius: 6, y: 2) + } + .buttonStyle(.plain) + } + } + } + } + } +} + +// 미리보기 +#Preview { + HomeView() +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/HomeViewModel.swift b/week04/mission/Week4_Magabox/Week3_Magabox/HomeViewModel.swift new file mode 100644 index 0000000..8ccf2ad --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/HomeViewModel.swift @@ -0,0 +1,170 @@ +// +// HomeViewModel.swift +// Week3_Magabox +// +// Created by 최우진 on 10/4/25. +// + +import SwiftUI + +class HomeViewModel: ObservableObject { + + // 화면 상태 + @Published var topTab: HomeTopTab = .home + @Published var chip: MovieChip = .chart + @Published var bottomTabIndex: Int = 0 + + // 더미 데이터 (필요 시 네트워크 대체) + @Published private(set) var movies: [Movie] = [ + Movie( + poster: "어쩔수가 없다", + title: "어쩔수가 없다", + audience: "누적관객수 20만", + header: "어쩔수가 없다", + subtitle: "F1 : The Movie", + overview: + """ + 최고가 되지 못한 전설 VS 최고가 되고 싶은 루키 + + 한때 주목받는 유망주였지만 끔찍한 사고로 F1에서 우승하지 못하고 + 한순간에 추락한 드라이버 ‘숀·헤이스’(브래드 피트). + 그의 오랜 동료 ‘루벤 세르반테스’(하비에르 바르뎀)에게 + 레이싱 복귀를 제안받으며 최하위 팀 APGXP에 합류한다. + """, + ageRating: "12세 이상 관람가", + releaseDate: "2025.06.25 개봉" + ), + Movie( + poster: "무한성", + title: "극장판 귀멸의 칼날: 무한성 편", + audience: "누적관객수 1", + header: "무한성", + subtitle: "F1 : The Movie", + overview: + """ + 최고가 되지 못한 전설 VS 최고가 되고 싶은 루키 + 한때 주목받는 유망주였지만 끔찍한 사고로 F1에서 우승하지 못하고 + 한순간에 추락한 드라이버 ‘숀·헤이스’(브래드 피트). + 그의 오랜 동료 ‘루벤 세르반테스’(하비에르 바르뎀)에게 + 레이싱 복귀를 제안받으며 최하위 팀 APGXP에 합류한다. + """, + ageRating: "12세 이상 관람가", + releaseDate: "2025.06.25 개봉" + ), + Movie( + poster: "f1", + title: "F1 더 무비", + audience: "누적관객수 -", + header: "f1_header", // ← 상세 상단 히어로 이미지 + subtitle: "F1 : The Movie", + overview: + """ + 최고가 되지 못한 전설 VS 최고가 되고 싶은 루키 + + 한때 주목받는 유망주였지만 끔찍한 사고로 F1에서 우승하지 못하고 + 한순간에 추락한 드라이버 ‘숀·헤이스’(브래드 피트). + 그의 오랜 동료 ‘루벤 세르반테스’(하비에르 바르뎀)에게 + 레이싱 복귀를 제안받으며 최하위 팀 APGXP에 합류한다. + """, + ageRating: "12세 이상 관람가", + releaseDate: "2025.06.25 개봉" + ), + Movie( + poster: "image 1", + title: "얼굴", + audience: "누적관객수 -", + header: "image 1", + subtitle: "F1 : The Movie", + overview: + """ + 최고가 되지 못한 전설 VS 최고가 되고 싶은 루키 + 한때 주목받는 유망주였지만 끔찍한 사고로 F1에서 우승하지 못하고 + 한순간에 추락한 드라이버 ‘숀·헤이스’(브래드 피트). + 그의 오랜 동료 ‘루벤 세르반테스’(하비에르 바르뎀)에게 + 레이싱 복귀를 제안받으며 최하위 팀 APGXP에 합류한다. + """, + ageRating: "12세 이상 관람가", + releaseDate: "2025.06.25 개봉" + ), + Movie( + poster: "image 2", + title: "정글", + audience: "누적관객수 -", + header: "image 2", + subtitle: "F1 : The Movie", + overview: + """ + 최고가 되지 못한 전설 VS 최고가 되고 싶은 루키 + 한때 주목받는 유망주였지만 끔찍한 사고로 F1에서 우승하지 못하고 + 한순간에 추락한 드라이버 ‘숀·헤이스’(브래드 피트). + 그의 오랜 동료 ‘루벤 세르반테스’(하비에르 바르뎀)에게 + 레이싱 복귀를 제안받으며 최하위 팀 APGXP에 합류한다. + """, + ageRating: "12세 이상 관람가", + releaseDate: "2025.06.25 개봉" + ) + ] + + @Published private(set) var upcomingMovies: [Movie] = [ + Movie( + poster: "image 1", + title: "얼굴", + audience: "누적관객수 -", + header: "image 1", + subtitle: "F1 : The Movie", + overview: + """ + 최고가 되지 못한 전설 VS 최고가 되고 싶은 루키 + 한때 주목받는 유망주였지만 끔찍한 사고로 F1에서 우승하지 못하고 + 한순간에 추락한 드라이버 ‘숀·헤이스’(브래드 피트). + 그의 오랜 동료 ‘루벤 세르반테스’(하비에르 바르뎀)에게 + 레이싱 복귀를 제안받으며 최하위 팀 APGXP에 합류한다. + """, + ageRating: "12세 이상 관람가", + releaseDate: "2025.06.25 개봉" + ), + Movie( + poster: "image 2", + title: "정글", + audience: "누적관객수 -", + header: "image 2", + subtitle: "F1 : The Movie", + overview: + """ + 최고가 되지 못한 전설 VS 최고가 되고 싶은 루키 + 한때 주목받는 유망주였지만 끔찍한 사고로 F1에서 우승하지 못하고 + 한순간에 추락한 드라이버 ‘숀·헤이스’(브래드 피트). + 그의 오랜 동료 ‘루벤 세르반테스’(하비에르 바르뎀)에게 + 레이싱 복귀를 제안받으며 최하위 팀 APGXP에 합류한다. + """, + ageRating: "12세 이상 관람가", + releaseDate: "2025.06.25 개봉" + ), + Movie( + poster: "f1", + title: "F1 더 무비", + audience: "누적관객수 -", + header: "f1_header", // ← 상세 상단 히어로 이미지 + subtitle: "F1 : The Movie", + overview: + """ + 최고가 되지 못한 전설 VS 최고가 되고 싶은 루키 + 한때 주목받는 유망주였지만 끔찍한 사고로 F1에서 우승하지 못하고 + 한순간에 추락한 드라이버 ‘숀·헤이스’(브래드 피트). + 그의 오랜 동료 ‘루벤 세르반테스’(하비에르 바르뎀)에게 + 레이싱 복귀를 제안받으며 최하위 팀 APGXP에 합류한다. + """, + ageRating: "12세 이상 관람가", + releaseDate: "2025.06.25 개봉" + ) + ] + + // 현재 칩에 따른 노출 리스트 + var displayedMovies: [Movie] { + chip == .chart ? movies : upcomingMovies + } + + // 액션 헬퍼 (원하면 로깅/트래킹 추가) + func selectTopTab(_ tab: HomeTopTab) { topTab = tab } + func selectChip(_ chip: MovieChip) { self.chip = chip } +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/LoginModel.swift b/week04/mission/Week4_Magabox/Week3_Magabox/LoginModel.swift new file mode 100644 index 0000000..c035007 --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/LoginModel.swift @@ -0,0 +1,15 @@ +// +// LoginModel.swift +// Megabox +// +// Created by 최우진 on 9/25/25. +// + +// LoginModel.swift + +import Foundation + +struct LoginModel { + var id: String = "" + var pwd: String = "" +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/LoginView.swift b/week04/mission/Week4_Magabox/Week3_Magabox/LoginView.swift new file mode 100644 index 0000000..dc9099c --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/LoginView.swift @@ -0,0 +1,115 @@ +import SwiftUI + +struct LoginView: View { + // ViewModel: 아이디/비밀번호 입력을 보관 + @State private var viewModel = LoginViewModel() + // 로컬 저장 자격(예시용): 실제 앱에서는 보안 저장소로 대체 권장 + @AppStorage("savedId") private var savedId: String = "cwj1213" + @AppStorage("savedPassword") private var savedPassword: String = "1111" + + // 로그인 성공 시 화면 전환 트리거 + @State private var goHome = false + + var body: some View { + NavigationStack { + VStack { + // MARK: - 상단 타이틀 + Text("로그인") + .font(.PretendardSemiBold24) + .foregroundColor(.black) + Spacer(minLength: 44) + + // MARK: - 로그인 입력 영역 + VStack { + // 아이디 / 비밀번호 필드 + VStack(spacing: 40) { + // 아이디 + VStack(alignment: .leading, spacing: 6) { + TextField("아이디", text: $viewModel.id) + .font(.PretendardMedium16) + .foregroundColor(.gray03) + .textInputAutocapitalization(.never) + .autocorrectionDisabled(true) + Rectangle() + .frame(height: 1) + .foregroundColor(.gray02) + } + + // 비밀번호 + VStack(alignment: .leading, spacing: 6) { + SecureField("비밀번호", text: $viewModel.pwd) + .font(.PretendardMedium16) + .foregroundColor(.gray03) + Rectangle() + .frame(height: 1) + .foregroundColor(.gray02) + } + } + + Spacer(minLength: 75) + + // MARK: - 로그인 버튼 / 회원가입 + VStack { + // 로그인: 입력값이 저장값과 동일할 때만 goHome = true + Button { + if viewModel.id == savedId && viewModel.pwd == savedPassword { + goHome = true + } else { + // 불일치 시 추가 피드백(알림/토스트 등) 필요하면 여기서 처리 + } + } label: { + Text("로그인") + .font(.PretendardBold18) + .foregroundColor(.white) + .frame(maxWidth: .infinity, minHeight: 54) + .background( + RoundedRectangle(cornerRadius: 12) + .fill(Color.purple04) + ) + } + .shadow(color: .black.opacity(0.25), radius: 12, x: 0, y: 8) + + // 내비게이션: goHome == true일 때 HomeView로 푸시 + .navigationDestination(isPresented: $goHome) { + HomeView() + .navigationBarBackButtonHidden(true) + } + + // (플레이스홀더) 회원가입 링크 텍스트 + Text("회원가입") + .font(.PretendardMedium13) + .foregroundColor(.gray04) + } + + Spacer(minLength: 17) + + // MARK: - 소셜 아이콘 3종 + HStack { + Spacer().frame(width: 71) + Image("naver").resizable().scaledToFit().frame(width: 40, height: 40) + Spacer() + Image("kakao").resizable().scaledToFit().frame(width: 40, height: 40) + Spacer() + Image("apple").resizable().scaledToFit().frame(width: 40, height: 40) + Spacer().frame(width: 71) + } + .frame(maxWidth: .infinity) + } + .frame(height: 323) + + Spacer(minLength: 17) + + // MARK: - 하단 배너 이미지 + Image("umc_image") + .resizable() + .scaledToFill() + .frame(width: 408, height: 266) + } + .padding(.horizontal, 16) + } + } +} + +#Preview { + LoginView() +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/LoginViewModel.swift b/week04/mission/Week4_Magabox/Week3_Magabox/LoginViewModel.swift new file mode 100644 index 0000000..9e12630 --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/LoginViewModel.swift @@ -0,0 +1,27 @@ +// +// LoginViewModel.swift +// Megabox +// +// Created by 최우진 on 9/25/25. +// + +// LoginViewModel.swift + +import Foundation +import Observation + + +@Observable //전역으로 사용할 수 있도록 설정 +class LoginViewModel { + var loginModel = LoginModel() + + var id: String { + get { loginModel.id } + set { loginModel.id = newValue } + } + + var pwd: String { + get { loginModel.pwd } + set { loginModel.pwd = newValue } + } +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/MemberInfoManagementView.swift b/week04/mission/Week4_Magabox/Week3_Magabox/MemberInfoManagementView.swift new file mode 100644 index 0000000..57b24bf --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/MemberInfoManagementView.swift @@ -0,0 +1,100 @@ +// +// MemberInfoManagementView.swift +// Megabox_2 +// +// Created by 최우진 on 9/26/25. +// + +import SwiftUI + +struct MemberInfoManagementView: View { + // 커스텀 뒤로가기 버튼을 위한 환경 변수 + @Environment(\.dismiss) var dismiss + + // AppStorage 변수 선언 + @AppStorage("savedId") private var savedId: String = "cwj1213" + @AppStorage("savedPassword") private var savedPassword: String = "1111" + @AppStorage("userName") private var userName: String = "최우진" + + // TextField의 입력을 실시간으로 받기 위한 @State 변수 + @State private var nameInput: String = "" + + var body: some View { + // 1. 가장 큰 VStack + VStack(spacing: 53) { + + // 2. 상단 네비게이션 바 (HStack) + HStack(spacing:0) { + // 커스텀 뒤로가기 버튼 + Button(action: { + dismiss() // 이 버튼을 누르면 이전 화면으로 돌아갑니다. + }) { + Image(systemName: "arrow.left") + .foregroundColor(.black) + } + + Spacer() + + Text("회원정보 관리") + .font(.PretendardMedium16) + + Spacer() + } + + + + // 3. 기본정보 파트 (VStack) + VStack(alignment: .leading, spacing: 26) { + Text("기본정보") + .font(.PretendardBold18) + + // 아이디 (Text 처리) + VStack(alignment: .leading, spacing: 3) { + Text(savedId) + .foregroundColor(.black).font(.PretendardMedium18) + Divider().background(Color.gray02) + } + + // 이름 (TextField + 변경 버튼) + VStack(alignment: .leading, spacing: 3) { + HStack { + TextField("이름", text: $nameInput).font(.PretendardMedium18) + + // 이름 변경 버튼 + Button(action: { + // TextField에 입력된 값을 AppStorage에 저장 + userName = nameInput + + }) { + ZStack { + // 1. 배경 레이어 + RoundedRectangle(cornerRadius: 16) + .stroke(Color.gray03, lineWidth: 1) + + // 2. 상단 레이어 + Text("변경") + .font(.PretendardMedium10) + .foregroundColor(.gray03) + }.frame(width: 60, height: 28) + } + } + Divider().background(Color.gray02) + } + } + + Spacer() + } + .padding(.horizontal,16) // 전체적인 좌우 여백 + .navigationBarBackButtonHidden(true) // SwiftUI의 기본 뒤로가기 버튼 숨기기 + .onAppear { + // 이 화면이 나타날 때, AppStorage에 저장된 이름을 TextField에 미리 채우도록 설정 + nameInput = userName + } + } +} + +#Preview { + NavigationStack { + MemberInfoManagementView() + } +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/MemberInfoView.swift b/week04/mission/Week4_Magabox/Week3_Magabox/MemberInfoView.swift new file mode 100644 index 0000000..5eb6672 --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/MemberInfoView.swift @@ -0,0 +1,184 @@ +import SwiftUI + +struct MemberInfoView: View { + // 로그인 뷰에서 저장한 아이디를 가져옵니다. + @AppStorage("savedId") private var savedId: String = "cwj1213" + @AppStorage("savedPassword") private var savedPassword: String = "1111" + @AppStorage("userName") private var userName: String = "최우진" + + var body: some View { + NavigationStack { //회원정보 View로 가도록 + VStack(spacing: 33) { + HStack(alignment: .top) { + // 이름과 포인트를 담는 왼쪽 VStack + VStack(alignment: .leading, spacing: 0) { + HStack(spacing:5) { + Text(userName) + .font(.PretendardBold24) + .fontWeight(.bold) + ZStack { + RoundedRectangle(cornerRadius: 6) + .fill(Color(red: 48/255, green: 209/255, blue: 201/255)) + Text("WELCOME") + .font(.PretendardMedium14) + .fontWeight(.bold) + .foregroundColor(.white) + } + .frame(width: 81, height: 25) + } + HStack(spacing: 9) { + Text("멤버십 포인트") + .font(.footnote) + .foregroundColor(.gray) + Text("500P") + .font(.footnote) + .fontWeight(.semibold) + } + } + Spacer() + // 회원정보 버튼 + NavigationLink(destination: MemberInfoManagementView()) { + VStack { + Text("회원정보") + .font(.PretendardSemiBold14) + .foregroundColor(.white) + } + .padding(.vertical, 4) + .frame(width: 72, height: 28) + .background(Color.gray07) + .cornerRadius(16) + } + } + VStack { + HStack(spacing : 3) { + Text("클럽 멤버십") + .font(.PretendardSemiBold16) + .foregroundColor(.white) + + Image(systemName: "chevron.right") + .font(.system(size: 14, weight: .semibold)) // 아이콘 크기/굵기 조절 + .foregroundColor(.white.opacity(0.8)) + + Spacer() + } + } + .frame(maxWidth: .infinity) + .padding(.vertical, 12) // 상하 패딩 12pt (높이를 46pt로 만듦) + .padding(.horizontal,8) + .background( + LinearGradient( + gradient: Gradient(colors: [ + Color(red: 0.67, green: 0.55, blue: 1), + Color(red: 0.56, green: 0.68, blue: 0.95), + Color(red: 0.36, green: 0.8, blue: 0.93) + ]), + //그라데이션 만들기 + startPoint: .leading, + endPoint: .trailing + ) + ) + .cornerRadius(8) + + ZStack { + // 배경과 테두리 + RoundedRectangle(cornerRadius: 8) + .fill(Color.white) + .stroke(Color.gray02, lineWidth: 1) + + + HStack (spacing: 43){ + VStack(spacing: 9) { + Text("쿠폰") + .font(.PretendardSemiBold16) + .foregroundColor(.gray02) + Text("2") + .font(.PretendardSemiBold18) + .foregroundColor(.black) + } + .frame(maxWidth: .infinity) + + Divider().frame(height: 31) + + VStack(spacing: 9) { + Text("스토어 교환권") + .font(.PretendardSemiBold16) + .foregroundColor(.gray02) + Text("0") + .font(.PretendardSemiBold18) + .foregroundColor(.black) + } + .frame(maxWidth: .infinity) + + Divider().frame(height: 31) + + VStack(spacing: 9) { + Text("모바일 티켓") + .font(.PretendardSemiBold16) + .foregroundColor(.gray02) + Text("0") + .font(.PretendardSemiBold18) + .foregroundColor(.black) + } + .frame(maxWidth: .infinity) + } + .padding(.vertical, 12) + .padding(.horizontal, 24) + } + .frame(height: 76) + + HStack(alignment: .top, spacing: 16) { + VStack(spacing: 12) { + Image("film-reel") + .resizable() + .scaledToFit() + .frame(height: 36) + Text("영화별예매") + .font(.PretendardMedium16) + } + .frame(maxWidth: .infinity) + + VStack(spacing: 12) { + Image("map") + .resizable() + .scaledToFit() + .frame(height: 36) + Text("극장별예매") + .font(.PretendardMedium16) + } + .frame(maxWidth: .infinity) + + VStack(spacing: 12) { + Image("sofa") + .resizable() + .scaledToFit() + .frame(height: 36) + Text("특별관예매") + .font(.PretendardMedium16) + } + .frame(maxWidth: .infinity) + + VStack(spacing: 12) { + Image("cinema") + .resizable() + .scaledToFit() + .frame(height: 36) + Text("모바일오더") + .font(.PretendardMedium16) + } + .frame(maxWidth: .infinity) + + } + + Spacer() + } + .padding(.horizontal, 24) // ← 여기서 전체 좌우 16pt 여백 줌 + .padding(.vertical, 95) + .background(Color(uiColor: .white)) // 전체 배경색 + } + .navigationBarBackButtonHidden(true) + } +} + +#Preview { + MemberInfoView() +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/MovieBookingView.swift b/week04/mission/Week4_Magabox/Week3_Magabox/MovieBookingView.swift new file mode 100644 index 0000000..ae62828 --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/MovieBookingView.swift @@ -0,0 +1,333 @@ +// +// MovieBookingView.swift +// Week3_Magabox +// +// Created by 최우진 on 10/13/25. +// + +import SwiftUI +import Combine + +// MARK: - Domain Models +struct BookingMovie: Identifiable, Hashable { + let id: UUID = .init() + let title: String + let posterName: String // Assets.xcassets 이미지 이름 + let ageBadge: String? // 예: "15", "12" 등 (옵션) +} + +enum TheaterArea: String, CaseIterable, Identifiable { // 강남, 홍대, 신촌 + case gangnam = "강남" + case hongdae = "홍대" + case sinchon = "신촌" + var id: String { rawValue } +} + +struct BookingShowTime: Identifiable, Hashable { + let id: UUID = .init() + let theater: TheaterArea + let date: Date // 상영 날짜(일자) + let time: String // "10:30", "14:10" 등 + let seatsRemain: Int +} + +// MARK: - Fake Repository (Combine 기반 더미 데이터) +protocol BookingRepositoryType { + func fetchMovies() -> AnyPublisher<[BookingMovie], Never> + func fetchShowtimes() -> AnyPublisher<[BookingShowTime], Never> +} + +final class BookingRepository: BookingRepositoryType { + func fetchMovies() -> AnyPublisher<[BookingMovie], Never> { + let items: [BookingMovie] = [ + .init(title: "무한성", posterName: "무한성", ageBadge: "15"), + .init(title: "어쩔수가 없다", posterName: "어쩔수가 없다", ageBadge: "15"), + .init(title: "얼굴", posterName: "얼굴", ageBadge: "15"), + .init(title: "재개봉", posterName: "재개봉", ageBadge: "15"), + .init(title: "F1", posterName: "f1", ageBadge: "12"), + .init(title: "image1", posterName: "image 1", ageBadge: nil), + .init(title: "image2", posterName: "image 2", ageBadge: nil), + .init(title: "image3", posterName: "image 3", ageBadge: nil) + ] + return Just(items).eraseToAnyPublisher() + } + + func fetchShowtimes() -> AnyPublisher<[BookingShowTime], Never> { + let base = Calendar.current.startOfDay(for: Date()) + func d(_ offset: Int) -> Date { Calendar.current.date(byAdding: .day, value: offset, to: base)! } + let list: [BookingShowTime] = [ + .init(theater: .gangnam, date: d(0), time: "10:40", seatsRemain: 42), + .init(theater: .gangnam, date: d(0), time: "13:10", seatsRemain: 5), + .init(theater: .hongdae, date: d(1), time: "12:00", seatsRemain: 23), + .init(theater: .hongdae, date: d(2), time: "19:40", seatsRemain: 11), + .init(theater: .sinchon, date: d(3), time: "09:10", seatsRemain: 7), + .init(theater: .sinchon, date: d(5), time: "21:30", seatsRemain: 18) + ] + return Just(list).eraseToAnyPublisher() + } +} + +// MARK: - ViewModel (MVVM + Combine) +final class MovieBookingViewModel: ObservableObject { + // Input + @Published var selectedMovie: BookingMovie? = nil + @Published var selectedArea: TheaterArea? = nil + @Published var selectedDate: Date? = nil + + // Output + @Published private(set) var movies: [BookingMovie] = [] + @Published private(set) var daysOfWeek: [Date] = [] // 오늘 포함 7일 + @Published private(set) var showtimes: [BookingShowTime] = [] + + // Derived state + @Published private(set) var isAreaEnabled: Bool = false + @Published private(set) var isDateEnabled: Bool = false + + private var bag = Set() + private let repo: BookingRepositoryType + + init(repo: BookingRepositoryType = BookingRepository()) { + self.repo = repo + makeDays() + bind() + load() + } + + private func load() { + repo.fetchMovies() + .receive(on: DispatchQueue.main) + .assign(to: &$movies) + + // 상영정보는 내부 저장 후 필터링해서 showtimes로 노출 + repo.fetchShowtimes() + .combineLatest($selectedArea.removeDuplicates(), $selectedDate.removeDuplicates()) + .map { all, area, date -> [BookingShowTime] in + guard let area, let date else { return [] } + let day = Calendar.current.startOfDay(for: date) + return all.filter { $0.theater == area && Calendar.current.isDate($0.date, inSameDayAs: day) } + .sorted { $0.time < $1.time } + } + .receive(on: DispatchQueue.main) + .assign(to: &$showtimes) + } + + private func makeDays() { + let today = Calendar.current.startOfDay(for: Date()) + daysOfWeek = (0..<7).compactMap { Calendar.current.date(byAdding: .day, value: $0, to: today) } + } + + private func bind() { + $selectedMovie + .map { $0 != nil } + .removeDuplicates() + .assign(to: &$isAreaEnabled) + + Publishers.CombineLatest($selectedMovie, $selectedArea) + .map { movie, area in movie != nil && area != nil } + .removeDuplicates() + .assign(to: &$isDateEnabled) + } + + // Helpers + func selectTodayIfNeeded() { + if selectedDate == nil { selectedDate = daysOfWeek.first } + } +} + +// MARK: - View +struct MovieBookingView: View { + @StateObject private var vm = MovieBookingViewModel() + + var body: some View { + VStack(spacing: 0) { + header + ScrollView(showsIndicators: false) { + VStack(alignment: .leading, spacing: 24) { + ageAndTitle + posterCarousel + areaChips + dateSelector + showtimeSection + } + .padding(.horizontal, 20) + .padding(.top, 16) + .padding(.bottom, 36) + } + } + .onAppear { vm.selectTodayIfNeeded() } + } +} + +// MARK: - Subviews +private extension MovieBookingView { + var header: some View { + ZStack(alignment: .bottomLeading) { + Color.purple.ignoresSafeArea(edges: .top) + Text("영화별 예매") + .font(.system(size: 22, weight: .semibold)) + .foregroundColor(.white) + .padding(.bottom, 14) + } + .frame(height: 100) + } + + var ageAndTitle: some View { + HStack(spacing: 8) { + if let age = vm.selectedMovie?.ageBadge { + Text(age) + .font(.system(size: 14, weight: .bold)) + .foregroundColor(.white) + .padding(.horizontal, 8) + .padding(.vertical, 4) + .background( + RoundedRectangle(cornerRadius: 6).fill(Color.orange) + ) + } + + Text(vm.selectedMovie?.title ?? "어쩔수가없다") + .font(.system(size: 24, weight: .semibold)) + + } + } + + var posterCarousel: some View { + ScrollView(.horizontal, showsIndicators: false) { + HStack(spacing: 16) { + ForEach(vm.movies) { movie in + VStack(spacing: 6) { + Image(movie.posterName) + .resizable() + .scaledToFill() + .frame(width: 96, height: 132) + .clipShape(RoundedRectangle(cornerRadius: 14)) + .overlay( + RoundedRectangle(cornerRadius: 14) + .stroke(vm.selectedMovie == movie ? Color.purple : Color.clear, lineWidth: 3) + ) + .onTapGesture { vm.selectedMovie = movie } + Text(movie.title) + .font(.system(size: 12)) + .lineLimit(1) + .frame(width: 96) + } + } + } + .padding(.vertical, 8) + } + } + + var areaChips: some View { + HStack(spacing: 10) { + ForEach(TheaterArea.allCases) { area in + Button { + guard vm.isAreaEnabled else { return } + vm.selectedArea = area + } label: { + Text(area.rawValue) + .font(.system(size: 16, weight: .semibold)) + .foregroundStyle(vm.selectedArea == area ? Color.white : Color.primary) + .padding(.horizontal, 16) + .padding(.vertical, 10) + .background( + Capsule().fill(vm.isAreaEnabled ? (vm.selectedArea == area ? Color.purple : Color.gray.opacity(0.2)) : Color.gray.opacity(0.15)) + ) + } + .buttonStyle(.plain) + .disabled(!vm.isAreaEnabled) + } + } + .padding(.top, 8) + } + + var dateSelector: some View { + ScrollView(.horizontal, showsIndicators: false) { + HStack(spacing: 16) { + ForEach(vm.daysOfWeek, id: \.self) { day in + let selected = vm.selectedDate.map { Calendar.current.isDate($0, inSameDayAs: day) } ?? false + Button { + guard vm.isDateEnabled else { return } + vm.selectedDate = day + } label: { + VStack(spacing: 6) { + Text(dayFormatted(day, pattern: "M.dd")) + .font(.system(size: 18, weight: .bold)) + Text(weekdayK(day)) + .font(.system(size: 12)) + } + .frame(width: 64, height: 64) + .background( + RoundedRectangle(cornerRadius: 16) + .fill(selected ? Color.purple : Color.gray.opacity(0.15)) + ) + .foregroundStyle(selected ? Color.white : Color.primary) + } + .buttonStyle(.plain) + .disabled(!vm.isDateEnabled) + } + } + .padding(.vertical, 12) + } + } + + var showtimeSection: some View { + VStack(alignment: .leading, spacing: 12) { + if vm.selectedMovie == nil { + Text("영화 선택하지 않았습니다. 극장 선택 버튼 활성화되면 안됩니다") + .font(.system(size: 14)) + .foregroundColor(.secondary) + } else if vm.selectedArea == nil { + Text("극장을 선택하세요. 포스터 선택 후 가능") + .font(.system(size: 14)) + .foregroundColor(.secondary) + } else if vm.showtimes.isEmpty { + Text("선택한 극장에 상영시간표가 없습니다") + .font(.system(size: 15, weight: .semibold)) + .foregroundColor(.secondary) + .padding(.top, 12) + } else { + ForEach(vm.showtimes) { s in + HStack { + VStack(alignment: .leading, spacing: 4) { + Text("상영관 \(s.theater.rawValue)") + .font(.system(size: 13)) + .foregroundColor(.secondary) + Text(s.time) + .font(.system(size: 18, weight: .bold)) + } + Spacer() + Text("잔여 \(s.seatsRemain)") + .font(.system(size: 14, weight: .semibold)) + .foregroundColor(.purple) + } + .padding(16) + .background( + RoundedRectangle(cornerRadius: 16) + .fill(Color.gray.opacity(0.1)) + ) + } + } + } + .padding(.top, 8) + } +} + +// MARK: - Utilities +private func dayFormatted(_ date: Date, pattern: String) -> String { + let f = DateFormatter() + f.locale = Locale(identifier: "ko_KR") + f.dateFormat = pattern + return f.string(from: date) +} + +private func weekdayK(_ date: Date) -> String { + let f = DateFormatter() + f.locale = Locale(identifier: "ko_KR") + f.dateFormat = "E" // 월 화 수 ... + var s = f.string(from: date) + if Calendar.current.isDateInToday(date) { s = "오늘" } + return s +} + +#Preview { + MovieBookingView() +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/SplashView.swift b/week04/mission/Week4_Magabox/Week3_Magabox/SplashView.swift new file mode 100644 index 0000000..bd95bf2 --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/SplashView.swift @@ -0,0 +1,15 @@ +import SwiftUI + +struct SplashView: View { + var body: some View { + VStack{ + Spacer() + Image("megabox_logo").resizable().scaledToFit().frame(width: 249, height: 84) + Spacer() + } + } +} + +#Preview { + SplashView() +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/Week3_MagaboxApp.swift b/week04/mission/Week4_Magabox/Week3_Magabox/Week3_MagaboxApp.swift new file mode 100644 index 0000000..8b16c53 --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/Week3_MagaboxApp.swift @@ -0,0 +1,28 @@ +// +// Week3_MagaboxApp.swift +// Week3_Magabox +// +// Created by 최우진 on 10/2/25. +// +import SwiftUI + +@main +struct MegaboxApp: App { + @State private var showLogin = true + + var body: some Scene { + WindowGroup { + if showLogin { + SplashView() + .onAppear { + DispatchQueue.main.asyncAfter(deadline: .now() + 2) { + showLogin = false + } + } + } + else { + LoginView() + } + } + } +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/color.swift b/week04/mission/Week4_Magabox/Week3_Magabox/color.swift new file mode 100644 index 0000000..ee92204 --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/color.swift @@ -0,0 +1,62 @@ +// +// color.swift +// Megabox +// +// Created by 최우진 on 9/20/25. +// + +import Foundation +import SwiftUI + +extension Color { + // 1) 이니셜라이저를 Color.swift로 옮기고, 팔레트보다 위에 둡니다. + init(hex: UInt, alpha: Double = 1.0) { + self.init(.sRGB, + red: Double((hex >> 16) & 0xFF) / 255.0, + green: Double((hex >> 8) & 0xFF) / 255.0, + blue: Double( hex & 0xFF) / 255.0, + opacity: alpha) + } + + // 2) 팔레트 정의 + // Blue + static let blue00 = Color(hex: 0xE5EAFA as UInt) + static let blue01 = Color(hex: 0xFFFFFF as UInt) + static let blue02 = Color(hex: 0xE3E9F5 as UInt) + static let blue03 = Color(hex: 0x8AAAD6 as UInt) + static let blue04 = Color(hex: 0x6C94C3 as UInt) + static let blue05 = Color(hex: 0x5C85B9 as UInt) + static let blue06 = Color(hex: 0x466F9E as UInt) + static let blue07 = Color(hex: 0x2F567F as UInt) + static let blue08 = Color(hex: 0x1E3C60 as UInt) + static let blue09 = Color(hex: 0x132847 as UInt) + + // Purple + static let purple00 = Color(hex: 0xF5E8FF as UInt) + static let purple01 = Color(hex: 0xE4C8FF as UInt) + static let purple02 = Color(hex: 0xC49CFF as UInt) + static let purple03 = Color(hex: 0x9C6EFF as UInt) + static let purple04 = Color(hex: 0x6F2CFF as UInt) // 버튼 색 + static let purple05 = Color(hex: 0x5C23CC as UInt) + static let purple06 = Color(hex: 0x491A99 as UInt) + static let purple07 = Color(hex: 0x371266 as UInt) + static let purple08 = Color(hex: 0x240933 as UInt) + static let purple09 = Color(hex: 0x1A0020 as UInt) + + // Grey + static let gray00 = Color(hex: 0xF8F9FA as UInt) + static let gray01 = Color(hex: 0xF1F3F5 as UInt) + static let gray02 = Color(hex: 0xE5E5EA as UInt) + static let gray03 = Color(hex: 0xD1D5DB as UInt) + static let gray04 = Color(hex: 0x9CA3AF as UInt) + static let gray05 = Color(hex: 0x6B7280 as UInt) + static let gray06 = Color(hex: 0x4B5563 as UInt) + static let gray07 = Color(hex: 0x374151 as UInt) + static let gray08 = Color(hex: 0x1F2937 as UInt) + static let gray09 = Color(hex: 0x111827 as UInt) + + // White / Black (토큰) + static let White = Color.white + static let Black = Color.black +} + diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Fonts.swift b/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Fonts.swift new file mode 100644 index 0000000..eb400a6 --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Fonts.swift @@ -0,0 +1,152 @@ +// +// Fonts.swift +// Week1_Practice +// +// Created by 최우진 on 9/20/25. +// + +import Foundation +import SwiftUI + +extension Font { + enum Pretend { + case extraBold + case bold + case semibold + case medium + case regular + case light + + var value: String { + switch self { + case .extraBold: + return "Pretendard-ExtraBold" + case .bold: + return "Pretendard-Bold" + case .semibold: + return "Pretendard-SemiBold" + case .medium: + return "Pretendard-Medium" + case .regular: + return "Pretendard-Regular" + case .light: + return "Pretendard-Light" + } + } + } + + static func pretend(type: Pretend, size: CGFloat) -> Font { + return .custom(type.value, size: size) + } + + static var PretendardBold30: Font { + return .pretend(type: .bold, size: 30) + } + + // 새로 추가한 스타일 + static var PretendardRegular16: Font { + return .pretend(type: .regular, size: 16) + } + + static var PretendardBold24: Font { + return .pretend(type: .bold, size: 24) + } + + static var PretendardSemiBold18: Font { + return .pretend(type: .semibold, size: 18) + } + + static var PretendardLight16: Font { + return .pretend(type: .light, size: 16) + } + + // Bold + static var PretendardBold18: Font { + return .pretend(type: .bold, size: 18) + } + + static var PretendardBold22: Font { + return .pretend(type: .bold, size: 22) + } + + // SemiBold + static var PretendardSemiBold38: Font { + return .pretend(type: .semibold, size: 38) + } + + static var PretendardSemiBold24: Font { + return .pretend(type: .semibold, size: 24) + } + + static var PretendardSemiBold16: Font { + return .pretend(type: .semibold, size: 16) + } + + static var PretendardSemiBold14: Font { + return .pretend(type: .semibold, size: 14) + } + + static var PretendardSemiBold13: Font { + return .pretend(type: .semibold, size: 13) + } + + static var PretendardSemiBold12: Font { + return .pretend(type: .semibold, size: 12) + } + + // Regular + static var PretendardRegular20: Font { + return .pretend(type: .regular, size: 20) + } + + static var PretendardRegular18: Font { + return .pretend(type: .regular, size: 18) + } + + static var PretendardRegular13: Font { + return .pretend(type: .regular, size: 13) + } + + static var PretendardRegular12: Font { + return .pretend(type: .regular, size: 12) + } + + static var PretendardRegular9: Font { + return .pretend(type: .regular, size: 9) + } + + // Medium + static var PretendardMedium18: Font { + return .pretend(type: .medium, size: 18) + } + + static var PretendardMedium16: Font { + return .pretend(type: .medium, size: 16) + } + + static var PretendardMedium14: Font { + return .pretend(type: .medium, size: 14) + } + + static var PretendardMedium13: Font { + return .pretend(type: .medium, size: 13) + } + + static var PretendardMedium10: Font { + return .pretend(type: .medium, size: 10) + } + + static var PretendardMedium8: Font { + return .pretend(type: .medium, size: 8) + } + + // Light + static var PretendardLight14: Font { + return .pretend(type: .light, size: 14) + } + + // ExtraBold + static var PretendardExtraBold24: Font { + return .pretend(type: .extraBold, size: 24) + } +} diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Black.otf b/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Black.otf new file mode 100644 index 0000000..a0d849e Binary files /dev/null and b/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Black.otf differ diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Bold.otf b/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Bold.otf new file mode 100644 index 0000000..8e5e30a Binary files /dev/null and b/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Bold.otf differ diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Pretendard-ExtraBold.otf b/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Pretendard-ExtraBold.otf new file mode 100644 index 0000000..388f3ca Binary files /dev/null and b/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Pretendard-ExtraBold.otf differ diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Pretendard-ExtraLight.otf b/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Pretendard-ExtraLight.otf new file mode 100644 index 0000000..40c8b69 Binary files /dev/null and b/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Pretendard-ExtraLight.otf differ diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Light.otf b/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Light.otf new file mode 100644 index 0000000..228679e Binary files /dev/null and b/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Light.otf differ diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Medium.otf b/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Medium.otf new file mode 100644 index 0000000..0575069 Binary files /dev/null and b/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Medium.otf differ diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Regular.otf b/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Regular.otf new file mode 100644 index 0000000..08bf4cf Binary files /dev/null and b/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Regular.otf differ diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Pretendard-SemiBold.otf b/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Pretendard-SemiBold.otf new file mode 100644 index 0000000..e7e36ab Binary files /dev/null and b/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Pretendard-SemiBold.otf differ diff --git a/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Thin.otf b/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Thin.otf new file mode 100644 index 0000000..77e792d Binary files /dev/null and b/week04/mission/Week4_Magabox/Week3_Magabox/resource/Fonts/Pretendard-Thin.otf differ diff --git a/week04/mission/Week4_Magabox/Week3_MagaboxTests/Week3_MagaboxTests.swift b/week04/mission/Week4_Magabox/Week3_MagaboxTests/Week3_MagaboxTests.swift new file mode 100644 index 0000000..f1493a8 --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_MagaboxTests/Week3_MagaboxTests.swift @@ -0,0 +1,17 @@ +// +// Week3_MagaboxTests.swift +// Week3_MagaboxTests +// +// Created by 최우진 on 10/2/25. +// + +import Testing +@testable import Week3_Magabox + +struct Week3_MagaboxTests { + + @Test func example() async throws { + // Write your test here and use APIs like `#expect(...)` to check expected conditions. + } + +} diff --git a/week04/mission/Week4_Magabox/Week3_MagaboxUITests/Week3_MagaboxUITests.swift b/week04/mission/Week4_Magabox/Week3_MagaboxUITests/Week3_MagaboxUITests.swift new file mode 100644 index 0000000..4245719 --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_MagaboxUITests/Week3_MagaboxUITests.swift @@ -0,0 +1,41 @@ +// +// Week3_MagaboxUITests.swift +// Week3_MagaboxUITests +// +// Created by 최우진 on 10/2/25. +// + +import XCTest + +final class Week3_MagaboxUITests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + @MainActor + func testExample() throws { + // UI tests must launch the application that they test. + let app = XCUIApplication() + app.launch() + + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + @MainActor + func testLaunchPerformance() throws { + // This measures how long it takes to launch your application. + measure(metrics: [XCTApplicationLaunchMetric()]) { + XCUIApplication().launch() + } + } +} diff --git a/week04/mission/Week4_Magabox/Week3_MagaboxUITests/Week3_MagaboxUITestsLaunchTests.swift b/week04/mission/Week4_Magabox/Week3_MagaboxUITests/Week3_MagaboxUITestsLaunchTests.swift new file mode 100644 index 0000000..dad038b --- /dev/null +++ b/week04/mission/Week4_Magabox/Week3_MagaboxUITests/Week3_MagaboxUITestsLaunchTests.swift @@ -0,0 +1,33 @@ +// +// Week3_MagaboxUITestsLaunchTests.swift +// Week3_MagaboxUITests +// +// Created by 최우진 on 10/2/25. +// + +import XCTest + +final class Week3_MagaboxUITestsLaunchTests: XCTestCase { + + override class var runsForEachTargetApplicationUIConfiguration: Bool { + true + } + + override func setUpWithError() throws { + continueAfterFailure = false + } + + @MainActor + func testLaunch() throws { + let app = XCUIApplication() + app.launch() + + // Insert steps here to perform after app launch but before taking a screenshot, + // such as logging into a test account or navigating somewhere in the app + + let attachment = XCTAttachment(screenshot: app.screenshot()) + attachment.name = "Launch Screen" + attachment.lifetime = .keepAlways + add(attachment) + } +}