전체 글
Flutter BLOC 기반의 Widget Test
BLOC 패턴을 적용하면 가독성있는 테스트 코드를 작성할 수 있다. 특히 각각의 BLOC 단위 테스트 말고도 BLOC과 상호작용하는 위젯을 테스트하는 코드도 깔끔하게 작성할 수 있다. 이 문서에서는 BLOC 패턴이 적용된 페이지 위젯을 테스트하는 위젯 테스트에 대하여 알아본다. 편의상 Bloc 대신 Cubit을 활용하였다. 위젯 테스트란? 화면에 그려진 위젯에 대하여 클릭이나 스크롤과 같은 이벤트가 발생했을 때 원하는 결과가 발생하는 지 확인하는 테스트. 예를 들어 로그인 버튼을 눌렀을 때 로그인 요청이 발생하는지 테스트하려면 앱을 켜서 직접 눌러보아야 하는데, 매번 사람이 테스트 할 수 없으니 코드 레벨에서 테스트 하여 결과값을 보장받는 것이다. 위젯 테스트는 단위 테스트보다 포괄적인 테스트를 수행한다..
Swift UI - Observable Object로 이벤트 프로그래밍
기존에 UIKit에서 화면 데이터의 값이 변경되었을 때 rxSwift를 통해서 변경을 감지하고 View를 갱신해주었습니다. SwiftUI도 마찬가지로 데이터 변경을 감지하고 View를 갱신할 수 있도록 하는 Combine 프레임워크가 있습니다. Combine 프레임워크는 iOS 13 이상부터 사용 가능합니다. Combine 프레임워크의 ObservableObject 는 아주 쉽게 여러분들의 데이터가 변경될 때마다 View를 갱신하는 코드를 작성하게 도와줍니다. 가볍게 ObservableObject 이 뭔지 알아보고 실제로 어떻게 사용하는지 예시 코드를 보겠습니다. ObservableObject ObservableObject 는 Combine 프레임워크에 포함된 Publisher입니다. Observable..
swift ui - navigation 활용하기
Swift UI에서 Navigation을 하려면 NavigationView 를 사용해야 한다. Swift UI라고 해서 기존에 없던 기능이 제공되는 것은 아니고 기존의 UI Kit의 네비게이션 시스템을 View로 다룰 수 있게 해놓은 것이다. iOS 버전이 증가하면서 부족했던 네비게이션 기능들이 추가되고 있으므로 업데이트를 항시 확인해주어야 한다. iOS 16부터는 NavigationStack 을 사용하는 것이 권장사항이다. 아직 16버전을 타겟하는 것은 이르기 때문에 iOS 17정도 나왔을 때 마이그레이션을 고민해본다. NavigationView NavigationView는 하나의 View Stack을 만들어주고 관리할 수 있게 한다. 사용법은 매우 간단하다. NavigationView 안에 페이지 뷰..
Java Spring 객체 생성 of 함수
Dto나 Entity를 새롭게 생성하는 경우 Setter로 생성하거나 Builder로 생성하게 됩니다. 프로젝트의 규모가 커지면 Dto 클래스나 Entity 클래스 객체를 여러 모듈에서 생성하는 경우가 발생하는데 인라인 형식으로 객체를 생성한다면 해당 클래스가 수정되었을 때 여러 곳에서 오류가 발생합니다. 이러한 문제를 해결하기 위해 도메인으로 정의된 객체를 생성하는 생성자 함수 of 메서드를 정의하는 방법을 활용할 수 있습니다. 예를 들어서 모임 접수를 나타내는 MeetReceipt 도메인 객체를 생성하는 of 함수는 다음과 같의 정의할 수 있습니다. public static MeetReceipt of(Long meetId, MeetReceiptRequestBody meetReceiptRequestBo..
플러터 싱글턴 구현하기
이 문서에서는 플러터에서 싱글턴을 구현하는 방법에 대해 알아봅니다. Class 이름 활용하기 싱글톤으로 만들고 싶은 클래스에 다음과 같이 코드를 작성합니다. class Database { static final Database _instance = Database._internal(); factory Database() => _instance; Database._internal(); } 위와 같이 작성하면 코드 어디에서든 ClassName()로 싱글톤 객체에 접근할 수 있게 됩니다. Database().getSomthing(); 공유 객체 생성하기 공유 객체를 정적으로 하나 선언하고 다른 객체를 만들지 못하도록 생성자를 private 선언합니다. class Database { static final sh..
플러터 원격 저장소 패키지 의존성 추가하기
Flutter 공식 패키지 저장소 pub.dev에 있는 패키지가 아닌 원격 저장소 (Git, Bitbucket ...)에 있는 패키지의 특정 버전을 사용하는 방법 Github 프로젝트 타겟팅 dependencies: package_you_want: git: url: ref: 9f90296751984b359937c38563da5b19db5550f5 Bitbucket 프로젝트 타겟팅 앱 프로젝트에 빗버킷에 올린 ollacare_app_theme 패키지 의존성을 추가하려면 다음과 같이 작성합니다. dependencies: ollacare_app_theme: git: url: git@bitbucket.org:blueant_git/ollacare_app_theme.git ref: master 원격 저장소의 특정 ..
개발자가 알아야 할 모바일 어트리뷰션
마케터와 모바일 어트리뷰션 협업을 하기 위해 작업에 대한 이해를 돕고자 문서를 작성하였습니다. 딥링크란? 딥링크(Deep Link)란 모바일 환경에서 사용자를 앱의 특정 페이지로 이동시키는 링크를 의미합니다. 딥링크는 다음과 같이 생겼습니다. ollacare://navigation/notices/3 딥링크는 URI 형식을 가집니다. 링크를 누르게 되면 특정 앱을 실행시키며 그 이후의 액션은 앱에서 설정해주어야 합니다. 딥링크는 이것이 전부입니다. 모바일 어트리뷰션 마케터는 페이스북, 유튜브, 인스타그램과 같은 매체 광고를 통하여 고객을 유치시키고 싶어 합니다. 광고의 형태에 따라 추구하는 방식이 오가닉, 논오가닉으로 나뉘는데 쉽게 생각하면 다음과 같습니다. 오가닉 : 사용자가 광고에 심어져있는 링크를 클..
플러터 프로젝트에 코드매직으로 CICD 도입하기
진행하고 있는 앱 서비스의 규모가 커지고 이해관계자가 다양해지고 많아짐에 따라 그동안 수동으로 진행했던 배포를 자동화해야 하는 필요성을 느꼈습니다. 회사 내부에서 파이어베이스 배포 서비스를 이용하여 내부 테스터들에게 앱을 배포하고 있는데 잦은 빌드 잦은 배포로 인해 업무의 효율성이 낮아졌기 때문이지요. 사내에서는 프로젝트 원격 저장소로 빗버킷을 이용하고 있기에 CI/CD 구축을 위해 빗버킷에서 제공하는 파이프라인을 사용할 수 있었지만 파이프라인은 리눅스 환경에서 돌아가기 때문에 iOS 앱을 빌드할 수 없었습니다. 따라서 남은 선택지는 1. macos 빌드 환경을 자체 구축한다 2. 외부 CICD 서비스를 이용한다 였고, 빠르게 구축하기 위해 돈을 주고 외부 CICD 서비스를 이용하기로 결정하였습니다. 저..
flutter 특정 원격 저장소 패키지 의존성 추가하기
목표 Flutter 공식 패키지 저장소 pub.dev에 있는 패키지가 아닌 원격 저장소 (Git, Bitbucket ...)에 있는 패키지의 특정 버전을 사용 Github 프로젝트 타겟팅 dependencies: package_you_want: git: url: ref: 9f90296751984b359937c38563da5b19db5550f5Bitbucket 프로젝트 타겟팅 앱 프로젝트에 빗버킷에 올린 ollacare_app_theme 패키지 의존성을 추가하려면 다음과 같이 작성합니다. dependencies: ollacare_app_theme: git: url: git@bitbucket.org:blueant_git/ollacare_app_theme.git ref: master원격 저장소의 특정 경로 패..
배포는 미리미리
플레이스토어에 앱을 배포하면서 처음으로 고통을 받았습니다. 원래라면 공개/비공개 테스트에서 검토를 한번 받고 프로덕션으로 트랙을 변경해서 빠르게 올리는게 배포 전략이었는데, 검토 기간이 예상 외로 길어지면서 일이 꼬이고 말았죠. 사업부에서는 업데이트 언제 되냐고 계속 물어보시고.. 저는 처음 겪는 일이라 일단 구글에 문의를 해보겠다 조금만 기달려달라고만 대답했습니다. '혹시 다시 새 버전으로 출시하면 심사 대기열의 앞 쪽으로 배치받지 않을까?' 라는 잘못된 판단으로 새 버전을 계속해서 올렸고 그 결과는 참담했습니다.. 알고보니까 이전에 심사가 완료되지 않은 것이 있다면 이전 것은 제쳐두고 마지막 제출된 사항으로 다시 재검토를 시작한다고 하더군요.. 구글에 문의한 답변을 읽고 처음 알았습니다. 어쨋든 러프..