반응형

 

플러터가 2.0이 발표되면서 프로젝트 관리에 이슈가 생겼다.

안정적인 프로젝트 운영을 위해 2.0으로 업그레이드하는 것이 마땅하나,

이미 1.0으로 개발을 완료한 프로젝트를 2.0으로 업그레이드하기란 그렇게 간단하지 않기 때문이다.

게다가 플러터 1.0으로 개발된 프로젝트가 많은 상황에 플러터 버전을 2.0으로 업그레이드하는 순간

모든 프로젝트들을 플러터 2.0에 맞게 마이그레이션해주어야 하는데 보통 일이 아니다.

 

나의 경우도 계속 2.0으로 업그레이드하는 것을 미루다가 플러터의 특정한 패키지 버그 해결을 위해

플러터 2.0 업그레이드가 불가피해져서 업그레이드하기로 결정했는데 다 바꾸기엔 무리가 있으니,

해당 프로젝트 하나만 플러터 2.0으로 마이그레이션 하기로 결정하였다.

이 때 사용하는 것이 FVM(Flutter Version Management)이라는 것이다.

이 FVM을 사용하게 되면 프로젝트별로 원하는 버전을 쉽게 변경해서 사용할 수 있다.

A라는 프로젝트는 플러터 1.0, B라는 프로젝트는 플러터 2.0 이런 식으로 선택적으로 사용할 수 있게 된다.

또 B라는 프로젝트가 플러터 2.0으로 사용하고 있더라도 fvm으로 1.0으로 변경해서 사용할 수도 있다.

 

이제 FVM 사용하는 방법을 설명할 것이다.

 

1. 먼저 FVM을 활성화한다.

터미널(혹은 명령프롬프트)을 열고 아래 명령을 실행한다.

dart pub global activate fvm

(위 명령이 되지 않는다면 pub global activate fcm 이 명령으로 실행해보도록 한다.)

※ 혹시나 무언가 잘못되어서 되돌려야 하는 경우라면 pub global deactivate fvm 명령을 사용하면 된다.

 

2. 환경변수 path를 실행해준다.

윈도우10 기준으로 보통 'C:\Users\사용자이름\AppData\Local\Pub\Cache\bin' 이 경로를 설정해주면 될 것이다.

MAC일 경우는 export PATH="$PATH":"/Users/사용자이름/.pub-cache/bin" 과 같은 형태로 지정해주면 된다.

(사용자이름은 본인의 PC에 설정된 사용자이름으로 치환해서 사용한다.)

그리고 MAC에서는 터미널 실행시마다 적용될 수 있게 ~/.bashprofile 파일 내에도 위 패스에 대한 것을 적용해주도록 한다.

(zsh을 사용한다면 ~/.zshrc를 수정해야 하며 없으면 생성하여 내용을 추가하면 된다.)

 

※ 혹시나 Dart 경로(나의 경우는 C:\flutter\bin\cache\dart-sdk\bin)도 환경변수에 지정되어 있지 않다면 지정해준다.

   Dart 경로를 추가하는 이유는 fvm 활성화 후 실행할 fvm 명령이 내부적으로 dart의 pub 명령어를 실행하기 때문이다.

 

경로 지정을 해주지 않을 경우 아래와 같은 오류가 발생할 수 있으므로 참고하도록 한다.

-------------------------------------------------------------------
Installed executable fvm.
Warning: Pub installs executables into C:\Users\Master\AppData\Local\Pub\Cache\bin, which is not on your path.
You can fix that by adding that directory to your system's "Path" environment variable.
A web search for "configure windows path" will show you how.
Activated fvm 1.3.7.
-------------------------------------------------------------------

 

3. fvm help 명령을 실행해서 설치가 정상적으로 되었는지 확인한다.

이런 형태로 명령어 목록이 뜬다면 정상적으로 설치된 것이다.

 

4. 사용할 플러터 버전을 설치한다.

fvm을 사용할 경우 fvm 내부에서 플러터 버전을 별도로 관리하므로,

기존에 쓰던 플러터 버전은 아무 의미가 없다.

나의 경우 기존 플러터 버전을 1.22.5를 사용했었고, 이 버전과 최신버전 두가지 버전으로 관리할 것이다.

아래 두 명령을 실행하여 플러터 두가지 버전을 모두 설치해준다.

fvm install 1.22.5

fvm install stable (이 명령은 최신의 안정적인 플러터 버전을 설치해준다.)

 

5. 설치된 버전을 확인해본다.

fvm list 명령을 사용하여 아래와 같이 설치된 버전 목록을 확인할 수 있으며,

해당 플러터 버전들이 어느 경로에서 관리되고 있는지도 확인할 수 있다.

 

