티스토리 뷰

Server

[Java] 앱 버전 분기하기

니용 2020. 8. 7. 15:24
반응형

Author: 니용

 


스마트폰이 발달하면서 앱 스토어 혹은 구글 플레이에서 앱(Application)을 다운받아서 사용하는 양이 거의 전부를 차지하고 있습니다. 

 

앱 하나하나마다 자신의 기기에 설치되어 있는 고유의 버전이 있습니다. 이것을 앱 버전이라고 하는데요, 클라이언트에서 소유한 앱 버전(즉, 스마트폰에 설치되어 있는 앱의 버전)을 가지고 서버에서 처리를 하는 방법에 대해 설명하려고 합니다. 

 

앱 버전

 

가장 먼저 앱 버전의 생김새를 알아야겠죠.

앱 버전은 크게 3가지로 구분되게 됩니다. 3가지 모두 숫자값을 주로 사용하고 상위 버전(최신에 나온 버전)의 경우 이전에 가졌던 숫자값보다 더 높은 값을 가지고 있습니다.

 

생긴 건 '2.41.5'와 같이 생겼으며, 명칭은 Major / Minor / Point로 보통 불리웁니다. 

즉, 위에 적어놓은 예시는 Major: 2 / Minor : 41 / Point: 5인 것이 됩니다.

 

앱 버전 업그레이드

 

앱 버전이 업그레이드 될 때는 순차적으로 오르게 됩니다.

1->2가 되거나 5->6이 됩니다.

1->4와 같이 3단계를 건너뛰는 것은 불가능합니다. 

 

처음에 앱이 출시가 되어 적용이 되는 버전은 대개 1.0.0입니다.

 

버전 업그레이드의 기준

 

가장 큰 메이저(Major) 버전의 경우 회사에 따라 다르지만 전면적으로 변경이 되는 큰 작업이 들어가거나 바라보고 있는 API의 호스트가 변경이 되는 경우 보통 버전 업그레이드를 진행합니다. 1버전에서 2버전이 되는 경우 다른 서버의 API를 호출하게 되죠.

 

마이너(Minor) 버전의 경우는 새로운 기능이라던가 서비스가 추가되는 경우 버전 업그레이드를 진행합니다. 

 

포인트 버전의 경우 버그 수정/기존 로직 튜닝 혹은 자잘한 이슈 대응을 할 때 업그레이드를 진행합니다.

 

버전의 비교

 

메이저 버전은 모든 버전의 상위 개념입니다. 메이저 버전이 같은 값이라면, 마이너 버전이 그 다음 순위이며 마이너 버전이 같다면 포인트 버전이 가장 하위 개념입니다. 쉬운 이해를 위해 예시를 들어보겠습니다.

 

2.0.0 > 1.5.8 : 메이저 버전이 2와 1의 비교이므로 2.0.0이 상위 버전입니다.

2.1.0 > 2.0.1 : 메이저 버전이 2로 같지만 마이너 버전이 1과 0의 비교이므로 2.1.0이 상위 버전입니다.

2.1.3 > 2.1.2 : 메이저 버전이 2이고, 마이너 버전이 1로 같지만 포인트 버전이 3과 2의 비교이므로 2.1.3이 상위 버전이 됩니다.

 

소스 코드에서 비교를 하는 방법

 

사실 (major).(minor).(point)는 하나의 문자열이므로 숫자 비교를 하는 것이 쉽지 않습니다. 자바를 기준으로 기존에는 유틸성 클래스를 만들어두고 사용하였었는데 심플하게 만든 결과물은 아래와 같았습니다.

 

public class AppVersionUtil {
    public static boolean isLaterVersion(String appVersion1, String appVersion2) {
        if(StringUtils.isBlank(appVersion1) || StringUtils.isBlank(appVersion2))
            return false;

        List<Integer> appVer1 = Arrays.stream(appVersion1.split("\\.")).map(str -> Integer.parseInt(StringUtils.isNotBlank(str) ? str : "0")).collect(toList());
        List<Integer> appVer2 = Arrays.stream(appVersion2.split("\\.")).map(str -> Integer.parseInt(StringUtils.isNotBlank(str) ? str : "0")).collect(toList());
        long a1 = 0, a2 = 0;
        if(appVer1.size() == 3  && appVer2.size() == 3)
            for(int i=0; i<3; i++) {
                a2 += appVer2.get(i) * (long) Math.pow(100, 2-i);
                a1 += appVer1.get(i) * (long) Math.pow(100, 2-i);
            }
        return a1 < a2;
    }
}

 

하지만 이렇게 적용을 하게 되면 어떤 버전이 상위 버전이 되고 하위 버전이 되는지 애매합니다.

