[SWIFT] String Compare (앱 버전 비교)
오늘은 Swift의 String Compare 메소드에 대해 포스팅을 해보려고 합니다.
포스팅을 하게 된 배경은 이번에 회사에서 진행하는 프로젝트에서 앱의 버전별로 현재 지원하는 최소 버전과 비교해서 팝업을 띄우는 스펙이 있었습니다. 근데, 막상하려고하니 어떻게 할지 감이 잘 안왔습니다..?
왜냐하면 앱의 버전은 "3.5.0", "3.7.0"과 같은 String 타입으로 되어있잖아요...
'이걸 어떻게 숫자로 비교할 수 있을까..?'라는 생각이 들었습니다.
그래서, 찾아보다보니 comapre이라는 메소드가 있어 해당 메소드를 이용해서 해결이 되었는데 어떻게 되어있는지 자세히 포스팅을 해보려고 합니다~
Compare이란?
우선 Compare을 알아보기 이전에간단하게 비교를 할 수 있는 기본에 사용하는 방법을 알아보겠습니다.
자주 사용하는 방법으로는 ==, != 연산부호를 이용한 비교들이있죠~
let password = "111111"
let passwordConfirm = "111111"
password == passwordConfirm
// true
let password = "111112"
let passwordConfirm = "111111"
password == passwordConfirm
// false
이런 간단한 예제가 있습니다.
이런 요구사항들은 충분히 compare을 이용하지 않더라도 기존에 사용하는 방법으로 쉽게 가능하죠.
그렇다면, 다음의 예제는 어떨까요??
대소문자만 다른 문자열의 비교입니다.
보면 알 수 있지만 그냥 비교하게 되면, 당연히 대문자와 소문자가 다르기 때문에 원하는 결과가 안나오죠 😭
하지만, 저희가 원하는 스펙은 비밀번호에서 대소문자에 관련없이 비교를 하는 것입니다.
let password = "a"
let passwordConrifm = "A"
password == passwordConfirm
// false
password.lowerCased() == passwordConrifm.lowerCased()
// true
보면 이 스펙을 위해서 위는 lowerCased()라는 메소드를 사용해서 비교를 했습니다.
물론, 이렇게만 해도 지금 해당 스펙을 충분히 구현할 수 있습니다.
그렇다면, 이번에는 comapre 메소드를 이용해서 비교를 해볼까요..?
let password = "a"
let passwordConrifm = "A"
password.compare(passwordConfirm, options: .caseInsensitive)
// .orderedSame ==> Equal
오... 뭔가 같다는 결과가 나온 것 같네요..?
true, false의 Bool 값은 아니지만 뭔가 같다는 것 같죠.
이렇게 NSString.CompareOptions 값을 넣어주고 옵션을 기반으로 두 값을 비교해서 ComparisionResult라는 enum 값을 결과로 얻을 수 있습니다. (NSString.CompareOptions에 대해서도 다음에 한 번 포스팅을 해볼게요,,, ㅎㅎ)
우선 ComparisionResult라는 결과 값의 enum에 대해서도 간단히 볼게요.
총 3가지의 case가 있어요
- orderedAscending : 왼쪽의 값이 오른쪽의 값보다 작다는 결과 (-1의 rawValue를 가지고 있습니다.)
- orderedSame : 왼쪽과 오른쪽의 값이 같다는 결과 (0의 rawValue를 가지고 있습니다.)
- orderedDescending : 왼쪽의 값이 오른쪽의 값보다 크다는 결과 (1의 rawValue를 가지고 있습니다.)
그렇다면 이제 앱의 최소지원버전과 현재 버전을 비교하는 구문을 작성해볼게요~
우선, 비교를 위해서 사용할 옵션은 .numeric 옵션입니다.
해당 옵션의 애플 설명을 보면 다음과 같습니다.
Numbers within strings are compared using numeric value, that is, Name2.txt < Name7.txt < Name25.txt.
Numeric comparison only applies to the numerals in the string, not other characters that would have meaning in a numeric representation such as a negative sign, a comma, or a decimal point. This option only applies to compare methods, not find
설명의 예시로 Name2.txt, Name7.txt, Name25.txt를 비교했는데요. 그대로 비교는 불가능하잖아요? 그래서 numeric 옵션을 이용해서 내부의 숫자 값만 비교를 할 수 있다는 것 같네요 ㅎ
자 한번 사용을 해볼게요.
let dongdong1 = "DongDongE1"
let dongdong2 = "DongDongE200"
dongdong1.compare(dongdong2, options: .numeric).rawValue
// -1 == .orderedAscending.rawValue
오,,, 왼쪽의 값이 오른쪽의 값보다 작다는 결과가 나왔죠...?!
근데, 여기서 주의해야할 점이 있더라구요.. 블로그를 하나씩 보다가 알게된 것인데요.
numeric으로 비교를 하는 것이 정말 순수하게 숫자만 추출해내서 비교하는 방법은 아닌 것 같네요..? ASCII 코드를 이용해서 비교하게 되는데, 만약 dongdong1 변수의 문자열이 ASCII 코드에서 더 큰 숫자를 나타내면 기대하는 결과가 안나오는 것 같습니다.
let dongdong1 = "aongDongE1"
let dongdong2 = "DongDongE200"
dongdong1.compare(dongdong2, options: .numeric).rawValue
// 1 == .orderedDescending
이렇게요... 'a'는 ASCII 코드로 'D'보다 큰 값을 가지죠...?
웬만하면 다른 문자들은 동일하고 정말 숫자 안에서 값만 다른 경우에 사용해야할 것 같네요.. 😭
이제는 최소 버전을 정말 비교해볼게요.
let supportableMinVersion = "3.5.0"
let currentAppVersion = "3.4.0"
currentAppVersion.compare(supportableMinVersion, options: .numeric).rawValue
// -1 == .orderedAscending.rawValue
let supportableMinVersion = "3.5.0"
let currentAppVersion = "3.5.0"
currentAppVersion.compare(supportableMinVersion, options: .numeric).rawValue
// 0 == .orderedSame
let supportableMinVersion = "3.5.0"
let currentAppVersion = "3.5.1"
currentAppVersion.compare(supportableMinVersion, options: .numeric).rawValue
// 1 == .orderedDescending.rawValue
이런식으로 비교가 되는데요.
어떤가요..? 기대한 값과 같이 나오는 것 같죠 ㅎㅎ
정확히 ASCII 코드로 비교한다는 뜻이 총합을 더하는 것 같지는 않구요.
여러가지를 해보았는데, 애플에서의 설명처럼 ',' '.' '-' 이런 부호들은 포함되지 않구요.
나머지의 ASCII 값들을 앞에서부터 비교해서 그 결과를 보여주는 것 같아요.
예를 들어, 밑의 예시와 같이 ',' 이전의 값을 먼저 비교해서 더 크니 뒤의 값은 보지않고 dongdong2 변수의 값이 더 크다고 판별해서 결과를 리턴해주는 것 같습니다. 이런 결과를 보여주면 당연히 앱의 버전 비교에는 맞겠죠?~ 왜냐하면 앞자리부터 더 큰 버전을 의미하게 되니까요~
let dongdong1 = "DazzzzzzzgDongE199,100000"
let dongdong2 = "DazzzzzzzgDongE200,200"
dongdong1.compare(dongdong2, options: .numeric).rawValue
// -1 == .orderedAscending.rawValue
오늘은 이렇게 compare() 이라는 메소드에 대해 알아봤는데요.
앱의 최소 버전 비교외에도 몇가지에서 필요한 경우에 사용할 수 있을 것 같네요 ㅎㅎ
오늘 포스팅은 여기까지 하겠습니다 :)
혹시 잘못된 정보나 궁금한 점이 있으면 댓글남겨주세요~