안녕하십니까. 모바일 FO 이승욱 매니저입니다.
약 2년 동안 React, Vue, SSR 등 많은 환경에서 여러 서비스를 개발해왔습니다. 현재는 Flutter를 통해서 앱개발을 하고 있는데, Flutter는 웹 기반의 프레임워크와 유사하면서도 다른 점도 많은 프레임워크인 것 같습니다. 웹과 달리 Flutter는 앱 화면을 위젯 기반으로 생성하며, 스타일링부터 적용되는 디자인 패턴도 다르기 때문입니다. Flutter는 독자분들이 잘 아시다시피 유명한 프레임워크고 많은 패턴과 좋은 라이브러리들이 나왔기에 저는 아직까지 많이 연구되지 않은 Code Push에 대해 저의 리서치 내용을 공유하고자 합니다.
고민을 하게 된 이유
웹과 API를 개발하다가 앱 개발팀에 왔을 때, 가장 어려운 점은 배포 프로세스였습니다. 우선 두 차이점을 하나씩 비교해도록 하겠습니다.
일반적으로 웹은 위 그림과 같이 유저가 브라우저를 통해서 웹서버에 접속하게 됩니다. 그 다음 로드 밸런서를 통해 인스턴스 안에서 실제로 돌고 있는 API에 접근하게 되고, 그 뒷단에 커넥션이 있는 DB 혹은 다른 API에 접근하는 아키텍처를 지니고 있습니다. 여기서 앱 서비스를 운영하게 된다면 한 가지 절차가 추가가 되는데 그것은 바로 .apk, .aab 혹은 .ipa 파일을 앱 스토어에 게시해야 한다는 점입니다.
이 과정을 한 번 살펴보도록 하겠습니다. 개발자가 개발을 하고 메인 브랜치에 병합하는 등 GIT Action을 수행하면 이를 감지해서 빌드 파일을 생성하고, fastlane 같은 서드파티 프레임워크를 이용해서 구글과 앱 스토어에 게재하게 됩니다. 게재를 한다는 것은 결국, 앱에 버전이 생긴다는 것이고 한 번 생성된 앱 버전은 영원히 소스를 고칠 수가 없습니다. 비록 새로운 버전을 게재하여 개선할 수는 있으나 한 번 올라간 버전은 영원히 남게되는 것입니다. 즉, 앱 소스를 웹처럼 즉각적으로 원격으로 수정할 수 없다는 리스크가 발생하게 됩니다.
문제를 해결하기 위한 방안들
저와 팀원들은 위 문제를 해결하기 위해서 여러가지 방안을 도출하였습니다.
1. 웹뷰의 활용
앱에서도 웹을 활용할 수 있습니다. 바로 웹뷰를 활용하는 것인데요. 현재 저희는 InAppWebview 라이브러리를 통해서 플러터 환경에서 웹뷰를 구동하고 있습니다. 웹뷰는 웹처럼 변경사항을 즉각 반영할 수 있을 뿐만 아니라 기존에 개발된 웹을 재사용할 수 있다는 점에서 자주 쓰이는 방식입니다. 결제처럼 장애 발생 시, 빠른 대응이 필요한 영역은 지금도 웹뷰를 많이 사용하고 있습니다.
하지만, 웹뷰도 네이티브 영역보다 사용성이 떨어질 뿐만 아니라 플랫폼이 다르기 때문에 안정성이 떨어지는 이슈가 있습니다.
제가 개발하면서 경험했던 대표적인 사례를 공유 드리도록 하겠습니다. 과거 프레시몰에는 유튜브 영상과 재료를 한 번에 보여줄 수 있는 끼니연구소가 있었습니다. 앱에서 유튜브 영상을 업로드하기 위해서는 여전히 웹뷰 위에서 iframe을 올릴 수 밖에 없습니다. (참고 / 유튜브 공식 문서https://developers.google.com/youtube) 저는 웹뷰와 아이프레임 조합으로 개발을 진행했으나, 한 화면에 두 웹뷰가 같이 보일 때 백화현상 혹은 영상이 나오지 않는 문제가 발생했었습니다. 해당 원인은 결국 찾지 못하였고, 웹뷰 패지키 변경 및 한 화면에 영상을 하나만 활성화하는 로직을 통해서 문제를 해결했었습니다. 웹뷰는 필요하고 좋은 방식이기는 하지만 필요한 기능에 따라 적합하지 않은 선택지일 수 있습니다.
2. UI 친화적인 API 설계
자주 바뀌는 UI를 api에서 관리할 수 있다면, 네이티브 영역에서도 웹뷰처럼 원격으로 제어할 수 있습니다. 색상, 폰트, 컨텐츠 내용을 모두 API에 위임하여 앱을 도화지처럼 쓸 수 있도록 구성하는 방법을 사용한 경험이 있습니다. 처음에는 편리하다고 생각을 했는데, 기획적으로 내용이 너무 바뀌거나 앱에서 준비되지 못한 UI를 그려야할 때는 앱 배포를 해야하는 점이 있습니다.
또한, 앱 개발팀에서 화면 UI를 컨트롤 하지 못하다 보니, 매번 수정 요청이 들어올 때마다 API 팀에 수정해달라고 문의를 넣어야 해서 답답함을 많이 느꼈던 것 같습니다.
Code Push 새로운 대안이 될까
code push는 OTA(Over the air update) 서비스 중 하나로 무선 통신을 통해서 애플리케이션 등을 업데이트하는 기술을 말합니다. Microsoft와 Expo에서 JS 기반 번들을 클라우스 서비스로 업데이트하면서 먼저 선보였고 해당 용어가 탄생하게 되었습니다.
Flutter에서는 여러 솔루션이 나오고 있는데, 오늘 제가 소개드릴 code push 솔루션은 shorebird입니다. 제가 Shorebird를 선택한 이유는 문서화가 잘 되어 있으며 플러터 개발자와 다트 엔진 개발자로 구성된 플러터 전문가로 이뤄진 팀이 개발한 솔루션이기 때문에 신뢰성이 다른 솔루션보다 있기 때문입니다.
실습 예제
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
- primarySwatch: Colors.blue,
+ primarySwatch: Colors.purple,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
플러터를 공부해본 사람들이 제일 처음 접하게 되는 카운터 앱입니다. 이 카운터 앱의 기본 배경색은 파란색으로 설정되어 있습니다. 저는 Shorebird의 공식 문서를 따라서 이 배경색을 보라색으로 변경해봤습니다. 이 앱이 설치된 모든 유저에게 보이는 UI를 성공적으로 변경할 수 있었습니다.
동작원리 및 아키텍쳐
그렇다면 Shorebird는 어떤 동작 원리와 아키텍쳐로 동작하는 지 설명드리도록 하겠습니다.
우선 Shorebird는 3가지 툴로 구성되어 있습니다.
- 배포와 빌드를 용이하게 해주는 CLI 툴
- 자체적으로 수정한 Flutter Engine
- 패치를 담당할 host server
먼저 개발자 PC에 CLI 툴을 설치합니다. CLI 툴을 통해서 Shorebird에서 자체적으로 수정한 Flutter를 받아옵니다. 개발자는 Flutter 명령어가 아닌, Shorebird 명령어를 통해 개발을 진행하고 빌드 파일을 생성하고 최종적으로는 스토어에 앱을 게재합니다. 여기서 자체적으로 플러터 엔진과 플러터 프레임워크를 수정했다는 얘기는 Flutter 엔진, Flutter 프레임워크, Flutter 빌드 루트 프로젝트를 Fork하여 유저가 앱을 실행하고 host server를 체크해서 변경점이 있다면 앱을 app update 할 수 있는 기능이 내포되어 있습니다. host server에는 소스를 저장하지는 않고, 바이너리된 파일과 버저닝을 위한 파일만이 존재합니다.
프로젝트 Fork 및 수정 내역은 공식 홈페이지에서 확인 가능합니다.
- 플러터 엔진 수정 내역: https://github.com/flutter/engine/compare/3.7.12...shorebirdtech:engine:stable_codepush
- 플러터 프레임워크 수정 내역: https://github.com/flutter/flutter/compare/3.7.8...shorebirdtech:flutter:stable_codepush
- 플러터 빌드 루트 수정 내역: https://github.com/shorebirdtech/buildroot/commit/7383548fa2306b5d53979ac5e9d176b35258811b
React Native의 Code Push와 다른 점
React Native | 비교 대상 | Flutter |
MS Visual Studio App Center | 관리 서비스 | Shorebird |
Js Bundle | 코드 푸시 범위 | Flutter Framework |
React Native (RN)의 경우에는 MS가 주관하는 App Center를 통해서 호스팅 서버를 운영합니다. 반면에 Shorebird의 경우에는 Shorebird에서 운영하는 호스팅 서버를 통해서 운영됩니다. 클라우드 서비스를 통해서 버전을 관리하고 대시보드를 제공한다는 점은 동일하나 MS에서 제공하는 기능이 더욱 강력합니다. Shorebird의 경우 CLI를 통해 코드 푸시를 릴리즈하는 반면, App Center는 UI 대시보드를 통해서 배포를 할 수 있습니다.
코드 푸시 범위는 코드 푸시 보다는 각각의 프레임워크의 차이점으로 볼 수 있습니다. RN 경우 JSI를 통해 Js Bundle을 실행시켜 앱을 구동합니다. 반면, 플러터는 Flutter 엔진이 dart 코드를 실행시켜 앱을 구동합니다. RN와 Flutter는 개발 언어나 동작 원리는 다르나, 각 플랫폼에서 하이브리드 영역만 적용이 가능합니다. 가령 메서드 채널링을 통해 동작하는 네이티브 로직을 수정한다면, 코드 푸시를 사용할 수 없습니다.
평가
코드 푸시를 실습해보면서 해당 기술에 대한 저의 개인적인 총평은 다음과 같습니다.
비용
빼 놓을 수 없는 부분입니다. 각 유저가 Shorebird의 서버에 접근해서 업데이트 여부를 체크하고 바이너리 파일을 받아와야 하기 때문에 네트워크 비용이 발생합니다. Shorebird 팀도 이 부분에 대한 비용처리를 위해 업데이트 1건당 비용을 받고 있습니다. 우리동네GS의 MAU (월간활동유저)가 100만 이상임을 감안했을 때, 결코 적지 않은 비용이 발생할 수 있습니다. Shorebird 팀과 논의했을 때, 비용을 조금 더 줄여줄 수 있다고는 했지만 더 많은 협상과 논의가 필요할 것으로 보입니다. 다만, 추후에는 Shorebird 호스팅 서버를 직접 온프레미스나 자체 클라우드로 이관하는 방법도 Shorebird 팀에서 검토 중이니 개선될 것이라고 기대해봐도 좋을 것 같습니다.
배포 속도
IOS 경우에는 alpha 버전 밖에 존재하지 않습니다. alpha 버전은 stable 버전과 달리 배포 적용 속도가 안드로이드보다 느립니다. 제가 실습 소스로 테스트했을 때는 워낙 경량화된 앱이기 때문에 큰 차이를 느끼지는 못했습니다. 다만, 앱 사이즈가 커지게 되면 적용 속도가 느리기 때문에 IOS에서 도입하는 것은 시기상조일 것으로 보입니다. 2023까지 IOS Stable 버전을 출시할 예정이라고 하니 마찬가지로 기대해봐도 좋을 것 같습니다.
코드 푸시의 적용 범위
코드 푸시는 만능이 아닙니다. 가령 앱에 특정 패지키가 설치되어있지 않았는데, 패키지가 있을 때만 동작할 수 있는 소스를 집어넣거나 정적 요소 (이미지, 아이콘) 등은 이미 들어가있지 않다면 소스가 반영되지 못하고 에러가 발생할 수 있습니다. 또한, 과도하게 앱의 성격을 바꿀만큼 UI / UX를 코드 푸시 만으로 바꾸게 된다면 심사 거절의 사유가 될 수 있습니다. 제가 생각하기에는 앱의 특정 로직을 변경하거나, 간단한 UI 처리 혹은 버그 개선 등으로 사용하게 된다면 유용하게 쓰일 수 있을 것으로 보입니다.
결론
결론적으로 팀에 적용된 git flow와 CI/CD 스크립트에서부터 Shorebird tools가 녹아 들어가야 하고, 버저닝 관리 방식도 스토어 버저닝과 Shorebird host server에서 관리하는 버저닝이 같이 관리가 되어야 합니다. 또한, code push는 현재는 유료이기 때문에 한 번 수행할 때마다 관리 부서와 함께 엄격하게 관리가 되어야 할 것으로 보입니다. IOS일 경우에는 배포 속도까지 염두해야 하기 때문에 팀 내부적으로 많은 것들이 바뀌어야 합니다. 즉시 적용하는 것은 시기상조처럼 보이나 계속 Shorebird가 개선되고 조직적으로도 해당 기술이 필요하게 된다면 가까운 미래에는 적용될 수 있다고 생각합니다.
이승욱 | 디지털서비스본부 > 모바일FO팀
우리동네GS 앱 개발 담당
신기술에 관심이 많고 도전하는 것을 좋아하는 엔지니어입니다.
'APP' 카테고리의 다른 글
우리동네GS Screen Reader 적용기 (0) | 2024.05.23 |
---|---|
엔터프라이즈 MSA 이야기 4탄 – GS SHOP 주문서비스팀의 현대화 여정 (2) | 2023.10.25 |
엔터프라이즈 MSA 이야기 3탄 – SR 도메인 편 (9) | 2023.08.01 |
우리동네GS BFF 구현기 Step 1 - 도입 배경과 설계 (1) | 2023.07.28 |
Flutter App 실시간 CDN 이미지 변경 상태 적용 방안 (1) | 2023.06.20 |