Skip to content

Commit 8efb993

Browse files
committed
[CHORE/#118] 강제 업데이트 기능 구현
1 parent 943a72d commit 8efb993

3 files changed

Lines changed: 120 additions & 0 deletions

File tree

DMU-iOS/DMU-iOS.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
F95DC1342B91B835001D3419 /* SearchNoticeDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = F95DC1332B91B835001D3419 /* SearchNoticeDTO.swift */; };
6767
F95DC1372B91BE55001D3419 /* SearchNotice.swift in Sources */ = {isa = PBXBuildFile; fileRef = F95DC1362B91BE55001D3419 /* SearchNotice.swift */; };
6868
F95DC1392B91E005001D3419 /* SearchNoticeRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = F95DC1382B91E005001D3419 /* SearchNoticeRepository.swift */; };
69+
F960A04B2C40C12800CAD21D /* AppStoreCheck.swift in Sources */ = {isa = PBXBuildFile; fileRef = F960A04A2C40C12800CAD21D /* AppStoreCheck.swift */; };
6970
F96760622B3AE1CB00C09F29 /* DMU_iOSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96760612B3AE1CB00C09F29 /* DMU_iOSApp.swift */; };
7071
F96760642B3AE1CB00C09F29 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F96760632B3AE1CB00C09F29 /* ContentView.swift */; };
7172
F96760662B3AE1CC00C09F29 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F96760652B3AE1CC00C09F29 /* Assets.xcassets */; };
@@ -144,6 +145,7 @@
144145
F95DC1332B91B835001D3419 /* SearchNoticeDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchNoticeDTO.swift; sourceTree = "<group>"; };
145146
F95DC1362B91BE55001D3419 /* SearchNotice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchNotice.swift; sourceTree = "<group>"; };
146147
F95DC1382B91E005001D3419 /* SearchNoticeRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchNoticeRepository.swift; sourceTree = "<group>"; };
148+
F960A04A2C40C12800CAD21D /* AppStoreCheck.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppStoreCheck.swift; sourceTree = "<group>"; };
147149
F967605E2B3AE1CB00C09F29 /* DMU-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DMU-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
148150
F96760612B3AE1CB00C09F29 /* DMU_iOSApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DMU_iOSApp.swift; sourceTree = "<group>"; };
149151
F96760632B3AE1CB00C09F29 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
@@ -313,6 +315,7 @@
313315
isa = PBXGroup;
314316
children = (
315317
F96760612B3AE1CB00C09F29 /* DMU_iOSApp.swift */,
318+
F960A04A2C40C12800CAD21D /* AppStoreCheck.swift */,
316319
F93F51232B47A31800654F6D /* UserSettings.swift */,
317320
F96760632B3AE1CB00C09F29 /* ContentView.swift */,
318321
);
@@ -931,6 +934,7 @@
931934
F9BCAA892B73D38100E717BF /* NoticeWebView.swift in Sources */,
932935
F9AF3C542B416E5D001779E3 /* ScheduleView.swift in Sources */,
933936
F93D03122BB251BF00F6AFDE /* NotificationViewModel.swift in Sources */,
937+
F960A04B2C40C12800CAD21D /* AppStoreCheck.swift in Sources */,
934938
F93D03042BB24D8300F6AFDE /* NotificationService.swift in Sources */,
935939
F9BB5B6A2B42D320002EDB68 /* SearchViewModel.swift in Sources */,
936940
F92116172B90621000A5507A /* DepartmentNoticeDTO.swift in Sources */,
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//
2+
// AppStoreCheck.swift
3+
// DMU-iOS
4+
//
5+
// Created by 이예빈 on 7/12/24.
6+
//
7+
8+
import UIKit
9+
10+
class AppStoreCheck {
11+
12+
// 현재 버전 : 타겟 -> 일반 -> Version
13+
static let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
14+
15+
// 개발자가 내부적으로 확인하기 위한 용도 : 타겟 -> 일반 -> Build
16+
static let buildNumber = Bundle.main.infoDictionary?["CFBundleVersion"] as? String
17+
static let appStoreOpenUrlString = "itms-apps://itunes.apple.com/app/apple-store/6480396503"
18+
19+
// 앱 스토어 최신 정보 확인
20+
func latestVersion(completion: @escaping (String?) -> Void) {
21+
let appleID = "6480396503"
22+
guard let url = URL(string: "https://itunes.apple.com/lookup?id=\(appleID)&country=kr") else {
23+
completion(nil)
24+
return
25+
}
26+
27+
let task = URLSession.shared.dataTask(with: url) { data, response, error in
28+
guard let data = data,
29+
let json = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any],
30+
let results = json["results"] as? [[String: Any]],
31+
let appStoreVersion = results.first?["version"] as? String else {
32+
completion(nil)
33+
return
34+
}
35+
completion(appStoreVersion)
36+
}
37+
task.resume()
38+
}
39+
40+
// 앱 스토어로 이동 -> urlStr 에 appStoreOpenUrlString 넣으면 이동
41+
func openAppStore() {
42+
guard let url = URL(string: AppStoreCheck.appStoreOpenUrlString) else { return }
43+
if UIApplication.shared.canOpenURL(url) {
44+
UIApplication.shared.open(url, options: [:], completionHandler: nil)
45+
}
46+
}
47+
}
48+

