본문 바로가기
Flutter

[Flutter] Android/Ios 업데이트 버전 스토어랑 체크하기

by Banlim 2021. 4. 20.

[삽질의 기록]

 

최근 진행하고 있는 프로젝트에서 어플리케이션 업데이트가 되었을 경우, 현재 디바이스의 버전과 비교하여 다를 경우 알림 팝업을 띄우는 기능이 있다. 기존 코드는 자체 서버와 비교하여 버전이 업데이트가 되었는지 체크하는 방식이었다. (즉, 스토어에 어플리케이션이 업데이트되면, 관리자가 직접 버전을 수정해야하는 불편함이 있었다.)

이런 불편함을 해소하고자 스토어의 버전과 비교하는 방식으로 수정했다.

 

처음에는, 'Upgrader' 라는 Flutter package를 사용하여 구현하려했으나, 최신 버전이 kakako_flutter_sdk: ^0.5.4 package와 충돌하여 사용할 수 없었다. (지금은 저 카카오 패키지가 0.6.1로 업데이트 되었다고 한다. 충돌나는지 확인해봐야지)

따라서, 위 패키지와 'new_version' 이라는 패키지의 Github를 참고하여 직접 코드에 작성하는 방법을 택했다.

 

pub.dev/packages/upgrader

 

upgrader | Flutter Package

Flutter package for prompting users to upgrade when there is a newer version of the app in the store.

pub.dev

pub.dev/packages/new_version

 

new_version | Flutter Package

Check if your user has the most recent version of your Flutter app.

pub.dev

 

앱/플레이 스토어의 현재 버전 상태는 Get으로 통신하여 가져올 수 있다.

 

// pubspec.yaml

dependencies:
  flutter:
    sdk: flutter
  
  platform: ^2.2.1
  http: ^0.12.0+4
  package_info: '>=0.4.3+4 <2.0.0'
  url_launcher: ^5.7.10
  . . .

 

// 안드로이드 플레이 스토어에서 현재 버전 가져오기

Future<String> _getAndroidStoreVersion(
      PackageInfo packageInfo) async {
    final id = packageInfo.packageName;
    final uri =
    Uri.https("play.google.com", "/store/apps/details", {"id": "$id"});
    final response = await http.get(uri);
    if (response.statusCode != 200) {
      debugPrint('Can\'t find an app in the Play Store with the id: $id');
      return "";
    }
    final document = parse(response.body);
    final elements = document.getElementsByClassName('hAyfc');
    final versionElement = elements.firstWhere(
          (elm) => elm.querySelector('.BgcNfc').text == 'Current Version',
    );
    return versionElement.querySelector('.htlgb').text;
  }

 

// IOS 앱스토어에서 현재 버전 가져오기

Future<dynamic> _getiOSStoreVersion(PackageInfo packageInfo) async {
    final id = packageInfo.packageName;

    final parameters = {"bundleId": "$id"};
     
    var uri = Uri.https("itunes.apple.com", "/lookup", parameters);
    final response = await http.get(uri);

    if (response.statusCode != 200) {
      debugPrint('Can\'t find an app in the App Store with the id: $id');
      return "";
    }

    final jsonObj = json.decode(response.body);
    
    /* 일반 print에서 일정 길이 이상의 문자열이 들어왔을 때, 
     해당 길이만큼 문자열이 출력된 후 나머지 문자열은 잘린다.
     debugPrint의 경우 일반 print와 달리 잘리지 않고 여러 행의 문자열 형태로 출력된다. */
    
    // debugPrint(response.body.toString());
    return jsonObj['results'][0]['version'];
  }

 

// 스플래시 화면의 init을 호출하는 메서드에서 아래 코드를 넣는다.

// Platform.isAndroid와 Platform.isIOS를 통해 현재 기기가 어떤 OS로 되어있는 장치인지 판단한 후, 각 상황에 알맞게 앞서 작성한 메서드를 호출한다.

// 추가로 그 외의 플랫폼일 경우나, 앞서 작성한 메서드에서 값에 오류가 있을 때에는 "" 값을 반환하여 업데이트 알림 팝업이 일어나지 않도록 구성하였다.

// ConstantString.update_need_text 값은 ConstantString 클래스 안에 String 값으로, "업데이트가 필요합니다. 스토어에서 업데이트 해주세요."와 같은 말이라고 생각하면 된다.

// 커스텀으로 구현한 두 개의 버튼(확인, 취소 와 같은 버튼) 다이얼로그에서 버튼을 눌렀을 경우 콜백으로 int형 값을 반환받는데, '업데이트 하러가기'와 같은 버튼을 눌렀을 경우, 0을 반환하도록 설정했다.

// 즉, '업데이트 하러가기' 버튼을 클릭하면 0이 반환되고, 이 반환 값을 기준으로 launch() 함수를 호출하여 getStoreUrlValue로 얻은 url 값을 통해 앱/플레이 스토어로 이동할 수 있다.

Future<bool> _initialize() async {
	
    PackageInfo packageInfo = await PackageInfo.fromPlatform();

    /* ***************************************** */
    // playStore || appStore -> version check
    /* ***************************************** */
    
    var storeVersion = Platform.isAndroid ? await _getAndroidStoreVersion(packageInfo) : Platform.isIOS ? await _getiOSStoreVersion(packageInfo) : "";

    print('my device version : ${packageInfo.version}');
    print('current store version: ${storeVersion.toString()}');

    if (storeVersion.toString().compareTo(packageInfo.version) != 0 && storeVersion.toString().compareTo("") != 0) {
      final int result = await CustomDialog().showTwoButtonDialog(
          context, ConstantString.update_need_text);
      if (result == 0) {
        launch(
            Constant.getStoreUrlValue(packageInfo.packageName, packageInfo.appName));
      }
    }

   . . .
   
  }

 

// getStoreUrlValue 메서드는 아래 코드와 같다.

String getStoreUrlValue(String packageName, String appName) {
  if (Platform.isAndroid) {
    return "https://play.google.com/store/apps/details?id=$packageName";
  } else if (Platform.isIOS)
    return "http://apps.apple.com/kr/app/$appName/id${ConstantString.APP_STORE_ID}";
  else
    return null;
}