diff --git a/hyeonseung/Study-Swift/ContactApp/ContactApp.xcodeproj/project.pbxproj b/hyeonseung/Study-Swift/ContactApp/ContactApp.xcodeproj/project.pbxproj new file mode 100644 index 0000000..449ac30 --- /dev/null +++ b/hyeonseung/Study-Swift/ContactApp/ContactApp.xcodeproj/project.pbxproj @@ -0,0 +1,441 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 56; + objects = { + +/* Begin PBXBuildFile section */ + 8B173F302BF5122700C9B07A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B173F2F2BF5122700C9B07A /* AppDelegate.swift */; }; + 8B173F322BF5122700C9B07A /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B173F312BF5122700C9B07A /* SceneDelegate.swift */; }; + 8B173F342BF5122700C9B07A /* MemberListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B173F332BF5122700C9B07A /* MemberListViewController.swift */; }; + 8B173F372BF5122700C9B07A /* Base in Resources */ = {isa = PBXBuildFile; fileRef = 8B173F362BF5122700C9B07A /* Base */; }; + 8B173F392BF5122800C9B07A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8B173F382BF5122800C9B07A /* Assets.xcassets */; }; + 8B173F3C2BF5122800C9B07A /* Base in Resources */ = {isa = PBXBuildFile; fileRef = 8B173F3B2BF5122800C9B07A /* Base */; }; + 8B173F442BF530EB00C9B07A /* AddMemberViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B173F432BF530EB00C9B07A /* AddMemberViewController.swift */; }; + 8B173F462BF5340900C9B07A /* MemberData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B173F452BF5340900C9B07A /* MemberData.swift */; }; + 8B173F4F2BF5358F00C9B07A /* 배트맨.png in Resources */ = {isa = PBXBuildFile; fileRef = 8B173F472BF5358F00C9B07A /* 배트맨.png */; }; + 8B173F502BF5358F00C9B07A /* 베조스.png in Resources */ = {isa = PBXBuildFile; fileRef = 8B173F482BF5358F00C9B07A /* 베조스.png */; }; + 8B173F512BF5358F00C9B07A /* 스티브.png in Resources */ = {isa = PBXBuildFile; fileRef = 8B173F492BF5358F00C9B07A /* 스티브.png */; }; + 8B173F522BF5358F00C9B07A /* 임꺽정.png in Resources */ = {isa = PBXBuildFile; fileRef = 8B173F4A2BF5358F00C9B07A /* 임꺽정.png */; }; + 8B173F532BF5358F00C9B07A /* 조커.png in Resources */ = {isa = PBXBuildFile; fileRef = 8B173F4B2BF5358F00C9B07A /* 조커.png */; }; + 8B173F542BF5358F00C9B07A /* 쿡.png in Resources */ = {isa = PBXBuildFile; fileRef = 8B173F4C2BF5358F00C9B07A /* 쿡.png */; }; + 8B173F552BF5358F00C9B07A /* 홍길동.png in Resources */ = {isa = PBXBuildFile; fileRef = 8B173F4D2BF5358F00C9B07A /* 홍길동.png */; }; + 8B173F5A2BF5BF7F00C9B07A /* MemberTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B173F582BF5BF7F00C9B07A /* MemberTableViewCell.swift */; }; + 8B173F5B2BF5BF7F00C9B07A /* MemberTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8B173F592BF5BF7F00C9B07A /* MemberTableViewCell.xib */; }; + 8B6516F92BF5F06B005515B2 /* MemberDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B6516F82BF5F06B005515B2 /* MemberDetailViewController.swift */; }; + 8BBC514F2BFC4D8D005EB184 /* ImageFileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BBC514E2BFC4D8D005EB184 /* ImageFileManager.swift */; }; + 8BBC51522BFC8D91005EB184 /* basic_profile2.jpeg in Resources */ = {isa = PBXBuildFile; fileRef = 8BBC51502BFC8D91005EB184 /* basic_profile2.jpeg */; }; + 8BBC51532BFC8D91005EB184 /* basic_profile.jpeg in Resources */ = {isa = PBXBuildFile; fileRef = 8BBC51512BFC8D91005EB184 /* basic_profile.jpeg */; }; + 8BBC51552BFCDA3E005EB184 /* MemberManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BBC51542BFCDA3E005EB184 /* MemberManager.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 8B173F2C2BF5122700C9B07A /* ContactApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ContactApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 8B173F2F2BF5122700C9B07A /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 8B173F312BF5122700C9B07A /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 8B173F332BF5122700C9B07A /* MemberListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemberListViewController.swift; sourceTree = ""; }; + 8B173F362BF5122700C9B07A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 8B173F382BF5122800C9B07A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 8B173F3B2BF5122800C9B07A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 8B173F3D2BF5122800C9B07A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 8B173F432BF530EB00C9B07A /* AddMemberViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddMemberViewController.swift; sourceTree = ""; }; + 8B173F452BF5340900C9B07A /* MemberData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemberData.swift; sourceTree = ""; }; + 8B173F472BF5358F00C9B07A /* 배트맨.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "배트맨.png"; sourceTree = ""; }; + 8B173F482BF5358F00C9B07A /* 베조스.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "베조스.png"; sourceTree = ""; }; + 8B173F492BF5358F00C9B07A /* 스티브.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "스티브.png"; sourceTree = ""; }; + 8B173F4A2BF5358F00C9B07A /* 임꺽정.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "임꺽정.png"; sourceTree = ""; }; + 8B173F4B2BF5358F00C9B07A /* 조커.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "조커.png"; sourceTree = ""; }; + 8B173F4C2BF5358F00C9B07A /* 쿡.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "쿡.png"; sourceTree = ""; }; + 8B173F4D2BF5358F00C9B07A /* 홍길동.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "홍길동.png"; sourceTree = ""; }; + 8B173F582BF5BF7F00C9B07A /* MemberTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemberTableViewCell.swift; sourceTree = ""; }; + 8B173F592BF5BF7F00C9B07A /* MemberTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MemberTableViewCell.xib; sourceTree = ""; }; + 8B6516F82BF5F06B005515B2 /* MemberDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemberDetailViewController.swift; sourceTree = ""; }; + 8BBC514E2BFC4D8D005EB184 /* ImageFileManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageFileManager.swift; sourceTree = ""; }; + 8BBC51502BFC8D91005EB184 /* basic_profile2.jpeg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = basic_profile2.jpeg; sourceTree = ""; }; + 8BBC51512BFC8D91005EB184 /* basic_profile.jpeg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = basic_profile.jpeg; sourceTree = ""; }; + 8BBC51542BFCDA3E005EB184 /* MemberManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemberManager.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8B173F292BF5122700C9B07A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 8B173F232BF5122700C9B07A = { + isa = PBXGroup; + children = ( + 8B173F2E2BF5122700C9B07A /* ContactApp */, + 8B173F2D2BF5122700C9B07A /* Products */, + ); + sourceTree = ""; + }; + 8B173F2D2BF5122700C9B07A /* Products */ = { + isa = PBXGroup; + children = ( + 8B173F2C2BF5122700C9B07A /* ContactApp.app */, + ); + name = Products; + sourceTree = ""; + }; + 8B173F2E2BF5122700C9B07A /* ContactApp */ = { + isa = PBXGroup; + children = ( + 8BBC51502BFC8D91005EB184 /* basic_profile2.jpeg */, + 8B173F2F2BF5122700C9B07A /* AppDelegate.swift */, + 8B173F582BF5BF7F00C9B07A /* MemberTableViewCell.swift */, + 8B6516F82BF5F06B005515B2 /* MemberDetailViewController.swift */, + 8B173F592BF5BF7F00C9B07A /* MemberTableViewCell.xib */, + 8B173F452BF5340900C9B07A /* MemberData.swift */, + 8B173F312BF5122700C9B07A /* SceneDelegate.swift */, + 8B173F332BF5122700C9B07A /* MemberListViewController.swift */, + 8B173F352BF5122700C9B07A /* Main.storyboard */, + 8B173F432BF530EB00C9B07A /* AddMemberViewController.swift */, + 8BBC51512BFC8D91005EB184 /* basic_profile.jpeg */, + 8B173F382BF5122800C9B07A /* Assets.xcassets */, + 8B173F3A2BF5122800C9B07A /* LaunchScreen.storyboard */, + 8B173F3D2BF5122800C9B07A /* Info.plist */, + 8B173F4E2BF5358F00C9B07A /* Member_Images */, + 8BBC514E2BFC4D8D005EB184 /* ImageFileManager.swift */, + 8BBC51542BFCDA3E005EB184 /* MemberManager.swift */, + ); + path = ContactApp; + sourceTree = ""; + }; + 8B173F4E2BF5358F00C9B07A /* Member_Images */ = { + isa = PBXGroup; + children = ( + 8B173F472BF5358F00C9B07A /* 배트맨.png */, + 8B173F482BF5358F00C9B07A /* 베조스.png */, + 8B173F492BF5358F00C9B07A /* 스티브.png */, + 8B173F4A2BF5358F00C9B07A /* 임꺽정.png */, + 8B173F4B2BF5358F00C9B07A /* 조커.png */, + 8B173F4C2BF5358F00C9B07A /* 쿡.png */, + 8B173F4D2BF5358F00C9B07A /* 홍길동.png */, + ); + name = Member_Images; + path = ../../../../../../../Downloads/Member_Images; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 8B173F2B2BF5122700C9B07A /* ContactApp */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8B173F402BF5122800C9B07A /* Build configuration list for PBXNativeTarget "ContactApp" */; + buildPhases = ( + 8B173F282BF5122700C9B07A /* Sources */, + 8B173F292BF5122700C9B07A /* Frameworks */, + 8B173F2A2BF5122700C9B07A /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ContactApp; + productName = ContactApp; + productReference = 8B173F2C2BF5122700C9B07A /* ContactApp.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 8B173F242BF5122700C9B07A /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1530; + LastUpgradeCheck = 1530; + TargetAttributes = { + 8B173F2B2BF5122700C9B07A = { + CreatedOnToolsVersion = 15.3; + }; + }; + }; + buildConfigurationList = 8B173F272BF5122700C9B07A /* Build configuration list for PBXProject "ContactApp" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 8B173F232BF5122700C9B07A; + productRefGroup = 8B173F2D2BF5122700C9B07A /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 8B173F2B2BF5122700C9B07A /* ContactApp */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8B173F2A2BF5122700C9B07A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8B173F522BF5358F00C9B07A /* 임꺽정.png in Resources */, + 8B173F552BF5358F00C9B07A /* 홍길동.png in Resources */, + 8B173F392BF5122800C9B07A /* Assets.xcassets in Resources */, + 8BBC51532BFC8D91005EB184 /* basic_profile.jpeg in Resources */, + 8B173F4F2BF5358F00C9B07A /* 배트맨.png in Resources */, + 8B173F542BF5358F00C9B07A /* 쿡.png in Resources */, + 8B173F3C2BF5122800C9B07A /* Base in Resources */, + 8B173F5B2BF5BF7F00C9B07A /* MemberTableViewCell.xib in Resources */, + 8B173F532BF5358F00C9B07A /* 조커.png in Resources */, + 8B173F372BF5122700C9B07A /* Base in Resources */, + 8B173F512BF5358F00C9B07A /* 스티브.png in Resources */, + 8B173F502BF5358F00C9B07A /* 베조스.png in Resources */, + 8BBC51522BFC8D91005EB184 /* basic_profile2.jpeg in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8B173F282BF5122700C9B07A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8B173F442BF530EB00C9B07A /* AddMemberViewController.swift in Sources */, + 8B173F5A2BF5BF7F00C9B07A /* MemberTableViewCell.swift in Sources */, + 8B173F462BF5340900C9B07A /* MemberData.swift in Sources */, + 8BBC51552BFCDA3E005EB184 /* MemberManager.swift in Sources */, + 8B173F342BF5122700C9B07A /* MemberListViewController.swift in Sources */, + 8B6516F92BF5F06B005515B2 /* MemberDetailViewController.swift in Sources */, + 8B173F302BF5122700C9B07A /* AppDelegate.swift in Sources */, + 8B173F322BF5122700C9B07A /* SceneDelegate.swift in Sources */, + 8BBC514F2BFC4D8D005EB184 /* ImageFileManager.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 8B173F352BF5122700C9B07A /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 8B173F362BF5122700C9B07A /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 8B173F3A2BF5122800C9B07A /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 8B173F3B2BF5122800C9B07A /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 8B173F3E2BF5122800C9B07A /* 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 = 17.4; + 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; + }; + 8B173F3F2BF5122800C9B07A /* 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 = 17.4; + 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; + }; + 8B173F412BF5122800C9B07A /* 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_TEAM = S8YQN7N24J; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = ContactApp/Info.plist; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + 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 = org.appcenter.ContactApp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 8B173F422BF5122800C9B07A /* 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_TEAM = S8YQN7N24J; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = ContactApp/Info.plist; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + 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 = org.appcenter.ContactApp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 8B173F272BF5122700C9B07A /* Build configuration list for PBXProject "ContactApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8B173F3E2BF5122800C9B07A /* Debug */, + 8B173F3F2BF5122800C9B07A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8B173F402BF5122800C9B07A /* Build configuration list for PBXNativeTarget "ContactApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8B173F412BF5122800C9B07A /* Debug */, + 8B173F422BF5122800C9B07A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 8B173F242BF5122700C9B07A /* Project object */; +} diff --git a/hyeonseung/Study-Swift/ContactApp/ContactApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/hyeonseung/Study-Swift/ContactApp/ContactApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/hyeonseung/Study-Swift/ContactApp/ContactApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/hyeonseung/Study-Swift/ContactApp/ContactApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/hyeonseung/Study-Swift/ContactApp/ContactApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/hyeonseung/Study-Swift/ContactApp/ContactApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/hyeonseung/Study-Swift/ContactApp/ContactApp.xcodeproj/xcshareddata/xcschemes/ContactApp.xcscheme b/hyeonseung/Study-Swift/ContactApp/ContactApp.xcodeproj/xcshareddata/xcschemes/ContactApp.xcscheme new file mode 100644 index 0000000..f577b4e --- /dev/null +++ b/hyeonseung/Study-Swift/ContactApp/ContactApp.xcodeproj/xcshareddata/xcschemes/ContactApp.xcscheme @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hyeonseung/Study-Swift/ContactApp/ContactApp/AddMemberViewController.swift b/hyeonseung/Study-Swift/ContactApp/ContactApp/AddMemberViewController.swift new file mode 100644 index 0000000..f5be338 --- /dev/null +++ b/hyeonseung/Study-Swift/ContactApp/ContactApp/AddMemberViewController.swift @@ -0,0 +1,110 @@ + +import UIKit + +class AddMemberViewController: UIViewController{ + + let imgPicker = UIImagePickerController() + + @IBOutlet weak var memberNum: UILabel! + @IBOutlet weak var memberName: UILabel! + @IBOutlet weak var memberAge: UILabel! + @IBOutlet weak var memberTel: UILabel! + @IBOutlet weak var memberAddress: UILabel! + + @IBOutlet weak var numTF: UITextField! + @IBOutlet weak var nameTF: UITextField! + @IBOutlet weak var ageTF: UITextField! + @IBOutlet weak var telTF: UITextField! + @IBOutlet weak var addressTF: UITextField! + + @IBOutlet weak var imgBtn: UIButton! + + @IBOutlet var selectedImage: UIImageView? + + override func viewDidLoad() { + super.viewDidLoad() + + self.imgBtn.layer.masksToBounds = true + self.imgBtn.layer.cornerRadius = self.imgBtn.frame.size.width / 2 + self.imgBtn.layer.backgroundColor = UIColor.lightGray.cgColor + + self.imgPicker.delegate = self + + memberNum.text = "멤버번호: " + memberName.text = "이 름: " + memberAge.text = "나 이: " + memberTel.text = "전화번호: " + memberAddress.text = "주 소: " + + setupView() + + } + + func setupView() { + imgBtn.addTarget(self, action: #selector(uploadPhoto), for: .touchUpInside) + + } + + @IBAction func uploadPhoto(_ sender: Any) { + + let imagePicker = UIImagePickerController() + imagePicker.sourceType = .photoLibrary + imagePicker.delegate = self + present(imagePicker, animated: true) + + } + + + @IBAction func saveMember(_ sender: Any) { + + let num = numTF.text ?? "" + let name = nameTF.text ?? "" + let age = ageTF.text ?? "" + let tel = telTF.text ?? "" + let address = addressTF.text ?? "" + + if selectedImage?.image == nil { + let defaultImages = ["basic_profile", "basic_profile2"] + let randomIndex = Int(arc4random_uniform(UInt32(defaultImages.count))) + selectedImage?.image = UIImage(named: defaultImages[randomIndex]) + } + + let imageName = selectedImage?.image + + + let data = MemberData(memberImage: imageName, memberNum: num, memberName: name, memberAge: age, memberTell: tel, memberAddress: address) + + MemberManager.shared.addMember(data) + + print("memberlist count: \(MemberManager.shared.countMember())") + self.navigationController?.popViewController(animated: true) + } + + + +} + +extension AddMemberViewController: + UIImagePickerControllerDelegate, UINavigationControllerDelegate{ + + func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { + if let pickedImage = info[.originalImage] as? UIImage { + + selectedImage?.image = pickedImage + selectedImage?.layer.cornerRadius = (self.selectedImage?.frame.height)!/2 + selectedImage?.clipsToBounds = true + selectedImage?.contentMode = .scaleToFill + + imgBtn.setImage(pickedImage, for: .normal) + imgBtn.imageView?.contentMode = .scaleAspectFill + imgBtn.clipsToBounds = true + } + + dismiss(animated: true, completion: nil) + } + + + func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { + dismiss(animated: true, completion: nil) + } +} diff --git a/hyeonseung/Study-Swift/ContactApp/ContactApp/AppDelegate.swift b/hyeonseung/Study-Swift/ContactApp/ContactApp/AppDelegate.swift new file mode 100644 index 0000000..3eecc26 --- /dev/null +++ b/hyeonseung/Study-Swift/ContactApp/ContactApp/AppDelegate.swift @@ -0,0 +1,36 @@ +// +// AppDelegate.swift +// ContactApp +// +// Created by 한현승 on 5/16/24. +// + +import UIKit + +@main +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/AccentColor.colorset/Contents.json b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/AppIcon.appiconset/Contents.json b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..13613e3 --- /dev/null +++ b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,13 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/Contents.json b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/basic_profile.imageset/Contents.json b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/basic_profile.imageset/Contents.json new file mode 100644 index 0000000..932953e --- /dev/null +++ b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/basic_profile.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "basic_profile.jpeg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/basic_profile.imageset/basic_profile.jpeg b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/basic_profile.imageset/basic_profile.jpeg new file mode 100644 index 0000000..aa86e51 Binary files /dev/null and b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/basic_profile.imageset/basic_profile.jpeg differ diff --git a/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/basic_profile2.imageset/Contents.json b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/basic_profile2.imageset/Contents.json new file mode 100644 index 0000000..03789b7 --- /dev/null +++ b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/basic_profile2.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "basic_profile2.jpeg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/basic_profile2.imageset/basic_profile2.jpeg b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/basic_profile2.imageset/basic_profile2.jpeg new file mode 100644 index 0000000..8b39d29 Binary files /dev/null and b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/basic_profile2.imageset/basic_profile2.jpeg differ diff --git "a/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\353\260\260\355\212\270\353\247\250.imageset/Contents.json" "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\353\260\260\355\212\270\353\247\250.imageset/Contents.json" new file mode 100644 index 0000000..0c29010 --- /dev/null +++ "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\353\260\260\355\212\270\353\247\250.imageset/Contents.json" @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "배트맨.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\353\260\260\355\212\270\353\247\250.imageset/\353\260\260\355\212\270\353\247\250.png" "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\353\260\260\355\212\270\353\247\250.imageset/\353\260\260\355\212\270\353\247\250.png" new file mode 100644 index 0000000..6a70aca Binary files /dev/null and "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\353\260\260\355\212\270\353\247\250.imageset/\353\260\260\355\212\270\353\247\250.png" differ diff --git "a/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\353\262\240\354\241\260\354\212\244.imageset/Contents.json" "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\353\262\240\354\241\260\354\212\244.imageset/Contents.json" new file mode 100644 index 0000000..2b3c821 --- /dev/null +++ "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\353\262\240\354\241\260\354\212\244.imageset/Contents.json" @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "베조스.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\353\262\240\354\241\260\354\212\244.imageset/\353\262\240\354\241\260\354\212\244.png" "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\353\262\240\354\241\260\354\212\244.imageset/\353\262\240\354\241\260\354\212\244.png" new file mode 100644 index 0000000..0d6962c Binary files /dev/null and "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\353\262\240\354\241\260\354\212\244.imageset/\353\262\240\354\241\260\354\212\244.png" differ diff --git "a/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\354\212\244\355\213\260\353\270\214.imageset/Contents.json" "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\354\212\244\355\213\260\353\270\214.imageset/Contents.json" new file mode 100644 index 0000000..385286d --- /dev/null +++ "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\354\212\244\355\213\260\353\270\214.imageset/Contents.json" @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "스티브.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\354\212\244\355\213\260\353\270\214.imageset/\354\212\244\355\213\260\353\270\214.png" "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\354\212\244\355\213\260\353\270\214.imageset/\354\212\244\355\213\260\353\270\214.png" new file mode 100644 index 0000000..442966d Binary files /dev/null and "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\354\212\244\355\213\260\353\270\214.imageset/\354\212\244\355\213\260\353\270\214.png" differ diff --git "a/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\354\236\204\352\272\275\354\240\225.imageset/Contents.json" "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\354\236\204\352\272\275\354\240\225.imageset/Contents.json" new file mode 100644 index 0000000..4119653 --- /dev/null +++ "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\354\236\204\352\272\275\354\240\225.imageset/Contents.json" @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "임꺽정.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\354\236\204\352\272\275\354\240\225.imageset/\354\236\204\352\272\275\354\240\225.png" "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\354\236\204\352\272\275\354\240\225.imageset/\354\236\204\352\272\275\354\240\225.png" new file mode 100644 index 0000000..ebb9b2d Binary files /dev/null and "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\354\236\204\352\272\275\354\240\225.imageset/\354\236\204\352\272\275\354\240\225.png" differ diff --git "a/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\354\241\260\354\273\244.imageset/Contents.json" "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\354\241\260\354\273\244.imageset/Contents.json" new file mode 100644 index 0000000..cea8f36 --- /dev/null +++ "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\354\241\260\354\273\244.imageset/Contents.json" @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "조커.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\354\241\260\354\273\244.imageset/\354\241\260\354\273\244.png" "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\354\241\260\354\273\244.imageset/\354\241\260\354\273\244.png" new file mode 100644 index 0000000..1e2c929 Binary files /dev/null and "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\354\241\260\354\273\244.imageset/\354\241\260\354\273\244.png" differ diff --git "a/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\354\277\241.imageset/Contents.json" "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\354\277\241.imageset/Contents.json" new file mode 100644 index 0000000..6cb4a71 --- /dev/null +++ "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\354\277\241.imageset/Contents.json" @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "쿡.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\354\277\241.imageset/\354\277\241.png" "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\354\277\241.imageset/\354\277\241.png" new file mode 100644 index 0000000..d14b48b Binary files /dev/null and "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\354\277\241.imageset/\354\277\241.png" differ diff --git "a/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\355\231\215\352\270\270\353\217\231.imageset/Contents.json" "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\355\231\215\352\270\270\353\217\231.imageset/Contents.json" new file mode 100644 index 0000000..d15b6de --- /dev/null +++ "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\355\231\215\352\270\270\353\217\231.imageset/Contents.json" @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "홍길동.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\355\231\215\352\270\270\353\217\231.imageset/\355\231\215\352\270\270\353\217\231.png" "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\355\231\215\352\270\270\353\217\231.imageset/\355\231\215\352\270\270\353\217\231.png" new file mode 100644 index 0000000..75ab262 Binary files /dev/null and "b/hyeonseung/Study-Swift/ContactApp/ContactApp/Assets.xcassets/\355\231\215\352\270\270\353\217\231.imageset/\355\231\215\352\270\270\353\217\231.png" differ diff --git a/hyeonseung/Study-Swift/ContactApp/ContactApp/Base.lproj/LaunchScreen.storyboard b/hyeonseung/Study-Swift/ContactApp/ContactApp/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/hyeonseung/Study-Swift/ContactApp/ContactApp/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hyeonseung/Study-Swift/ContactApp/ContactApp/Base.lproj/Main.storyboard b/hyeonseung/Study-Swift/ContactApp/ContactApp/Base.lproj/Main.storyboard new file mode 100644 index 0000000..bcd6b4a --- /dev/null +++ b/hyeonseung/Study-Swift/ContactApp/ContactApp/Base.lproj/Main.storyboard @@ -0,0 +1,442 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hyeonseung/Study-Swift/ContactApp/ContactApp/ImageFileManager.swift b/hyeonseung/Study-Swift/ContactApp/ContactApp/ImageFileManager.swift new file mode 100644 index 0000000..f7e5bad --- /dev/null +++ b/hyeonseung/Study-Swift/ContactApp/ContactApp/ImageFileManager.swift @@ -0,0 +1,49 @@ +// +// ImageFileManager.swift +// ContactApp +// +// Created by 한현승 on 5/21/24. +// + +import Foundation +import UIKit + + +class ImageFileManager { + // 싱글톤 + static let shared: ImageFileManager = ImageFileManager() + + + func saveImage(image: UIImage, name: String, onSuccess: @escaping((Bool)-> Void)){ + guard let data: Data = image.pngData() else {return} + + if let directory: NSURL = try? FileManager.default.url(for: .documentDirectory, + in: .userDomainMask, + appropriateFor: nil, + create: false) as NSURL { + do{ + try data.write(to: directory.appendingPathExtension(name)!) + onSuccess(true) + } catch let err as NSError { + print("Could not saveImage: \(err), \(err.userInfo)") + onSuccess(false) + } + } + } + + func getSavedImage(named: String) -> UIImage? { + if let dir: URL = try? FileManager.default.url(for: .documentDirectory, + in: .userDomainMask, + appropriateFor: nil, + create: false) { + let path: String + = URL(fileURLWithPath: dir.absoluteString) + .appendingPathComponent(named).path + + let image: UIImage? = UIImage(contentsOfFile: path) + + return image + } + return nil + } +} diff --git a/hyeonseung/Study-Swift/ContactApp/ContactApp/Info.plist b/hyeonseung/Study-Swift/ContactApp/ContactApp/Info.plist new file mode 100644 index 0000000..b59d62f --- /dev/null +++ b/hyeonseung/Study-Swift/ContactApp/ContactApp/Info.plist @@ -0,0 +1,29 @@ + + + + + NSCameraUsageDescription + + NSPhotoLibraryAddUsageDescription + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + UISceneStoryboardFile + Main + + + + + + diff --git a/hyeonseung/Study-Swift/ContactApp/ContactApp/MemberData.swift b/hyeonseung/Study-Swift/ContactApp/ContactApp/MemberData.swift new file mode 100644 index 0000000..ad5615d --- /dev/null +++ b/hyeonseung/Study-Swift/ContactApp/ContactApp/MemberData.swift @@ -0,0 +1,31 @@ +// +// MemberData.swift +// ContactApp +// +// Created by 한현승 on 5/16/24. +// + +import Foundation +import UIKit + + +struct MemberData { + var memberImage: UIImage? + var memberNum: String? + var memberName: String? + var memberAge: String? + var memberTell: String? + var memberAddress: String? + + init(memberImage: UIImage?, memberNum: String?, memberName: String?, memberAge: String?, memberTell: String?, memberAddress: String?) { + self.memberImage = memberImage + self.memberNum = memberNum + self.memberName = memberName + self.memberAge = memberAge + self.memberTell = memberTell + self.memberAddress = memberAddress + } + + + +} diff --git a/hyeonseung/Study-Swift/ContactApp/ContactApp/MemberDetailViewController.swift b/hyeonseung/Study-Swift/ContactApp/ContactApp/MemberDetailViewController.swift new file mode 100644 index 0000000..5ef6303 --- /dev/null +++ b/hyeonseung/Study-Swift/ContactApp/ContactApp/MemberDetailViewController.swift @@ -0,0 +1,121 @@ +//// +//// MemberDetailViewController.swift +//// ContactApp +//// +//// Created by 한현승 on 5/16/24. +//// +// +import Foundation +import UIKit + + + +class MemberDetailViewController: UIViewController { + + @IBOutlet weak var memberNum: UILabel! + @IBOutlet weak var memberName: UILabel! + @IBOutlet weak var memberAge: UILabel! + @IBOutlet weak var memberTel: UILabel! + @IBOutlet weak var memberAddress: UILabel! + + @IBOutlet weak var numTF: UITextField! + @IBOutlet weak var nameTF: UITextField! + @IBOutlet weak var ageTF: UITextField! + @IBOutlet weak var telTF: UITextField! + @IBOutlet weak var addressTF: UITextField! + + @IBOutlet weak var imgBtn: UIButton! + + var memberIndex: Int? + let memberInfo = MemberManager.shared + @IBOutlet var selectedImage: UIImageView? + + override func viewDidLoad() { + super.viewDidLoad() + + self.imgBtn.layer.masksToBounds = true + self.imgBtn.layer.cornerRadius = self.imgBtn.frame.size.width / 2 + + memberNum.text = "멤버번호: " + memberName.text = "이 름: " + memberAge.text = "나 이: " + memberTel.text = "전화번호: " + memberAddress.text = "주 소: " + + if let index = memberIndex, let info = memberInfo.getMember(index: index){ + numTF?.text = info.memberNum + nameTF?.text = info.memberName + ageTF?.text = info.memberAge + telTF?.text = info.memberTell + addressTF?.text = info.memberAddress + + selectedImage?.image = info.memberImage + selectedImage?.layer.cornerRadius = (selectedImage?.frame.height)!/2 + selectedImage?.clipsToBounds = true + selectedImage?.layer.borderWidth = 0 + selectedImage?.contentMode = .scaleAspectFill + // 이미지 버튼 설정 + imgBtn.setImage(info.memberImage, for: .normal) + imgBtn.imageView?.contentMode = .scaleToFill + imgBtn.clipsToBounds = true + + } + + } + + @IBAction func updateMember(_ sender: Any) { + guard let index = memberIndex else {return} + + let updatedNum = numTF.text ?? "" + let updatedName = nameTF.text ?? "" + let updatedAge = ageTF.text ?? "" + let updatedTel = telTF.text ?? "" + let updatedAddress = addressTF.text ?? "" + + let updatedImageName = selectedImage?.image + + var updateMember = memberInfo.getMember(index: index) + updateMember?.memberImage = updatedImageName + updateMember?.memberNum = updatedNum + updateMember?.memberName = updatedName + updateMember?.memberAge = updatedAge + updateMember?.memberTell = updatedTel + updateMember?.memberAddress = updatedAddress + + if let updateMember = updateMember { + memberInfo.updateMember(index: index, member: updateMember) + } + + self.navigationController?.popViewController(animated: true) + } + +} + + +extension MemberDetailViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate { + + @IBAction func uploadPhoto(_ sender: Any) { + let imagePicker = UIImagePickerController() + imagePicker.sourceType = .photoLibrary + imagePicker.delegate = self + present(imagePicker, animated: true) + } + + func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { + if let pickedImage = info[.originalImage] as? UIImage { + selectedImage?.image = pickedImage + selectedImage?.layer.cornerRadius = (self.selectedImage?.frame.height)!/2 + selectedImage?.clipsToBounds = true + selectedImage?.contentMode = .scaleToFill + + imgBtn.setImage(pickedImage, for: .normal) + imgBtn.imageView?.contentMode = .scaleToFill + imgBtn.clipsToBounds = true + } + dismiss(animated: true, completion: nil) + } + + func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { + dismiss(animated: true, completion: nil) + } +} diff --git a/hyeonseung/Study-Swift/ContactApp/ContactApp/MemberListViewController.swift b/hyeonseung/Study-Swift/ContactApp/ContactApp/MemberListViewController.swift new file mode 100644 index 0000000..6be872b --- /dev/null +++ b/hyeonseung/Study-Swift/ContactApp/ContactApp/MemberListViewController.swift @@ -0,0 +1,80 @@ +// +// ViewController.swift +// ContactApp +// +// Created by 한현승 on 5/16/24. +// + +import UIKit + + +class MemberListViewController: UIViewController { + + let memberlist = MemberManager.shared + + @IBOutlet weak var listTableView: UITableView! + + + override func viewDidLoad() { + super.viewDidLoad() + + listTableView.delegate = self + listTableView.dataSource = self + + registerNib() + } + + private func registerNib() { + let nibName = UINib(nibName: MemberTableViewCell.identifier, bundle: nil) + listTableView.register(nibName, forCellReuseIdentifier: MemberTableViewCell.identifier) + } + + @IBAction func addMember(_ sender: Any) { + guard let addVC = self.storyboard?.instantiateViewController(withIdentifier: "AddMemberViewController") as? AddMemberViewController else {return} + + self.navigationController?.pushViewController(addVC, animated: true) + } + + override func viewDidAppear(_ animated: Bool) { + listTableView.reloadData() + } + + +} + +extension MemberListViewController: UITableViewDataSource, UITableViewDelegate{ + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return memberlist.countMember() + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + guard let cell = listTableView.dequeueReusableCell(withIdentifier: MemberTableViewCell.identifier, for: indexPath) as? MemberTableViewCell else { + return UITableViewCell() + } + + if let member = memberlist.getMember(index: indexPath.row){ + + cell.memberImage.image = member.memberImage + cell.memberName.text = member.memberName + cell.memberAddress.text = member.memberAddress + } + + return cell + } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return 70 + + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + guard let detailVC = self.storyboard?.instantiateViewController(withIdentifier: "MemberDetailViewController") as? MemberDetailViewController else {return} + + + detailVC.memberIndex = indexPath.row + self.navigationController?.pushViewController(detailVC, animated: true) + } + + +} diff --git a/hyeonseung/Study-Swift/ContactApp/ContactApp/MemberManager.swift b/hyeonseung/Study-Swift/ContactApp/ContactApp/MemberManager.swift new file mode 100644 index 0000000..1727a91 --- /dev/null +++ b/hyeonseung/Study-Swift/ContactApp/ContactApp/MemberManager.swift @@ -0,0 +1,87 @@ +// +// MemberManager.swift +// ContactApp +// +// Created by 한현승 on 5/21/24. +// + +import Foundation +import UIKit + + +class MemberManager { + static let shared = MemberManager() + + private init() { + self.memberlist = [ + MemberData(memberImage: UIImage(named: "배트맨"), + memberNum: "1", + memberName: "배트맨", + memberAge: "20", + memberTell: "010-1234-1234", + memberAddress: "인천대학교"), + MemberData(memberImage: UIImage(named: "임꺽정"), + memberNum: "2", + memberName: "임꺽정", + memberAge: "20", + memberTell: "010-1234-1234", + memberAddress: "한국"), + MemberData(memberImage: UIImage(named: "베조스"), + memberNum: "3", + memberName: "베조스", + memberAge: "40", + memberTell: "010-1234-1234", + memberAddress: "NASA"), + MemberData(memberImage: UIImage(named: "스티브"), + memberNum: "4", + memberName: "스티브", + memberAge: "20", + memberTell: "010-1234-1234", + memberAddress: "APPLE"), + MemberData(memberImage: UIImage(named: "조커"), + memberNum: "5", + memberName: "조커", + memberAge: "20", + memberTell: "010-1234-1234", + memberAddress: "아메리카"), + MemberData(memberImage: UIImage(named: "쿡"), + memberNum: "6", + memberName: "쿡", + memberAge: "20", + memberTell: "010-1234-1234", + memberAddress: "인천대학교"), + MemberData(memberImage: UIImage(named: "홍길동"), + memberNum: "7", + memberName: "홍길동", + memberAge: "20", + memberTell: "010-1234-1234", + memberAddress: "한국 고전소설"), + + ] + } + + private var memberlist = [MemberData]() + + // add + func addMember(_ member: MemberData){ + memberlist.append(member) + } + + // update + func updateMember( index: Int, member: MemberData){ + guard index >= 0 && index < memberlist.count else {return} + memberlist[index] = member + } + + // get + func getMember(index: Int) -> MemberData? { + return memberlist[index] + } + + + func countMember() -> Int { + return memberlist.count + } + + +} diff --git a/hyeonseung/Study-Swift/ContactApp/ContactApp/MemberTableViewCell.swift b/hyeonseung/Study-Swift/ContactApp/ContactApp/MemberTableViewCell.swift new file mode 100644 index 0000000..92d5600 --- /dev/null +++ b/hyeonseung/Study-Swift/ContactApp/ContactApp/MemberTableViewCell.swift @@ -0,0 +1,37 @@ +// +// MemberTableViewCell.swift +// ContactApp +// +// Created by 한현승 on 5/16/24. +// + +import UIKit + +class MemberTableViewCell: UITableViewCell { + + + @IBOutlet weak var memberImage: UIImageView! + @IBOutlet weak var memberName: UILabel! + @IBOutlet weak var memberAddress: UILabel! + + + override func awakeFromNib() { + super.awakeFromNib() + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + memberImage.layer.cornerRadius = memberImage.frame.height/2 + memberImage.layer.borderWidth = 0 + memberImage.clipsToBounds = true + memberImage.contentMode = .scaleToFill + } + +} + +extension UITableViewCell { + static var identifier: String { + return String(describing: self) + } +} diff --git a/hyeonseung/Study-Swift/ContactApp/ContactApp/MemberTableViewCell.xib b/hyeonseung/Study-Swift/ContactApp/ContactApp/MemberTableViewCell.xib new file mode 100644 index 0000000..76ccac3 --- /dev/null +++ b/hyeonseung/Study-Swift/ContactApp/ContactApp/MemberTableViewCell.xib @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hyeonseung/Study-Swift/ContactApp/ContactApp/SceneDelegate.swift b/hyeonseung/Study-Swift/ContactApp/ContactApp/SceneDelegate.swift new file mode 100644 index 0000000..f578ce8 --- /dev/null +++ b/hyeonseung/Study-Swift/ContactApp/ContactApp/SceneDelegate.swift @@ -0,0 +1,52 @@ +// +// SceneDelegate.swift +// ContactApp +// +// Created by 한현승 on 5/16/24. +// + +import UIKit + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + guard let _ = (scene as? UIWindowScene) else { return } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} + diff --git a/hyeonseung/Study-Swift/ContactApp/ContactApp/basic_profile.jpeg b/hyeonseung/Study-Swift/ContactApp/ContactApp/basic_profile.jpeg new file mode 100644 index 0000000..aa86e51 Binary files /dev/null and b/hyeonseung/Study-Swift/ContactApp/ContactApp/basic_profile.jpeg differ diff --git a/hyeonseung/Study-Swift/ContactApp/ContactApp/basic_profile2.jpeg b/hyeonseung/Study-Swift/ContactApp/ContactApp/basic_profile2.jpeg new file mode 100644 index 0000000..8b39d29 Binary files /dev/null and b/hyeonseung/Study-Swift/ContactApp/ContactApp/basic_profile2.jpeg differ diff --git a/hyeonseung/Study-Swift/ContactApp/README.md b/hyeonseung/Study-Swift/ContactApp/README.md new file mode 100644 index 0000000..7b2e788 --- /dev/null +++ b/hyeonseung/Study-Swift/ContactApp/README.md @@ -0,0 +1,15 @@ +# 연락처 리스트 앱 + +### 시연 영상 + +https://github.com/inu-appcenter/iOS-study-16th/assets/109841880/0a2faa27-4d2f-4884-a4e9-c29288b7ef1c + + + +#### 메인 화면 - 친구목록 +![Simulator Screenshot - iPhone 15 Pro - 2024-05-22 at 01 27 00](https://github.com/inu-appcenter/iOS-study-16th/assets/109841880/e272c15b-892a-494c-9754-46289a743cd5) + + +#### 친구 추가 화면 + +![Simulator Screenshot - iPhone 15 Pro - 2024-05-22 at 01 28 16](https://github.com/inu-appcenter/iOS-study-16th/assets/109841880/90865da6-18af-4502-8c3c-069a0807845f) diff --git a/hyeonseung/Study-Swift/MusicSearch/MusicSearch.xcodeproj/project.pbxproj b/hyeonseung/Study-Swift/MusicSearch/MusicSearch.xcodeproj/project.pbxproj new file mode 100644 index 0000000..27eceff --- /dev/null +++ b/hyeonseung/Study-Swift/MusicSearch/MusicSearch.xcodeproj/project.pbxproj @@ -0,0 +1,384 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 56; + objects = { + +/* Begin PBXBuildFile section */ + 8BBC51632BFD1A4D005EB184 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BBC51622BFD1A4D005EB184 /* AppDelegate.swift */; }; + 8BBC51652BFD1A4D005EB184 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BBC51642BFD1A4D005EB184 /* SceneDelegate.swift */; }; + 8BBC51672BFD1A4D005EB184 /* SearchMusicViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BBC51662BFD1A4D005EB184 /* SearchMusicViewController.swift */; }; + 8BBC516A2BFD1A4D005EB184 /* Base in Resources */ = {isa = PBXBuildFile; fileRef = 8BBC51692BFD1A4D005EB184 /* Base */; }; + 8BBC516C2BFD1A4E005EB184 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8BBC516B2BFD1A4E005EB184 /* Assets.xcassets */; }; + 8BBC516F2BFD1A4E005EB184 /* Base in Resources */ = {isa = PBXBuildFile; fileRef = 8BBC516E2BFD1A4E005EB184 /* Base */; }; + 8BBC51772BFD1C52005EB184 /* MusicInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BBC51762BFD1C52005EB184 /* MusicInfo.swift */; }; + 8BBC519F2BFDE36C005EB184 /* MusicCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BBC519E2BFDE36C005EB184 /* MusicCollectionViewCell.swift */; }; + 8BBC51A12BFEF664005EB184 /* SearchResultsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BBC51A02BFEF664005EB184 /* SearchResultsViewController.swift */; }; + 8BBC51A32BFEFFCB005EB184 /* MusicImageCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BBC51A22BFEFFCA005EB184 /* MusicImageCollectionViewCell.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 8BBC515F2BFD1A4D005EB184 /* MusicSearch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MusicSearch.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 8BBC51622BFD1A4D005EB184 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 8BBC51642BFD1A4D005EB184 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 8BBC51662BFD1A4D005EB184 /* SearchMusicViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchMusicViewController.swift; sourceTree = ""; }; + 8BBC51692BFD1A4D005EB184 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 8BBC516B2BFD1A4E005EB184 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 8BBC516E2BFD1A4E005EB184 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 8BBC51702BFD1A4E005EB184 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 8BBC51762BFD1C52005EB184 /* MusicInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MusicInfo.swift; sourceTree = ""; }; + 8BBC519E2BFDE36C005EB184 /* MusicCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MusicCollectionViewCell.swift; sourceTree = ""; }; + 8BBC51A02BFEF664005EB184 /* SearchResultsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultsViewController.swift; sourceTree = ""; }; + 8BBC51A22BFEFFCA005EB184 /* MusicImageCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MusicImageCollectionViewCell.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8BBC515C2BFD1A4D005EB184 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 8BBC51562BFD1A4C005EB184 = { + isa = PBXGroup; + children = ( + 8BBC51612BFD1A4D005EB184 /* MusicSearch */, + 8BBC51602BFD1A4D005EB184 /* Products */, + ); + sourceTree = ""; + }; + 8BBC51602BFD1A4D005EB184 /* Products */ = { + isa = PBXGroup; + children = ( + 8BBC515F2BFD1A4D005EB184 /* MusicSearch.app */, + ); + name = Products; + sourceTree = ""; + }; + 8BBC51612BFD1A4D005EB184 /* MusicSearch */ = { + isa = PBXGroup; + children = ( + 8BBC51622BFD1A4D005EB184 /* AppDelegate.swift */, + 8BBC51642BFD1A4D005EB184 /* SceneDelegate.swift */, + 8BBC51A02BFEF664005EB184 /* SearchResultsViewController.swift */, + 8BBC519E2BFDE36C005EB184 /* MusicCollectionViewCell.swift */, + 8BBC51762BFD1C52005EB184 /* MusicInfo.swift */, + 8BBC51A22BFEFFCA005EB184 /* MusicImageCollectionViewCell.swift */, + 8BBC51662BFD1A4D005EB184 /* SearchMusicViewController.swift */, + 8BBC51682BFD1A4D005EB184 /* Main.storyboard */, + 8BBC516B2BFD1A4E005EB184 /* Assets.xcassets */, + 8BBC516D2BFD1A4E005EB184 /* LaunchScreen.storyboard */, + 8BBC51702BFD1A4E005EB184 /* Info.plist */, + ); + path = MusicSearch; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 8BBC515E2BFD1A4D005EB184 /* MusicSearch */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8BBC51732BFD1A4E005EB184 /* Build configuration list for PBXNativeTarget "MusicSearch" */; + buildPhases = ( + 8BBC515B2BFD1A4D005EB184 /* Sources */, + 8BBC515C2BFD1A4D005EB184 /* Frameworks */, + 8BBC515D2BFD1A4D005EB184 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = MusicSearch; + productName = MusicSearch; + productReference = 8BBC515F2BFD1A4D005EB184 /* MusicSearch.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 8BBC51572BFD1A4C005EB184 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1540; + LastUpgradeCheck = 1540; + TargetAttributes = { + 8BBC515E2BFD1A4D005EB184 = { + CreatedOnToolsVersion = 15.4; + }; + }; + }; + buildConfigurationList = 8BBC515A2BFD1A4C005EB184 /* Build configuration list for PBXProject "MusicSearch" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 8BBC51562BFD1A4C005EB184; + productRefGroup = 8BBC51602BFD1A4D005EB184 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 8BBC515E2BFD1A4D005EB184 /* MusicSearch */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8BBC515D2BFD1A4D005EB184 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8BBC516C2BFD1A4E005EB184 /* Assets.xcassets in Resources */, + 8BBC516F2BFD1A4E005EB184 /* Base in Resources */, + 8BBC516A2BFD1A4D005EB184 /* Base in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8BBC515B2BFD1A4D005EB184 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8BBC51672BFD1A4D005EB184 /* SearchMusicViewController.swift in Sources */, + 8BBC51632BFD1A4D005EB184 /* AppDelegate.swift in Sources */, + 8BBC51A32BFEFFCB005EB184 /* MusicImageCollectionViewCell.swift in Sources */, + 8BBC51652BFD1A4D005EB184 /* SceneDelegate.swift in Sources */, + 8BBC519F2BFDE36C005EB184 /* MusicCollectionViewCell.swift in Sources */, + 8BBC51772BFD1C52005EB184 /* MusicInfo.swift in Sources */, + 8BBC51A12BFEF664005EB184 /* SearchResultsViewController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 8BBC51682BFD1A4D005EB184 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 8BBC51692BFD1A4D005EB184 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 8BBC516D2BFD1A4E005EB184 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 8BBC516E2BFD1A4E005EB184 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 8BBC51712BFD1A4E005EB184 /* 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 = 17.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; + }; + 8BBC51722BFD1A4E005EB184 /* 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 = 17.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; + }; + 8BBC51742BFD1A4E005EB184 /* 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_TEAM = S8YQN7N24J; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MusicSearch/Info.plist; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + 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 = org.appcenter.MusicSearch; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 8BBC51752BFD1A4E005EB184 /* 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_TEAM = S8YQN7N24J; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = MusicSearch/Info.plist; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + 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 = org.appcenter.MusicSearch; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 8BBC515A2BFD1A4C005EB184 /* Build configuration list for PBXProject "MusicSearch" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8BBC51712BFD1A4E005EB184 /* Debug */, + 8BBC51722BFD1A4E005EB184 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8BBC51732BFD1A4E005EB184 /* Build configuration list for PBXNativeTarget "MusicSearch" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8BBC51742BFD1A4E005EB184 /* Debug */, + 8BBC51752BFD1A4E005EB184 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 8BBC51572BFD1A4C005EB184 /* Project object */; +} diff --git a/hyeonseung/Study-Swift/MusicSearch/MusicSearch.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/hyeonseung/Study-Swift/MusicSearch/MusicSearch.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/hyeonseung/Study-Swift/MusicSearch/MusicSearch.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/hyeonseung/Study-Swift/MusicSearch/MusicSearch.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/hyeonseung/Study-Swift/MusicSearch/MusicSearch.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/hyeonseung/Study-Swift/MusicSearch/MusicSearch.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/hyeonseung/Study-Swift/MusicSearch/MusicSearch/AppDelegate.swift b/hyeonseung/Study-Swift/MusicSearch/MusicSearch/AppDelegate.swift new file mode 100644 index 0000000..5990fb4 --- /dev/null +++ b/hyeonseung/Study-Swift/MusicSearch/MusicSearch/AppDelegate.swift @@ -0,0 +1,36 @@ +// +// AppDelegate.swift +// MusicSearch +// +// Created by 한현승 on 5/22/24. +// + +import UIKit + +@main +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/hyeonseung/Study-Swift/MusicSearch/MusicSearch/Assets.xcassets/AccentColor.colorset/Contents.json b/hyeonseung/Study-Swift/MusicSearch/MusicSearch/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/hyeonseung/Study-Swift/MusicSearch/MusicSearch/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/hyeonseung/Study-Swift/MusicSearch/MusicSearch/Assets.xcassets/AppIcon.appiconset/Contents.json b/hyeonseung/Study-Swift/MusicSearch/MusicSearch/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..13613e3 --- /dev/null +++ b/hyeonseung/Study-Swift/MusicSearch/MusicSearch/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,13 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/hyeonseung/Study-Swift/MusicSearch/MusicSearch/Assets.xcassets/Contents.json b/hyeonseung/Study-Swift/MusicSearch/MusicSearch/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/hyeonseung/Study-Swift/MusicSearch/MusicSearch/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/hyeonseung/Study-Swift/MusicSearch/MusicSearch/Base.lproj/LaunchScreen.storyboard b/hyeonseung/Study-Swift/MusicSearch/MusicSearch/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/hyeonseung/Study-Swift/MusicSearch/MusicSearch/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hyeonseung/Study-Swift/MusicSearch/MusicSearch/Base.lproj/Main.storyboard b/hyeonseung/Study-Swift/MusicSearch/MusicSearch/Base.lproj/Main.storyboard new file mode 100644 index 0000000..07afca0 --- /dev/null +++ b/hyeonseung/Study-Swift/MusicSearch/MusicSearch/Base.lproj/Main.storyboard @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hyeonseung/Study-Swift/MusicSearch/MusicSearch/Info.plist b/hyeonseung/Study-Swift/MusicSearch/MusicSearch/Info.plist new file mode 100644 index 0000000..dd3c9af --- /dev/null +++ b/hyeonseung/Study-Swift/MusicSearch/MusicSearch/Info.plist @@ -0,0 +1,25 @@ + + + + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + UISceneStoryboardFile + Main + + + + + + diff --git a/hyeonseung/Study-Swift/MusicSearch/MusicSearch/MusicCollectionViewCell.swift b/hyeonseung/Study-Swift/MusicSearch/MusicSearch/MusicCollectionViewCell.swift new file mode 100644 index 0000000..ad4cf2a --- /dev/null +++ b/hyeonseung/Study-Swift/MusicSearch/MusicSearch/MusicCollectionViewCell.swift @@ -0,0 +1,50 @@ +// +// MusicCollectionViewCell.swift +// MusicSearch +// +// Created by 한현승 on 5/22/24. +// + +import UIKit + +final class MusicCollectionViewCell: UICollectionViewCell { + + @IBOutlet var musicImage: UIImageView! + @IBOutlet weak var title: UILabel! + @IBOutlet weak var artist: UILabel! + @IBOutlet weak var collectionTitle: UILabel! + @IBOutlet weak var releaseDate: UILabel! + + + func configure(music: Music){ + self.title.text = music.trackName + self.artist.text = music.artistName + self.collectionTitle.text = music.collectionName + + let outputDateFormat = DateFormatter() + outputDateFormat.dateFormat = "yyyy-MM-dd" + + let inputDateFormat = DateFormatter() + inputDateFormat.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" + + if let date = inputDateFormat.date(from: music.releaseDate){ + self.releaseDate.text = outputDateFormat.string(from: date) + }else{ + self.releaseDate.text = music.releaseDate + } + + Task{ + if let url = URL(string: music.artworkUrl100){ + let (data, _) = try await URLSession.shared.data(from: url) + DispatchQueue.main.async { + guard let image = UIImage(data: data) else {return} + self.musicImage.image = image + } + } + + } + + } + +} + diff --git a/hyeonseung/Study-Swift/MusicSearch/MusicSearch/MusicImageCollectionViewCell.swift b/hyeonseung/Study-Swift/MusicSearch/MusicSearch/MusicImageCollectionViewCell.swift new file mode 100644 index 0000000..39372f6 --- /dev/null +++ b/hyeonseung/Study-Swift/MusicSearch/MusicSearch/MusicImageCollectionViewCell.swift @@ -0,0 +1,49 @@ +// +// MusicImageCollectionViewCell.swift +// MusicSearch +// +// Created by 한현승 on 5/23/24. +// + +import UIKit + +final class MusicImageCollectionViewCell: UICollectionViewCell { + + let musicImage: UIImageView = { + let imageView = UIImageView() + imageView.translatesAutoresizingMaskIntoConstraints = false + imageView.contentMode = .scaleAspectFill + imageView.clipsToBounds = true + return imageView + }() + + func configure(music: Music){ + Task{ + if let url = URL(string: music.artworkUrl100){ + let (data, _) = try await URLSession.shared.data(from: url) + DispatchQueue.main.async { + guard let image = UIImage(data: data) else {return} + self.musicImage.image = image + } + + } + } + } + + override init(frame: CGRect) { + super.init(frame: frame) + contentView.addSubview(musicImage) + + NSLayoutConstraint.activate([ + musicImage.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 1), + musicImage.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 1), + musicImage.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -1), + musicImage.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -1) + ]) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} + diff --git a/hyeonseung/Study-Swift/MusicSearch/MusicSearch/MusicInfo.swift b/hyeonseung/Study-Swift/MusicSearch/MusicSearch/MusicInfo.swift new file mode 100644 index 0000000..3b98f33 --- /dev/null +++ b/hyeonseung/Study-Swift/MusicSearch/MusicSearch/MusicInfo.swift @@ -0,0 +1,25 @@ +// +// MusicInfo.swift +// MusicSearch +// +// Created by 한현승 on 5/22/24. +// + +import Foundation + + +// Swift <-> JSON +struct MusicInfo: Codable { + var resultCount: Int + var results: [Music] +} + + +struct Music: Codable { + var artworkUrl60: String + var artworkUrl100: String + var trackName: String + var artistName: String + var collectionName: String + var releaseDate: String +} diff --git a/hyeonseung/Study-Swift/MusicSearch/MusicSearch/SceneDelegate.swift b/hyeonseung/Study-Swift/MusicSearch/MusicSearch/SceneDelegate.swift new file mode 100644 index 0000000..c14d428 --- /dev/null +++ b/hyeonseung/Study-Swift/MusicSearch/MusicSearch/SceneDelegate.swift @@ -0,0 +1,52 @@ +// +// SceneDelegate.swift +// MusicSearch +// +// Created by 한현승 on 5/22/24. +// + +import UIKit + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + guard let _ = (scene as? UIWindowScene) else { return } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} + diff --git a/hyeonseung/Study-Swift/MusicSearch/MusicSearch/SearchMusicViewController.swift b/hyeonseung/Study-Swift/MusicSearch/MusicSearch/SearchMusicViewController.swift new file mode 100644 index 0000000..dbbfd34 --- /dev/null +++ b/hyeonseung/Study-Swift/MusicSearch/MusicSearch/SearchMusicViewController.swift @@ -0,0 +1,138 @@ +// +// ViewController.swift +// MusicSearch +// +// Created by 한현승 on 5/22/24. +// + +import UIKit + +final class SearchMusicViewController: UIViewController { + + var musicData: [Music] = [] + var searchController = UISearchController(searchResultsController: nil) + var resultsViewController: SearchResultsViewController! + + @IBOutlet weak var collectionView: UICollectionView! + + override func viewDidLoad() { + super.viewDidLoad() + + + collectionView.dataSource = self + collectionView.delegate = self + // searchBar.delegate = self + + resultsViewController = SearchResultsViewController() + searchController = UISearchController(searchResultsController: resultsViewController) + searchController.searchResultsUpdater = self + searchController.obscuresBackgroundDuringPresentation = false + searchController.searchBar.placeholder = "Search" + navigationItem.title = "Music Search" + navigationItem.searchController = searchController + definesPresentationContext = true + + Task{ + await fetchData(searchTerm: "jazz") + } + + + if let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout { + layout.scrollDirection = .vertical + layout.minimumLineSpacing = 0 + layout.minimumInteritemSpacing = 0 + + } +} + + + func fetchData(searchTerm: String?) async { + let term: String + if let searchTerm = searchTerm, !searchTerm.isEmpty { + term = searchTerm + } + else { + term = "jack+johnson" + } + + guard let url = URL(string: "https://itunes.apple.com/search?media=music&term=\(term)") else {return} + print(url) + do { + let( data, _) = try await URLSession.shared.data(from: url) + let musicInfo = try JSONDecoder().decode(MusicInfo.self, from: data) + self.musicData = musicInfo.results + }catch { + print("error >> \(error)") + } + DispatchQueue.main.async { + self.collectionView.reloadData() + } + } + +} + + +extension SearchMusicViewController: UISearchResultsUpdating{ + + func updateSearchResults(for searchController: UISearchController) { + guard let text = searchController.searchBar.text else {return} + + + print(text) + Task { + await fetchData(searchTerm: text) + if let resultsVC = searchController.searchResultsController as? SearchResultsViewController { + resultsVC.updateData(with: self.musicData) + } + + } + + +// if let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout{ +// +// let width = (collectionView.frame.width - 3 ) / 3 +// print("keyword 변경 \(width)") +// layout.itemSize = CGSize(width: width, height: 130) +// +// layout.invalidateLayout() +// } + } + +} + + + +extension SearchMusicViewController: UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout { + // 어떻게 표현할건지 -> Cell 사용 + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MusicCollectionViewCell.identifier, for: indexPath) as? MusicCollectionViewCell else { + return UICollectionViewCell() + } + + let music = musicData[indexPath.item] + cell.configure(music: music) + return cell + } + + // 몇개의 데이터가 들어오는지 + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + + return musicData.count + } + + + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { + + return CGSize(width: collectionView.frame.width , height: 130) + + } + + +} + + +extension MusicCollectionViewCell { + static var identifier: String{ + return String(describing: self) + } +} diff --git a/hyeonseung/Study-Swift/MusicSearch/MusicSearch/SearchResultsViewController.swift b/hyeonseung/Study-Swift/MusicSearch/MusicSearch/SearchResultsViewController.swift new file mode 100644 index 0000000..e6107a9 --- /dev/null +++ b/hyeonseung/Study-Swift/MusicSearch/MusicSearch/SearchResultsViewController.swift @@ -0,0 +1,83 @@ +// +// SearchMusicDetailViewController.swift +// MusicSearch +// +// Created by 한현승 on 5/23/24. +// + +import UIKit + +final class SearchResultsViewController: UIViewController { + + var musicData: [Music] = [] + + var collectionView: UICollectionView! + + override func viewDidLoad() { + super.viewDidLoad() + + let layout = UICollectionViewFlowLayout() + layout.scrollDirection = .vertical + layout.minimumLineSpacing = 1 + layout.minimumInteritemSpacing = 1 + + //self.view.bounds + collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) + collectionView.translatesAutoresizingMaskIntoConstraints = false + collectionView.dataSource = self + collectionView.delegate = self + collectionView.register(MusicImageCollectionViewCell.self, forCellWithReuseIdentifier: MusicImageCollectionViewCell.identifier) + + self.view.addSubview(collectionView) + + + NSLayoutConstraint.activate([ + collectionView.topAnchor.constraint(equalTo: view.topAnchor), + collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor) + ]) + } + + func updateData(with musicData: [Music]){ + self.musicData = musicData + self.collectionView.reloadData() + } + + +} + +extension SearchResultsViewController: UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout{ + + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return musicData.count + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + + guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MusicImageCollectionViewCell.identifier, for: indexPath) as? MusicImageCollectionViewCell else { + return UICollectionViewCell() + } + + let music = musicData[indexPath.item] + cell.configure(music: music) + return cell + } + + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { + + let width = (collectionView.frame.width - 2 ) / 3 + + return CGSize(width: width , height: width) + + } + + + +} + +extension MusicImageCollectionViewCell { + static var identifier: String{ + return String(describing: self) + } +} diff --git a/hyeonseung/Study-Swift/MusicSearch/README.md b/hyeonseung/Study-Swift/MusicSearch/README.md new file mode 100644 index 0000000..45bec7e --- /dev/null +++ b/hyeonseung/Study-Swift/MusicSearch/README.md @@ -0,0 +1,24 @@ +# 음악 검색 앱 구현 + +## 주요 기능 - 네트워크 통신 +- 애플 뮤직(itunes) API +GET 방식으로 사용 +`https://itunes.apple.com/search?media=music&term={searchTerm}` +- 동기/ 비동기 + `@escaping closure` 를 사용하지 않고 `async, await` 사용 +- `URLSession` + +## Flow +

+ +## 시연 화면 +### 영상 + +https://github.com/inu-appcenter/iOS-study-16th/assets/109841880/db570ae2-72e8-400d-a99a-7b20476ef2e7 + +### 초기화면 +

+ +### 검색화면 +

+