상세 컨텐츠

본문 제목

[Swift] 강제업데이트 앱버전 비교하기

iOS 캐기/Swift 캐기

by Atlas 2022. 2. 17. 00:25

본문

728x90
반응형

시나리오 : 강제업데이트 지원을 위한 앱버전 확인 및 비교 방법을 알아보자

* 우선 강제업데이트는 각 스토어에서 권장하는 방식이 아님

 

그럼에도 우리는 강제업데이트 기능을 지원해야 할때가 있음.

설치되어 있는 앱 버전과 서버 API를 통해서 모바일 앱 버전체크를 해도 되지만

Firebase의 RemoteConfig를 활용하는 것도 좋은 방법임(참조링크는 하단)

 

 

보통 이렇게 문자열로 가져와서 비교를 하려고 많이들 시도할 것임 

//app버전 가져오기
let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
let miniMumVersion = "1.0.0" //앱의 사용 최소 지원 버전을 1.0.0으로 가정

 

그리고는 의식의 흐름대로 if문에서 비교 연산자('<' , '>')로 비교하려고 코드를 이와 같이 간단하게 짜려고 생각할 것임.

누구나 그렇게 생각할 수 있음 ㅋㅋ

(하지만 쓰기전 고민을 먼저한다면 엄지척 👍 , 고민하지 않고 쓰더라도 괜찮다 이제 알아가면 되는것뿐임 👍👍)

//like using Elvis Operator X)
//간단하게 이렇게 확인할 수도 있겠지만
let versionCompare = appVersion < minimumVersion ? "need to update" : "don't need to"
print(versionCompare)

//대부분 이렇게 사용하지 싶음
if appVersion < minimumVersion {
	// 업데이트 관련 로직 
}else{
	// etc 
}

 

자, 이때 우리는 이게 최선인가? 를 생각해 볼 필요가 있음. 

 

비교연산자를 사용하면 문자열의 순서를 비교할 수 있음,

이 말인 즉슨, 비교연산자를 사용하게 되면 문자열의 ASCII(아스키) 값을 비교하여 결과를 리턴하게 되는 것임. 

 

예제로 보면,

let appVersion: String = "9" // 앱의 버전 
let miniMumVersion: String = "8" //최소버전 

// 이 구문을 실행하게 되면 어떤결과가 나올 것 같은지 생각해보자
 print(appVersion < miniMumVersion)

당연히 false 겠지 라고 생각할 것이다. 

 

let appVersion: String = "9" // 앱의 버전 
let miniMumVersion: String = "8" //최소버전 
//아스키값을 확인해 보자
print(UnicodeScalar(appVersion)?.value) // 57
print(UnicodeScalar(miniMumVersion)?.value) // 56


 8의 아스키값은: 56,  9의 아스키값은 57
즉,  appVersion < miniMumVersion 은 57 < 56  이기 때문에 false가 return됨

 

자, 그러면 아래의 결과는 어떨것  같은지 생각해 보자.

let appVersion: String = "10" // 앱의 버전 
let miniMumVersion: String = "9" //최소버전 

//이번에도 똑같을까 ? 
 print(appVersion < miniMumVersion)

9의 아스키값은 57 , 10의 아스키 값은? 

 

let appVersion: String = "10"
let miniMumVersion: String = "9"

 //아스키값을 확인해 보자
print(UnicodeScalar(appVersion)?.value) // nil
print(UnicodeScalar(miniMumVersion)?.value) // 57

"10" 문자열의 아스키값이 nil 이 return 되는걸 확인할 수 있음 .

왜냐하면 무조건 Character 이여아 하기 때문이다. 그래서 nil이 return 되는 것임. 

 

그럼 어떻게 두 변수를 비교했을 때 결과 값이 나오는 건지 궁금해지기 시작할 것이다. 

이럴경우는 각 자리수의 해당하는 값의 아스키 값으로 비교를 하게 된다. 

 

10 이면 
'1' 과 '0' 각 글자별로 아스키값을 가져와서 
'1'의 아스키값 '49' 와 '0'의 아스키값 '48'로 각 글자별 위치로 비교를 함.

9의 아스키 코드 
57 ... 그런데 두번째글자는 없.... 이럴때는 0으로 비교가 된다고 함.

즉 
       첫번째 글자 위치 | 두번째 글자 위치
10진수       1       |      0     
아스키       49       |     48
10진수       9       |            
아스키       57       |      0 // 값이 없으니 0으로 비교 

 아스키값만 글자 위치로 비교해 보면 이와같음 
 
   첫번째 글자 위치 | 두번째 글자 위치
       49       |     48
       57       |      0 
     
 이렇게 비교가 된다고 보면 됨 .