DMU-iOS/DMU-iOS/App/DMU_iOSApp.swift

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,82 @@ struct DMU_iOSApp: App {
3535
UINavigationBar.appearance().standardAppearance = appearanceNavigationBar
3636
}
3737

38+
@Environment(\.scenePhase) private var scenePhase
39+
3840
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
3941

4042
var body: some Scene {
4143
WindowGroup {
4244
ContentView()
45+
.onAppear {
46+
checkAndUpdateIfNeeded()
47+
}
48+
.onChange(of: scenePhase) { newPhase in
49+
if newPhase == .active {
50+
checkAndUpdateIfNeeded()
51+
}
52+
}
4353
.environmentObject(UserSettings())
4454
}
4555
}
56+
57+
func checkAndUpdateIfNeeded() {
58+
AppStoreCheck().latestVersion { marketingVersion in
59+
DispatchQueue.main.async {
60+
guard let marketingVersion = marketingVersion else {
61+
print("앱스토어 버전을 찾지 못했습니다.")
62+
return
63+
}
64+
65+
// 현재 기기의 버전
66+
let currentProjectVersion = AppStoreCheck.appVersion ?? ""
67+
68+
// 앱스토어의 버전을 .을 기준으로 나눈 것
69+
let splitMarketingVersion = marketingVersion.split(separator: ".").compactMap { Int($0) }
70+
71+
// 현재 기기의 버전을 .을 기준으로 나눈 것
72+
let splitCurrentProjectVersion = currentProjectVersion.split(separator: ".").compactMap { Int($0) }
73+
74+
if splitCurrentProjectVersion.count == 3 && splitMarketingVersion.count == 3 {
75+
// 버전을 순차적으로 비교
76+
for (current, marketing) in zip(splitCurrentProjectVersion, splitMarketingVersion) {
77+
if current < marketing {
78+
showUpdateAlert(version: marketingVersion)
79+
return
80+
} else if current > marketing {
81+
print("현재 최신 버전입니다.")
82+
return
83+
}
84+
}
85+
print("현재 최신 버전입니다.")
86+
} else {
87+
print("버전 형식이 올바르지 않습니다.")
88+
}
89+
}
90+
}
91+
}
92+
93+
func showUpdateAlert(version: String) {
94+
guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
95+
let window = windowScene.windows.first else {
96+
print("윈도우 씬을 찾을 수 없습니다.")
97+
return
98+
}
99+
100+
let alert = UIAlertController(
101+
title: "업데이트 알림",
102+
message: "더 나은 서비스를 위해 DMforU가 수정되었어요.\n업데이트할까요?",
103+
preferredStyle: .alert
104+
)
105+
106+
let updateAction = UIAlertAction(title: "업데이트", style: .default) { _ in
107+
// 업데이트 버튼을 누르면 해당 앱스토어로 이동한다.
108+
AppStoreCheck().openAppStore()
109+
}
110+
111+
alert.addAction(updateAction)
112+
window.rootViewController?.present(alert, animated: true, completion: nil)
113+
}
46114
}
47115

48116
//MARK: - Firebase Cloud Message

0 commit comments

Comments
 (0)