6. 내가 원하는 프로젝트에 원하는 플러터 버전을 적용한다.

터미널에서 플러터 버전을 적용할 프로젝트 경로로 이동한다.

그리고 fvm use라는 명령어를 사용하여 원하는 버전으로 변경할 수 있다.

최신버전의 플러터 버전을 사용하기 위해 아래 명령을 실행한다.

fvm use stable (다른 버전을 사용하려면 fvm use 다른버전을 입력하면 된다.)

위와 같이 표시된다면 정상적으로 버전이 변경된 것이다.

 

※ 오류 대응 방법

(1) Could not install stable 에러 발생

만약 위와 같은 에러가 뜬다면, 명령프롬프트에 관리자 권한이 필요한 것일 수 있다.

윈도우10이라면 PowerShell을 관리자 권한으로 실행해서 사용하면 정상적으로 동작할 것이다.

 

(2) FVM 업그레이드를 요하는 문구

___________________________________________________
FVM Update Available 1.3.7 → 2.2.2
Changelog: https://pub.dev/packages/fvm/changelog
Run pub global activate fvm to update
___________________________________________________

 

위와 같이 뜨는 경우는 flutter upgrade를 통해 기존에 사용하던 플러터를 최신버전으로 업그레이드하면 된다.

그리고 다시 fvm을 활성화하는 명령을 실행해주면 정상적으로 동작하게 된다.

 

7. 해당 프로젝트에 원하는 버전이 정상적으로 적용되었는지 확인한다.

fvm flutter --version 명령을 실행한다.

위와 같이 정상적으로 stable 버전이 선택된 것을 확인할 수 있다.

flutter --version 명령을 실행할 경우 fvm 외부의 플러터 버전이 보여지므로 착오하지 않도록 한다.

 

8. 안드로이드 스튜디오에서 fvm에서 설정한 버전을 사용하도록 변경한다.

아무리 fvm use로 버전 변경을 하더라도 해당 프로젝트에서 fvm 플러터 버전을 참조하도록 경로 수정을 하지 않는다면 의미가 없다.

안드로이드 스튜디오를 실행하고 File -> Setting -> Languages & Frameworks -> Flutter -> Flutter SDK Path를 프로젝트 루트에 생성된 .fvm/flutter_sdk 의 경로를 지정해주면 된다.

위와 같이 적용하고 OK 버튼을 눌러주면 모든 설정이 끝난다.

이제 해당 프로젝트를 빌드하거나 디버깅을 하게 되면 적용된 플러터 버전으로 실행할 수 있을 것이다.

다만, 적용한 플러터 버전에 맞게 프로젝트 내의 소스 코드나 패키지도 마이그레이션해야 정상적으로 실행될 것이다.

그리고 터미널에서 빌드시에 flutter build apk, flutter build ios 등의 명령들을 사용하게 되는데, 

이 때에도 fvm flutter build apk, fvm flutter build ios와 같이 적용 중인 플러터 버전으로 빌드할 수 있는 명령어로 사용해야한다.

반응형
반응형

 

오늘은 AWS에서 가장 많이 쓰는 EC2의 T계열 인스턴스의 특성을 설명한다.

EC2를 사용할 때 가장 흔하게 t2.micro 프리티어를 사용한다.

처음 사용할 때만 해도 특별한 생각 없이 사용했었는데 cpu 성능을 제공하는 방식이 조금 특별하다.

일반적으로 CPU 성능이 정해져있어서 24시간 같은 성능을 제공할 것이라 생각하지만,

T계열 인스턴스들은 기본 성능을 제공하다가, 유저들이 몰리거나 하는 등 기준 이상의 성능이 필요할 경우 버스트 기능이 동작하게 된다. 물론, 공짜는 아니고 인스턴스 사양마다 제공되는 크레딧이 다르고 그 크레딧이 남아있는 동안 버스트 기능을 사용할 수 있다.

 

기준 이하 성능 사용을 지속할 경우 크레딧이 쌓이고(한계치 있음), 그 이상의 성능을 사용할 경우 크레딧을 소모시킨다.

크레딧이 다 소모되면, 기준 이상의 성능을 발휘하지 못하고 성능은 급격히 떨어지게 된다.

이러한 특성은 평소에는 CPU사용률 저조하다가 특정 시간대에 높은 사용률을 사용해야 할 경우 매우 효율적이다.

 

그렇지 않고, 24시간 내내 부하가 존재하는 서버의 경우 m4, m5 계열의 인스턴스를 사용하는 것이 바람직하다.

이 계열의 경우는 T계열처럼 크레딧 개념을 사용하지 않고 항상 같은 성능을 제공해준다.

