[SWIFT] String Compare (앱 버전 비교)

2021. 10. 10. 01:35SWIFT

반응형

오늘은 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() 이라는 메소드에 대해 알아봤는데요. 

앱의 최소 버전 비교외에도 몇가지에서 필요한 경우에 사용할 수 있을 것 같네요 ㅎㅎ

 

오늘 포스팅은 여기까지 하겠습니다 :)

혹시 잘못된 정보나 궁금한 점이 있으면 댓글남겨주세요~ 

반응형

'SWIFT' 카테고리의 다른 글

[Swift] Codable (1)  (0) 2022.04.24
[SWIFT] ArraySlice  (2) 2022.02.25
[SWIFT] KVO (Key - Value - Observing)  (0) 2021.09.26
[SWIFT] KVC (Key - Value - Coding)  (0) 2021.09.20
[SWIFT] Swift Method Dispatch - Dynamic, Static  (0) 2021.06.11