Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/#311 앱스토어의 앱 버전과 기존 앱의 버전을 추적하여 강제 업데이트 기능 #313

Open
wants to merge 11 commits into
base: dev
Choose a base branch
from
Open
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ public extension [String: Plist.Value] {
"NMFClientId": "$(NAVERMAP_CLIENT_ID)",
"TERMS_OF_PRIVACY_URL": "$(TERMS_OF_PRIVACY_URL)",
"LOCATION_PRIVACY_URL": "$(LOCATION_PRIVACY_URL)",
"INQURY_URL": "$(INQURY_URL)"
"INQURY_URL": "$(INQURY_URL)",
"APPLE_ID": "$(APPLE_ID)",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

APPLE_ID가 유저의 apple 계정 id로 유추되어서 APPSTORE_ID와 같이 표현하면 어떨까요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

변경하겠습니다 !

]

static let additionalInfoPlist: Self = [
Expand Down
64 changes: 64 additions & 0 deletions Projects/App/Sources/AppStoreCheck.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//
// AppStoreCheck.swift
// App
//
// Created by Jisoo Ham on 5/26/24.
// Copyright © 2024 Pepsi-Club. All rights reserved.
//

import UIKit

import Core

public final class AppStoreCheck {

/// 프로젝트 버전
let appVersion = String.getCurrentVersion()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사용되지 않는 변수인데 남겨두신 이유가 있으신가요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sceneDelegate에서 가져다 쓰려고 뒀는데 scene에서도 또 변수 만들어서 썼네요 🥲 수정하겠습니다 ~


/// 앱스토어에 등록된 앱의 ID
static let appleID = Bundle.main.object(forInfoDictionaryKey: "APPLE_ID") as? String

/// 앱스토어 연결 링크
static let appStoreURLString
= "itms-apps://itunes.apple.com/app/apple-store/"

/// 앱스토어에 등록된 최신 버전 가져오는 함수

static public func latestVersion() async -> String? {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

함수 시그니처를 () -> Observable으로 변경하는 게 어떨까요?

guard let appleID = AppStoreCheck.appleID,
let url
= URL(string: "https://itunes.apple.com/lookup?id=\(appleID)&country=kr")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

린트 오류 수정바랍니다!

else { return nil }

do {
let (data, _) = try await URLSession.shared.data(
for: URLRequest(url: url)
)

guard 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
} catch {
return nil
}
}

/// URL을 통해 앱스토어 오픈
static public func openAppStore() {
guard let appleID,
let url = URL(string: AppStoreCheck.appStoreURLString + appleID)
else { return }

if UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url)
}
}
}
50 changes: 49 additions & 1 deletion Projects/App/Sources/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ final class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var deeplinkHandler: DeeplinkHandler?

func scene(
_ scene: UIScene,
_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions
) {
Expand All @@ -37,6 +37,10 @@ final class SceneDelegate: UIResponder, UIWindowSceneDelegate {
)
appCoordinator?.start()
window?.makeKeyAndVisible()

Task {
await self.checkAndUpdateIfNeeded()
}
deeplinkHandler = .init(appCoordinator: appCoordinator)
if let url = connectionOptions.urlContexts.first?.url {
deeplinkHandler?.handleUrl(url: url)
Expand All @@ -52,7 +56,11 @@ final class SceneDelegate: UIResponder, UIWindowSceneDelegate {
func sceneWillResignActive(_ scene: UIScene) {
}

/// 앱이 Foreground로 전환될때 실행될 함수
func sceneWillEnterForeground(_ scene: UIScene) {
Task {
await self.checkAndUpdateIfNeeded()
}
}

func sceneDidEnterBackground(_ scene: UIScene) {
Expand All @@ -66,5 +74,45 @@ final class SceneDelegate: UIResponder, UIWindowSceneDelegate {
deeplinkHandler?.handleUrl(url: url)
}
}

private func checkAndUpdateIfNeeded() async {
guard let marketingVersion = await AppStoreCheck.latestVersion()
else { return }

/// 현재 기기 버전
let currentProjectVersion = String.getCurrentVersion()

/// .을 기준으로 나눔
let splitMarketingVersion = marketingVersion.split(separator: ".").map { $0 }
let splitCurrentProjectVersion = currentProjectVersion.split(separator: ".").map { $0 }

if splitCurrentProjectVersion.count > 0 && splitMarketingVersion.count > 0 {
// Major 버전만을 비교
if splitCurrentProjectVersion[0] < splitMarketingVersion[0] {
self.showUpdateAlert(version: marketingVersion)
} else {
print("현재 최신 버전입니다.")
}

}
}

private func showUpdateAlert(version: String) {
let alert = UIAlertController(
title: "업데이트 알림",
message: "더 나은 서비스를 위해 업데이트 되었어요 ! 업데이트 해주세요.",
preferredStyle: .alert
)

let alertAction = UIAlertAction(
title: "업데이트",
style: .default) { _ in
AppStoreCheck.openAppStore()
}

alert.addAction(alertAction)
window?.rootViewController?.present(alert, animated: true)

}
}

3 changes: 2 additions & 1 deletion Projects/Core/Sources/Extension/String+.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@ public extension String {
return serverKey
}

/// 프로젝트 버전
static func getCurrentVersion() -> String {
guard let dictionary = Bundle.main.infoDictionary,
let version = dictionary["CFBundleShortVersionString"] as? String
else { return "" }
else { return "1" }
return version
}

Expand Down
Loading