flutter(35)
-
앱 초기 부팅 시 Isolate 초기화 실패와 리렌더링
1. 사건의 발단 때는 바야흐로 필요한 앱의 기능 대부분을 만들어가는 시점, 최적화 관련된 문제가 말이 많았다. 정확한 원인은 발견하지 못했지만 초기 부팅시 렌더링 관련해서 리소스를 많이 잡아먹고 있었고, 어디서 렌더링 관련된 문제가 발생하는지 정확히 파악하지 못하고 있었다. 어찌됐건 앱은 출시해야했고 다른 동료분이 앱 초기 부팅 시점에 HTTP 요청을 과도하게 요청해서 문제가 발생한다면, HTTP 요청을 다른 스레드에서 하도록 만들면 되지 않냐는 얘기를 했다. 어찌됐건 당시에는 별달리 뾰족한 방법도 없었기에, 정말 HTTP 요청하는 모듈을 별도 Isolate로 분리했다. 아무튼 Flutter/Dart의 특징에 대해 잘 알고 있는 분도 아니었는데 왜 그런 얘기를 수용했는지 모르겠다. 아마 절박해서 그런..
2025.08.02 -
[Flutter] ListView.builder에서 가변 크기 요소들의 무한 스크롤 구현하기
문제 상황ListView.builder를 사용해서 무한 스크롤을 구현하려고 하는데, 문제는 리스트 내부에 표현해야하는 요소들의 값이 가변적인 높이를 가지고 있다는 점이었다. 별 생각없이 높이로 하드코딩된 값을 지정하고 구현했을 때야 동작이야 하긴 하지만, 태블릿처럼 화면이 커지거나 레이아웃이 변경될 경우에는 하드코딩된 값을 지정하기 어렵다는 문제도 있었다. 이번에는 이런 경우를 대비해서 ListView.builder에 GlobalKey를 할당하고, ListView의 자식 요소의 높이값을 직접 계산하는 방법을 살펴본다.ListView.builder의 자식 요소의 높이가 가변적으로 달라지는 예시로는 다음과 같은 상황이 있다.텍스트의 길이에 따라 카드 높이가 달라지는 경우이미지 비율에 따라 높이가 변하는 경우..
2025.07.10 -
GestureDetector와 InteractiveViewer를 중첩하여 제어하기
이전에 GestureDetector()을 사용해서 제스쳐를 통해 Widget을 제어하는 기능을 구현했었다. 간단하게 PseudoCode를 작성하면 다음과 같은 형식이다.GestureDetector( onHorizontalDragStart: (DragStartDetails details) { viewModel .updateDragStartPoint(details.globalPosition.dx); }, onHorizontalDragEnd: (DragEndDetails details) { viewModel.initializeDragStartPoint(); }, onHorizontalDragUpdate: (DragUpdateDeta..
2025.07.07 -
[Flutter] InteractiveViewer와 ViewportIndicator 구현 삽질기
문제의 시작Flutter로 InteractiveViewer를 사용해서 큰 이미지나 콘텐츠를 확대/축소할 수 있는 기능을 구현할 일이 생겼다. 사용자가 2배, 3배로 확대해서 볼 수 있게 하는 건데, 문제는 확대한 상태에서 사용자가 현재 어느 부분을 보고 있는지 알기 어렵다는 것이었다.요구사항은 간단했다: "확대했을 때 현재 보고 있는 영역을 작은 박스로 표시해주세요. 포토샵 네비게이터 패널처럼요."처음엔 "아, 그거 쉽지"라고 생각했는데... 막상 구현해보니 생각보다 복잡했다. 특히 좌표계 변환 부분에서 꽤 삽질을 했다.왜 ViewportIndicator가 필요한가?사용자가 큰 이미지나 영상을 확대할 때의 문제점을 생각해보자:🔍 2배 확대하면 전체의 1/4만 화면에 보임📍 현재 어느 부분을 보고 있는..
2025.06.30 -
Dart에서의 안전한 JSON 파싱
Dart는 강타입 언어다. 즉, 컴파일 시점에 타입이 결정되므로 런타임에 타입과 관련된 에러가 발생하는 일은 드물다. 단, Dart에는 Typescript에서 제공하는 Any와 비슷한 역할을 하는 dynamic이 존재한다. 최근에는 HTTP 요청을 통해 전송되는 패킷 본문에 보통 JSON 포멧을 많이 사용하는데, 이 JSON 객체 안에 어떤 타입이 들어있는지 정확하게 추론이 불가능하다. 이럴 때 주로 사용되는 것이 바로 dynamic이며, 특히 백엔드는 약타입 언어를 사용하는 경우 API 명세가 정확하게 지켜지지 않으면 이따금 JSON 내부 타입을 파싱하는 과정에서 예외가 빵빵 터지게되는 것이다.JSON 응답의 타입은 어떻게 신뢰할 수 있을까?보통 Dart에서 응답을 받은 데이터를 사용하기 위해서는, 데..
2025.06.05 -
[Flutter/iOS] 자체서명 인증서(Self-signed certificate)를 우회한 HLS 스트리밍 구현 / GCDWebServer를 사용한 로컬 프록시 서버 구현
문제 배경Flutter를 사용해서 HLS로 영상 스트리밍 기능을 구현해야 하는데, 스트리밍 서버가 동작하는 IoT 장치에서는 외부에서 접속할 수 있는 공개망에 연결되어 있다는 보장이 없었습니다. 보안상의 이유로 내부망에 연결되어서 사용되는 경우가 대부분이고, 공장에서 생성되는 시점에 HTTPS를 지원해야하다보니 Self-signed Certificate를 사용하고 있었습니다. 처음에는 Flutter에서 제공하는 video_player 패키지를 사용하려고 했으나, 애석하게도 Self-signed Certificate를 처리할 수 있는 방법이 없었습니다. 결국 네이티브에서 제공하는 플레이어를 사용하기로 결정했는데, Android는 전체적인 SSL 연결을 커스터마이징할 수 있는 기능을 제공하기 때문에 어렵지 ..
2025.04.21