즉, 첫 글자의 '1' 과 '9' 를 비교하게 되다 보니 이처럼 true 가 나오는 것임. 

 

물론 이 경우 그러면 한글자의 경우 두글자 처럼 즉 '9'의 경우 '09' 이렇게 해주면 되지않을까 라는 잔머리가 먼저 돌지만 

더 좋은 방법이 분명 있을것이라고 생각하고 스택오버플로우를 검색해면 좋음.

 

스택오버플로우에 검색해보면 여러방법이 있으나 내가 맘에들어하는 방법으로 정리해 보겠음.

 

let appVersion: String = "10"
let miniMumVersion: String = "9"


// Tada~ Look who is here!! 
if appVersion.compare(miniMumVersion,options: .numeric) == .orderedAscending {
    print ("need to update")
}else{
    print("don't need to")
}

바로 String의 compare 함수를 활용하는 것임.

 

애플 레퍼런스를 확인해보길 권장함!! 여기는 좋던 싫던 무조건 자주 보는게 좋음.

https://developer.apple.com/documentation/foundation/nsstring/1414082-compare

 

Apple Developer Documentation

 

developer.apple.com

 

우리가 사용할 함수가 이 친구인데, 잘보면 options 가 있음. 

 

요걸 클릭하게 되면 이렇게 상세페이지에서 더 디테일하게 확인이 가능함. 읽어보길 바라며 링크 첨부한것이니 꼭 읽어보길 바람.

https://developer.apple.com/documentation/foundation/nsstring/1410893-compare

 

Apple Developer Documentation

 

developer.apple.com

 

여기 Declaration에서 옵션을 클릭해서 어떤 속성들이 있는지 찾아보자. 

결론부터 말하자면 우리는 이 속성을 쓸것임 

 

문자열 내의 숫자는 Numeric 값(숫자)을 사용하여 비교된다고 함. 

예로 Name2.txt < Name7.txt < Name25.txt  를 보면 이마를 탁 치게 될 것이다.  

바로 이녀석이다! 하고 ㅋㅋㅋ 

 

다시 돌아오면 

compare함수는 ComparisonResult 값을 돌려준다고 문서에 정의되어 있다. 

보기 좋게 정렬하면 이와 같음.

 ComparisonResult.orderedAscending the receiver precedes aString in lexical ordering,
 ComparisonResult.orderedSame the receiver and aString are equivalent in lexical value,
 ComparisonResult.orderedDescending if the receiver follows aString.
 
 
.orderedAscending : 왼쪽값이 오른쪽값보다 작을 때
.orderedSame : 두 값이 같을 때
.orderedDescending : 왼쪽의 값이 오른쪽값보다 클 때

 

이제 이 코드가 마법처럼 이해될 것임.

let appVersion: String = "1.0.9"
let miniMumVersion: String = "1.0.10"


if appVersion.compare(miniMumVersion,options: .numeric) == .orderedAscending {
    print ("need to update")
}else{
    print("don't need to")
}

 

 

마무리 

- 간략하게 쓰려고 했으나 쓰다보니 욕심이 생겨서 길게 써버림..

- 역시 개발은 알아가는 아하! 모멘트가 올때 너무 기분이 좋음

 

via GIPHY

 

다음글 : "업데이트 팝업이 떠서 들어갔는데 업데이트 표시가 안 떠요" 에 대처하는 방법 

 

https://artieee.tistory.com/17

 

[경험]강제업데이트 앱버전 비교하기 & 앱 업데이트 새로고침 하는 방법-02

시나리오 : iOS 나 AOS 나 강제 업데이트 지원에 대한 니즈가 항상 있고, 하지만 이런 프로세스 자체가 애플의 앱스토어나 구글의 플레이스토어가 권장하는 방식이 아니지만 이 니즈를 최대한 만

artieee.tistory.com

 

 

관련자료

GitHub: 

https://github.com/PotatoArtie/Potato-iOS/tree/master/Labs/VersionComparePotato.playground

 

GitHub - PotatoArtie/Potato-iOS

Contribute to PotatoArtie/Potato-iOS development by creating an account on GitHub.

github.com

 

 

Firebase RemoteConfig :

https://firebase.google.com/products/remote-config?gclid=Cj0KCQiA3rKQBhCNARIsACUEW_YJ_STyHy6zyDB0jDIyMGwO-O4Dzpwt_SOBLxcnPenKMOAvduwRCu0aAgk7EALw_wcB&gclsrc=aw.ds

 

Firebase 원격 구성 | 즉석에서 앱 맞춤설정

Firebase 원격 구성을 사용하면 Firebase Console에서 즉석으로 앱의 동작과 모양을 변경하고 애널리틱스에서 실적을 추적할 수 있습니다.

firebase.google.com

 

 

 

반응형

관련글 더보기

댓글 영역