다만, 가격이 비싸다는 장점이 있기 때문에 자신의 서버가 어느 특성에 적합한지를 판단하여 사양을 결정하는 것이 좋다.

 

T계열 인스턴스 사용시 크레딧의 상태는 CloudWatch에서 확인할 수 있다.

추가로 무제한 모드라는 것이 존재하는데, 이는 크레딧을 모두 소모하고 난 후에도 기준 이상의 성능을 사용할 때 비용을 추가하여 기준 이상의 성능을 사용할 수 있는 모드이다.

t2 인스턴스는 무제한 모드가 기본으로 꺼져있지만, t3 인스턴스의 경우 무제한 모드가 기본으로 옵션이 켜져있으므로 참고하기 바란다.

 

프리티어를 쓰는게 아니라면 t2보다는 t3 계열 인스턴스 사용하는 것을 추천하며,(아무래도 성능 향상, 비용 절감 등의 효과가 있다)

t3 계열의 경우 t3와 t3a가 나눠지는데, 두 계열 성능은 크게 다르지 않고 가격은 t3a가 싸다.

t3는 intel cpu, t3a는 amd cpu를 쓰는데, 가성비를 따져보면 t3a가 더 나은 것으로 생각된다.

 

반응형
반응형

 

보통 페이지 이동시 Navigator의 pushNamed 혹은 push를 이용한다. 

반대로 페이지를 종료할 경우 pop 함수를 이용한다.

그런데 이러한 기능을 사용하다가 처음 페이지 혹은 앞의 특정 페이지까지 바로 이동해야 할 경우가 발생할 수 있다.

물론 pop() 함수를 여러번 사용하여 해당 문제를 해결할 수도 있지만,

push된 페이지 수가 많을 경우 그만큼 pop을 호출해야 하므로 매우 비효율적이고,

특정 액션에 따라 페이지를 진입하여 경우에 따라 pop()해야 되는 개수가 달라지는 경우는 pop()함수로 해결이 불가능하다.

이 때, popUntil() 함수를 사용하게 되면 특정 페이지까지 pop()을 호출한 것 같은 효과를 낼 수 있다.

 

Navigator.popUntil(context, ModalRoute.withName("/"));

 

위 코드는 첫 홈화면까지 pop()을 진행하는 코드이다.

다만 주의해야 할 것이 있다.

popUntil의 두번째 인수로 사용되는 것이 어떤 것을 의미하는지 알아야 한다.

위 코드에서는 "/"으로 쓰였는데 루트로 이동하는 코드이지만 이것 또한 주의할 것이 있다.

 

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Demo',
      debugShowCheckedModeBanner: false,
      onGenerateRoute: _routes(),
      home: MainScreen(),
    );
  }
}

 

위 코드는 가장 메인에 해당하는 코드인데, MaterialApp의 home 속성이 MainScreen()로 지정되어있다.

즉, 이 상황에서 여러 push가 이루어지고, Navigator.popUntil(context, ModalRoute.withName("/")); 코드가 실행되면, MainScreen() 화면까지 pop()이 이루어지게 된다.

 

그 다음 또 간과할 수 있는 문제가 있다.

홈화면이 스플래시 화면이거나 로그인 화면 등의 경우 해당 화면 액션 처리 후 pushReplacement() 를 통해 Back으로 돌아와도 해당 화면으로 돌아가지 않게 조치하는 경우가 있다.

 

Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context) => SecondScreen());

위의 코드를 사용하여 첫 홈화면 MainScreen()에서 SecondScreen()로 바뀌었다고 가정하자.

이 때 여러 push로 다른 화면들을 띄워놓고 Navigator.popUntil(context, ModalRoute.withName("/")); 코드를 실행하면 어떻게 될까?

첫 페이지는 SecondScreen()로 바뀌었으니 해당 화면까지 pop()이 되어야 할 것 같지만 SecondScreen()에 대한 라우팅 정보가 없으므로 제대로 홈까지 찾아가지 못하고 모두 pop() 처리를 해버릴 것이다.

 

Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context) => SecondScreen(), settings: RouteSettings(name: "/")));

 

위와 같이 settings 속성으로 SecondScreen() 화면이 "/" 라우팅을 가진 스크린이라는 것을 알려준다.

그렇다면 이 때부터는 popUntil로 "/"를 지정하더라도 SecondScreen()까지만 pop()을 정상적으로 처리할 것이다.

 

정리하면, popUntil을 정상적으로 사용하기 위해 어떤 페이지든 이동할 때 Routesettings 속성을 반드시 지정하도록 하자.

반응형

+ Recent posts