View
Flutter 3.24 버전에서부터 Swift Package Manager (이하 Swift PM 또는 SPM) 을 패키지 관리 도구로 공식적으로 지원하기 시작했다!
ㅤ
회사 내에서 플러터 업데이트나 새로운 기술에 대해 호기심이 많으신 팀원분이 계신데, 내가 이전에 iOS 개발에 대한 경험이 있다보니 “SPM을 우리도 도입하면 괜찮을까? 어떤 장점들이 있을까?” 에 대해서 나에게 물어봐주셨다. 나도 요런 부분들이 궁금하기도 하고, 애플과 플러터의 조합에 호기심도 생겨서 SPM 적용에 대한 정보 서치와 현 시점에서의 생산성 개선 정도에 대해서 테스트를 해봤다.
ㅤ
그 결과와 내 생각은 글 하단에 작성해뒀다!
ㅤ
여기 Medium 글을 확인해보면, 플러터 3.24 버전부터 Swift PM을 지원한다. 아직 Early Support 이기는 하지만, 이제 수면 위로 드러난 만큼 빠른 발전을 시작하지 않을까 생각된다. (도키도키…🥹)
ㅤ
2019년에 애플이 Xcode에서 SPM를 제공하며 본격적으로 SPM을 메인 패키지관리 툴로 밀어주기 시작하는 시점에 플러터 깃허브 이슈 내 에서 코코아팟 대신 SPM을 사용할 수 있으면 좋겠다는 의견이 나오기 시작했던 것으로 보인다. 위 링크 속 의견을 살펴보면, SPM이 애플에서 지원하는 1st-party 툴이기에 앞으로 점진적으로 SPM이 코코아팟을 대체해갈 것이라 생각하고, 플러터에서도 이를 패키지 관리를 위해 사용하려면 어떻게 해야할 지에 대해 논의하고 있다.
ㅤ
플러터 업데이트 내역을 살펴보면 코코아팟도 계속해서 업데이트를 할 것이라 되어있지만, 지금까지 잘 사용해오고 있었던 코코아팟을 두고 SPM을 도입한 것에 대해, SPM의 장단점은 무엇이고 현재 프로젝트에 도입이 가능할 지에 대해 살펴보고자 한다.
ㅤ
CocoaPods과 Swift PM
SPM 적용에 따른 성능 개선 여부에 대해 알아보기 위해서, 우선 기존의 방식들에 대한 장단점을 찾아보았다.
ㅤ
👋 코코아팟과 SPM의 동일한 장점
- 패키지 간의 의존성에 대한 관리를 간단하게 처리할 수 있다.
(사실상 패키지 관리 도구로서의 역할)- 패키지간에 의존성이 있을 경우, 충돌이 나지 않게 관리해준다.
- outdated 된 패키지가 있는 경우, 쉽게 버전업을 처리할 수 있다.
ㅤ
👍 코코아팟과 비교했을 때, SPM의 장점
- 프로젝트 내에 필요한 파일만을 추가해, 프로젝트 자체의 크기를 줄일 수 있다.
- 빌드 시간이 빠르다.
- 프로젝트 외부에 패키지를 가져오는 코코아팟과 다르게, 프로젝트 내에서 패키지를 관리하기에 별도의 링크 과정이 필요 없다.
- 직접 소스코드를 컴파일해 사용하며, 캐싱을 잘 처리해 변경되지 않은 모듈은 다시 빌드하지 않는다.
코코아팟은 자주 패키지를 새로 빌드하느라 시간이 더 걸린다.
- Xcode에서 GUI 기반으로 패키지 관리가 가능하며, Xcode가 알아서 설정을 관리해준다. 간단하다
- 리눅스에서도 동작한다.
ㅤ
👎 코코아팟과 비교했을 때, SPM의 단점
- 대부분의 패키지가 코코아팟을 지원하는 반면에, 일부 패키지만 SPM을 지원한다.
- 초창기에는 지원하는 패키지 수가 적었지만, 점차 SPM도 지원하는 패키지가 늘어나는 중이다.
규모 있는 패키지는 최근 2년간 패키지가 업데이트가 되었다면, 대부분 SPM을 지원한다고 보면 된다. - SPM을 지원하지 않는 패키지는 Cocoapod으로 알아서 import를 하기 때문에, 어떤 패키지가 SPM을 지원하지 않는지에 대해 따로 신경쓰거나 관리해주지 않아도 된다.
- 그러나 자체적으로 SPM을 지원하더라도, 플러터 플러그인이 SPM으로 가져오지 못하는 패키지가 아직 많다! 아직은 이 부분이 가장 큰 문제인 듯 하다…! 🤔🤔
- 초창기에는 지원하는 패키지 수가 적었지만, 점차 SPM도 지원하는 패키지가 늘어나는 중이다.
- 처음에 패키지를 가져오는게 엄청 느리다는 평가가 종종 있다.
- 단일 브랜치 및 커밋만 가져오는게 아니라, 몇 년간의 기록이 담긴 전체 레포지토리를 다운받음
- 그러나 이 부분에 대해서는, 오히려 전체 레포를 가져오는게 더 빠르다는 깃허브 인프라팀의 의견이 있다!
ㅤ
성능 비교 테스트
실제로 플러터 패키지에 Swift PM을 적용했을 때 빌드시간이 줄어들지에 대해 확인해보기 위해 개인 프로젝트에 SPM을 적용해 빌드 시간의 차이를 비교해봤다.
ㅤ
테스트 준비 - SPM 활성화
테스트를 위해서 Swift PM을 활성화시키는 절차는 플러터의 공식문서를 참고했다.
https://docs.flutter.dev/packages-and-plugins/swift-package-manager/for-app-developers#how-to-turn-off-swift-package-manager
ㅤ
flutter channel main --no-cache-artifacts
flutter config --enable-swift-package-manager
위 두 명령어만 입력해주면, 플러터를 최신 버전으로 업데이트 해준 뒤 SPM을 활성화 시켜준다. 사실 플러터가 3.24 버전 이상이라면 굳이 업그레이드 없이 SPM 활성화만 해줘도 될 것 같다. (시키는 대로 입력하고 나니 플러터가 3.26 ~ pre 버전이라 사실 약간 불안해서 그렇다 🤣)
ㅤ
flutter channel main --no-cache-artifacts
flutter config --enable-swift-package-manager
>>>
Downloading Darwin arm64 Dart SDK from Flutter engine ad3dd0df0fe7bf60e153378ddf1c6a69bb39c38e...
** Resuming transfer from byte position 30552064
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 177M 100 177M 0 0 5422k 0 0:00:33 0:00:33 --:--:-- 5688k
Building flutter tool...
Resolving dependencies...
Downloading packages...
Got dependencies.
Setting "enable-swift-package-manager" value to "true".
You may need to restart any open editors for them to read new settings.
ㅤ
flutter run
>>>
Downloading ios tools... 18.7s
Downloading ios-profile tools... 16.9s
Downloading ios-release tools... 27.5s
Downloading Web SDK... 10.8s
...
ios/Runner/AppDelegate.swift uses the deprecated @UIApplicationMain attribute, updating.
Adding Swift Package Manager integration... 3.5s
.gitignore does not ignore Swift Package Manager build directories, updating.
Running pod install... 20.1s
Running Xcode build... ⣽
ㅤ
요렇게 요렇게 활성화가 되고 나서, flutter run 으로 iOS 빌드를 한 번 해주고 나면 Swift Package Manager 키워드가 로그에도 나오고, Xcode에서 프로젝트를 열어봤을 때 파일 목록 아래에 Package Dependency 라는 새로운 하위 항목이 생긴 것을 확인할 수 있다.
ㅤ
ㅤ
테스트 진행 - 직접 iOS 빌드 해보기
테스트 환경
Flutter 3.26.0-1.0.pre.204 • channel main • https://github.com/flutter/flutter.git
Framework • revision e0ca194660 (18 hours ago) • 2024-09-25 03:51:01 -0400
Engine • revision ad3dd0df0f
Tools • Dart 3.6.0 (build 3.6.0-277.0.dev) • DevTools 2.40.0-dev.1
ㅤ
테스트 방식
플러터 프로젝트를 2개로 복제해, 하나는 SPM을 적용하지 않은 버전 (코코아팟 버전), 하나는 SPM을 활성화한 버전으로 준비했다.
- SPM 활성화 여부를 제외한 나머지 소스코드 및 import 하는 패키지 개수와 버전 등의 설정은 모두 동일하다.
- 두 프로젝트 모두 동일한 경로의 Flutter SDK를 사용하도록 세팅해주었다.
ㅤ
이렇게 준비한 2개의 프로젝트에 대해, 각각 5회씩 flutter clean
명령어로 프로젝트를 한 번 비워준 뒤, flutter build ios
로 iOS 빌드를 수행해줬다. 빌드 시간에 최대한 영향을 주지 않기 위해서 빌드가 진행되는 동안에 맥북으로 다른 작업은 수행하지 않았으며, 한 번에 하나의 프로젝트만 빌드를 진행하였다.
ㅤ
테스트 결과
테스트 수행 결과는 pod install 시간과 Xcode 빌드 시간으로 나눠 체크하였고, 5번의 실행 평균으로 그 값을 비교하였다.
ㅤ
결론부터 확인해보면, Swift PM의 활성화를 통해 왼쪽의 Xcode 빌드 시간은 약 2% 정도 감소했고 오른쪽의 pod install
시간은 약 5% 정도 감소한 것을 확인할 수 있다.
ㅤ
개선이 되기는 하는데,,, 뭔가 기존 시스템을 변경할 만큼의 큰 개선인가..? 는 잘 모르겠다. 생산성 측면에서 결국 중요한건 Xcode 빌드 시간일텐데, 2% 도 개선이 되지 않아 좀 아쉽게 느껴졌다.
ㅤ
물론 앱 개발 중 테스트를 위한 빌드를 할 때도 많지만, 현재 회사 시스템에서는 CI/CD를 위해 빌드 머신에서 iOS 빌드가 돌아가도록 세팅이 되어있는데 이 빌드량도 꽤 되고, 테스트를 수행하다보니 빌드 시간도 어느정도 소요되는 것으로 알고있다. 이 시간을 줄여 생산성을 높이는 것이 “SPM 도입 어때요? 드릉드릉…!” 이라는 이야기가 나왔던 이유였는데, 적용하기에는 아직은 개선량이 좀 미흡하지 않나 싶다.
ㅤ
(빌드 머신 및 서버 운용에 1억이 들어서 2%를 절약한거라면 모르겠지만, 현재 규모에서는 10만원 드는데 2천원을 절약한 느낌이라 굳이굳이? 인 것 같다.)
ㅤ
- 테스트를 진행하면서, pod install 이전에 package를 다운로드할 때 SwiftPM을 적용했을 때 패키지의 개수가 더 늘어나는 모습을 보여줬다. 아마도 SPM을 활성화하면
lint
,freezed
,analyzer
같은 개발 도구들이 package에 포함되어서 이렇게 보이는 것 같다. 패키지 개수가 오히려 늘어난게 아닌가 싶었는데, SPM을 적용했을 때 pod install이나 빌드 시간이 줄어든 것을 봤을 때, 패키지 개수가 증가한게 빌드 시간에 영향을 주지는 않는 것으로 추측된다.
ㅤ
ㅤ
기대에 미치지 못한 SPM 적용 결과에 대한 나의 생각 👀💭
기대했던 것보다 빌드 속도 개선이 많이 이루어지지 않아서 당황스러웠다. 이게 맞나..? 혹시나 싶어 SPM 패키지들을 다시 확인해봤다.
ㅤ
여기에서 플러터-SPM 연동을 위해 추가된 패키지인 FlutterGeneratedPluginSwiftPackage를 제외하면, 총 4개의 패키지만 SPM을 통해 관리되도록 넘어온 것을 확인할 수 있다. Firebase를 포함해 프로젝트 내에서 30가지 정도의 패키지를 사용하고 있었음에도, Package Manager로 전환된 Pod package들을 확인해보니 작은 패키지들만 들어와있었다.
ㅤ
의외였던 점은, SPM 을 통해 전환되기를 바랬던 패키지들이 대부분 SPM을 이미 지원하고 있는 패키지라는 점이다. 예를 들어, Firebase 같은 경우에도 이전에 iOS 프로젝트를 하면서 import 해서 사용했었는데, 그게 코코아팟에서 SPM으로 넘어오지 않았다. 아래 링크를 보면, SPM으로 프로젝트에 의존성을 추가하는 방법에 대해서도 자세히 나와있다.
ㅤ
아마도, 단순히 패키지가 SPM을 통한 관리를 지원한다고 하더라도 Flutter 플러그인에서 이를 적용할 수 있게 추가 작업이 되어있지 않으면 SPM 활성화를 하더라도 플러터가 패키지를 자동으로 전환해주지 않는 것 같다. 개인 프로젝트에서 사용중인 가장 무거운 패키지가 Firebase인데, 빌드시간에서 영향력이 큰 패키지의 CocoaPod → SPM 전환이 이루어지지 않아 빌드시간 상의 큰 개선이 없는 점을 미루어 볼 때, 회사 프로젝트도 SPM을 활성화했을 때에도 당장은 빌드 시간상의 이점을 크게 볼 수는 없을 것으로 생각됐다.
ㅤ
이걸 보면서, 어쩌면 플러터가 SPM을 이제 지원하기 시작하는 만큼, 이제는 직접 수동으로 SPM을 통해 Firebase, Datadog 등의 패키지들을 설치한 뒤, 플러터 플러그인을 통해 프로젝트 내부에 바인딩 시켜주는 방법이 있지 않을까? 라는 생각이 들었다. 그러나, 이 경우에는 플러터 개발을 위해 pubspec에 올라와있는 패키지와 Xcode의 SwiftPM에서 관리하는 패키지 간의 네이밍 충돌이 발생하거나 패키지의 버전 관리를 위해서는 pubspec 파일과 별도로 Xcode에서 버전 변경 및 패키지 간의 의존성 관리 해줘야하는 단점이 있을 것이라는 생각이 들었다.
ㅤ
다행인 점은, 아래 이슈 등을 통해서 사람들이 플러터의 SPM 지원을 위해 다양한 Task를 기록하고 처리하고 있는 것 같다. 이후에 플러터의 Swift PM을 지원하는 패키지가 더 많아지고, 플러그인 개발이 좀 더 진행되면 엔터프라이즈 급의 프로젝트에서도 SPM 활성화를 고려해봐도 되지 않을까 싶다.
https://github.com/flutter/flutter/issues/126005
> 이 이슈는 2023년 4월에 올라온 이슈이다. 아마 기존부터 SPM의 적용을 위해 여러 시도들이 있어왔던 것 같다.
'Develop > Flutter 개발' 카테고리의 다른 글
[Flutter] 같은 열거 값 이름을 가진 서로 다른 두 Enum 간의 변환에는 findWhere을 사용하자! (0) | 2024.09.28 |
---|---|
[Flutter] Dart의 void 타입은 null이 아니다 / this function has a return type of void and cannot be used (0) | 2024.09.20 |
[Flutter] 플러터의 화면 렌더링 과정 (2) | 2024.07.24 |
[Flutter] Dart는 Native Machine Code로 컴파일 되지만, Dart VM은 여전히 사용된다? (0) | 2024.07.12 |
[Flutter] 플러터 코드로만 Sign in with Apple 유저의 회원탈퇴 (Revoke) 기능 구현하기 (3) | 2024.06.26 |