서론
이번에 프로젝트를 진행하는데 고객님의 요구사항 중에 외국인도 사용할 수 있도록 다국어버전으로 만들어달라는 요구가 있었다. Flutter에는 다국어에 대한 다양한 구현방식이 있는데 아래의 4가지로 구분하는 것을 어디선가 읽었다.
- Internationalization(국제화)
- Localization(지역화)
- Globalization(국제화)
- Multilingalization(다국어화)
뭐 다 거기서 거기인 느낌인데 나는 이것들이 뭐가 다른지 잘 모르겠다. 뭐 i18n, l10n g11n, m17n 이라는 개념은 잘 모르지만 일단 Flutter에서 다국어를 구현하는 방법들에 대하여 검색해봤다. 다국어를 위한 패키지는 pub.dev에서 ‘localization’으로 검색해보니 929개 패키지가 검색되었는데 여기저기 구현예제를 검색해보니 대표적인 다국어 패키지는 아래의 2가지인 것 같다.
- flutter_localization(https://pub.dev/packages/flutter_localization)
- easy_localization(https://pub.dev/packages/easy_localization)
두가지 패키지를 다 써봤는데 일단 flutter_localization은 intl 패키지가 필요하기도 하고 이번에 적용하려고 하는데 버전이 업데이트 되면서 뭔가 flutter 프레임워크랑 잘 안맞는 것 같고 뭐가 문제인지 패키지 import도 잘 안되서 구현이 까다로웠다.

그래서 Likes와 Popularity가 높은 easy_localization으로 선회하여 작업 하기로 했다.


easy_localization의 좋아요 수가 다국어 관련 패키지 중 가장 높다. 물론 PUB POINT(패키지 점수)가 10점 낮긴한데 앱에서 점수에 대한 정보를 확인해보면 크게 이슈가 있는 내용은 아니고 Flutter에서 지원하는 Web Asambly 기능이나 Deprecate 되는 기능을 아직 반영하지 않은 정도라 적용하는데 크게 문제가 있을 것 같진않아 이번 프로젝트에 적용하였다.(뭐 이런 문제도 곧 업데이트를 통해 해결하겠지..)

자 이제 Flutter에 easy_localization을 적용해보도록 하자.
1. 프로젝트 생성 및 문제 해결
1 | $ flutter create easy_localization_sample |
프로젝트 생성 자체는 어려운일은 없다. 그냥 flutter cli 로 생성하면 순식간에 만들어진다.

그냥 Flutter CLI로 프로젝트를 생성하고 Visual Studio Code를 실행해서 보니 android에 빨강색으로 표시되어있는 것을 확인할 수 있었다. 나는 본능적으로 코딩영역에 붉은색이 보이면 불안감이 든다. 무슨 오류가 발생한건지 두렵다. 해결 못하면 어떡하지?
걱정만 해봐야 아무것도 해결할 수 없다. 오류를 해결해보자. 저 오류는 “The supplied phased action failed with an exception.” 인데 Exception 메시지를 찬찬히 읽어보니 간단하게 이야기 하자면 “Android Gradle은 Java 버전이 17이상인 JDK를 써야하는데 너는 11버전을 쓰고 있음. JDK 버전을 17로 바꿔줘”라고 한다. 해결방법으로 제시된 내용은 아래와 같다.

- IDE 세팅을 바꿔줘
- JAVA_HOME 환경변수를 바꿔줘
- gradle.properties에 org.gradle.java.home 설정을 바꿔줘
위 세가지 방법중에 나는 그냥 Visual Studio Code의 환경설정을 손봐줬다. 나는 동시에 진행 중인 프로젝트들이 많아서 Global 설정을 건들수는 없고 그냥 Workspace 설정만 손대서 해결하겠다.

Visual Studio Code를 재실행했다. 설정을 적용해보면 새로운 오류가 또 발생했다.

뭐 간단하게 이야기 하자면 .generateLockfiles에 task를 생성할 수 없다는 이야기인데 이것도 해결해야겠다. 이 문제는 gradlew.bat 파일에서 JAVA_HOME 설정이 제대로 안되서 발생하는 문제다. 그래서 나는 아래와 같이 JAVA_HOME을 수동으로 잡아줘서 해결했다.

위처럼 내용을 수정하고 Visual Studio Code를 재시작하면 모든 문제가 해결된 것을 확인할 수 있다.(사실 문제를 해결하지 않아도 앱은 잘 동작하지만….)

2. 패키지 설치
설치하는 방법은 pub.dev 에 설명을 읽어보면 바로 확인할 수 있다.

1 | $ flutter pub add easy_localization |
패키지 설치는 어려울 것 없다. 그냥 CLI에다가 저렇게 치면 된다. 그러면 알아서 pubspec.yml에 dependency에 항목이 자동으로 추가되고 패키지도 최신버전으로 설치된다.


자, 이제 코딩을 할 준비는 마쳤다.
3. easy_localization 세팅
일단 디렉토리를 하나 만들어줘야한다. 나는 프로젝트 root에 assets/i18n 디렉토리를 만들었다.

그리고 pubspec.yml 파일에 있는 assets 설정을 수정하자. 프로젝트를 만들면 assets 관련 설정이 주석처리되어있는데 주석을 풀고 아래와 같이 수정하자.

main.dart 파일에 easy_localization 패키지를 App에 적용하자.
1 | // main.dart |
일단 WidgetFlutterBinding을 ensureInitialized(초기화 보장)하여 EasyLocalization를 Flutter Widget에 Binding 할 수 있도록 준비한다.
언젠가 WidgetsFlutterBinding과 관련해 글을 쓰긴하겠지만 간단하게 설명하자면 개발문서에는 Flutter 엔진에 어떤 기능을 Binding 할 수 있도록하는 일종의 glue(접착제)라고 설명하고 있다.
EasyLocalization 이라는게 String객체나 Text 위젯에 tr이라는 메서드를 붙여서 다국어를 적용하는 방식이라서 이런 Binding 기능이 필요하다.
path는 방금 만든 assets의 i18n 디렉토리를 지정하고 supportedLocales 에는 지원할 언어를 설정한다. 이때 Locale 객체를 Locale(‘en’)으로 생성하면 나중에 언어팩을 en.json 이라고 만들어야하고 혹시 Locale(‘en’, ‘US’)라고 생성하면 언어 파일을 ‘en-US.json’이라고 생성해야한다. 나는 어차피 샘플을 만드는 거라서 그냥 Locale(‘en’) 이라고 만들었다.
failbackLocale은 지원하지 않는 언어로 앱에 진입했을 때 보여질 기본 언어를 설정한다.
여기까지 코딩했다면 일단 기본적인 세팅은 마쳤다. 언어 파일을 만들자.

1 | // en.json |
1 | // ko.json |
4. 코딩
이제 MyHome 위젯을 만들어보자. 프로젝트를 생성할 때 자동적으로 생성되는 메인 위젯은 StatefulWidget인데 언어를 동적으로 바꿔주는 기능을 만들 생각이니 그대로 내버려두자.
(StatefulWidget과 StatelessWidget에 대해서도 나중에 글을 써보겠다. 아마 다음 포스팅에 쓰지 않을까..)
1 | // main.dart |
위 처럼 코딩하면 다국어가 적용되는 것을 확인할 수 있는데 여기서 잊지 말아야할 것은 아래의 코드 영역이다.
1 | // main.dart |
- localizationDelegates : 앱의 다국어 위젯에 대한 대리 객체(Delegate). 대리객체는 이 애플리케이션의 다국어 위젯에 대한 모든 지역화된 리소스를 집합적으로 정의. 이 속성을 정의하면 supportedLocales, Locale 속성을 설정해야한다.
- supportedLocales : 지원하는 지역 설정
- locale : 현재 지역 설정
이 3가지 속성을 깜빡하기 쉬운데 이 속성들을 설정하는 걸 까먹으면 나처럼 삽질을 해야한다.(난 이것 때문에 30분 동안 내가 뭘 잘못했는지 반성의 시간을 갖게 되었다….제길)
이건 easy_localization뿐 아니라 다른 다국어 패키지들도 마찬가지로 해당된다.
위의 코드들을 정상적으로 잘 적용했다면 앱을 실행해보자.
5. 결과확인

언어가 동적으로 변경되는 것을 확인할 수 있다.
결론
누군가에게 이 포스팅이 도움이 되기를 바라며 다음엔 StatefulWidget과 StatelessWidget에 대해서 알아보자. 안녕!