From 938e876a839601129882c2884df91874c77d097b Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Thu, 29 Dec 2022 16:32:47 +0900 Subject: [PATCH 1/7] =?UTF-8?q?[Setting]=20#1=20-=20.gitignore=EC=97=90=20?= =?UTF-8?q?.DS=5FStore=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 2de5e93b..33136889 100644 --- a/.gitignore +++ b/.gitignore @@ -106,4 +106,5 @@ iOSInjectionProject/ /*.gcno **/xcshareddata/WorkspaceSettings.xcsettings -# End of https://www.toptal.com/developers/gitignore/api/xcode,swift,cocoapods \ No newline at end of file +# End of https://www.toptal.com/developers/gitignore/api/xcode,swift,cocoapods +.DS_Store From 97f05eaeda2c831865ef1b2394c4944a5a0ffe33 Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Thu, 29 Dec 2022 16:40:39 +0900 Subject: [PATCH 2/7] =?UTF-8?q?[Setting]=20#1=20-=20Xcode=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=EC=A0=9D=ED=8A=B8=20=EC=83=9D=EC=84=B1=20=EB=B0=8F=20?= =?UTF-8?q?iOS=20=EB=B2=84=EC=A0=84=2014.0=EC=9C=BC=EB=A1=9C=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Runnect-iOS.xcodeproj/project.pbxproj | 361 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + Runnect-iOS/Runnect-iOS/AppDelegate.swift | 36 ++ .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 13 + .../Runnect-iOS/Assets.xcassets/Contents.json | 6 + .../Base.lproj/LaunchScreen.storyboard | 25 ++ .../Runnect-iOS/Base.lproj/Main.storyboard | 24 ++ Runnect-iOS/Runnect-iOS/Info.plist | 25 ++ Runnect-iOS/Runnect-iOS/SceneDelegate.swift | 52 +++ Runnect-iOS/Runnect-iOS/ViewController.swift | 19 + 12 files changed, 587 insertions(+) create mode 100644 Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj create mode 100644 Runnect-iOS/Runnect-iOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 Runnect-iOS/Runnect-iOS.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 Runnect-iOS/Runnect-iOS/AppDelegate.swift create mode 100644 Runnect-iOS/Runnect-iOS/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 Runnect-iOS/Runnect-iOS/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 Runnect-iOS/Runnect-iOS/Assets.xcassets/Contents.json create mode 100644 Runnect-iOS/Runnect-iOS/Base.lproj/LaunchScreen.storyboard create mode 100644 Runnect-iOS/Runnect-iOS/Base.lproj/Main.storyboard create mode 100644 Runnect-iOS/Runnect-iOS/Info.plist create mode 100644 Runnect-iOS/Runnect-iOS/SceneDelegate.swift create mode 100644 Runnect-iOS/Runnect-iOS/ViewController.swift diff --git a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj new file mode 100644 index 00000000..95355fc6 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj @@ -0,0 +1,361 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 56; + objects = { + +/* Begin PBXBuildFile section */ + CE4545C9295D7AF4003201E1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4545C8295D7AF4003201E1 /* AppDelegate.swift */; }; + CE4545CB295D7AF4003201E1 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4545CA295D7AF4003201E1 /* SceneDelegate.swift */; }; + CE4545CD295D7AF4003201E1 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4545CC295D7AF4003201E1 /* ViewController.swift */; }; + CE4545D0295D7AF4003201E1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CE4545CE295D7AF4003201E1 /* Main.storyboard */; }; + CE4545D2295D7AF5003201E1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CE4545D1295D7AF5003201E1 /* Assets.xcassets */; }; + CE4545D5295D7AF5003201E1 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CE4545D3295D7AF5003201E1 /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + CE4545C5295D7AF4003201E1 /* Runnect-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Runnect-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + CE4545C8295D7AF4003201E1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + CE4545CA295D7AF4003201E1 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + CE4545CC295D7AF4003201E1 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + CE4545CF295D7AF4003201E1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + CE4545D1295D7AF5003201E1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + CE4545D4295D7AF5003201E1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + CE4545D6295D7AF5003201E1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + CE4545C2295D7AF4003201E1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + CE4545BC295D7AF4003201E1 = { + isa = PBXGroup; + children = ( + CE4545C7295D7AF4003201E1 /* Runnect-iOS */, + CE4545C6295D7AF4003201E1 /* Products */, + ); + sourceTree = ""; + }; + CE4545C6295D7AF4003201E1 /* Products */ = { + isa = PBXGroup; + children = ( + CE4545C5295D7AF4003201E1 /* Runnect-iOS.app */, + ); + name = Products; + sourceTree = ""; + }; + CE4545C7295D7AF4003201E1 /* Runnect-iOS */ = { + isa = PBXGroup; + children = ( + CE4545C8295D7AF4003201E1 /* AppDelegate.swift */, + CE4545CA295D7AF4003201E1 /* SceneDelegate.swift */, + CE4545CC295D7AF4003201E1 /* ViewController.swift */, + CE4545CE295D7AF4003201E1 /* Main.storyboard */, + CE4545D1295D7AF5003201E1 /* Assets.xcassets */, + CE4545D3295D7AF5003201E1 /* LaunchScreen.storyboard */, + CE4545D6295D7AF5003201E1 /* Info.plist */, + ); + path = "Runnect-iOS"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + CE4545C4295D7AF4003201E1 /* Runnect-iOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = CE4545D9295D7AF5003201E1 /* Build configuration list for PBXNativeTarget "Runnect-iOS" */; + buildPhases = ( + CE4545C1295D7AF4003201E1 /* Sources */, + CE4545C2295D7AF4003201E1 /* Frameworks */, + CE4545C3295D7AF4003201E1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Runnect-iOS"; + productName = "Runnect-iOS"; + productReference = CE4545C5295D7AF4003201E1 /* Runnect-iOS.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + CE4545BD295D7AF4003201E1 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1410; + LastUpgradeCheck = 1410; + TargetAttributes = { + CE4545C4295D7AF4003201E1 = { + CreatedOnToolsVersion = 14.1; + }; + }; + }; + buildConfigurationList = CE4545C0295D7AF4003201E1 /* Build configuration list for PBXProject "Runnect-iOS" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = CE4545BC295D7AF4003201E1; + productRefGroup = CE4545C6295D7AF4003201E1 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + CE4545C4295D7AF4003201E1 /* Runnect-iOS */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + CE4545C3295D7AF4003201E1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CE4545D5295D7AF5003201E1 /* LaunchScreen.storyboard in Resources */, + CE4545D2295D7AF5003201E1 /* Assets.xcassets in Resources */, + CE4545D0295D7AF4003201E1 /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + CE4545C1295D7AF4003201E1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CE4545CD295D7AF4003201E1 /* ViewController.swift in Sources */, + CE4545C9295D7AF4003201E1 /* AppDelegate.swift in Sources */, + CE4545CB295D7AF4003201E1 /* SceneDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + CE4545CE295D7AF4003201E1 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + CE4545CF295D7AF4003201E1 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + CE4545D3295D7AF5003201E1 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + CE4545D4295D7AF5003201E1 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + CE4545D7295D7AF5003201E1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++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; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + CE4545D8295D7AF5003201E1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++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; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + CE4545DA295D7AF5003201E1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "Runnect-iOS/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 = "com.runnect.Runnect-iOS"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + CE4545DB295D7AF5003201E1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "Runnect-iOS/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 = "com.runnect.Runnect-iOS"; + 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 */ + CE4545C0295D7AF4003201E1 /* Build configuration list for PBXProject "Runnect-iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CE4545D7295D7AF5003201E1 /* Debug */, + CE4545D8295D7AF5003201E1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + CE4545D9295D7AF5003201E1 /* Build configuration list for PBXNativeTarget "Runnect-iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CE4545DA295D7AF5003201E1 /* Debug */, + CE4545DB295D7AF5003201E1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = CE4545BD295D7AF4003201E1 /* Project object */; +} diff --git a/Runnect-iOS/Runnect-iOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Runnect-iOS/Runnect-iOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..919434a6 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Runnect-iOS/Runnect-iOS.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Runnect-iOS/Runnect-iOS.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Runnect-iOS/Runnect-iOS/AppDelegate.swift b/Runnect-iOS/Runnect-iOS/AppDelegate.swift new file mode 100644 index 00000000..3acc8543 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/AppDelegate.swift @@ -0,0 +1,36 @@ +// +// AppDelegate.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +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/Runnect-iOS/Runnect-iOS/Assets.xcassets/AccentColor.colorset/Contents.json b/Runnect-iOS/Runnect-iOS/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 00000000..eb878970 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Runnect-iOS/Runnect-iOS/Assets.xcassets/AppIcon.appiconset/Contents.json b/Runnect-iOS/Runnect-iOS/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..13613e3e --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/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/Runnect-iOS/Runnect-iOS/Assets.xcassets/Contents.json b/Runnect-iOS/Runnect-iOS/Assets.xcassets/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Runnect-iOS/Runnect-iOS/Base.lproj/LaunchScreen.storyboard b/Runnect-iOS/Runnect-iOS/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..865e9329 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Runnect-iOS/Runnect-iOS/Base.lproj/Main.storyboard b/Runnect-iOS/Runnect-iOS/Base.lproj/Main.storyboard new file mode 100644 index 00000000..25a76385 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Base.lproj/Main.storyboard @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Runnect-iOS/Runnect-iOS/Info.plist b/Runnect-iOS/Runnect-iOS/Info.plist new file mode 100644 index 00000000..dd3c9afd --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Info.plist @@ -0,0 +1,25 @@ + + + + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + UISceneStoryboardFile + Main + + + + + + diff --git a/Runnect-iOS/Runnect-iOS/SceneDelegate.swift b/Runnect-iOS/Runnect-iOS/SceneDelegate.swift new file mode 100644 index 00000000..9300673c --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/SceneDelegate.swift @@ -0,0 +1,52 @@ +// +// SceneDelegate.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +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/Runnect-iOS/Runnect-iOS/ViewController.swift b/Runnect-iOS/Runnect-iOS/ViewController.swift new file mode 100644 index 00000000..123c3e6c --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/ViewController.swift @@ -0,0 +1,19 @@ +// +// ViewController.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import UIKit + +class ViewController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view. + } + + +} + From 172d73ba249b56e3e26311ce179fdac96a66e863 Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Thu, 29 Dec 2022 16:51:23 +0900 Subject: [PATCH 3/7] =?UTF-8?q?[Setting]=20#1=20-=20=EB=9D=BC=EC=9D=B4?= =?UTF-8?q?=EB=B8=8C=EB=9F=AC=EB=A6=AC=20=EC=84=A4=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Moya, SnapKit, NMapsMap, Kingfisher --- Runnect-iOS/Podfile | 16 +++++ Runnect-iOS/Podfile.lock | 38 ++++++++++ .../Runnect-iOS.xcodeproj/project.pbxproj | 71 +++++++++++++++++++ .../contents.xcworkspacedata | 10 +++ .../xcshareddata/IDEWorkspaceChecks.plist | 8 +++ Runnect-iOS/Runnect-iOS/ViewController.swift | 2 +- 6 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 Runnect-iOS/Podfile create mode 100644 Runnect-iOS/Podfile.lock create mode 100644 Runnect-iOS/Runnect-iOS.xcworkspace/contents.xcworkspacedata create mode 100644 Runnect-iOS/Runnect-iOS.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/Runnect-iOS/Podfile b/Runnect-iOS/Podfile new file mode 100644 index 00000000..f82d3dbf --- /dev/null +++ b/Runnect-iOS/Podfile @@ -0,0 +1,16 @@ +# Uncomment the next line to define a global platform for your project +platform :ios, '14.0' + +target 'Runnect-iOS' do + # Comment the next line if you don't want to use dynamic frameworks + use_frameworks! + + pod 'NMapsMap' + pod 'Kingfisher', '~> 7.0' + pod 'SnapKit', '~> 5.6.0' + pod 'Moya', '~> 15.0' + + + # Pods for Runnect-iOS + +end diff --git a/Runnect-iOS/Podfile.lock b/Runnect-iOS/Podfile.lock new file mode 100644 index 00000000..f73983c6 --- /dev/null +++ b/Runnect-iOS/Podfile.lock @@ -0,0 +1,38 @@ +PODS: + - Alamofire (5.6.4) + - Kingfisher (7.4.1) + - Moya (15.0.0): + - Moya/Core (= 15.0.0) + - Moya/Core (15.0.0): + - Alamofire (~> 5.0) + - NMapsGeometry (1.0.1) + - NMapsMap (3.16.1): + - NMapsGeometry + - SnapKit (5.6.0) + +DEPENDENCIES: + - Kingfisher (~> 7.0) + - Moya (~> 15.0) + - NMapsMap + - SnapKit (~> 5.6.0) + +SPEC REPOS: + trunk: + - Alamofire + - Kingfisher + - Moya + - NMapsGeometry + - NMapsMap + - SnapKit + +SPEC CHECKSUMS: + Alamofire: 4e95d97098eacb88856099c4fc79b526a299e48c + Kingfisher: cd762a593a61b2fbecf7645c00f9a801a3ebfc9c + Moya: 138f0573e53411fb3dc17016add0b748dfbd78ee + NMapsGeometry: 53c573ead66466681cf123f99f698dc8071a4b83 + NMapsMap: 926c3a303d381a24bec8da3cd6e198f50af93ae9 + SnapKit: e01d52ebb8ddbc333eefe2132acf85c8227d9c25 + +PODFILE CHECKSUM: f23513cb80e72754bbf29355e1160abe4b35c783 + +COCOAPODS: 1.11.3 diff --git a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj index 95355fc6..a1343778 100644 --- a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj +++ b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 0AEBD608F3973389E8E1C6D6 /* Pods_Runnect_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 015778D02D5CDE0838284CD7 /* Pods_Runnect_iOS.framework */; }; CE4545C9295D7AF4003201E1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4545C8295D7AF4003201E1 /* AppDelegate.swift */; }; CE4545CB295D7AF4003201E1 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4545CA295D7AF4003201E1 /* SceneDelegate.swift */; }; CE4545CD295D7AF4003201E1 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4545CC295D7AF4003201E1 /* ViewController.swift */; }; @@ -16,6 +17,8 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 015778D02D5CDE0838284CD7 /* Pods_Runnect_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runnect_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 3C3033C911343B5C57EB68E7 /* Pods-Runnect-iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runnect-iOS.debug.xcconfig"; path = "Target Support Files/Pods-Runnect-iOS/Pods-Runnect-iOS.debug.xcconfig"; sourceTree = ""; }; CE4545C5295D7AF4003201E1 /* Runnect-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Runnect-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; CE4545C8295D7AF4003201E1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; CE4545CA295D7AF4003201E1 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -24,6 +27,7 @@ CE4545D1295D7AF5003201E1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; CE4545D4295D7AF5003201E1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; CE4545D6295D7AF5003201E1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E837271A78E1C0A0C30789BF /* Pods-Runnect-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runnect-iOS.release.xcconfig"; path = "Target Support Files/Pods-Runnect-iOS/Pods-Runnect-iOS.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -31,17 +35,38 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 0AEBD608F3973389E8E1C6D6 /* Pods_Runnect_iOS.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 3F7098551CF7A77F3FE7EB2B /* Pods */ = { + isa = PBXGroup; + children = ( + 3C3033C911343B5C57EB68E7 /* Pods-Runnect-iOS.debug.xcconfig */, + E837271A78E1C0A0C30789BF /* Pods-Runnect-iOS.release.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; + 4BAB0487E0060209ADC1C28C /* Frameworks */ = { + isa = PBXGroup; + children = ( + 015778D02D5CDE0838284CD7 /* Pods_Runnect_iOS.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; CE4545BC295D7AF4003201E1 = { isa = PBXGroup; children = ( CE4545C7295D7AF4003201E1 /* Runnect-iOS */, CE4545C6295D7AF4003201E1 /* Products */, + 3F7098551CF7A77F3FE7EB2B /* Pods */, + 4BAB0487E0060209ADC1C28C /* Frameworks */, ); sourceTree = ""; }; @@ -74,9 +99,11 @@ isa = PBXNativeTarget; buildConfigurationList = CE4545D9295D7AF5003201E1 /* Build configuration list for PBXNativeTarget "Runnect-iOS" */; buildPhases = ( + 5E54A0A4C236151ED373DD47 /* [CP] Check Pods Manifest.lock */, CE4545C1295D7AF4003201E1 /* Sources */, CE4545C2295D7AF4003201E1 /* Frameworks */, CE4545C3295D7AF4003201E1 /* Resources */, + CF0A7C4CF1329EF14A755C46 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -133,6 +160,48 @@ }; /* End PBXResourcesBuildPhase section */ +/* Begin PBXShellScriptBuildPhase section */ + 5E54A0A4C236151ED373DD47 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runnect-iOS-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + CF0A7C4CF1329EF14A755C46 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runnect-iOS/Pods-Runnect-iOS-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runnect-iOS/Pods-Runnect-iOS-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runnect-iOS/Pods-Runnect-iOS-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ CE4545C1295D7AF4003201E1 /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -282,6 +351,7 @@ }; CE4545DA295D7AF5003201E1 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 3C3033C911343B5C57EB68E7 /* Pods-Runnect-iOS.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; @@ -309,6 +379,7 @@ }; CE4545DB295D7AF5003201E1 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = E837271A78E1C0A0C30789BF /* Pods-Runnect-iOS.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; diff --git a/Runnect-iOS/Runnect-iOS.xcworkspace/contents.xcworkspacedata b/Runnect-iOS/Runnect-iOS.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..07cc0133 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Runnect-iOS/Runnect-iOS.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Runnect-iOS/Runnect-iOS.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Runnect-iOS/Runnect-iOS/ViewController.swift b/Runnect-iOS/Runnect-iOS/ViewController.swift index 123c3e6c..0b971380 100644 --- a/Runnect-iOS/Runnect-iOS/ViewController.swift +++ b/Runnect-iOS/Runnect-iOS/ViewController.swift @@ -11,7 +11,7 @@ class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - // Do any additional setup after loading the view. + view.backgroundColor = .blue } From 857003d34b69a24cce0d45c0fd38d111385babae Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Thu, 29 Dec 2022 17:14:17 +0900 Subject: [PATCH 4/7] =?UTF-8?q?[Setting]=20#1=20-=20=ED=8F=B4=EB=8D=94?= =?UTF-8?q?=EB=A7=81=20=EB=B0=8F=20Main.storyboard=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Runnect-iOS.xcodeproj/project.pbxproj | 191 ++++++++++++++++-- .../Runnect-iOS/Base.lproj/Main.storyboard | 24 --- .../Runnect-iOS/Global/Extension/.gitkeep | 0 .../Runnect-iOS/Global/Literal/.gitkeep | 0 .../AccentColor.colorset/Contents.json | 0 .../AppIcon.appiconset/Contents.json | 0 .../Resource}/Assets.xcassets/Contents.json | 0 .../{ => Global/Supports}/AppDelegate.swift | 0 .../Base.lproj/LaunchScreen.storyboard | 0 .../{ => Global/Supports}/SceneDelegate.swift | 10 +- .../Runnect-iOS/Global/UIComponents/.gitkeep | 1 + Runnect-iOS/Runnect-iOS/Global/Utils/.gitkeep | 0 Runnect-iOS/Runnect-iOS/Info.plist | 2 - Runnect-iOS/Runnect-iOS/Network/Dto/.gitkeep | 0 .../Runnect-iOS/Network/Foundation/.gitkeep | 0 .../Runnect-iOS/Network/Model/.gitkeep | 0 .../Runnect-iOS/Network/Router/.gitkeep | 0 .../Runnect-iOS/Network/Service/.gitkeep | 0 .../Presentation/SignIn/VC/.gitkeep | 0 .../Presentation/SignIn/Views/.gitkeep | 0 .../TabBar}/ViewController.swift | 0 21 files changed, 179 insertions(+), 49 deletions(-) delete mode 100644 Runnect-iOS/Runnect-iOS/Base.lproj/Main.storyboard create mode 100644 Runnect-iOS/Runnect-iOS/Global/Extension/.gitkeep create mode 100644 Runnect-iOS/Runnect-iOS/Global/Literal/.gitkeep rename Runnect-iOS/Runnect-iOS/{ => Global/Resource}/Assets.xcassets/AccentColor.colorset/Contents.json (100%) rename Runnect-iOS/Runnect-iOS/{ => Global/Resource}/Assets.xcassets/AppIcon.appiconset/Contents.json (100%) rename Runnect-iOS/Runnect-iOS/{ => Global/Resource}/Assets.xcassets/Contents.json (100%) rename Runnect-iOS/Runnect-iOS/{ => Global/Supports}/AppDelegate.swift (100%) rename Runnect-iOS/Runnect-iOS/{ => Global/Supports}/Base.lproj/LaunchScreen.storyboard (100%) rename Runnect-iOS/Runnect-iOS/{ => Global/Supports}/SceneDelegate.swift (80%) create mode 100644 Runnect-iOS/Runnect-iOS/Global/UIComponents/.gitkeep create mode 100644 Runnect-iOS/Runnect-iOS/Global/Utils/.gitkeep create mode 100644 Runnect-iOS/Runnect-iOS/Network/Dto/.gitkeep create mode 100644 Runnect-iOS/Runnect-iOS/Network/Foundation/.gitkeep create mode 100644 Runnect-iOS/Runnect-iOS/Network/Model/.gitkeep create mode 100644 Runnect-iOS/Runnect-iOS/Network/Router/.gitkeep create mode 100644 Runnect-iOS/Runnect-iOS/Network/Service/.gitkeep create mode 100644 Runnect-iOS/Runnect-iOS/Presentation/SignIn/VC/.gitkeep create mode 100644 Runnect-iOS/Runnect-iOS/Presentation/SignIn/Views/.gitkeep rename Runnect-iOS/Runnect-iOS/{ => Presentation/TabBar}/ViewController.swift (100%) diff --git a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj index a1343778..ccf9d184 100644 --- a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj +++ b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj @@ -11,9 +11,9 @@ CE4545C9295D7AF4003201E1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4545C8295D7AF4003201E1 /* AppDelegate.swift */; }; CE4545CB295D7AF4003201E1 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4545CA295D7AF4003201E1 /* SceneDelegate.swift */; }; CE4545CD295D7AF4003201E1 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4545CC295D7AF4003201E1 /* ViewController.swift */; }; - CE4545D0295D7AF4003201E1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CE4545CE295D7AF4003201E1 /* Main.storyboard */; }; CE4545D2295D7AF5003201E1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CE4545D1295D7AF5003201E1 /* Assets.xcassets */; }; CE4545D5295D7AF5003201E1 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CE4545D3295D7AF5003201E1 /* LaunchScreen.storyboard */; }; + CE6655BF295D82E200C64E12 /* .gitkeep in Resources */ = {isa = PBXBuildFile; fileRef = CE6655BE295D82E200C64E12 /* .gitkeep */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -23,10 +23,20 @@ CE4545C8295D7AF4003201E1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; CE4545CA295D7AF4003201E1 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; CE4545CC295D7AF4003201E1 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; - CE4545CF295D7AF4003201E1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; CE4545D1295D7AF5003201E1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; CE4545D4295D7AF5003201E1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; CE4545D6295D7AF5003201E1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + CE6655B8295D81C900C64E12 /* .gitkeep */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitkeep; sourceTree = ""; }; + CE6655B9295D82A100C64E12 /* .gitkeep */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitkeep; sourceTree = ""; }; + CE6655BA295D82BF00C64E12 /* .gitkeep */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitkeep; sourceTree = ""; }; + CE6655BB295D82C600C64E12 /* .gitkeep */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitkeep; sourceTree = ""; }; + CE6655BC295D82CF00C64E12 /* .gitkeep */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitkeep; sourceTree = ""; }; + CE6655BD295D82D800C64E12 /* .gitkeep */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitkeep; sourceTree = ""; }; + CE6655BE295D82E200C64E12 /* .gitkeep */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitkeep; sourceTree = ""; }; + CE6655C0295D82F000C64E12 /* .gitkeep */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitkeep; sourceTree = ""; }; + CE6655C1295D82F700C64E12 /* .gitkeep */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitkeep; sourceTree = ""; }; + CE6655C5295D83B700C64E12 /* .gitkeep */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitkeep; sourceTree = ""; }; + CE6655C6295D83BD00C64E12 /* .gitkeep */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitkeep; sourceTree = ""; }; E837271A78E1C0A0C30789BF /* Pods-Runnect-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runnect-iOS.release.xcconfig"; path = "Target Support Files/Pods-Runnect-iOS/Pods-Runnect-iOS.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -48,7 +58,6 @@ 3C3033C911343B5C57EB68E7 /* Pods-Runnect-iOS.debug.xcconfig */, E837271A78E1C0A0C30789BF /* Pods-Runnect-iOS.release.xcconfig */, ); - name = Pods; path = Pods; sourceTree = ""; }; @@ -81,15 +90,169 @@ CE4545C7295D7AF4003201E1 /* Runnect-iOS */ = { isa = PBXGroup; children = ( + CE6655AA295D7FAE00C64E12 /* Global */, + CE6655A9295D7FAA00C64E12 /* Network */, + CE6655A8295D7F7D00C64E12 /* Presentation */, + CE4545D6295D7AF5003201E1 /* Info.plist */, + ); + path = "Runnect-iOS"; + sourceTree = ""; + }; + CE6655A8295D7F7D00C64E12 /* Presentation */ = { + isa = PBXGroup; + children = ( + CE6655AB295D7FBC00C64E12 /* TabBar */, + CE6655C2295D836D00C64E12 /* SignIn */, + ); + path = Presentation; + sourceTree = ""; + }; + CE6655A9295D7FAA00C64E12 /* Network */ = { + isa = PBXGroup; + children = ( + CE6655B0295D800700C64E12 /* Dto */, + CE6655AF295D7FF600C64E12 /* Foundation */, + CE6655AE295D7FF000C64E12 /* Service */, + CE6655AD295D7FEA00C64E12 /* Router */, + CE6655AC295D7FE400C64E12 /* Model */, + ); + path = Network; + sourceTree = ""; + }; + CE6655AA295D7FAE00C64E12 /* Global */ = { + isa = PBXGroup; + children = ( + CE6655B6295D803C00C64E12 /* UIComponents */, + CE6655B5295D803800C64E12 /* Literal */, + CE6655B4295D803400C64E12 /* Resource */, + CE6655B3295D802800C64E12 /* Supports */, + CE6655B2295D801A00C64E12 /* Extension */, + CE6655B1295D801700C64E12 /* Utils */, + ); + path = Global; + sourceTree = ""; + }; + CE6655AB295D7FBC00C64E12 /* TabBar */ = { + isa = PBXGroup; + children = ( + CE4545CC295D7AF4003201E1 /* ViewController.swift */, + ); + path = TabBar; + sourceTree = ""; + }; + CE6655AC295D7FE400C64E12 /* Model */ = { + isa = PBXGroup; + children = ( + CE6655C1295D82F700C64E12 /* .gitkeep */, + ); + path = Model; + sourceTree = ""; + }; + CE6655AD295D7FEA00C64E12 /* Router */ = { + isa = PBXGroup; + children = ( + CE6655C0295D82F000C64E12 /* .gitkeep */, + ); + path = Router; + sourceTree = ""; + }; + CE6655AE295D7FF000C64E12 /* Service */ = { + isa = PBXGroup; + children = ( + CE6655BE295D82E200C64E12 /* .gitkeep */, + ); + path = Service; + sourceTree = ""; + }; + CE6655AF295D7FF600C64E12 /* Foundation */ = { + isa = PBXGroup; + children = ( + CE6655BD295D82D800C64E12 /* .gitkeep */, + ); + path = Foundation; + sourceTree = ""; + }; + CE6655B0295D800700C64E12 /* Dto */ = { + isa = PBXGroup; + children = ( + CE6655BC295D82CF00C64E12 /* .gitkeep */, + ); + path = Dto; + sourceTree = ""; + }; + CE6655B1295D801700C64E12 /* Utils */ = { + isa = PBXGroup; + children = ( + CE6655BB295D82C600C64E12 /* .gitkeep */, + ); + path = Utils; + sourceTree = ""; + }; + CE6655B2295D801A00C64E12 /* Extension */ = { + isa = PBXGroup; + children = ( + CE6655BA295D82BF00C64E12 /* .gitkeep */, + ); + path = Extension; + sourceTree = ""; + }; + CE6655B3295D802800C64E12 /* Supports */ = { + isa = PBXGroup; + children = ( + CE4545D3295D7AF5003201E1 /* LaunchScreen.storyboard */, CE4545C8295D7AF4003201E1 /* AppDelegate.swift */, CE4545CA295D7AF4003201E1 /* SceneDelegate.swift */, - CE4545CC295D7AF4003201E1 /* ViewController.swift */, - CE4545CE295D7AF4003201E1 /* Main.storyboard */, + ); + path = Supports; + sourceTree = ""; + }; + CE6655B4295D803400C64E12 /* Resource */ = { + isa = PBXGroup; + children = ( CE4545D1295D7AF5003201E1 /* Assets.xcassets */, - CE4545D3295D7AF5003201E1 /* LaunchScreen.storyboard */, - CE4545D6295D7AF5003201E1 /* Info.plist */, ); - path = "Runnect-iOS"; + path = Resource; + sourceTree = ""; + }; + CE6655B5295D803800C64E12 /* Literal */ = { + isa = PBXGroup; + children = ( + CE6655B9295D82A100C64E12 /* .gitkeep */, + ); + path = Literal; + sourceTree = ""; + }; + CE6655B6295D803C00C64E12 /* UIComponents */ = { + isa = PBXGroup; + children = ( + CE6655B8295D81C900C64E12 /* .gitkeep */, + ); + path = UIComponents; + sourceTree = ""; + }; + CE6655C2295D836D00C64E12 /* SignIn */ = { + isa = PBXGroup; + children = ( + CE6655C4295D838100C64E12 /* Views */, + CE6655C3295D837800C64E12 /* VC */, + ); + path = SignIn; + sourceTree = ""; + }; + CE6655C3295D837800C64E12 /* VC */ = { + isa = PBXGroup; + children = ( + CE6655C6295D83BD00C64E12 /* .gitkeep */, + ); + path = VC; + sourceTree = ""; + }; + CE6655C4295D838100C64E12 /* Views */ = { + isa = PBXGroup; + children = ( + CE6655C5295D83B700C64E12 /* .gitkeep */, + ); + path = Views; sourceTree = ""; }; /* End PBXGroup section */ @@ -152,9 +315,9 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + CE6655BF295D82E200C64E12 /* .gitkeep in Resources */, CE4545D5295D7AF5003201E1 /* LaunchScreen.storyboard in Resources */, CE4545D2295D7AF5003201E1 /* Assets.xcassets in Resources */, - CE4545D0295D7AF4003201E1 /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -216,14 +379,6 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ - CE4545CE295D7AF4003201E1 /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - CE4545CF295D7AF4003201E1 /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; CE4545D3295D7AF5003201E1 /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( @@ -361,7 +516,6 @@ INFOPLIST_FILE = "Runnect-iOS/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 = ( @@ -389,7 +543,6 @@ INFOPLIST_FILE = "Runnect-iOS/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 = ( diff --git a/Runnect-iOS/Runnect-iOS/Base.lproj/Main.storyboard b/Runnect-iOS/Runnect-iOS/Base.lproj/Main.storyboard deleted file mode 100644 index 25a76385..00000000 --- a/Runnect-iOS/Runnect-iOS/Base.lproj/Main.storyboard +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Runnect-iOS/Runnect-iOS/Global/Extension/.gitkeep b/Runnect-iOS/Runnect-iOS/Global/Extension/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Runnect-iOS/Runnect-iOS/Global/Literal/.gitkeep b/Runnect-iOS/Runnect-iOS/Global/Literal/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Runnect-iOS/Runnect-iOS/Assets.xcassets/AccentColor.colorset/Contents.json b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from Runnect-iOS/Runnect-iOS/Assets.xcassets/AccentColor.colorset/Contents.json rename to Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/Runnect-iOS/Runnect-iOS/Assets.xcassets/AppIcon.appiconset/Contents.json b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from Runnect-iOS/Runnect-iOS/Assets.xcassets/AppIcon.appiconset/Contents.json rename to Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/Runnect-iOS/Runnect-iOS/Assets.xcassets/Contents.json b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/Contents.json similarity index 100% rename from Runnect-iOS/Runnect-iOS/Assets.xcassets/Contents.json rename to Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/Contents.json diff --git a/Runnect-iOS/Runnect-iOS/AppDelegate.swift b/Runnect-iOS/Runnect-iOS/Global/Supports/AppDelegate.swift similarity index 100% rename from Runnect-iOS/Runnect-iOS/AppDelegate.swift rename to Runnect-iOS/Runnect-iOS/Global/Supports/AppDelegate.swift diff --git a/Runnect-iOS/Runnect-iOS/Base.lproj/LaunchScreen.storyboard b/Runnect-iOS/Runnect-iOS/Global/Supports/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from Runnect-iOS/Runnect-iOS/Base.lproj/LaunchScreen.storyboard rename to Runnect-iOS/Runnect-iOS/Global/Supports/Base.lproj/LaunchScreen.storyboard diff --git a/Runnect-iOS/Runnect-iOS/SceneDelegate.swift b/Runnect-iOS/Runnect-iOS/Global/Supports/SceneDelegate.swift similarity index 80% rename from Runnect-iOS/Runnect-iOS/SceneDelegate.swift rename to Runnect-iOS/Runnect-iOS/Global/Supports/SceneDelegate.swift index 9300673c..af639051 100644 --- a/Runnect-iOS/Runnect-iOS/SceneDelegate.swift +++ b/Runnect-iOS/Runnect-iOS/Global/Supports/SceneDelegate.swift @@ -13,10 +13,12 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { 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 } + guard let windowScene = (scene as? UIWindowScene) else { return } + + let window = UIWindow(windowScene: windowScene) + window.rootViewController = ViewController() + self.window = window + window.makeKeyAndVisible() } func sceneDidDisconnect(_ scene: UIScene) { diff --git a/Runnect-iOS/Runnect-iOS/Global/UIComponents/.gitkeep b/Runnect-iOS/Runnect-iOS/Global/UIComponents/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/UIComponents/.gitkeep @@ -0,0 +1 @@ + diff --git a/Runnect-iOS/Runnect-iOS/Global/Utils/.gitkeep b/Runnect-iOS/Runnect-iOS/Global/Utils/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Runnect-iOS/Runnect-iOS/Info.plist b/Runnect-iOS/Runnect-iOS/Info.plist index dd3c9afd..0eb786dc 100644 --- a/Runnect-iOS/Runnect-iOS/Info.plist +++ b/Runnect-iOS/Runnect-iOS/Info.plist @@ -15,8 +15,6 @@ Default Configuration UISceneDelegateClassName $(PRODUCT_MODULE_NAME).SceneDelegate - UISceneStoryboardFile - Main diff --git a/Runnect-iOS/Runnect-iOS/Network/Dto/.gitkeep b/Runnect-iOS/Runnect-iOS/Network/Dto/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Runnect-iOS/Runnect-iOS/Network/Foundation/.gitkeep b/Runnect-iOS/Runnect-iOS/Network/Foundation/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Runnect-iOS/Runnect-iOS/Network/Model/.gitkeep b/Runnect-iOS/Runnect-iOS/Network/Model/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Runnect-iOS/Runnect-iOS/Network/Router/.gitkeep b/Runnect-iOS/Runnect-iOS/Network/Router/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Runnect-iOS/Runnect-iOS/Network/Service/.gitkeep b/Runnect-iOS/Runnect-iOS/Network/Service/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Runnect-iOS/Runnect-iOS/Presentation/SignIn/VC/.gitkeep b/Runnect-iOS/Runnect-iOS/Presentation/SignIn/VC/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Runnect-iOS/Runnect-iOS/Presentation/SignIn/Views/.gitkeep b/Runnect-iOS/Runnect-iOS/Presentation/SignIn/Views/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/Runnect-iOS/Runnect-iOS/ViewController.swift b/Runnect-iOS/Runnect-iOS/Presentation/TabBar/ViewController.swift similarity index 100% rename from Runnect-iOS/Runnect-iOS/ViewController.swift rename to Runnect-iOS/Runnect-iOS/Presentation/TabBar/ViewController.swift From 68fd58470b248c0083138fcd29559024b11ec840 Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Thu, 29 Dec 2022 18:24:56 +0900 Subject: [PATCH 5/7] =?UTF-8?q?[Setting]=20#1=20-=20Extension,=20Utils=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Runnect-iOS.xcodeproj/project.pbxproj | 182 +++++++++++++++++- .../Runnect-iOS/Global/Extension/.gitkeep | 0 .../Global/Extension/Combine+/CancelBag.swift | 25 +++ .../Extension/Combine+/Publisher+Driver.swift | 27 +++ .../Combine+/Publisher+UIControl.swift | 63 ++++++ .../Extension/Foundation+/Result+.swift | 26 +++ .../Extension/Foundation+/String+.swift | 67 +++++++ .../Global/Extension/Foundation+/URL+.swift | 20 ++ .../Global/Extension/UIKit+/UIButton+.swift | 92 +++++++++ .../Global/Extension/UIKit+/UIColor+.swift | 26 +++ .../Global/Extension/UIKit+/UIDevice+.swift | 66 +++++++ .../Global/Extension/UIKit+/UIImage+.swift | 36 ++++ .../Global/Extension/UIKit+/UILabel+.swift | 140 ++++++++++++++ .../Extension/UIKit+/UIStackView+.swift | 16 ++ .../Global/Extension/UIKit+/UISwitch+.swift | 37 ++++ .../Global/Extension/UIKit+/UITabBar+.swift | 17 ++ .../Extension/UIKit+/UITableView+.swift | 27 +++ .../Extension/UIKit+/UITextField+.swift | 37 ++++ .../Global/Extension/UIKit+/UITextView+.swift | 54 ++++++ .../Global/Extension/UIKit+/UIView+.swift | 51 +++++ .../Extension/UIKit+/UIViewController+.swift | 27 +++ .../Runnect-iOS/Global/Literal/.gitkeep | 0 .../Global/Literal/StringLiterals.swift | 18 ++ .../Global/Literal/UserDefaultKeyList.swift | 14 ++ .../Global/Protocols/KeyPathFindable.swift | 36 ++++ Runnect-iOS/Runnect-iOS/Global/Utils/.gitkeep | 0 .../Runnect-iOS/Global/Utils/JsonCoder.swift | 27 +++ .../Global/Utils/UserDefaultWrapper.swift | 29 +++ .../Runnect-iOS/Global/Utils/addToolBar.swift | 41 ++++ .../Runnect-iOS/Global/Utils/adjusted+.swift | 41 ++++ .../Global/Utils/applyShadow.swift | 41 ++++ .../Global/Utils/calculatePastTime.swift | 53 +++++ .../Global/Utils/calculateTopInset.swift | 53 +++++ .../Global/Utils/getClassName.swift | 26 +++ .../Runnect-iOS/Global/Utils/makeAlert.swift | 37 ++++ .../Global/Utils/makeVibrate.swift | 37 ++++ .../Runnect-iOS/Global/Utils/setImage.swift | 54 ++++++ .../Global/Utils/setRootViewController.swift | 37 ++++ .../Utils/setStatusBarBackgroundColor.swift | 23 +++ .../Global/Utils/setTextLineHeight.swift | 42 ++++ 40 files changed, 1639 insertions(+), 6 deletions(-) delete mode 100644 Runnect-iOS/Runnect-iOS/Global/Extension/.gitkeep create mode 100644 Runnect-iOS/Runnect-iOS/Global/Extension/Combine+/CancelBag.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Extension/Combine+/Publisher+Driver.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Extension/Combine+/Publisher+UIControl.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Extension/Foundation+/Result+.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Extension/Foundation+/String+.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Extension/Foundation+/URL+.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIButton+.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIColor+.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIDevice+.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIImage+.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UILabel+.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIStackView+.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UISwitch+.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UITabBar+.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UITableView+.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UITextField+.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UITextView+.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIView+.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIViewController+.swift delete mode 100644 Runnect-iOS/Runnect-iOS/Global/Literal/.gitkeep create mode 100644 Runnect-iOS/Runnect-iOS/Global/Literal/StringLiterals.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Literal/UserDefaultKeyList.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Protocols/KeyPathFindable.swift delete mode 100644 Runnect-iOS/Runnect-iOS/Global/Utils/.gitkeep create mode 100644 Runnect-iOS/Runnect-iOS/Global/Utils/JsonCoder.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Utils/UserDefaultWrapper.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Utils/addToolBar.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Utils/adjusted+.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Utils/applyShadow.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Utils/calculatePastTime.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Utils/calculateTopInset.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Utils/getClassName.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Utils/makeAlert.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Utils/makeVibrate.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Utils/setImage.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Utils/setRootViewController.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Utils/setStatusBarBackgroundColor.swift create mode 100644 Runnect-iOS/Runnect-iOS/Global/Utils/setTextLineHeight.swift diff --git a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj index ccf9d184..c460591a 100644 --- a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj +++ b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj @@ -14,6 +14,42 @@ CE4545D2295D7AF5003201E1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CE4545D1295D7AF5003201E1 /* Assets.xcassets */; }; CE4545D5295D7AF5003201E1 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CE4545D3295D7AF5003201E1 /* LaunchScreen.storyboard */; }; CE6655BF295D82E200C64E12 /* .gitkeep in Resources */ = {isa = PBXBuildFile; fileRef = CE6655BE295D82E200C64E12 /* .gitkeep */; }; + CE6655C8295D849F00C64E12 /* StringLiterals.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6655C7295D849F00C64E12 /* StringLiterals.swift */; }; + CE6655CA295D84DD00C64E12 /* UserDefaultKeyList.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6655C9295D84DD00C64E12 /* UserDefaultKeyList.swift */; }; + CE6655CD295D856300C64E12 /* KeyPathFindable.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6655CC295D856300C64E12 /* KeyPathFindable.swift */; }; + CE6655D0295D85FF00C64E12 /* CancelBag.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6655CF295D85FF00C64E12 /* CancelBag.swift */; }; + CE6655D2295D862A00C64E12 /* Publisher+Driver.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6655D1295D862A00C64E12 /* Publisher+Driver.swift */; }; + CE6655D4295D865B00C64E12 /* Publisher+UIControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6655D3295D865B00C64E12 /* Publisher+UIControl.swift */; }; + CE6655D7295D86F900C64E12 /* String+.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6655D6295D86F900C64E12 /* String+.swift */; }; + CE6655D9295D871B00C64E12 /* URL+.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6655D8295D871B00C64E12 /* URL+.swift */; }; + CE6655DC295D873500C64E12 /* UIButton+.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6655DB295D873500C64E12 /* UIButton+.swift */; }; + CE6655DE295D877F00C64E12 /* UIColor+.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6655DD295D877F00C64E12 /* UIColor+.swift */; }; + CE6655E0295D87D200C64E12 /* UIDevice+.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6655DF295D87D200C64E12 /* UIDevice+.swift */; }; + CE6655E2295D87EB00C64E12 /* UIImage+.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6655E1295D87EB00C64E12 /* UIImage+.swift */; }; + CE6655E4295D884600C64E12 /* UILabel+.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6655E3295D884600C64E12 /* UILabel+.swift */; }; + CE6655E6295D887F00C64E12 /* UIStackView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6655E5295D887F00C64E12 /* UIStackView+.swift */; }; + CE6655E8295D889600C64E12 /* UISwitch+.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6655E7295D889600C64E12 /* UISwitch+.swift */; }; + CE6655EA295D88B200C64E12 /* UITabBar+.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6655E9295D88B200C64E12 /* UITabBar+.swift */; }; + CE6655EC295D88D000C64E12 /* UITableView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6655EB295D88D000C64E12 /* UITableView+.swift */; }; + CE6655EE295D88E600C64E12 /* UITextField+.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6655ED295D88E600C64E12 /* UITextField+.swift */; }; + CE6655F0295D891B00C64E12 /* UITextView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6655EF295D891B00C64E12 /* UITextView+.swift */; }; + CE6655F2295D894D00C64E12 /* UIView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6655F1295D894D00C64E12 /* UIView+.swift */; }; + CE6655F4295D898400C64E12 /* UIViewController+.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6655F3295D898400C64E12 /* UIViewController+.swift */; }; + CE6655F6295D90B600C64E12 /* addToolBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6655F5295D90B600C64E12 /* addToolBar.swift */; }; + CE6655F8295D90CF00C64E12 /* adjusted+.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6655F7295D90CF00C64E12 /* adjusted+.swift */; }; + CE6655FA295D90E000C64E12 /* applyShadow.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6655F9295D90E000C64E12 /* applyShadow.swift */; }; + CE6655FC295D90F500C64E12 /* calculatePastTime.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6655FB295D90F500C64E12 /* calculatePastTime.swift */; }; + CE6655FE295D912300C64E12 /* calculateTopInset.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6655FD295D912300C64E12 /* calculateTopInset.swift */; }; + CE665600295D915D00C64E12 /* getClassName.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6655FF295D915D00C64E12 /* getClassName.swift */; }; + CE665602295D918000C64E12 /* JsonCoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE665601295D918000C64E12 /* JsonCoder.swift */; }; + CE665604295D91B100C64E12 /* makeAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE665603295D91B100C64E12 /* makeAlert.swift */; }; + CE665606295D91C500C64E12 /* makeVibrate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE665605295D91C500C64E12 /* makeVibrate.swift */; }; + CE665608295D921500C64E12 /* setImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE665607295D921500C64E12 /* setImage.swift */; }; + CE66560A295D924A00C64E12 /* Result+.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE665609295D924A00C64E12 /* Result+.swift */; }; + CE66560C295D928300C64E12 /* setRootViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE66560B295D928300C64E12 /* setRootViewController.swift */; }; + CE66560E295D92A500C64E12 /* setStatusBarBackgroundColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE66560D295D92A500C64E12 /* setStatusBarBackgroundColor.swift */; }; + CE665610295D92C200C64E12 /* setTextLineHeight.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE66560F295D92C200C64E12 /* setTextLineHeight.swift */; }; + CE665612295D92E400C64E12 /* UserDefaultWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE665611295D92E400C64E12 /* UserDefaultWrapper.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -27,9 +63,6 @@ CE4545D4295D7AF5003201E1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; CE4545D6295D7AF5003201E1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; CE6655B8295D81C900C64E12 /* .gitkeep */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitkeep; sourceTree = ""; }; - CE6655B9295D82A100C64E12 /* .gitkeep */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitkeep; sourceTree = ""; }; - CE6655BA295D82BF00C64E12 /* .gitkeep */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitkeep; sourceTree = ""; }; - CE6655BB295D82C600C64E12 /* .gitkeep */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitkeep; sourceTree = ""; }; CE6655BC295D82CF00C64E12 /* .gitkeep */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitkeep; sourceTree = ""; }; CE6655BD295D82D800C64E12 /* .gitkeep */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitkeep; sourceTree = ""; }; CE6655BE295D82E200C64E12 /* .gitkeep */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitkeep; sourceTree = ""; }; @@ -37,6 +70,42 @@ CE6655C1295D82F700C64E12 /* .gitkeep */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitkeep; sourceTree = ""; }; CE6655C5295D83B700C64E12 /* .gitkeep */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitkeep; sourceTree = ""; }; CE6655C6295D83BD00C64E12 /* .gitkeep */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitkeep; sourceTree = ""; }; + CE6655C7295D849F00C64E12 /* StringLiterals.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringLiterals.swift; sourceTree = ""; }; + CE6655C9295D84DD00C64E12 /* UserDefaultKeyList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultKeyList.swift; sourceTree = ""; }; + CE6655CC295D856300C64E12 /* KeyPathFindable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyPathFindable.swift; sourceTree = ""; }; + CE6655CF295D85FF00C64E12 /* CancelBag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CancelBag.swift; sourceTree = ""; }; + CE6655D1295D862A00C64E12 /* Publisher+Driver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Publisher+Driver.swift"; sourceTree = ""; }; + CE6655D3295D865B00C64E12 /* Publisher+UIControl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Publisher+UIControl.swift"; sourceTree = ""; }; + CE6655D6295D86F900C64E12 /* String+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+.swift"; sourceTree = ""; }; + CE6655D8295D871B00C64E12 /* URL+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+.swift"; sourceTree = ""; }; + CE6655DB295D873500C64E12 /* UIButton+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIButton+.swift"; sourceTree = ""; }; + CE6655DD295D877F00C64E12 /* UIColor+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+.swift"; sourceTree = ""; }; + CE6655DF295D87D200C64E12 /* UIDevice+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIDevice+.swift"; sourceTree = ""; }; + CE6655E1295D87EB00C64E12 /* UIImage+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+.swift"; sourceTree = ""; }; + CE6655E3295D884600C64E12 /* UILabel+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UILabel+.swift"; sourceTree = ""; }; + CE6655E5295D887F00C64E12 /* UIStackView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIStackView+.swift"; sourceTree = ""; }; + CE6655E7295D889600C64E12 /* UISwitch+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UISwitch+.swift"; sourceTree = ""; }; + CE6655E9295D88B200C64E12 /* UITabBar+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITabBar+.swift"; sourceTree = ""; }; + CE6655EB295D88D000C64E12 /* UITableView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITableView+.swift"; sourceTree = ""; }; + CE6655ED295D88E600C64E12 /* UITextField+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITextField+.swift"; sourceTree = ""; }; + CE6655EF295D891B00C64E12 /* UITextView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITextView+.swift"; sourceTree = ""; }; + CE6655F1295D894D00C64E12 /* UIView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+.swift"; sourceTree = ""; }; + CE6655F3295D898400C64E12 /* UIViewController+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+.swift"; sourceTree = ""; }; + CE6655F5295D90B600C64E12 /* addToolBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = addToolBar.swift; sourceTree = ""; }; + CE6655F7295D90CF00C64E12 /* adjusted+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "adjusted+.swift"; sourceTree = ""; }; + CE6655F9295D90E000C64E12 /* applyShadow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = applyShadow.swift; sourceTree = ""; }; + CE6655FB295D90F500C64E12 /* calculatePastTime.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = calculatePastTime.swift; sourceTree = ""; }; + CE6655FD295D912300C64E12 /* calculateTopInset.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = calculateTopInset.swift; sourceTree = ""; }; + CE6655FF295D915D00C64E12 /* getClassName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = getClassName.swift; sourceTree = ""; }; + CE665601295D918000C64E12 /* JsonCoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JsonCoder.swift; sourceTree = ""; }; + CE665603295D91B100C64E12 /* makeAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = makeAlert.swift; sourceTree = ""; }; + CE665605295D91C500C64E12 /* makeVibrate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = makeVibrate.swift; sourceTree = ""; }; + CE665607295D921500C64E12 /* setImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = setImage.swift; sourceTree = ""; }; + CE665609295D924A00C64E12 /* Result+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Result+.swift"; sourceTree = ""; }; + CE66560B295D928300C64E12 /* setRootViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = setRootViewController.swift; sourceTree = ""; }; + CE66560D295D92A500C64E12 /* setStatusBarBackgroundColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = setStatusBarBackgroundColor.swift; sourceTree = ""; }; + CE66560F295D92C200C64E12 /* setTextLineHeight.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = setTextLineHeight.swift; sourceTree = ""; }; + CE665611295D92E400C64E12 /* UserDefaultWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultWrapper.swift; sourceTree = ""; }; E837271A78E1C0A0C30789BF /* Pods-Runnect-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runnect-iOS.release.xcconfig"; path = "Target Support Files/Pods-Runnect-iOS/Pods-Runnect-iOS.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -128,6 +197,7 @@ CE6655B3295D802800C64E12 /* Supports */, CE6655B2295D801A00C64E12 /* Extension */, CE6655B1295D801700C64E12 /* Utils */, + CE6655CB295D851800C64E12 /* Protocols */, ); path = Global; sourceTree = ""; @@ -183,7 +253,20 @@ CE6655B1295D801700C64E12 /* Utils */ = { isa = PBXGroup; children = ( - CE6655BB295D82C600C64E12 /* .gitkeep */, + CE6655F5295D90B600C64E12 /* addToolBar.swift */, + CE6655F7295D90CF00C64E12 /* adjusted+.swift */, + CE6655F9295D90E000C64E12 /* applyShadow.swift */, + CE6655FB295D90F500C64E12 /* calculatePastTime.swift */, + CE6655FD295D912300C64E12 /* calculateTopInset.swift */, + CE6655FF295D915D00C64E12 /* getClassName.swift */, + CE665601295D918000C64E12 /* JsonCoder.swift */, + CE665603295D91B100C64E12 /* makeAlert.swift */, + CE665605295D91C500C64E12 /* makeVibrate.swift */, + CE665607295D921500C64E12 /* setImage.swift */, + CE66560B295D928300C64E12 /* setRootViewController.swift */, + CE66560D295D92A500C64E12 /* setStatusBarBackgroundColor.swift */, + CE66560F295D92C200C64E12 /* setTextLineHeight.swift */, + CE665611295D92E400C64E12 /* UserDefaultWrapper.swift */, ); path = Utils; sourceTree = ""; @@ -191,7 +274,9 @@ CE6655B2295D801A00C64E12 /* Extension */ = { isa = PBXGroup; children = ( - CE6655BA295D82BF00C64E12 /* .gitkeep */, + CE6655DA295D872900C64E12 /* UIKit+ */, + CE6655D5295D86EB00C64E12 /* Foundation+ */, + CE6655CE295D85E900C64E12 /* Combine+ */, ); path = Extension; sourceTree = ""; @@ -217,7 +302,8 @@ CE6655B5295D803800C64E12 /* Literal */ = { isa = PBXGroup; children = ( - CE6655B9295D82A100C64E12 /* .gitkeep */, + CE6655C7295D849F00C64E12 /* StringLiterals.swift */, + CE6655C9295D84DD00C64E12 /* UserDefaultKeyList.swift */, ); path = Literal; sourceTree = ""; @@ -255,6 +341,54 @@ path = Views; sourceTree = ""; }; + CE6655CB295D851800C64E12 /* Protocols */ = { + isa = PBXGroup; + children = ( + CE6655CC295D856300C64E12 /* KeyPathFindable.swift */, + ); + path = Protocols; + sourceTree = ""; + }; + CE6655CE295D85E900C64E12 /* Combine+ */ = { + isa = PBXGroup; + children = ( + CE6655CF295D85FF00C64E12 /* CancelBag.swift */, + CE6655D1295D862A00C64E12 /* Publisher+Driver.swift */, + CE6655D3295D865B00C64E12 /* Publisher+UIControl.swift */, + ); + path = "Combine+"; + sourceTree = ""; + }; + CE6655D5295D86EB00C64E12 /* Foundation+ */ = { + isa = PBXGroup; + children = ( + CE6655D6295D86F900C64E12 /* String+.swift */, + CE6655D8295D871B00C64E12 /* URL+.swift */, + CE665609295D924A00C64E12 /* Result+.swift */, + ); + path = "Foundation+"; + sourceTree = ""; + }; + CE6655DA295D872900C64E12 /* UIKit+ */ = { + isa = PBXGroup; + children = ( + CE6655DB295D873500C64E12 /* UIButton+.swift */, + CE6655DD295D877F00C64E12 /* UIColor+.swift */, + CE6655DF295D87D200C64E12 /* UIDevice+.swift */, + CE6655E1295D87EB00C64E12 /* UIImage+.swift */, + CE6655E3295D884600C64E12 /* UILabel+.swift */, + CE6655E5295D887F00C64E12 /* UIStackView+.swift */, + CE6655E7295D889600C64E12 /* UISwitch+.swift */, + CE6655E9295D88B200C64E12 /* UITabBar+.swift */, + CE6655EB295D88D000C64E12 /* UITableView+.swift */, + CE6655ED295D88E600C64E12 /* UITextField+.swift */, + CE6655EF295D891B00C64E12 /* UITextView+.swift */, + CE6655F1295D894D00C64E12 /* UIView+.swift */, + CE6655F3295D898400C64E12 /* UIViewController+.swift */, + ); + path = "UIKit+"; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -370,9 +504,45 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + CE665604295D91B100C64E12 /* makeAlert.swift in Sources */, + CE6655EA295D88B200C64E12 /* UITabBar+.swift in Sources */, + CE665602295D918000C64E12 /* JsonCoder.swift in Sources */, CE4545CD295D7AF4003201E1 /* ViewController.swift in Sources */, + CE6655F4295D898400C64E12 /* UIViewController+.swift in Sources */, + CE6655CD295D856300C64E12 /* KeyPathFindable.swift in Sources */, + CE6655E4295D884600C64E12 /* UILabel+.swift in Sources */, + CE6655FA295D90E000C64E12 /* applyShadow.swift in Sources */, + CE665606295D91C500C64E12 /* makeVibrate.swift in Sources */, + CE66560A295D924A00C64E12 /* Result+.swift in Sources */, + CE66560E295D92A500C64E12 /* setStatusBarBackgroundColor.swift in Sources */, + CE6655D7295D86F900C64E12 /* String+.swift in Sources */, CE4545C9295D7AF4003201E1 /* AppDelegate.swift in Sources */, + CE6655C8295D849F00C64E12 /* StringLiterals.swift in Sources */, + CE6655E0295D87D200C64E12 /* UIDevice+.swift in Sources */, + CE6655E8295D889600C64E12 /* UISwitch+.swift in Sources */, + CE6655F6295D90B600C64E12 /* addToolBar.swift in Sources */, + CE6655F0295D891B00C64E12 /* UITextView+.swift in Sources */, + CE6655EE295D88E600C64E12 /* UITextField+.swift in Sources */, + CE6655F8295D90CF00C64E12 /* adjusted+.swift in Sources */, CE4545CB295D7AF4003201E1 /* SceneDelegate.swift in Sources */, + CE6655FE295D912300C64E12 /* calculateTopInset.swift in Sources */, + CE6655D0295D85FF00C64E12 /* CancelBag.swift in Sources */, + CE6655DC295D873500C64E12 /* UIButton+.swift in Sources */, + CE6655D4295D865B00C64E12 /* Publisher+UIControl.swift in Sources */, + CE6655EC295D88D000C64E12 /* UITableView+.swift in Sources */, + CE66560C295D928300C64E12 /* setRootViewController.swift in Sources */, + CE6655D9295D871B00C64E12 /* URL+.swift in Sources */, + CE6655DE295D877F00C64E12 /* UIColor+.swift in Sources */, + CE665608295D921500C64E12 /* setImage.swift in Sources */, + CE665612295D92E400C64E12 /* UserDefaultWrapper.swift in Sources */, + CE665610295D92C200C64E12 /* setTextLineHeight.swift in Sources */, + CE6655E2295D87EB00C64E12 /* UIImage+.swift in Sources */, + CE6655D2295D862A00C64E12 /* Publisher+Driver.swift in Sources */, + CE6655E6295D887F00C64E12 /* UIStackView+.swift in Sources */, + CE6655CA295D84DD00C64E12 /* UserDefaultKeyList.swift in Sources */, + CE6655F2295D894D00C64E12 /* UIView+.swift in Sources */, + CE665600295D915D00C64E12 /* getClassName.swift in Sources */, + CE6655FC295D90F500C64E12 /* calculatePastTime.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Runnect-iOS/Runnect-iOS/Global/Extension/.gitkeep b/Runnect-iOS/Runnect-iOS/Global/Extension/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/Runnect-iOS/Runnect-iOS/Global/Extension/Combine+/CancelBag.swift b/Runnect-iOS/Runnect-iOS/Global/Extension/Combine+/CancelBag.swift new file mode 100644 index 00000000..d42da6fe --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Extension/Combine+/CancelBag.swift @@ -0,0 +1,25 @@ +// +// CancelBag.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import Combine + +class CancelBag { + var subscriptions = Set() + + func cancel() { + subscriptions.forEach { $0.cancel() } + subscriptions.removeAll() + } + + init() { } +} + +extension AnyCancellable { + func store(in cancelBag: CancelBag) { + cancelBag.subscriptions.insert(self) + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Extension/Combine+/Publisher+Driver.swift b/Runnect-iOS/Runnect-iOS/Global/Extension/Combine+/Publisher+Driver.swift new file mode 100644 index 00000000..db865d74 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Extension/Combine+/Publisher+Driver.swift @@ -0,0 +1,27 @@ +// +// Publisher+Driver.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import Combine +import Foundation + +public typealias Driver = AnyPublisher + +public extension Publisher { + func asDriver() -> Driver { + return self.catch { _ in Empty() } + .receive(on: RunLoop.main) + .eraseToAnyPublisher() + } + + static func just(_ output: Output) -> Driver { + return Just(output).eraseToAnyPublisher() + } + + static func empty() -> Driver { + return Empty().eraseToAnyPublisher() + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Extension/Combine+/Publisher+UIControl.swift b/Runnect-iOS/Runnect-iOS/Global/Extension/Combine+/Publisher+UIControl.swift new file mode 100644 index 00000000..57298e79 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Extension/Combine+/Publisher+UIControl.swift @@ -0,0 +1,63 @@ +// +// Publisher+UIControl.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import UIKit +import Combine + +protocol CombineCompatible { } + +extension UIControl: CombineCompatible { } + +extension CombineCompatible where Self: UIControl { + func publisher(for events: UIControl.Event) -> UIControlPublisher { + return UIControlPublisher(control: self, events: events) + } +} + +final class UIControlSubscription: Subscription where SubscriberType.Input == Control { + private var subscriber: SubscriberType? + private let control: Control + + init(subscriber: SubscriberType, control: Control, event: UIControl.Event) { + self.subscriber = subscriber + self.control = control + control.addTarget(self, action: #selector(eventHandler), for: event) + } + + func request(_ demand: Subscribers.Demand) { + + } + + func cancel() { + subscriber = nil + } + + @objc private func eventHandler() { + _ = subscriber?.receive(control) + } +} + +struct UIControlPublisher: Publisher { + + public typealias Output = Control + public typealias Failure = Never + + let control: Control + let controlEvents: UIControl.Event + + init(control: Control, events: UIControl.Event) { + self.control = control + self.controlEvents = events + } + + func receive(subscriber: S) where S: Subscriber, + S.Failure == UIControlPublisher.Failure, + S.Input == UIControlPublisher.Output { + let subscription = UIControlSubscription(subscriber: subscriber, control: control, event: controlEvents) + subscriber.receive(subscription: subscription) + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Extension/Foundation+/Result+.swift b/Runnect-iOS/Runnect-iOS/Global/Extension/Foundation+/Result+.swift new file mode 100644 index 00000000..60dd7648 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Extension/Foundation+/Result+.swift @@ -0,0 +1,26 @@ +// +// Result+.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import Foundation + +extension Result { + @discardableResult + func success(_ successHandler: (Success) -> Void) -> Result { + if case .success(let value) = self { + successHandler(value) + } + return self + } + + @discardableResult + func `catch`(_ failureHandler: (Failure) -> Void) -> Result { + if case .failure(let error) = self { + failureHandler(error) + } + return self + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Extension/Foundation+/String+.swift b/Runnect-iOS/Runnect-iOS/Global/Extension/Foundation+/String+.swift new file mode 100644 index 00000000..a26b84d4 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Extension/Foundation+/String+.swift @@ -0,0 +1,67 @@ +// +// String+.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import UIKit + +extension String { + + /// String을 UIImage로 반환하는 메서드 + func makeImage() -> UIImage? { + if let data = Data(base64Encoded: self, options: .ignoreUnknownCharacters) { + return UIImage(data: data) + } + return nil + } + + /// 서버에서 들어온 Date String을 Date 타입으로 반환하는 메서드 + private func toDate() -> Date { + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" + dateFormatter.timeZone = TimeZone(identifier: "KST") + if let date = dateFormatter.date(from: self) { + return date + } else { + print("toDate() convert error") + return Date() + } + } + + /// serverTimeToString의 용도 정의 + enum TimeStringCase { + case forNotification + case forDefault + } + + /// 서버에서 들어온 Date String을 UI에 적용 가능한 String 타입으로 반환하는 메서드 + func serverTimeToString(forUse: TimeStringCase) -> String { + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "yy/MM/dd" + + let currentTime = Int(Date().timeIntervalSince1970) + + switch forUse { + case .forNotification: + let getTime = self.toDate().timeIntervalSince1970 + let displaySec = currentTime - Int(getTime) + let displayMin = displaySec / 60 + let displayHour = displayMin / 60 + let displayDay = displayHour / 24 + + if displayDay >= 1 { + return dateFormatter.string(from: self.toDate()) + } else if displayHour >= 1 { + return "\(displayHour)시간 전" + } else if displayMin >= 1 { + return "\(displayMin)분 전" + } else { + return "1분 전" + } + case .forDefault: + return dateFormatter.string(from: self.toDate()) + } + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Extension/Foundation+/URL+.swift b/Runnect-iOS/Runnect-iOS/Global/Extension/Foundation+/URL+.swift new file mode 100644 index 00000000..e06d6dca --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Extension/Foundation+/URL+.swift @@ -0,0 +1,20 @@ +// +// URL+.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import Foundation + +extension URL { + /// - Description: URL에 한국어가 있는 경우, 퍼센트 문자로 치환합니다 + static func decodeURL(urlString: String) -> URL? { + if let url = URL(string: urlString) { + return url + } else { + let encodedString = urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? urlString + return URL(string: encodedString) + } + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIButton+.swift b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIButton+.swift new file mode 100644 index 00000000..70dcfdce --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIButton+.swift @@ -0,0 +1,92 @@ +// +// UIButton+.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import UIKit + +extension UIButton { + + /// 버튼 Background Color를 상태별로 지정하는 메서드 + func setBackgroundColor(_ color: UIColor, for state: UIControl.State) { + let minimumSize: CGSize = CGSize(width: 1.0, height: 1.0) + + UIGraphicsBeginImageContext(minimumSize) + + if let context = UIGraphicsGetCurrentContext() { + context.setFillColor(color.cgColor) + context.fill(CGRect(origin: .zero, size: minimumSize)) + } + + let colorImage = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + + self.clipsToBounds = true + self.setBackgroundImage(colorImage, for: state) + } + + func setUnderline() { + guard let title = title(for: .normal) else { return } + let attributedString = NSMutableAttributedString(string: title) + attributedString.addAttribute(.underlineStyle, + value: NSUnderlineStyle.single.rawValue, + range: NSRange(location: 0, length: title.count) + ) + setAttributedTitle(attributedString, for: .normal) + } +} + +extension UIButton { + + /** + button에 대해 addTarget해서 일일이 처리안하고, closure 형태로 동작을 처리하기 위해 다음과 같은 extension을 활용합니다 + press를 작성하고, 안에 버튼이 눌렸을 때, 동작하는 함수를 만듭니다. + + clicked(completion : @escaping ((Bool) -> Void)) 함수를 활용해, + 버튼이 눌렸을때, 줄어들었다가 다시 늘어나는 (Popping)효과를 추가해서 + 사용자에게 버튼이 눌렸다는 인터렉션을 제공합니다! + + 진동은 선택 가능하게 바꾸었습니다. + + iOS14부터는 UIAction의 addAction이 가능 + iOS13까지는 NSObject형태로 등록해서 처리하는 방식으로 분기처리합니다. + */ + + func press(vibrate: Bool = false, + animated: Bool = true, + for controlEvents: UIControl.Event = .touchUpInside, _ closure: @escaping() -> Void) { + if #available(iOS 14.0, *) { + self.addAction(UIAction { _ in closure() + if animated { self.clickedAnimation(vibrate: vibrate) } + }, for: controlEvents) + } else { + @objc class ClosureSleeve: NSObject { + let closure: () -> Void + init(_ closure: @escaping() -> Void) { self.closure = closure } + @objc func invoke() { closure() } + } + let sleeve = ClosureSleeve(closure) + self.addTarget(sleeve, action: #selector(ClosureSleeve.invoke), for: controlEvents) + objc_setAssociatedObject(self, "\(UUID())", sleeve, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN) + } + } + + /** + 해당 함수를 통해서 Poppin 효과를 처리합니다. + - Description: + 줄어드는 정도를 조절하고싶다면 ,ScaleX,Y값을 조절합니다(최대값 1). + 낮을수록 많이 줄어듦. + */ + func clickedAnimation(vibrate: Bool) { + if vibrate { makeVibrate(degree: .light) } + UIView.animate(withDuration: 0.1, animations: { + self.transform = CGAffineTransform(scaleX: 0.95, y: 0.95) }, completion: { _ in + UIView.animate(withDuration: 0.1, animations: { + self.transform = CGAffineTransform.identity + }) + } + ) + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIColor+.swift b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIColor+.swift new file mode 100644 index 00000000..3ac1d752 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIColor+.swift @@ -0,0 +1,26 @@ +// +// UIColor+.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import UIKit + +extension UIColor { + convenience init(red: Int, green: Int, blue: Int) { + assert(red >= 0 && red <= 255, "Invalid red component") + assert(green >= 0 && green <= 255, "Invalid green component") + assert(blue >= 0 && blue <= 255, "Invalid blue component") + + self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: 1.0) + } + + convenience init(rgb: Int) { + self.init( + red: (rgb >> 16) & 0xFF, + green: (rgb >> 8) & 0xFF, + blue: rgb & 0xFF + ) + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIDevice+.swift b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIDevice+.swift new file mode 100644 index 00000000..e4113cda --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIDevice+.swift @@ -0,0 +1,66 @@ +// +// UIDevice+.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import UIKit + +extension UIDevice { + static let iOSVersion = "\(current.systemName) \(current.systemVersion)" + + private static var hardwareString: String { + var systemInfo = utsname() + uname(&systemInfo) + let machineMirror = Mirror(reflecting: systemInfo.machine) + let model = machineMirror.children.reduce("") { identifier, element in + guard let value = element.value as? Int8, value != 0 else { return identifier } + return identifier + String(UnicodeScalar(UInt8(value))) + } + return model + } + + /// Referenced the following URL. + /// [List of iOS and iPadOS devices](https://en.wikipedia.org/wiki/List_of_iOS_and_iPadOS_devices) + private static var modelDictionary: [String: String] { + return [ + "i386": "Simulator", // 32 bit + "x86_64": "Simulator", // 64 bit + "iPhone8,1": "iPhone 6S", + "iPhone8,2": "iPhone 6S Plus", + "iPhone8,4": "iPhone SE 1st generation", + "iPhone9,1": "iPhone 7", + "iPhone9,3": "iPhone 7", + "iPhone9,2": "iPhone 7 Plus", + "iPhone9,4": "iPhone 7 Plus", + "iPhone10,1": "iPhone 8", + "iPhone10,4": "iPhone 8", + "iPhone10,2": "iPhone 8 Plus", + "iPhone10,5": "iPhone 8 Plus", + "iPhone10,3": "iPhone X", + "iPhone10,6": "iPhone X", + "iPhone11,2": "iPhone XS", + "iPhone11,4": "iPhone XS Max", + "iPhone11,6": "iPhone XS Max", + "iPhone11,8": "iPhone XR", + "iPhone12,1": "iPhone 11", + "iPhone12,3": "iPhone 11 Pro", + "iPhone12,5": "iPhone 11 Pro Max", + "iPhone12,8": "iPhone SE 2nd generation", + "iPhone13,1": "iPhone 12 Mini", + "iPhone13,2": "iPhone 12", + "iPhone13,3": "iPhone 12 Pro", + "iPhone13,4": "iPhone 12 Pro Max", + "iPhone14,4": "iPhone 13 Mini", + "iPhone14,5": "iPhone 13", + "iPhone14,2": "iPhone 13 Pro", + "iPhone14,3": "iPhone 13 Pro Max", + "iPhone14,6": "iPhone SE 3nd generation" + ] + } + + static var iPhoneModel: String { + return modelDictionary[hardwareString] ?? "Unknown iPhone - \(hardwareString)" + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIImage+.swift b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIImage+.swift new file mode 100644 index 00000000..50a36e0a --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIImage+.swift @@ -0,0 +1,36 @@ +// +// UIImage+.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import UIKit + +extension UIImage { + /// 이미지의 용량을 줄이기 위해서 리사이즈. + /// - 가로, 세로 중 짧은 것이 720 보다 작다면 그대로 반환. + /// - 가로, 세로 중 짧은 것이 720 보다 크다면 720 으로 리사이즈해서 반환. + func resize() -> UIImage { + let width = self.size.width + let height = self.size.height + let resizeLength: CGFloat = 720.0 + + var scale: CGFloat + + if height >= width { + scale = width <= resizeLength ? 1 : resizeLength / width + } else { + scale = height <= resizeLength ? 1 :resizeLength / height + } + + let newHeight = height * scale + let newWidth = width * scale + let size = CGSize(width: newWidth, height: newHeight) + let render = UIGraphicsImageRenderer(size: size) + let renderImage = render.image { _ in + self.draw(in: CGRect(origin: .zero, size: size)) + } + return renderImage + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UILabel+.swift b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UILabel+.swift new file mode 100644 index 00000000..a4133e34 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UILabel+.swift @@ -0,0 +1,140 @@ +// +// UILabel+.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import UIKit + +extension UILabel { + + /// 행간 조정 메서드 + func setLineSpacing(lineSpacing: CGFloat) { + if let text = self.text { + let attributedStr = NSMutableAttributedString(string: text) + let style = NSMutableParagraphStyle() + style.lineSpacing = lineSpacing + attributedStr.addAttribute(NSAttributedString.Key.paragraphStyle, value: style, range: NSMakeRange(0, attributedStr.length)) + self.attributedText = attributedStr + } + } + + func setLineSpacingWithChaining(lineSpacing: CGFloat) -> UILabel { + let label = self + if let text = self.text { + let style = NSMutableParagraphStyle() + style.lineSpacing = lineSpacing + let attributes: [NSAttributedString.Key: Any] = [ + .paragraphStyle: style + ] + label.attributedText = NSAttributedString(string: text, attributes: attributes) + } + return label + } + + /// 자간 설정 메서드 + func setCharacterSpacing(_ spacing: CGFloat) { + let attributedStr = NSMutableAttributedString(string: self.text ?? "") + attributedStr.addAttribute(NSAttributedString.Key.kern, value: spacing, range: NSMakeRange(0, attributedStr.length)) + self.attributedText = attributedStr + } + + /// 자간과 행간을 모두 조정하는 메서드 + func setLineAndCharacterSpacing(lineSpacing: CGFloat, characterSpacing: CGFloat) { + if let text = self.text { + let attributedStr = NSMutableAttributedString(string: text) + let style = NSMutableParagraphStyle() + style.lineSpacing = lineSpacing + attributedStr.addAttribute(NSAttributedString.Key.paragraphStyle, value: style, range: NSMakeRange(0, attributedStr.length)) + attributedStr.addAttribute(NSAttributedString.Key.kern, value: characterSpacing, range: NSMakeRange(0, attributedStr.length)) + self.attributedText = attributedStr + } + } + + /// 라벨 일부 font 변경해주는 함수 + /// - targerString에는 바꾸고자 하는 특정 문자열을 넣어주세요 + /// - font에는 targetString에 적용하고자 하는 UIFont를 넣어주세요 + func partFontChange(targetString: String, font: UIFont) { + let fullText = self.text ?? "" + let range = (fullText as NSString).range(of: targetString) + let attributedString = NSMutableAttributedString(string: fullText) + attributedString.addAttribute(.font, value: font, range: range) + self.attributedText = attributedString + } + + /// 라벨 일부 textColor 변경해주는 함수 + /// - targetString에는 바꾸고자 하는 특정 문자열을 넣어주세요 + /// - textColor에는 targetString에 적용하고자 하는 특정 UIColor에 넣어주세요 + func partColorChange(targetString: String, textColor: UIColor) { + let fullText = self.text ?? "" + let range = (fullText as NSString).range(of: targetString) + let attributedString = NSMutableAttributedString(string: fullText) + attributedString.addAttribute(.foregroundColor, value: textColor, range: range) + self.attributedText = attributedString + } + + func htmlToString(_ targetString: String) -> NSAttributedString? { + let text = targetString + + guard let data = text.data(using: .utf8) else { + return NSAttributedString() + } + do { + return try NSAttributedString(data: data, + options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], + documentAttributes: nil) + } catch { + return NSAttributedString() + } + } + + func setAttributedText(targetFontList: [String: UIFont], + targetColorList: [String: UIColor]) { + let fullText = self.text ?? "" + let attributedString = NSMutableAttributedString(string: fullText) + for dic in targetFontList { + let range = (fullText as NSString).range(of: dic.key) + attributedString.addAttribute(.font, value: dic.value, range: range) + } + + for dic in targetColorList { + let range = (fullText as NSString).range(of: dic.key) + attributedString.addAttribute(.foregroundColor, value: dic.value, range: range) + } + self.attributedText = attributedString + } + + /// 라벨 내의 특정 문자열의 CGRect 을 반환 + /// - Parameter subText: CGRect 을 알고 싶은 특정 문자열. + func rectFromString(with subText: String) -> CGRect? { + guard let attributedText = attributedText else { return nil } + guard let labelText = self.text else { return nil } + + // 전체 텍스트(labelText)에서 subText만큼의 range를 구합니다. + guard let subRange = labelText.range(of: subText) else { return nil } + let range = NSRange(subRange, in: labelText) + + // attributedText를 기반으로 한 NSTextStorage를 선언하고 NSLayoutManager를 추가합니다. + let layoutManager = NSLayoutManager() + let textStorage = NSTextStorage(attributedString: attributedText) + textStorage.addLayoutManager(layoutManager) + + // instrinsicContentSize를 기반으로 NSTextContainer를 선언하고 + let textContainer = NSTextContainer(size: intrinsicContentSize) + // 정확한 CGRect를 구해야하므로 padding 값은 0을 줍니다. + textContainer.lineFragmentPadding = 0.0 + // layoutManager에 추가합니다. + layoutManager.addTextContainer(textContainer) + + var glyphRange = NSRange() + // 주어진 범위(rage)에 대한 실질적인 glyphRange를 구합니다. + layoutManager.characterRange( + forGlyphRange: range, + actualGlyphRange: &glyphRange + ) + + // textContainer 내의 지정된 glyphRange에 대한 CGRect 값을 반환합니다. + return layoutManager.boundingRect(forGlyphRange: glyphRange, in: textContainer) + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIStackView+.swift b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIStackView+.swift new file mode 100644 index 00000000..26f27a83 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIStackView+.swift @@ -0,0 +1,16 @@ +// +// UIStackView+.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import UIKit + +extension UIStackView { + func addArrangedSubviews(_ views: UIView...) { + for view in views { + self.addArrangedSubview(view) + } + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UISwitch+.swift b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UISwitch+.swift new file mode 100644 index 00000000..afaf389c --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UISwitch+.swift @@ -0,0 +1,37 @@ +// +// UISwitch+.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import UIKit + +extension UISwitch { + + func totalSize(width: CGFloat, height: CGFloat) { + + let standardHeight: CGFloat = 31 + let standardWidth: CGFloat = 51 + + let heightRatio = height / standardHeight + let widthRatio = width / standardWidth + + transform = CGAffineTransform(scaleX: widthRatio, y: heightRatio) + } + + func thumbSize(scaleX: CGFloat, scaleY: CGFloat) { + if let thumb = self.subviews[0].subviews[1].subviews[2] as? UIImageView { + thumb.transform = CGAffineTransform(scaleX: scaleX, y: scaleY) + } + + self.subviews[0].subviews[0].layer.cornerRadius = 0 + } + + func backgroundCornerRadius(cornerRadius: CGFloat) { + // deselected + self.subviews[0].subviews[0].layer.cornerRadius = cornerRadius + // selected + self.subviews[0].subviews[1].layer.cornerRadius = cornerRadius + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UITabBar+.swift b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UITabBar+.swift new file mode 100644 index 00000000..3fe75ab5 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UITabBar+.swift @@ -0,0 +1,17 @@ +// +// UITabBar+.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import UIKit + +extension UITabBar { + + static func clearShadow() { + UITabBar.appearance().shadowImage = UIImage() + UITabBar.appearance().backgroundImage = UIImage() + UITabBar.appearance().backgroundColor = UIColor.white + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UITableView+.swift b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UITableView+.swift new file mode 100644 index 00000000..88722077 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UITableView+.swift @@ -0,0 +1,27 @@ +// +// UITableView+.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import UIKit + +extension UITableView { + + /// TableView 하단 빈 셀 없애는 메서드 + func setBottomEmptyView() { + let dummyView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: 0)) + self.tableFooterView = dummyView + } + + func fitContentInset(inset: UIEdgeInsets!) { + self.contentInset = inset + self.scrollIndicatorInsets = inset + } + + /// TableView 마지막 separator, 빈 셀 separator 숨기는 메서드 + func removeSeparatorsOfEmptyCellsAndLastCell() { + tableFooterView = UIView(frame: CGRect(origin: .zero, size: CGSize(width: 0, height: 1))) + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UITextField+.swift b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UITextField+.swift new file mode 100644 index 00000000..0eb4d443 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UITextField+.swift @@ -0,0 +1,37 @@ +// +// UITextField+.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import UIKit + +extension UITextField { + func addLeftPadding(width: CGFloat) { + let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: width, height: self.frame.height)) + self.leftView = paddingView + self.leftViewMode = .always + } + + func addRightPadding(width: CGFloat) { + let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: width, height: self.frame.height)) + self.rightView = paddingView + self.rightViewMode = .always + } + + /// UITextField의 상태를 리턴함 + var isEmpty: Bool { + if text?.isEmpty ?? true { + return true + } + return false + } + + /// 자간 설정 메서드 + func setCharacterSpacing(_ spacing: CGFloat) { + let attributedStr = NSMutableAttributedString(string: self.text ?? "") + attributedStr.addAttribute(NSAttributedString.Key.kern, value: spacing, range: NSMakeRange(0, attributedStr.length)) + self.attributedText = attributedStr + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UITextView+.swift b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UITextView+.swift new file mode 100644 index 00000000..37053082 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UITextView+.swift @@ -0,0 +1,54 @@ +// +// UITextView+.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import UIKit + +extension UITextView { + + /// 자간 설정 메서드 + func setCharacterSpacing(_ spacing: CGFloat) { + let attributedStr = NSMutableAttributedString(string: self.text ?? "") + attributedStr.addAttribute(NSAttributedString.Key.kern, value: spacing, range: NSMakeRange(0, attributedStr.length)) + self.attributedText = attributedStr + } + + /// 세로 중앙정렬 메서드 + func centerVertically() { + let fittingSize = CGSize(width: bounds.width, height: CGFloat.greatestFiniteMagnitude) + let size = sizeThatFits(fittingSize) + let topOffset = (bounds.size.height - size.height * zoomScale) / 2 + let positiveTopOffset = max(1, topOffset) + contentOffset.y = -positiveTopOffset + } + + /// line 수 카운트 메서드 + func numberOfLines() -> Int { + let layoutManager = layoutManager + let numberOfGlyphs = layoutManager.numberOfGlyphs + var lineRange: NSRange = NSMakeRange(0, 1) + var index = 0 + var numberOfLines = 0 + + while index < numberOfGlyphs { + layoutManager.lineFragmentRect(forGlyphAt: index, effectiveRange: &lineRange) + index = NSMaxRange(lineRange) + numberOfLines += 1 + } + return numberOfLines + } + + /// 행간 조정 메서드 + func setLineSpacing(lineSpacing: CGFloat) { + if let text = self.text { + let attributeString = NSMutableAttributedString(string: text) + let style = NSMutableParagraphStyle() + style.lineSpacing = lineSpacing + attributeString.addAttribute(NSAttributedString.Key.paragraphStyle, value: style, range: NSMakeRange(0, attributeString.length)) + self.attributedText = attributeString + } + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIView+.swift b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIView+.swift new file mode 100644 index 00000000..75efc0b1 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIView+.swift @@ -0,0 +1,51 @@ +// +// UIView+.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import UIKit + +extension UIView { + + // UIView 여러 개 인자로 받아서 한 번에 addSubview + func addSubviews(_ views: UIView...) { + views.forEach { self.addSubview($0) } + } + + func addSubviewFromNib(view: UIView) { + let view = Bundle.main.loadNibNamed(view.className, owner: self, options: nil)?.first as! UIView + view.frame = bounds + view.clipsToBounds = true + addSubview(view) + } + + func setGradient() { + let gradient = CAGradientLayer() + gradient.frame = bounds + gradient.colors = [UIColor.init(white: 1, alpha: 0).cgColor, UIColor.init(white: 1, alpha: 1).cgColor] + gradient.locations = [0.0, 0.8, 1.0] + gradient.startPoint = CGPoint(x: 1.0, y: 0.2) + gradient.endPoint = CGPoint(x: 1.0, y: 1) + layer.insertSublayer(gradient, at: 0) + } + + func roundCorners(cornerRadius: CGFloat, maskedCorners: CACornerMask) { + clipsToBounds = true + layer.cornerRadius = cornerRadius + layer.maskedCorners = CACornerMask(arrayLiteral: maskedCorners) + } +} + +class XibView: UIView { + override init(frame: CGRect) { + super.init(frame: frame) + addSubviewFromNib(view: self) + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + addSubviewFromNib(view: self) + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIViewController+.swift b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIViewController+.swift new file mode 100644 index 00000000..9920f612 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIViewController+.swift @@ -0,0 +1,27 @@ +// +// UIViewController+.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import UIKit + +extension UIViewController { + + /** + - Description: 화면 터치시 작성 종료 + */ + /// 화면 터치시 작성 종료하는 메서드 + open override func touchesBegan(_ touches: Set, with event: UIEvent?) { + self.view.endEditing(true) + } + + /** + - Description: 화면 터치시 키보드 내리는 Extension + */ + @objc + func dismissKeyboard() { + view.endEditing(true) + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Literal/.gitkeep b/Runnect-iOS/Runnect-iOS/Global/Literal/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/Runnect-iOS/Runnect-iOS/Global/Literal/StringLiterals.swift b/Runnect-iOS/Runnect-iOS/Global/Literal/StringLiterals.swift new file mode 100644 index 00000000..2854c91e --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Literal/StringLiterals.swift @@ -0,0 +1,18 @@ +// +// StringLiterals.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import Foundation + +struct I18N { + struct Default { + static let error = "에러" + static let networkError = "네트워크 오류가 발생했습니다." + static let delete = "삭제" + static let cancel = "취소" + static let ok = "확인" + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Literal/UserDefaultKeyList.swift b/Runnect-iOS/Runnect-iOS/Global/Literal/UserDefaultKeyList.swift new file mode 100644 index 00000000..c7ed5ade --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Literal/UserDefaultKeyList.swift @@ -0,0 +1,14 @@ +// +// UserDefaultKeyList.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import Foundation + +struct UserDefaultKeyList { + struct Auth { + @UserDefaultWrapper(key: "deviceId") public static var deviceId + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Protocols/KeyPathFindable.swift b/Runnect-iOS/Runnect-iOS/Global/Protocols/KeyPathFindable.swift new file mode 100644 index 00000000..4ecc8812 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Protocols/KeyPathFindable.swift @@ -0,0 +1,36 @@ +// +// KeyPathFindable.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import Foundation + +@dynamicMemberLookup +public struct KeyFinder { + + private var base: Base + + public init(_ base: Base) { + self.base = base + } + + public subscript(dynamicMember keyPath: ReferenceWritableKeyPath) -> ReferenceWritableKeyPath { + return keyPath + } +} + +public protocol KeyPathFindable { + associatedtype Base: AnyObject + var kf: KeyFinder { get } +} + +public extension KeyPathFindable where Self: AnyObject { + var kf: KeyFinder { + get { KeyFinder(self) } + set { } + } +} + +extension NSObject: KeyPathFindable { } diff --git a/Runnect-iOS/Runnect-iOS/Global/Utils/.gitkeep b/Runnect-iOS/Runnect-iOS/Global/Utils/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/Runnect-iOS/Runnect-iOS/Global/Utils/JsonCoder.swift b/Runnect-iOS/Runnect-iOS/Global/Utils/JsonCoder.swift new file mode 100644 index 00000000..5c20ea05 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Utils/JsonCoder.swift @@ -0,0 +1,27 @@ +// +// JsonCoder.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import Foundation + +/** + + - Description: + + JsonEncoder와 decoder를 편리하게 접근하는 용도입니다. + 'Json.decoder.decode'와 같이 호출 가능합니다. + +*/ + +public enum Json { + public static let encoder: JSONEncoder = { + let encoder = JSONEncoder() + encoder.outputFormatting = .prettyPrinted + return encoder + }() + + public static let decoder = JSONDecoder() +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Utils/UserDefaultWrapper.swift b/Runnect-iOS/Runnect-iOS/Global/Utils/UserDefaultWrapper.swift new file mode 100644 index 00000000..3a7d2cf7 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Utils/UserDefaultWrapper.swift @@ -0,0 +1,29 @@ +// +// UserDefaultWrapper.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import Foundation + +@propertyWrapper struct UserDefaultWrapper { + + var wrappedValue: T? { + get { + return UserDefaults.standard.object(forKey: self.key) as? T + } + + set { + if newValue == nil { + UserDefaults.standard.removeObject(forKey: key) + } else { UserDefaults.standard.setValue(newValue, forKey: key) } + } + } + + private let key: String + + init(key: String) { + self.key = key + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Utils/addToolBar.swift b/Runnect-iOS/Runnect-iOS/Global/Utils/addToolBar.swift new file mode 100644 index 00000000..2c1e4714 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Utils/addToolBar.swift @@ -0,0 +1,41 @@ +// +// addToolBar.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import UIKit + +extension UIViewController { + + func addToolbar(textfields: [UITextField]) { + let toolBarKeyboard = UIToolbar() + toolBarKeyboard.sizeToFit() + let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) + let btnDoneBar = UIBarButtonItem(title: "완료", style: .done, target: self, action: #selector(self.dismissKeyBoard)) + toolBarKeyboard.items = [flexSpace, btnDoneBar] + textfields.forEach { + $0.inputAccessoryView = toolBarKeyboard + } + } + + func addToolBar(textView: UITextView) { + let toolBarKeyboard = UIToolbar() + toolBarKeyboard.sizeToFit() + let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) + let btnDoneBar = UIBarButtonItem(title: "완료", style: .done, target: self, action: #selector(self.dismissKeyBoard)) + toolBarKeyboard.items = [flexSpace, btnDoneBar] + toolBarKeyboard.tintColor = UIColor.red + textView.inputAccessoryView = toolBarKeyboard + } + + @objc func dismissKeyBoard() { + self.view.endEditing(true) + } + + func addTapGesture() { + let tap = UITapGestureRecognizer(target: self, action: #selector(dismissKeyBoard)) + self.view.addGestureRecognizer(tap) + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Utils/adjusted+.swift b/Runnect-iOS/Runnect-iOS/Global/Utils/adjusted+.swift new file mode 100644 index 00000000..adc093d9 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Utils/adjusted+.swift @@ -0,0 +1,41 @@ +// +// adjusted+.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import UIKit + +/** + - Description: + 스크린 너비 375를 기준으로 디자인이 나왔을 때 현재 기기의 스크린 사이즈에 비례하는 수치를 Return한다. + + - Note: + 기기별 대응에 사용하면 된다. + ex) (size: 20.adjusted) + */ + +extension CGFloat { + var adjusted: CGFloat { + let ratio: CGFloat = UIScreen.main.bounds.width / 375 + return self * ratio + } + + var adjustedH: CGFloat { + let ratio: CGFloat = UIScreen.main.bounds.height / 812 + return self * ratio + } +} + +extension Double { + var adjusted: Double { + let ratio: Double = Double(UIScreen.main.bounds.width / 375) + return self * ratio + } + + var adjustedH: Double { + let ratio: Double = Double(UIScreen.main.bounds.height / 812) + return self * ratio + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Utils/applyShadow.swift b/Runnect-iOS/Runnect-iOS/Global/Utils/applyShadow.swift new file mode 100644 index 00000000..392029a7 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Utils/applyShadow.swift @@ -0,0 +1,41 @@ +// +// applyShadow.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import UIKit + +/** + + - Description: + + View의 Layer 계층(CALayer)에 shadow를 간편하게 입힐 수 있는 메서드입니다. + 피그마에 나와있는 shadow 속성 값을 그대로 기입하면 됩니다! + + */ + +public extension CALayer { + func applyShadow( + color: UIColor = .black, + alpha: Float = 0.5, + x: CGFloat = 0, + y: CGFloat = 2, + blur: CGFloat = 4, + spread: CGFloat = 0) { + + masksToBounds = false + shadowColor = color.cgColor + shadowOpacity = alpha + shadowOffset = CGSize(width: x, height: y) + shadowRadius = blur / 2.0 + if spread == 0 { + shadowPath = nil + } else { + let dx = -spread + let rect = bounds.insetBy(dx: dx, dy: dx) + shadowPath = UIBezierPath(rect: rect).cgPath + } + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Utils/calculatePastTime.swift b/Runnect-iOS/Runnect-iOS/Global/Utils/calculatePastTime.swift new file mode 100644 index 00000000..96fbabcd --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Utils/calculatePastTime.swift @@ -0,0 +1,53 @@ +// +// calculatePastTime.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import Foundation + +public func calculatePastTime(date: String) -> String { + + let minute = 60 + let hour = minute * 60 + let day = hour * 60 + let week = day * 7 + + var message: String = "" + + let UTCDate = Date() + let formatter = DateFormatter() + formatter.timeZone = TimeZone(secondsFromGMT: 32400) + formatter.dateFormat = "yyyy-MM-dd HH:mm:ss" + let defaultTimeZoneStr = formatter.string(from: UTCDate) + + let format = DateFormatter() + format.dateFormat = "yyyy-MM-dd HH:mm:ss" + format.locale = Locale(identifier: "ko_KR") + + guard let tempDate = format.date(from: date) else {return ""} + let krTime = format.date(from: defaultTimeZoneStr) + + let articleDate = format.string(from: tempDate) + var useTime = Int(krTime!.timeIntervalSince(tempDate)) + useTime = useTime - 32400 + + if useTime < minute { + message = "방금 전" + } else if useTime < hour { + message = String(useTime/minute) + "분 전" + } else if useTime < day { + message = String(useTime/hour) + "시간 전" + } else if useTime < week { + message = String(useTime/day) + "일 전" + } else if useTime < week * 4 { + message = String(useTime/week) + "주 전" + } else { + let timeArray = articleDate.components(separatedBy: " ") + let dateArray = timeArray[0].components(separatedBy: "-") + message = dateArray[1] + "월 " + dateArray[2] + "일" + } + + return message +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Utils/calculateTopInset.swift b/Runnect-iOS/Runnect-iOS/Global/Utils/calculateTopInset.swift new file mode 100644 index 00000000..19d746b0 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Utils/calculateTopInset.swift @@ -0,0 +1,53 @@ +// +// calculateTopInset.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import UIKit + +/** + - Description: + + 상단의 탑 safe Area를 계산하는 함수입니다 + 노치가 있는 경우에는 safe area inset 만큼 음수값을 주고, + 노치가 없는 경우에는 -44로 고정값을 부여합니다 + */ + +public extension UIViewController { + func calculateTopInset() -> CGFloat { + let windows = UIApplication.shared.windows[0] + let topInset = windows.safeAreaInsets.top + + if UIDevice.current.hasNotch { + return topInset * -1 + } else { + return -44 + } + } + + func safeAreaBottomInset() -> CGFloat { + if #available(iOS 11.0, *) { + let window = self.view.window + let bottomPadding = window?.safeAreaInsets.bottom + return bottomPadding ?? 0.0 + } else { + return 0.0 + } + } +} + +/** + + - Description: + + 해당 기기가, notch를 가지고 있는지 bottom safe area inset를 계산해서 판단하는 연산 프로퍼티입니다. + + */ + +public extension UIDevice { + var hasNotch: Bool { + UIScreen.main.bounds.height > 736 ? true : false + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Utils/getClassName.swift b/Runnect-iOS/Runnect-iOS/Global/Utils/getClassName.swift new file mode 100644 index 00000000..15692eb4 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Utils/getClassName.swift @@ -0,0 +1,26 @@ +// +// getClassName.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import UIKit + +/** + + - Description: + + 각 VC,TVC,CVC의 className을 String으로 가져올 수 있도록 연산 프로퍼티를 설정합니다. + 요 값들은 나중에 Identifier에 잘 써먹을 수 있습니다 ^__^ +*/ + +extension NSObject { + public static var className: String { + NSStringFromClass(self.classForCoder()).components(separatedBy: ".").last! + } + + public var className: String { + NSStringFromClass(self.classForCoder).components(separatedBy: ".").last! + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Utils/makeAlert.swift b/Runnect-iOS/Runnect-iOS/Global/Utils/makeAlert.swift new file mode 100644 index 00000000..b7765339 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Utils/makeAlert.swift @@ -0,0 +1,37 @@ +// +// makeAlert.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import UIKit + +/** + + - Description: + + 요청하는(OK,취소)버튼만 있는 UIAlertController를 간편하게 만들기 위한 extension입니다. + + - parameters: + - title: 알림창에 뜨는 타이틀 부분입니다. + - message: 타이틀 밑에 뜨는 메세지 부분입니다. + - okAction: 확인버튼을 눌렀을 때 동작하는 부분입니다. + - cancelAction: 취소버튼을 눌렀을 때 동작하는 부분입니다. + - completion: 해당 UIAlertController가 띄워졌을 때, 동작하는 부분입니다. + + + */ +public extension UIViewController { + func makeAlert(title: String, + message: String, + okAction: ((UIAlertAction) -> Void)? = nil, + completion: (() -> Void)? = nil) { + makeVibrate() + let alertViewController = UIAlertController(title: title, message: message, + preferredStyle: .alert) + let okAction = UIAlertAction(title: "확인", style: .default, handler: okAction) + alertViewController.addAction(okAction) + self.present(alertViewController, animated: true, completion: completion) + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Utils/makeVibrate.swift b/Runnect-iOS/Runnect-iOS/Global/Utils/makeVibrate.swift new file mode 100644 index 00000000..630b1e23 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Utils/makeVibrate.swift @@ -0,0 +1,37 @@ +// +// makeVibrate.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import UIKit + +/** + + - Description: + + VC나 View 내에서 해당 함수를 호출하면, 햅틱이 발생하는 메서드입니다. + 버튼을 누르거나 유저에게 특정 행동이 발생했다는 것을 알려주기 위해 다음과 같은 햅틱을 활용합니다. + + - parameters: + - degree: 터치의 세기 정도를 정의합니다. 보통은 medium,light를 제일 많이 활용합니다?! + 따라서 파라미터 기본값을 . medium으로 정의했습니다. + +*/ + +public extension UIViewController { + + func makeVibrate(degree: UIImpactFeedbackGenerator.FeedbackStyle = .medium) { + let generator = UIImpactFeedbackGenerator(style: degree) + generator.impactOccurred() + } +} + +public extension UIView { + + func makeVibrate(degree: UIImpactFeedbackGenerator.FeedbackStyle = .medium) { + let generator = UIImpactFeedbackGenerator(style: degree) + generator.impactOccurred() + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Utils/setImage.swift b/Runnect-iOS/Runnect-iOS/Global/Utils/setImage.swift new file mode 100644 index 00000000..d05d2898 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Utils/setImage.swift @@ -0,0 +1,54 @@ +// +// setImage.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import UIKit +import Kingfisher + +public extension UIImageView { + func setImage(with urlString: String, placeholder: String? = nil, completion: ((UIImage?) -> Void)? = nil) { + let cache = ImageCache.default + if urlString == "" { + // URL 빈 이미지로 넘겨 받았을 경우, 아래에 UIImage에 기본 사진을 추가 하면 된다. + self.image = UIImage() + } else { + cache.retrieveImage(forKey: urlString) { result in + result.success { imageCache in + if let image = imageCache.image { + self.image = image + completion?(image) + } else { + self.setNewImage(with: urlString, placeholder: placeholder, completion: completion) + } + }.catch { _ in + self.setNewImage(with: urlString, placeholder: placeholder, completion: completion) + } + } + } + } + + private func setNewImage(with urlString: String, placeholder: String? = "img_placeholder", completion: ((UIImage?) -> Void)? = nil) { + guard let url = URL(string: urlString) else { return } + let resource = ImageResource(downloadURL: url, cacheKey: urlString) + let placeholderImage = UIImage(named: "img_placeholder") + let placeholder = placeholderImage + + self.kf.setImage( + with: resource, + placeholder: placeholder, + options: [ + .scaleFactor(UIScreen.main.scale/4), + .transition(.fade(0.5)), + .cacheMemoryOnly + ], + completionHandler: { result in + result.success { imageResult in + completion?(imageResult.image) + } + } + ) + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Utils/setRootViewController.swift b/Runnect-iOS/Runnect-iOS/Global/Utils/setRootViewController.swift new file mode 100644 index 00000000..09cd12e0 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Utils/setRootViewController.swift @@ -0,0 +1,37 @@ +// +// setRootViewController.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import UIKit + +/** + + - Description: + + RootViewController를 만들어주는 유틸입니다. SnapShot을 찍어서 전환합니다. + +*/ +enum ViewControllerUtils { + static func setRootViewController(window: UIWindow, viewController: UIViewController, withAnimation: Bool) { + if !withAnimation { + window.rootViewController = viewController + window.makeKeyAndVisible() + return + } + + if let snapshot = window.snapshotView(afterScreenUpdates: true) { + viewController.view.addSubview(snapshot) + window.rootViewController = viewController + window.makeKeyAndVisible() + + UIView.animate(withDuration: 0.4, animations: { + snapshot.layer.opacity = 0 + }, completion: { _ in + snapshot.removeFromSuperview() + }) + } + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Utils/setStatusBarBackgroundColor.swift b/Runnect-iOS/Runnect-iOS/Global/Utils/setStatusBarBackgroundColor.swift new file mode 100644 index 00000000..c3c83b1f --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Utils/setStatusBarBackgroundColor.swift @@ -0,0 +1,23 @@ +// +// setStatusBarBackgroundColor.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import UIKit + +extension UIViewController { + public func setStatusBarBackgroundColor(_ color: UIColor?) { + if #available(iOS 13.0, *) { + let window = UIApplication.shared.windows.first + let statusBarManager = window?.windowScene?.statusBarManager + let statusBarView = UIView(frame: statusBarManager?.statusBarFrame ?? .zero) + statusBarView.backgroundColor = color + window?.addSubview(statusBarView) + } else { + let statusBarView = UIApplication.shared.value(forKey: "statusBar") as? UIView + statusBarView?.backgroundColor = color + } + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Utils/setTextLineHeight.swift b/Runnect-iOS/Runnect-iOS/Global/Utils/setTextLineHeight.swift new file mode 100644 index 00000000..8a207bb4 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Utils/setTextLineHeight.swift @@ -0,0 +1,42 @@ +// +// setTextLineHeight.swift +// Runnect-iOS +// +// Created by sejin on 2022/12/29. +// + +import UIKit + +extension UILabel { + public func setTextWithLineHeight(text: String?, lineHeightMultiple: CGFloat) { + if let text = text { + let style = NSMutableParagraphStyle() + style.lineHeightMultiple = lineHeightMultiple + + let attributes: [NSAttributedString.Key: Any] = [ + .paragraphStyle: style + ] + + let attrString = NSAttributedString(string: text, + attributes: attributes) + self.attributedText = attrString + } + } +} + +extension UITextView { + public func setTextWithLineHeight(text: String?, lineHeightMultiple: CGFloat) { + if let text = text { + let style = NSMutableParagraphStyle() + style.lineHeightMultiple = lineHeightMultiple + + let attributes: [NSAttributedString.Key: Any] = [ + .paragraphStyle: style + ] + + let attrString = NSAttributedString(string: text, + attributes: attributes) + self.attributedText = attrString + } + } +} From d93a08ca9306379a9784c397d21bf35c5643177a Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Thu, 29 Dec 2022 18:56:29 +0900 Subject: [PATCH 6/7] =?UTF-8?q?[Setting]=20#1=20-=20SwiftLint=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Runnect-iOS/.swiftlint.yml | 16 +++++++++++++ .../Runnect-iOS.xcodeproj/project.pbxproj | 23 +++++++++++++++++++ .../Global/Extension/UIKit+/UIView+.swift | 2 +- .../Global/Utils/calculatePastTime.swift | 2 +- .../Presentation/TabBar/ViewController.swift | 3 --- 5 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 Runnect-iOS/.swiftlint.yml diff --git a/Runnect-iOS/.swiftlint.yml b/Runnect-iOS/.swiftlint.yml new file mode 100644 index 00000000..b4b8db1c --- /dev/null +++ b/Runnect-iOS/.swiftlint.yml @@ -0,0 +1,16 @@ +disabled_rules: + - trailing_whitespace + - identifier_name + - line_length + - type_name + - legacy_constructor + - unused_setter_value + +included: + - Runnect-iOS +excluded: + # AppDelegate, SceneDelegate file 무시 + - Runnect-iOS/Global/Supports/AppDelegate.swift + - Runnect-iOS/Global/Supports/SceneDelegate.swift + +force_cast: warning diff --git a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj index c460591a..dd2eb573 100644 --- a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj +++ b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj @@ -50,6 +50,7 @@ CE66560E295D92A500C64E12 /* setStatusBarBackgroundColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE66560D295D92A500C64E12 /* setStatusBarBackgroundColor.swift */; }; CE665610295D92C200C64E12 /* setTextLineHeight.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE66560F295D92C200C64E12 /* setTextLineHeight.swift */; }; CE665612295D92E400C64E12 /* UserDefaultWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE665611295D92E400C64E12 /* UserDefaultWrapper.swift */; }; + CE665615295D989A00C64E12 /* .swiftlint.yml in Resources */ = {isa = PBXBuildFile; fileRef = CE665614295D989A00C64E12 /* .swiftlint.yml */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -106,6 +107,7 @@ CE66560D295D92A500C64E12 /* setStatusBarBackgroundColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = setStatusBarBackgroundColor.swift; sourceTree = ""; }; CE66560F295D92C200C64E12 /* setTextLineHeight.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = setTextLineHeight.swift; sourceTree = ""; }; CE665611295D92E400C64E12 /* UserDefaultWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultWrapper.swift; sourceTree = ""; }; + CE665614295D989A00C64E12 /* .swiftlint.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = .swiftlint.yml; sourceTree = ""; }; E837271A78E1C0A0C30789BF /* Pods-Runnect-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runnect-iOS.release.xcconfig"; path = "Target Support Files/Pods-Runnect-iOS/Pods-Runnect-iOS.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -141,6 +143,7 @@ CE4545BC295D7AF4003201E1 = { isa = PBXGroup; children = ( + CE665614295D989A00C64E12 /* .swiftlint.yml */, CE4545C7295D7AF4003201E1 /* Runnect-iOS */, CE4545C6295D7AF4003201E1 /* Products */, 3F7098551CF7A77F3FE7EB2B /* Pods */, @@ -397,6 +400,7 @@ buildConfigurationList = CE4545D9295D7AF5003201E1 /* Build configuration list for PBXNativeTarget "Runnect-iOS" */; buildPhases = ( 5E54A0A4C236151ED373DD47 /* [CP] Check Pods Manifest.lock */, + CE665613295D980700C64E12 /* ShellScript */, CE4545C1295D7AF4003201E1 /* Sources */, CE4545C2295D7AF4003201E1 /* Frameworks */, CE4545C3295D7AF4003201E1 /* Resources */, @@ -449,6 +453,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + CE665615295D989A00C64E12 /* .swiftlint.yml in Resources */, CE6655BF295D82E200C64E12 /* .gitkeep in Resources */, CE4545D5295D7AF5003201E1 /* LaunchScreen.storyboard in Resources */, CE4545D2295D7AF5003201E1 /* Assets.xcassets in Resources */, @@ -480,6 +485,24 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; + CE665613295D980700C64E12 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 12; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "export PATH=\"$PATH:/opt/homebrew/bin\"\nif which swiftlint > /dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n"; + }; CF0A7C4CF1329EF14A755C46 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; diff --git a/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIView+.swift b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIView+.swift index 75efc0b1..5b0f12ee 100644 --- a/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIView+.swift +++ b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIView+.swift @@ -15,7 +15,7 @@ extension UIView { } func addSubviewFromNib(view: UIView) { - let view = Bundle.main.loadNibNamed(view.className, owner: self, options: nil)?.first as! UIView + guard let view = Bundle.main.loadNibNamed(view.className, owner: self, options: nil)?.first as? UIView else { return } view.frame = bounds view.clipsToBounds = true addSubview(view) diff --git a/Runnect-iOS/Runnect-iOS/Global/Utils/calculatePastTime.swift b/Runnect-iOS/Runnect-iOS/Global/Utils/calculatePastTime.swift index 96fbabcd..ccde8c97 100644 --- a/Runnect-iOS/Runnect-iOS/Global/Utils/calculatePastTime.swift +++ b/Runnect-iOS/Runnect-iOS/Global/Utils/calculatePastTime.swift @@ -31,7 +31,7 @@ public func calculatePastTime(date: String) -> String { let articleDate = format.string(from: tempDate) var useTime = Int(krTime!.timeIntervalSince(tempDate)) - useTime = useTime - 32400 + useTime -= 32400 if useTime < minute { message = "방금 전" diff --git a/Runnect-iOS/Runnect-iOS/Presentation/TabBar/ViewController.swift b/Runnect-iOS/Runnect-iOS/Presentation/TabBar/ViewController.swift index 0b971380..36555ce9 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/TabBar/ViewController.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/TabBar/ViewController.swift @@ -13,7 +13,4 @@ class ViewController: UIViewController { super.viewDidLoad() view.backgroundColor = .blue } - - } - From b949752a52110650fedce929e6e6083449ea0bd5 Mon Sep 17 00:00:00 2001 From: SeJin Lee Date: Thu, 29 Dec 2022 20:40:30 +0900 Subject: [PATCH 7/7] =?UTF-8?q?[Setting]=20#1=20-=20PR=20=ED=83=AC?= =?UTF-8?q?=ED=94=8C=EB=A6=BF=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/PULL_REQUEST_TEMPLATE.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..60e76aaf --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,25 @@ +## 🌱 작업한 내용 + + + +- 작업 내용 1 + +## 🌱 PR Point + + + +- PR Point 1 + +## 📸 스크린샷 + + + +| 구현 내용 | 스크린샷 | +| :-------------: | :----------: | +| ex. 로그인 화면 | 파일첨부바람 | + +## 📮 관련 이슈 + + + +- Resolved: #이슈번호