diff --git a/WebAppUIKitBase.xcodeproj/project.pbxproj b/WebAppUIKitBase.xcodeproj/project.pbxproj
index 29fdb8b..39e5df9 100644
--- a/WebAppUIKitBase.xcodeproj/project.pbxproj
+++ b/WebAppUIKitBase.xcodeproj/project.pbxproj
@@ -6,6 +6,11 @@
objectVersion = 77;
objects = {
+/* Begin PBXBuildFile section */
+ A7D80D4D2CC5DFFF00E93F4D /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = A7D80D4C2CC5DFFF00E93F4D /* SnapKit */; };
+ A7D80D502CC5E01D00E93F4D /* Alamofire in Frameworks */ = {isa = PBXBuildFile; productRef = A7D80D4F2CC5E01D00E93F4D /* Alamofire */; };
+/* End PBXBuildFile section */
+
/* Begin PBXFileReference section */
A749CDFD2CC5D8CD0038D13D /* WebAppUIKitBase.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WebAppUIKitBase.app; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
@@ -36,6 +41,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ A7D80D4D2CC5DFFF00E93F4D /* SnapKit in Frameworks */,
+ A7D80D502CC5E01D00E93F4D /* Alamofire in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -78,6 +85,8 @@
);
name = WebAppUIKitBase;
packageProductDependencies = (
+ A7D80D4C2CC5DFFF00E93F4D /* SnapKit */,
+ A7D80D4F2CC5E01D00E93F4D /* Alamofire */,
);
productName = WebAppUIKitBase;
productReference = A749CDFD2CC5D8CD0038D13D /* WebAppUIKitBase.app */;
@@ -107,6 +116,10 @@
);
mainGroup = A749CDF42CC5D8CD0038D13D;
minimizedProjectReferenceProxies = 1;
+ packageReferences = (
+ A7D80D4B2CC5DFFF00E93F4D /* XCRemoteSwiftPackageReference "SnapKit" */,
+ A7D80D4E2CC5E01D00E93F4D /* XCRemoteSwiftPackageReference "Alamofire" */,
+ );
preferredProjectObjectVersion = 77;
productRefGroup = A749CDFE2CC5D8CD0038D13D /* Products */;
projectDirPath = "";
@@ -144,20 +157,20 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 1;
+ CURRENT_PROJECT_VERSION = 2.0.8.1;
DEVELOPMENT_TEAM = 45MYH7ZHUQ;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = WebAppUIKitBase/Info.plist;
+ INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "검색과 길안내를 위해 사용합니다.";
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";
+ INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
+ INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
- MARKETING_VERSION = 1.0;
+ MARKETING_VERSION = 2.0.8;
PRODUCT_BUNDLE_IDENTIFIER = "kr.kro.sean-k.WebAppUIKitBase";
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
@@ -176,20 +189,20 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 1;
+ CURRENT_PROJECT_VERSION = 2.0.8.1;
DEVELOPMENT_TEAM = 45MYH7ZHUQ;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = WebAppUIKitBase/Info.plist;
+ INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "검색과 길안내를 위해 사용합니다.";
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";
+ INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
+ INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
- MARKETING_VERSION = 1.0;
+ MARKETING_VERSION = 2.0.8;
PRODUCT_BUNDLE_IDENTIFIER = "kr.kro.sean-k.WebAppUIKitBase";
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
@@ -343,6 +356,38 @@
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
+
+/* Begin XCRemoteSwiftPackageReference section */
+ A7D80D4B2CC5DFFF00E93F4D /* XCRemoteSwiftPackageReference "SnapKit" */ = {
+ isa = XCRemoteSwiftPackageReference;
+ repositoryURL = "https://github.com/SnapKit/SnapKit.git";
+ requirement = {
+ kind = upToNextMajorVersion;
+ minimumVersion = 5.7.1;
+ };
+ };
+ A7D80D4E2CC5E01D00E93F4D /* XCRemoteSwiftPackageReference "Alamofire" */ = {
+ isa = XCRemoteSwiftPackageReference;
+ repositoryURL = "https://github.com/Alamofire/Alamofire.git";
+ requirement = {
+ kind = upToNextMajorVersion;
+ minimumVersion = 5.10.1;
+ };
+ };
+/* End XCRemoteSwiftPackageReference section */
+
+/* Begin XCSwiftPackageProductDependency section */
+ A7D80D4C2CC5DFFF00E93F4D /* SnapKit */ = {
+ isa = XCSwiftPackageProductDependency;
+ package = A7D80D4B2CC5DFFF00E93F4D /* XCRemoteSwiftPackageReference "SnapKit" */;
+ productName = SnapKit;
+ };
+ A7D80D4F2CC5E01D00E93F4D /* Alamofire */ = {
+ isa = XCSwiftPackageProductDependency;
+ package = A7D80D4E2CC5E01D00E93F4D /* XCRemoteSwiftPackageReference "Alamofire" */;
+ productName = Alamofire;
+ };
+/* End XCSwiftPackageProductDependency section */
};
rootObject = A749CDF52CC5D8CD0038D13D /* Project object */;
}
diff --git a/WebAppUIKitBase.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/WebAppUIKitBase.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
new file mode 100644
index 0000000..1d89461
--- /dev/null
+++ b/WebAppUIKitBase.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
@@ -0,0 +1,24 @@
+{
+ "originHash" : "4d1117f641c000c6545947e4d48e126cc17473ec53f643df82900a33ad4936b2",
+ "pins" : [
+ {
+ "identity" : "alamofire",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/Alamofire/Alamofire.git",
+ "state" : {
+ "revision" : "e16d3481f5ed35f0472cb93350085853d754913f",
+ "version" : "5.10.1"
+ }
+ },
+ {
+ "identity" : "snapkit",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/SnapKit/SnapKit.git",
+ "state" : {
+ "revision" : "2842e6e84e82eb9a8dac0100ca90d9444b0307f4",
+ "version" : "5.7.1"
+ }
+ }
+ ],
+ "version" : 3
+}
diff --git a/WebAppUIKitBase.xcodeproj/project.xcworkspace/xcuserdata/seankim.xcuserdatad/UserInterfaceState.xcuserstate b/WebAppUIKitBase.xcodeproj/project.xcworkspace/xcuserdata/seankim.xcuserdatad/UserInterfaceState.xcuserstate
index 6c34935..a0b0982 100644
Binary files a/WebAppUIKitBase.xcodeproj/project.xcworkspace/xcuserdata/seankim.xcuserdatad/UserInterfaceState.xcuserstate and b/WebAppUIKitBase.xcodeproj/project.xcworkspace/xcuserdata/seankim.xcuserdatad/UserInterfaceState.xcuserstate differ
diff --git a/WebAppUIKitBase.xcodeproj/xcuserdata/seankim.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/WebAppUIKitBase.xcodeproj/xcuserdata/seankim.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
new file mode 100644
index 0000000..f49fa77
--- /dev/null
+++ b/WebAppUIKitBase.xcodeproj/xcuserdata/seankim.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
@@ -0,0 +1,6 @@
+
+
+
diff --git a/WebAppUIKitBase/AppDelegate.swift b/WebAppUIKitBase/AppDelegate.swift
deleted file mode 100644
index 2678098..0000000
--- a/WebAppUIKitBase/AppDelegate.swift
+++ /dev/null
@@ -1,36 +0,0 @@
-//
-// AppDelegate.swift
-// WebAppUIKitBase
-//
-// Created by Sean Kim on 10/21/24.
-//
-
-import UIKit
-
-@main
-class AppDelegate: UIResponder, UIApplicationDelegate {
-
-
-
- func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
- // Override point for customization after application launch.
- return true
- }
-
- // MARK: UISceneSession Lifecycle
-
- func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
- // Called when a new scene session is being created.
- // Use this method to select a configuration to create the new scene with.
- return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
- }
-
- func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
- // Called when the user discards a scene session.
- // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
- // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
- }
-
-
-}
-
diff --git a/WebAppUIKitBase/Common/AppDelegate.swift b/WebAppUIKitBase/Common/AppDelegate.swift
index 4dd12c0..a110ff7 100644
--- a/WebAppUIKitBase/Common/AppDelegate.swift
+++ b/WebAppUIKitBase/Common/AppDelegate.swift
@@ -7,25 +7,43 @@
import UIKit
+import AdSupport
+import AppTrackingTransparency
+
@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)
+
+ /// 앱이 Active 로 전환될때 호출 : back -> fore 시 호출
+ func applicationDidBecomeActive(_ application: UIApplication) {
+
+ DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
+ ATTrackingManager.requestTrackingAuthorization(completionHandler: { status in
+ switch status {
+ case .notDetermined:
+ printLog(status)
+ case .restricted:
+ printLog(status)
+ case .denied:
+ printLog(status)
+ case .authorized:
+ printLog(status)
+ }
+ })
+ }
}
-
- 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.
+
+ func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
+ let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
+ let token = tokenParts.joined()
+ printLog("Device Tokens: \(token)")
}
diff --git a/WebAppUIKitBase/Common/CommonUtils.swift b/WebAppUIKitBase/Common/CommonUtils.swift
index f62c8e7..931064e 100644
--- a/WebAppUIKitBase/Common/CommonUtils.swift
+++ b/WebAppUIKitBase/Common/CommonUtils.swift
@@ -5,4 +5,128 @@
// Created by Sean Kim on 10/21/24.
//
-import Foundation
+import UIKit
+import CoreLocation
+
+import Alamofire
+
+class CommonUtils: NSObject, CLLocationManagerDelegate {
+ static let shared: CommonUtils = CommonUtils()
+
+ private override init() {}
+
+ //MARK: - Location
+ weak var locationDelegate: LocationDelegate?
+
+ let locationManager: CLLocationManager = {
+ let manager = CLLocationManager()
+ manager.desiredAccuracy = kCLLocationAccuracyBest
+ manager.distanceFilter = kCLDistanceFilterNone
+ return manager
+ }()
+ var lastLocation: CLLocation?
+
+
+ public func checkLocationPermission() {
+ printLog("[위치] Check Loc Permission")
+ locationManager.delegate = self
+ locationManager.requestWhenInUseAuthorization()
+ self.toggleUpdatingLocation(true)
+ }
+
+ public func toggleUpdatingLocation(_ toggle: Bool) {
+ if toggle {
+ locationManager.startUpdatingLocation()
+ } else {
+ locationManager.stopUpdatingLocation()
+ }
+ }
+
+ // 14이상인 경우만 산정해서 한거라서 14.0 미만을 원하면 다른 메서드를 만들어야 함
+ func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
+ printLog("[위치] locationManagerDidChangeAuthorization") // 처음 불러 올 떄 요거 불려짐
+ switch manager.authorizationStatus {
+ case .authorizedAlways, .authorizedWhenInUse, .authorized:
+ printLog("[위치] 권한 허용")
+ self.locationDelegate?.checkPermission(true)
+ self.toggleUpdatingLocation(true)
+ default:
+ printLog("[위치] 권한 미허용 & 기타 오류")
+ self.locationDelegate?.checkPermission(false)
+ self.toggleUpdatingLocation(false)
+
+ }
+ }
+
+ // 14이상인 경우만 산정해서 한거라서 14.0 미만을 원하면 다른 메서드를 만들어야 함
+ func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
+ printLog("[위치] didUpdateLocations") // 요건 값을 가져올 때 불려짐
+ switch manager.authorizationStatus {
+ case .authorizedAlways, .authorizedWhenInUse:
+ printLog("[위치] 권한 허용")
+ self.locationDelegate?.checkPermission(true)
+ if let location = locations.first{
+ printLog("[위치] 정보 수신 성공")
+ self.locationDelegate?.getLocation(location)
+ }
+ default:
+ printLog("[위치] 권한 미허용 & 기타 오류")
+ self.locationDelegate?.checkPermission(false)
+ }
+ }
+
+ func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
+ printLog("[위치] didFailWithError")
+ self.locationDelegate?.checkPermission(false)
+ }
+
+
+// MARK: - URL
+ func afGET(url: String, param: [String:String], headers: HTTPHeaders?) async throws -> Any {
+ return try await withCheckedThrowingContinuation { continuation in
+ AF.request(url,
+ method: .get,
+ parameters: param,
+ headers: headers)
+ .validate(statusCode: 200 ..< 300)
+ .responseString { response in
+ printLog("[LOG] response: \(response)")
+ switch response.result {
+ case .success(let value):
+ printLog("[LOG]")
+ continuation.resume(returning: value)
+ case .failure(let error):
+ printLog("[LOG]")
+ continuation.resume(throwing: error)
+ }
+ }
+ }
+ }
+
+ public func jsonToDict(_ input: String) -> [String: Any] {
+ if let jsonData = input.data(using: .utf8){
+ do {
+ if let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any] {
+ return jsonObject
+ }
+ } catch let error { // 이 부분
+ printLog("JSON ERROR: \(error))")
+ }
+ }
+ return [:]
+ }
+
+ public func jsonToType(_ input: String, as type: T.Type) -> T? {
+ if let jsonData = input.data(using: .utf8) {
+ do {
+ let decodedObject = try JSONDecoder().decode(T.self, from: jsonData)
+ return decodedObject
+ } catch let error {
+ printLog("JSON 디코딩 오류: \(error)")
+ }
+ }
+ return nil
+ }
+
+}
+
diff --git a/WebAppUIKitBase/Common/Prefix.swift b/WebAppUIKitBase/Common/Prefix.swift
index e9c4a3b..ff44f75 100644
--- a/WebAppUIKitBase/Common/Prefix.swift
+++ b/WebAppUIKitBase/Common/Prefix.swift
@@ -4,7 +4,7 @@
//
// Created by Sean Kim on 2/20/24.
//
-import SwiftUI
+import UIKit
// MARK: - TYPEALIAS
typealias VOID_TO_VOID = () -> ()
@@ -26,13 +26,6 @@ public func printLog(_ object: T, _ file: String = #file, _ function: String
#if DEBUG
let dateString = Date().convertString("yyyy/MM/dd HH:mm:ss:SSS")
Swift.print(
-// """
-// __________ __________
-// |* TIME = [\(dateString)] || FILE = [\(file.lastPathComponent)]
-// | NAME = [\(function)] || LINE = [\(line)]
-// |>>> PRINT = \(object)
-//  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
-// """
"""
__________ __________ __________ __________
* LOCATION : [\(file.lastPathComponent) : \(line)] - \(function)
@@ -149,9 +142,6 @@ func copyToClipboard(_ text: String){
-// MARK: - CUSTOM COMPONENTS
-
-
// MARK: - EXTENSION
extension String {
/// 마지막 경로 구성 요소
@@ -379,34 +369,27 @@ extension Date {
}
}
-
-extension Font {
- enum NPS_Font : String {
- case regular
- case bold
+extension UIViewController {
+ public func makeUIAlert(title: String, message: String, okTitle: String, okAction:((UIAlertAction) -> Void)? = nil, completion: (() -> ())? = nil) {
+ let alertController = UIAlertController(title: "\(title)", message: "\(message)", preferredStyle: .alert)
+ let okAction = UIAlertAction(title: "\(okTitle)", style: .default, handler: okAction)
+ alertController.addAction(okAction)
+ self.present(alertController, animated: true, completion: completion)
+ }
+
+ public func makeUITwoAlert(title: String, message: String, okTitle: String, okAction:((UIAlertAction) -> Void)? = nil, cancelTitle: String, cancelAction:((UIAlertAction) -> Void)? = nil, completion: (() -> ())? = nil) {
+ let alertController = UIAlertController(title: "\(title)", message: "\(message)", preferredStyle: .alert)
+ let okAction = UIAlertAction(title: "\(okTitle)", style: .default, handler: okAction)
+ alertController.addAction(okAction)
- var value: String {
- switch self {
- case .regular:
- return "NPS-font-Regular"
- case .bold:
- return "NPS-font-Bold"
- }
- }
+ let cancelAction = UIAlertAction(title: "\(cancelTitle)", style: .cancel, handler: cancelAction)
+ alertController.addAction(cancelAction)
+
+ self.present(alertController, animated: true, completion: completion)
}
-
- static func nps(font: NPS_Font = .regular, size: CGFloat = 12) -> Font {
- return .custom(font.value, size: size)
- }
-
-
}
-extension View {
- func endTextEditing() {
- UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
- }
-}
+
// MARK: - ANNOTATION
diff --git a/WebAppUIKitBase/Common/Protocol/LoactionProtocol.swift b/WebAppUIKitBase/Common/Protocol/LoactionProtocol.swift
index a351262..034daa4 100644
--- a/WebAppUIKitBase/Common/Protocol/LoactionProtocol.swift
+++ b/WebAppUIKitBase/Common/Protocol/LoactionProtocol.swift
@@ -5,4 +5,15 @@
// Created by Sean Kim on 10/21/24.
//
-import Foundation
+//import Foundation
+import CoreLocation
+
+protocol LocationDelegate: NSObject {
+ func checkPermission(_ type: Bool)
+ func getLocation(_ location: CLLocation)
+}
+
+extension LocationDelegate {
+ func checkPermission(_ type: Bool) {}
+ func getLocation(_ location: CLLocation) {}
+}
diff --git a/WebAppUIKitBase/Common/SceneDelegate.swift b/WebAppUIKitBase/Common/SceneDelegate.swift
index 8838e81..980d035 100644
--- a/WebAppUIKitBase/Common/SceneDelegate.swift
+++ b/WebAppUIKitBase/Common/SceneDelegate.swift
@@ -22,34 +22,15 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
window?.makeKeyAndVisible()
}
- 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 scene(_ scene: UIScene, openURLContexts URLContexts: Set) {
+ guard let url = URLContexts.first?.url else {
+ return
+ }
}
-
- 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/WebAppUIKitBase/Info.plist b/WebAppUIKitBase/Info.plist
index dd3c9af..0eb786d 100644
--- a/WebAppUIKitBase/Info.plist
+++ b/WebAppUIKitBase/Info.plist
@@ -15,8 +15,6 @@
Default Configuration
UISceneDelegateClassName
$(PRODUCT_MODULE_NAME).SceneDelegate
- UISceneStoryboardFile
- Main
diff --git a/WebAppUIKitBase/IntroVC.swift b/WebAppUIKitBase/IntroVC.swift
deleted file mode 100644
index c03da97..0000000
--- a/WebAppUIKitBase/IntroVC.swift
+++ /dev/null
@@ -1,8 +0,0 @@
-//
-// IntroVC.swift
-// WebAppUIKitBase
-//
-// Created by Sean Kim on 10/21/24.
-//
-
-import Foundation
diff --git a/WebAppUIKitBase/Scene/AppDelegate.swift b/WebAppUIKitBase/Scene/AppDelegate.swift
deleted file mode 100644
index 4dd12c0..0000000
--- a/WebAppUIKitBase/Scene/AppDelegate.swift
+++ /dev/null
@@ -1,33 +0,0 @@
-//
-// AppDelegate.swift
-// WebAppUIKitBase
-//
-// Created by Sean Kim on 10/21/24.
-//
-
-import UIKit
-
-@main
-class AppDelegate: UIResponder, UIApplicationDelegate {
- func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
- // Override point for customization after application launch.
- return true
- }
-
- // MARK: UISceneSession Lifecycle
-
- func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
- // Called when a new scene session is being created.
- // Use this method to select a configuration to create the new scene with.
- return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
- }
-
- func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
- // Called when the user discards a scene session.
- // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
- // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
- }
-
-
-}
-
diff --git a/WebAppUIKitBase/Scene/IntroVC.swift b/WebAppUIKitBase/Scene/IntroVC.swift
index 1e67d9e..35836a3 100644
--- a/WebAppUIKitBase/Scene/IntroVC.swift
+++ b/WebAppUIKitBase/Scene/IntroVC.swift
@@ -6,12 +6,205 @@
//
import UIKit
+import Alamofire
+
+import SnapKit
+import CoreLocation
class IntroVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
+ CommonUtils.shared.locationDelegate = self
+ }
+ override func viewDidAppear(_ animated: Bool) {
+ super.viewDidAppear(animated)
+ if isIllegalDevice() {
+ self.makeUIAlert(title: "안내",
+ message: "변경된 OS를 사용하는 기기는 서비스를 이용할 수 없습니다.",
+ okTitle: "확인") { _ in
+ exit(1)
+ }
+ } else {
+ if NetworkReachabilityManager.default?.isReachable == false {
+ self.makeUIAlert(title: "서비스 연결 문제 발생",
+ message: """
+ 네트워크 문제로 서비스에 연결하지 못하였습니다.
+ 네트워크 상태를 확인후 다시 실행해주세요.
+ """,
+ okTitle: "확인") { _ in
+ exit(1)
+ }
+ } else {
+ self.checkAppVersion()
+ }
+ }
+ }
+
+
+ private func checkAppVersion() {
+ Task {
+ do {
+ let result = try await CommonUtils.shared.afGET(url:VER_URL,
+ param: VER_PARAM,
+ headers: VER_HEADERS)
+// let result = """
+// {"status":{"code":"000","message":"성공"},"data":{"finalVer":"2.0.8","forceVer":"2.0.6","forceUpdtYn":"P","remark":"기능추가","checkVer":"9.9.9"}}
+// """
+ printLog("Success : \(result)")
+ let response = CommonUtils.shared.jsonToType("\(result)", as: VersionResponse.self)
+
+ if let code = response?.status.code, code == "000" {
+ if let currentVer = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String,
+ let finalVer = response?.data.finalVer, let forceVer = response?.data.forceVer,
+ let checkVer = response?.data.checkVer, let forceUpdtYn = response?.data.forceUpdtYn
+ {
+ switch self.versionCompare(currentVer, finalVer) {
+ case .equal, .bigger: // 업데이트 처리 필요 없음
+ CommonUtils.shared.checkLocationPermission()
+ case .smaller:
+ switch self.versionCompare(currentVer, forceVer) {
+ case .equal, .bigger:
+ if forceUpdtYn == "P" {// PASS라서 P 한건데 Y 해도 된다.
+ self.makeUITwoAlert(title: "업데이트 안내",
+ message: "최신 버전이 새로 나왔어요\n지금 업데이트하시겠어요?",
+ okTitle: "지금 업데이트",
+ okAction: { _ in
+ let appStoreURL = URL(string: "http://www.naver.com")!
+ UIApplication.shared.open(appStoreURL, options: [:], completionHandler: nil)
+ exit(1)
+ }, cancelTitle: "나중에") { _ in
+ CommonUtils.shared.checkLocationPermission()
+ }
+ } else {
+ CommonUtils.shared.checkLocationPermission()
+ }
+ case .smaller:
+ self.makeUIAlert(title: "업데이트 안내",
+ message: "앱을 사용하시려면\n최신버전으로 업데이트 해주세요",
+ okTitle: "지금 업데이트") { _ in
+ let appStoreURL = URL(string: "http://www.naver.com")!
+ UIApplication.shared.open(appStoreURL, options: [:], completionHandler: nil)
+ exit(1)
+ }
+ }
+ }
+ }
+ else {
+ throw NSError(domain: "com.version.API",
+ code: Int(response?.status.code ?? "") ?? -1,
+ userInfo: [NSLocalizedDescriptionKey: "Version is Wrong"])
+ }
+ } else {
+ throw NSError(domain: "com.version.API",
+ code: Int(response?.status.code ?? "") ?? -1,
+ userInfo: [NSLocalizedDescriptionKey: "Version is Wrong"])
+ }
+ } catch {
+ printLog("App Check ERROR: \(error)")
+ self.makeUIAlert(title: "서비스 연결 문제 발생",
+ message: """
+ 일시적인 장애 또는 네트워크 문제로
+ 서비스에 연결하지 못하였습니다.
+ 문제가 계속될 경우 고객센터로 문의해 주세요
+ """,
+ okTitle: "확인") { _ in
+ exit(1)
+ }
+ }
+ }
+ }
+ /// compareVer에 비교를 할 문자열을 넣어주면 된다.
+ ///
+ /// [결과 해석: 현재 버전이 비교 버전보다 (RESULT) 하다.]
+ private func versionCompare(_ currentVer: String, _ compareVer: String) -> CompareVersion {
+ let currentArray = currentVer.components(separatedBy: ["."]).map {Int($0) ?? 0}
+ let compareArray = compareVer.components(separatedBy: ["."]).map {Int($0) ?? 0}
+ printLog("Ver current: \(currentArray)")
+ printLog("Ver force: \(compareArray)")
+ for i in 0 ..< currentArray.count {
+ if currentArray[i] > compareArray[i] {
+ // 현재 버전이 비교하려는 버전보다 큰 경우 == 그냥 일반 동작을 시키면 된다.
+ return .bigger
+ } else if currentArray[i] < compareArray[i] {
+ // 현재 버전이 비교하려는 버전보다 작은 경우 == 업데이트 조건 처리
+ return .smaller
+ }
+ }
+
+ // 현재 버전이 비교 버전과 동일
+ return .equal
+ }
+
+ private func moveToWeb() {
+ let VC = MainWebVC()
+ if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
+ let window = windowScene.windows.first {
+ window.rootViewController = VC
+ }
}
}
+
+extension IntroVC: LocationDelegate {
+
+ func checkPermission(_ type: Bool) {
+ if type {
+// CommonUtils.CommonUtils.shared.saveUdData("Y", forKey: "locationYn")
+ } else {
+// CommonUtils.CommonUtils.shared.saveUdData("N", forKey: "locationYn")
+ self.moveToWeb()
+ }
+ }
+
+ func getLocation(_ location: CLLocation) {
+ CommonUtils.shared.locationManager.stopUpdatingLocation()
+ let lat = location.coordinate.latitude
+ let lng = location.coordinate.longitude
+ CommonUtils.shared.lastLocation = location
+ printLog("Intro \(String(describing: CommonUtils.shared.lastLocation))")
+ printLog("Intro Delegate = lattitude : \(lat) longitude : \(lng)")
+ printLog("위치 권한 허용 > 웹뷰 start")
+ self.moveToWeb()
+ }
+}
+
+
+
+enum CompareVersion: Int {
+ case equal = 0
+ case bigger
+ case smaller
+}
+
+class VersionResponse: Codable {
+ let status: Status
+ let data: VersionData
+}
+/// API 확인 변수
+///
+/// code: API 정상 확인 코드 (e.g. 000: 정상)
+///
+/// message: 코드에 대한 설명
+class Status: Codable {
+ let code, message: String
+
+}
+
+/// API 데이터 변수
+///
+/// finaclVer: 현재 가장 최신 버전
+///
+/// forceVer: 이 버전보다 미만의 버전은 강제 업데이트 시행
+///
+/// checkVer: 개발용 및 업데이트 관련 버전
+///
+/// forceUpdYn: P(Y) 등의 값일 시 finalVer보다 미만의 경우 선택 업데이트 동작 시행
+///
+/// remark: 현재 버전 관련한 설명
+class VersionData: Codable {
+ let finalVer, forceVer, checkVer: String?
+ let forceUpdtYn: String?
+ let remark: String?
+}
diff --git a/WebAppUIKitBase/Scene/MainWebVC.swift b/WebAppUIKitBase/Scene/MainWebVC.swift
index e9b227b..5e19d60 100644
--- a/WebAppUIKitBase/Scene/MainWebVC.swift
+++ b/WebAppUIKitBase/Scene/MainWebVC.swift
@@ -5,4 +5,15 @@
// Created by Sean Kim on 10/21/24.
//
-import Foundation
+import UIKit
+import WebKit
+
+import SnapKit
+
+class MainWebVC: UIViewController {
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+ self.view.backgroundColor = .white
+ }
+}
diff --git a/WebAppUIKitBase/Scene/SceneDelegate.swift b/WebAppUIKitBase/Scene/SceneDelegate.swift
deleted file mode 100644
index 8838e81..0000000
--- a/WebAppUIKitBase/Scene/SceneDelegate.swift
+++ /dev/null
@@ -1,55 +0,0 @@
-//
-// SceneDelegate.swift
-// WebAppUIKitBase
-//
-// Created by Sean Kim on 10/21/24.
-//
-
-import UIKit
-
-class SceneDelegate: UIResponder, UIWindowSceneDelegate {
-
- var window: UIWindow?
-
-
- func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
- guard let windowScene = (scene as? UIWindowScene) else { return }
- window = UIWindow(frame: UIScreen.main.bounds)
- window?.windowScene = windowScene
- // 여기서 메인 화면 띄우는 걸 함
- window?.rootViewController = IntroVC()
-
- window?.makeKeyAndVisible()
- }
-
- 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/WebAppUIKitBase/SecretCode.swift b/WebAppUIKitBase/SecretCode.swift
deleted file mode 100644
index 612a4ad..0000000
--- a/WebAppUIKitBase/SecretCode.swift
+++ /dev/null
@@ -1,8 +0,0 @@
-//
-// SecretCode.swift
-// WebAppUIKitBase
-//
-// Created by Sean Kim on 10/21/24.
-//
-
-import Foundation