물론 파라미터 명 또는 변수 명을 변경하여 사용하면 가능합니다. 

현재 개선된 소스는 아래에 있습니다. 

import org.apache.commons.lang3.StringUtils;

@SuppressWarnings("unused")
public class AppVersion implements Comparable<AppVersion>{
	private int major;
	private int minor;
	private int point;
	public AppVersion(String appVersionString){
		try {
			String[] appVersionArray = StringUtils.split(appVersionString,".");
			this.major = Integer.parseInt(appVersionArray[0]);
			this.minor = Integer.parseInt(appVersionArray[1]);
			this.point = Integer.parseInt(appVersionArray[2]);
		}
		catch(Exception ignored){ }
	}

	@Override
	public String toString() {
		return this.major+"."+this.minor+"."+this.point;
	}

	@Override
	public int compareTo(AppVersion o) {
        //메이저 버전 비교
		int majorDiff = Integer.compare(this.major, o.major);
		if(majorDiff != 0){
			return majorDiff;
		}
		else{
            //마이너 버전 비교
			int minorDiff = Integer.compare(this.minor,o.minor);
			if(minorDiff != 0){
				return minorDiff;
			}
			else{
                //포인트 버전 비교
				return Integer.compare(this.point, o.point);
			}
		}
	}

	@Override
	public boolean equals(Object o) {
		if (this == o) return true;
		if (o == null || getClass() != o.getClass()) return false;
		AppVersion that = (AppVersion) o;
		return this.compareTo(that) == 0;
	}

	public int getMajor() {
		return major;
	}

	public void setMajor(int major) {
		this.major = major;
	}

	public int getMinor() {
		return minor;
	}

	public void setMinor(int minor) {
		this.minor = minor;
	}

	public int getPoint() {
		return point;
	}

	public void setPoint(int point) {
		this.point = point;
	}

	public static boolean isGreaterThan(String base, String target){
		return isGreaterThan(new AppVersion(base),new AppVersion(target));
	}
	
	public static boolean isGreaterThan(AppVersion base, AppVersion target){
		return base.compareTo(target) > 0;
	}

	public static boolean isGreaterEqual(String base, String target){
		return isGreaterEqual(new AppVersion(base),new AppVersion(target));
	}
	
	public static boolean isGreaterEqual(AppVersion base, AppVersion target){
		return base.compareTo(target) >= 0;
	}

	public static boolean isLessThan(String base, String target){
		return isLessThan(new AppVersion(base),new AppVersion(target));
	}
	
	public static boolean isLessThan(AppVersion base, AppVersion target){
		return base.compareTo(target) < 0;
	}

	public static boolean isLessEqual(String base, String target){
		return isLessEqual(new AppVersion(base),new AppVersion(target));
	}
	
	public static boolean isLessEqual(AppVersion base, AppVersion target){
		return base.compareTo(target) <= 0;
	}
}

 

조금 더 소스가 깔끔해진 느낌이 듭니다!

사용 방법은 정말 간편하게 사용할 수 있습니다.

 

소스 코드 사용 예제

public class AppVersionTestClass {
    public static void main(String[] args) {
    
        System.out.println(AppVersion.isGreaterThan("1.2.3", "1.2.3")); // false
        System.out.println(AppVersion.isGreaterEqual("1.2.3", "1.2.3")); // true
        System.out.println(AppVersion.isGreaterThan("1.2.3", "1.3.0")); // false
        System.out.println(AppVersion.isGreaterEqual("2.0.0", "1.2.3")); // true
        
        System.out.println(AppVersion.isLessThan("1.2.3", "1.3.0")); // true
        System.out.println(AppVersion.isLessEqual("1.2.3", "1.2.3")); // true
    }
}

 

예를 들어 앱 버전이 1.3.0 이상 버전에서 특정 로직을 수행하고 싶다면 이와 같이 작성 가능합니다.

public class AppVersionTest {
   public void doSomething(String appVersion) {
       if(AppVersion.isGreaterEqual(appVersion, "1.3.0")) {
          // TODO 
       }
   }
} 

앱 버전이 1.7.3과 1.13.2의 사이인 경우 이와 같이 적용하면 됩니다.

public class AppVersionTest {
   public void doSomething(String appVersion) {
       if(AppVersion.isGreaterThan(appVersion, "1.7.2")
           && AppVersion.isLessEqual(appVersion, "1.13.2")) {
          // TODO 
       }
   }
} 

앱 버전 1.15.0 미만 버전인 경우 이와 같이 사용할 수 있습니다.

public class AppVersionTest {
   public void doSomething(String appVersion) {
       if(AppVersion.isLessThan(appVersion, "1.15.0")) {
          // TODO 
       }
   }
} 

 

반응형
댓글
공지사항