[iOS] 강제 업데이트 / 앱스토어 최신버전 확인하기

ohtt-iOS·2021년 9월 6일
1

iOS

목록 보기
17/24
post-thumbnail
post-custom-banner

📍 업데이트 로직이 필요한 이유 ?

서비스를 운영 하다보면 자잘자잘한 버그를 고쳐서 업데이트를 하는데
어떤 버전같은 경우에는 심각한 버그가 있어서 사용자가 더이상 사용할 수 없게끔 해야할 때가 있다.
이럴 때 업데이트 로직이 심어져 있지 않다면 ,,,
사용자가 직접 앱스토어에 가서 업데이트를 하지 않는 한 업데이트를 강제로 시킬 방법이 없다 🥲

그래서 안정적으로 서비스를 운영하기 위해서는 처음부터 강제 업데이트 기능을 넣어두는 것이 정신 건강에 좋을 것이다.

실제로 밀키웨이 초반 버전에 업데이트 로직이 안들어가있어서 현재도 마음 고생을 하는 중 😐



👀 그래서 어떻게 ?

다른 방법도 있을 수도 있지만 내가 아는 방법 두가지를 소개해보면

서버와 연결

서버에서 버전 체크용 api를 만들어서
클라가 앱이 실행될 때 현재 버전을 담아서 보낸다 -> 업데이트가 필요한 버전인지 체크 -> 응답에 따라서 처리

클라이언트에서 해결

현재 앱스토어의 버전과 비교 -> 업데이트가 필요한지 (어떨 때 필요한지 체크하는 것도 클라에서) -> 처리

아래에 작성할 방법은 두번째 방법이다.
이 과정에서 겪은 문제도 함께 정리해두어야지



✍🏻 업데이트 로직 짜기

어떨 때 업데이트 화면을 띄울 것인가를 정해야한다.
매 업데이트마다 강제 업데이트가 되면 사용자가 간단한 버그수정에도 업데이트를 하게 되어서 불편함을 느낄 수 있다.
그래서 우리는 꼭 업데이트가 필요한 버전에서 강제 업데이트 화면을 띄우기로 했고,
그 기준을 첫번째 , 두번째 자리가 바뀌었을 때 로 정했다.


func needUpdate() -> Bool {
        
        guard
            let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String,
            let url = URL(string: "http://itunes.apple.com/lookup?bundleId=앱의 번들아이디"),
            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]],
            results.count > 0,
            let appStoreVersion = results[0]["version"] as? String
        
        else { return false }
        
        
        let nowVersionArr = version.split(separator: ".").map { $0 }
        let storeVersionArr = appStoreVersion.split(separator: ".").map { $0 }
        
        print(nowVersionArr)
        print(storeVersionArr)
        
        // 가장 앞자리가 다르면 -> 업데이트 필요
        if nowVersionArr[0] < storeVersionArr[0] {
            return true
        } else {
            if  nowVersionArr[1] < storeVersionArr[1] { // 두번째 자리가 달라도 업데이트 필요
                return true
            } else { return false } // 그 이외에는 업데이트 필요 없음
        }
        
    }


🙉 문제점 발생 !

이 로직을 넣고 문제점을 발견했다.
어떨 때는 업데이트 화면이 뜨고, 어떨 때는 안뜨고 ... 이런 버그가 생겼다
(버전 업데이트가 필요한 상황이었는데도 불구하고... )

스택오버플로우 에서 해결책을 찾았다 !

저기 앱스토어 주소에서 http를 https 로 바꾸면 되는거였다 !

http로 해두어도 이게 계속 지속되는 문제는 아닌 것 같고
업데이트 버전을 올리고 24시간 정도 동안 이전 데이터를 응답하는 경우가 생겨서 그런 듯 싶다.

암튼 https 로 하면 최신 응답이 온다고 한다.

profile
오뜨 삽질 🔨 블로그
post-custom-banner

2개의 댓글

comment-user-thumbnail
2022년 6월 28일

안녕하세요! 좋은 글 써주셔서 감사합니다!!

마지막에
// Major 또는 Minor 자리가 최신 스토어 버전보다 작으면 -> 업데이트 필요
(nowVersionArr[0] < storeVersionArr[0]) ||
((nowVersionArr[0] <= storeVersionArr[0]) && (nowVersionArr[1] < storeVersionArr[1])) {
return true
}
return false
로 바꾸면 코드 Depth를 줄일 수 있을 것 같아요!


let json = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any]
그리고 위에 부분 options에 .allowFragments 가 Deprecated 된 거 같아요.
대신 .fragmentsAllowed를 쓰라고 하네요!
문서 -> https://developer.apple.com/documentation/foundation/jsonserialization/readingoptions/1416042-allowfragments

근데 애플문서 설명보니까 parser가 배열이나 사전이 아닌 top-level의 객체를 허용하도록 지정한다. 라고하는데 바로 뒤에서 as? 로 사전으로 타입캐스팅하고 있으니까 결국은 사전만 허용된거 아닌가? 라고 생각해서 옵션 안넣고 해봤는데 잘 작동하네요! 🥸


xcode에서 JSONSerialization.jsonObject -> Jump To Definition 보니까 주석에
Set the NSJSONReadingAllowFragments option if the parser should allow top-level objects that are not an NSArray or NSDictionary
이런글이 있더라구요! 옵션은 빼고 써도 될 거 같아요.

답글 달기
comment-user-thumbnail
2023년 1월 10일

https 로 했는데 버전 가져오는데 최신으로 안가져오더라구요. ㅠㅠ
24시간 지난 후 최신 버전 가져왔어요. 🥲

답글 달기