From 6e722e4884664f52f8dd1c285f4f9aa0d802c058 Mon Sep 17 00:00:00 2001 From: yungu0010 Date: Thu, 23 Nov 2023 23:57:40 +0900 Subject: [PATCH 1/4] =?UTF-8?q?[Feat]=20#205=20-=20=EC=84=A0=ED=83=9D?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20-=20=ED=86=A0=ED=81=B0=20=EC=9C=A0?= =?UTF-8?q?=ED=9A=A8=20=ED=8C=90=EB=8B=A8=20=EB=A1=9C=EC=A7=81=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iOS-NOTTODO/Application/AppDelegate.swift | 141 ++++++++++++++---- 1 file changed, 114 insertions(+), 27 deletions(-) diff --git a/iOS-NOTTODO/iOS-NOTTODO/Application/AppDelegate.swift b/iOS-NOTTODO/iOS-NOTTODO/Application/AppDelegate.swift index 8e4a9897..f5dc3f41 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Application/AppDelegate.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Application/AppDelegate.swift @@ -28,13 +28,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { KakaoSDK.initSDK(appKey: Bundle.main.kakaoAPIKey) FirebaseApp.configure() - if KeychainUtil.getAccessToken() != "" { - self.skipAuthView() - print("토큰 유효") - } else { - // self.showAuthView() - // 토큰이 유효하지 않을 경우 일단은 온보딩->로그인->홈 이렇게만 가도록 - } + checkForUpdate() // 메시지 대리자 설정 Messaging.messaging().delegate = self @@ -43,9 +37,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate { Messaging.messaging().isAutoInitEnabled = true // 푸시 알림 권한 설정 및 푸시 알림에 앱 등록 - UNUserNotificationCenter.current().delegate = self - let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound] - UNUserNotificationCenter.current().requestAuthorization(options: authOptions, completionHandler: { _, _ in }) + // UNUserNotificationCenter.current().delegate = self + // let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound] + // UNUserNotificationCenter.current().requestAuthorization(options: authOptions, completionHandler: { _, _ in }) // device token 요청. application.registerForRemoteNotifications() @@ -53,17 +47,17 @@ class AppDelegate: UIResponder, UIApplicationDelegate { return true } - func showAuthView() { - DispatchQueue.main.async { - if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene, - let window = windowScene.windows.first { - let authViewController = AuthViewController() - let navigationController = UINavigationController(rootViewController: authViewController) - window.rootViewController = navigationController - window.makeKeyAndVisible() - } - } - } +// func showAuthView() { +// DispatchQueue.main.async { +// if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene, +// let window = windowScene.windows.first { +// let authViewController = AuthViewController() +// let navigationController = UINavigationController(rootViewController: authViewController) +// window.rootViewController = navigationController +// window.makeKeyAndVisible() +// } +// } +// } func skipAuthView() { // 홈 화면으로 바로 이동 @@ -103,22 +97,115 @@ func application(_ application: UIApplication, didDiscardSceneSessions sceneSess extension AppDelegate: MessagingDelegate { /// 현재 등록 토큰 가져오기. - func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) { - if let fcmToken = fcmToken { - KeychainUtil.setFcmToken(fcmToken) - } + func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) { + if let fcmToken = fcmToken { + KeychainUtil.setFcmToken(fcmToken) } + } } extension AppDelegate: UNUserNotificationCenterDelegate { - + /// foreground에서 러닝 중에 앱에 도착하는 알림을 다루는 메서드 func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler([.list, .sound, .badge, .banner]) } - + /// 도착한 notification에 대한 유저의 반응을 다루는 메서드 func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { completionHandler() } } + +extension AppDelegate { + func checkForUpdate() { + // 앱스토어 버전 + guard let appstoreVersion = getAppstoreVersion() else { return } + + // 현재 설치된 앱의 버전 + guard let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String else { return } + + if compareVersion(userVersion: appVersion, appstoreVersion: appstoreVersion) { + DispatchQueue.main.async { + self.showUpdateAlert() + } + } else { + if KeychainUtil.getAccessToken() != "" { + self.skipAuthView() + print("토큰 유효") + } + } + } + + /// 버전 비교하는 메서드 + func compareVersion(userVersion: String, appstoreVersion:String) -> Bool { + let userMajor = userVersion.split(separator: ".").map {Int($0)!}[0] + let appstoreMajor = appstoreVersion.split(separator: ".").map {Int($0)!}[0] + + if userMajor < appstoreMajor { + return true + } + + let userMinor = userVersion.split(separator: ".").map {Int($0)!}[1] + let appstoreMinor = appstoreVersion.split(separator: ".").map {Int($0)!}[1] + + if userMinor < appstoreMinor { + return true + } + + let userPatch = userVersion.split(separator: ".").map {Int($0)!}[2] + let appstorePatch = appstoreVersion.split(separator: ".").map {Int($0)!}[2] + + if userPatch < appstorePatch { + return true + } + + return false + } + + /// 앱스토어에 배포된 버전 가져오는 메서드 + func getAppstoreVersion() -> String? { + let appleID = Bundle.main.appleId + guard let url = URL(string: "https://itunes.apple.com/lookup?id=\(appleID)"), + let data = try? Data(contentsOf: url), + let json = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any], + let results = json["results"] as? [[String: Any]], + let appStoreVersion = results[0]["version"] as? String else { + return nil + } + return appStoreVersion + } + + /// 선택 업데이트 경고창 + func showUpdateAlert() { + let alertController = UIAlertController( + title: I18N.update, + message: I18N.updateAlert, + preferredStyle: .alert + ) + + let updateAction = UIAlertAction(title: I18N.update, style: .default) { _ in + // App Store로 이동 + if let appStoreURL = URL(string: "https://itunes.apple.com/app/\(Bundle.main.appleId)") { + UIApplication.shared.open(appStoreURL, options: [:], completionHandler: {_ in + if KeychainUtil.getAccessToken() != "" { + self.skipAuthView() + print("토큰 유효") + } + }) + } + } + + let cancelAction = UIAlertAction(title: I18N.later, style: .default) + + alertController.addAction(updateAction) + alertController.addAction(cancelAction) + + if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene { + if let keyWindow = windowScene.windows.first, + let rootViewController = keyWindow.rootViewController { + rootViewController.present(alertController, animated: true, completion: nil) + } + } + } +} From 264da30afe445738ce3971564e1539555e0eb945 Mon Sep 17 00:00:00 2001 From: yungu0010 Date: Thu, 23 Nov 2023 23:58:43 +0900 Subject: [PATCH 2/4] =?UTF-8?q?[Add]=20#205=20-=20=EC=84=A0=ED=83=9D=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=EB=A5=BC=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20appId=EC=99=80=20=EB=AC=B8=EC=9E=90=EC=97=B4=20?= =?UTF-8?q?=EB=A6=AC=ED=84=B0=EB=9F=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj | 4 ++-- .../iOS-NOTTODO/Global/Extensions/Bundle+.swift | 12 ++++++++++++ .../iOS-NOTTODO/Global/Literals/Strings.swift | 6 ++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj b/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj index 92673262..90f50f11 100644 --- a/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj +++ b/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj @@ -1519,7 +1519,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.1; + MARKETING_VERSION = 1.0.0; PRODUCT_BUNDLE_IDENTIFIER = "nottodo.iOS-NOTTODO"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1557,7 +1557,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.1; + MARKETING_VERSION = 1.0.0; PRODUCT_BUNDLE_IDENTIFIER = "nottodo.iOS-NOTTODO"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/Bundle+.swift b/iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/Bundle+.swift index 89f96b1e..d752fe1d 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/Bundle+.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Global/Extensions/Bundle+.swift @@ -44,4 +44,16 @@ extension Bundle { } return value } + + var appleId: String { + guard let filePath = Bundle.main.path(forResource: "API_KEY", ofType: "plist") else { + fatalError("Could't find file 'API_KEY.plist'.") + } + let plist = NSDictionary(contentsOfFile: filePath) + + guard let value = plist?.object(forKey: "APPLE_ID") as? String else { + fatalError("Couldn't find key 'APPLE_ID' in 'API_KEY.plist'.") + } + return value + } } diff --git a/iOS-NOTTODO/iOS-NOTTODO/Global/Literals/Strings.swift b/iOS-NOTTODO/iOS-NOTTODO/Global/Literals/Strings.swift index 04be6159..dd7d65c9 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Global/Literals/Strings.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Global/Literals/Strings.swift @@ -162,6 +162,12 @@ struct I18N { static let delete = "삭제하기" static let deleteModalTitle = "삭제하시겠습니까?" static let deleteModalSubtitle = "한 번 삭제하면 되돌릴 수 없어요." + static let update = "업데이트" + static let updateAlert = """ + 최신 업데이트가 있습니다. + 업데이트하시겠습니까? + """ + static let later = "나중에" /// home static let subText = "*달성 가능한 계획을 위해 다가올 일주일만 선택할 수 있어요" From 25f866ac77ae6ee90548c0f3db27221946185b65 Mon Sep 17 00:00:00 2001 From: yungu0010 Date: Thu, 30 Nov 2023 20:01:29 +0900 Subject: [PATCH 3/4] =?UTF-8?q?[Chore]=20#205=20-=20lint=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- iOS-NOTTODO/iOS-NOTTODO/Application/AppDelegate.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iOS-NOTTODO/iOS-NOTTODO/Application/AppDelegate.swift b/iOS-NOTTODO/iOS-NOTTODO/Application/AppDelegate.swift index f5dc3f41..6a1ae761 100644 --- a/iOS-NOTTODO/iOS-NOTTODO/Application/AppDelegate.swift +++ b/iOS-NOTTODO/iOS-NOTTODO/Application/AppDelegate.swift @@ -138,7 +138,7 @@ extension AppDelegate { } /// 버전 비교하는 메서드 - func compareVersion(userVersion: String, appstoreVersion:String) -> Bool { + func compareVersion(userVersion: String, appstoreVersion: String) -> Bool { let userMajor = userVersion.split(separator: ".").map {Int($0)!}[0] let appstoreMajor = appstoreVersion.split(separator: ".").map {Int($0)!}[0] From b2f53c71e807ae24430881b277826ca3f9015729 Mon Sep 17 00:00:00 2001 From: yungu0010 Date: Thu, 30 Nov 2023 20:03:40 +0900 Subject: [PATCH 4/4] =?UTF-8?q?[Fix]=20#205=20-=20version=20=EC=B5=9C?= =?UTF-8?q?=EC=8B=A0=EC=9C=BC=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj b/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj index 90f50f11..92673262 100644 --- a/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj +++ b/iOS-NOTTODO/iOS-NOTTODO.xcodeproj/project.pbxproj @@ -1519,7 +1519,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.0; + MARKETING_VERSION = 1.0.1; PRODUCT_BUNDLE_IDENTIFIER = "nottodo.iOS-NOTTODO"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1557,7 +1557,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.0; + MARKETING_VERSION = 1.0.1; PRODUCT_BUNDLE_IDENTIFIER = "nottodo.iOS-NOTTODO"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = "";