Flutter Material SnackBar 걷어내기 --- Overlay 기반 Glassmorphism Toast + Apple HIG 시스템 색상

Material SnackBar가 거슬리기 시작한 순간 Flutter 앱에서 Glass 디자인 시스템을 구축하면서 Material Design 컴포넌트를 하나씩 걷어내고 있었다. AlertDialog는 GlassDialog로, Card는 GlassCard로, AppBar는 GlassAppBar로. 하나씩 바꿔가니 앱 전체가 반투명 블러 기반의 통일된 느낌이 잡혔다. 그런데 문제가 하나 남았다. 토스트 알림이었다. ScaffoldMessenger.of(context).showSnackBar()로 띄우는 Material SnackBar가 화면 하단에 불투명한 초록/파랑/주황 배경으로 뜨는데, Glass로 바뀐 나머지 UI와 전혀 어울리지 않았다. 하단 고정 위치도 마음에 안 들었다. iOS 네이티브 앱들처럼 상단에서 슬라이딩으로 내려왔다가 올라가는 토스트가 필요했다. ...

2026-03-24 · 7분 소요 · Seunghan

Flutter 노트 앱 디자인 리뉴얼 — Bear 스타일 에디터와 Glassmorphism 알림 적용기

Flutter로 노트 앱을 만들다 보면 어느 순간 기능은 다 있는데 “네이티브 앱 같지 않다"는 느낌이 든다. 버튼은 Glass 디자인 시스템으로 마이그레이션했는데, 정작 에디터 화면과 알림 히스토리는 초기 Material3 코드 그대로 방치돼 있었다. const Divider(), Colors.blue.shade50, OutlineInputBorder() — 이런 것들이 앱 전체 톤을 깨고 있었다. Bear 앱의 에디터 UX를 참고하고, iOS 26 Liquid Glass에서 영감 받은 Glassmorphism을 알림 카드에 적용해봤다. 이 글에서는 실제 삽질 과정과 구현 코드를 정리한다. Bear 앱은 왜 글쓰기가 편한가 Bear는 Apple Design Award를 받은 마크다운 노트 앱이다. “도구가 방해하지 않는다(Tools stay out of your way)“가 핵심 철학이다. 실제로 Bear 에디터를 열면 눈에 띄는 UI 요소가 거의 없다. 제목, 날짜, 본문 — 이 세 가지만 보인다. ...

2026-03-24 · 8분 소요 · Seunghan

모바일 앱 로그인이 자꾸 풀리는 진짜 이유 — JWT Refresh Token 아키텍처 완전 정리

모바일 앱을 운영하다 보면 가장 많이 받는 불만 중 하나가 “로그인이 자꾸 풀려요"다. 카카오톡이나 인스타그램은 한 번 로그인하면 직접 로그아웃하기 전까지 영원히 유지되는데, 내 앱은 왜 하루만 지나면 다시 로그인하라고 하는 걸까? 이 글은 Flutter 앱 + Rails 8 API 환경에서 로그인 세션이 반복적으로 풀리는 문제를 추적하고 해결한 과정을 기록한다. 단순히 “TTL을 늘려라"가 아니라, JWT 인증 시스템의 구조적 문제를 하나씩 찾아가는 과정이다. 증상: 1시간마다 로그인이 풀림 앱을 백그라운드에 두었다가 1시간 후에 열면 로그인 화면으로 돌아간다. 사용 중에는 문제가 없는데, 잠깐 앱을 닫았다 열면 세션이 사라진다. ...

2026-03-23 · 7분 소요 · Seunghan

App Store 스크린샷 리젝 2.3.3 해결기 — AI 생성 이미지에서 실제 앱 캡처로

App Store에 첫 앱을 제출했는데, 스크린샷 문제로 리젝당했다. 해결까지의 삽질 기록. 리젝 사유 Guideline 2.3.3 - Performance: Accurate Metadata The screenshots do not show the actual app in use in the majority of the screenshots. 심사 디바이스: iPad Air 11-inch (M3) 원인 Gemini Image Generation API로 Neo-Brutalism 스타일의 가짜 UI 마케팅 이미지를 만들어서 스크린샷으로 제출했다. 앱 화면과 전혀 다른 디자인이었으니 당연한 결과. Apple이 요구하는 건: 대다수(majority) 스크린샷이 실제 앱 사용 화면이어야 함 마케팅/프로모션 자료만으로는 부적절 스플래시/로그인 화면만으로도 부족 다만, 실제 앱 화면 + 텍스트 오버레이 조합은 허용된다. 대부분의 앱이 이 방식을 쓴다. ...

2026-03-11 · 4분 소요 · Seunghan

Flutter BottomSheet가 네비게이션 바를 덮는다면 — showDialog로 바꿔야 하는 이유

폼 입력이 필요한 화면에서 showModalBottomSheet를 쓰다 보면 자연스러운 UX처럼 느껴진다. 그런데 앱에 하단 네비게이션 바가 있으면 바텀시트가 올라오면서 네비게이션을 덮어버리는 문제가 생긴다. 기능적으로는 동작하지만, 시각적으로 답답하다. 세 가지 문제를 한 번에 해결했다. 바텀시트 → 중앙 모달 전환 TextButton 취소 버튼이 노란색으로 렌더링되어 안 보이는 가독성 문제 share_plus로 SQLite 파일 공유 시 발생하는 PlatformException 문제 1: BottomSheet가 네비게이션 바를 가린다 현상 showModalBottomSheet로 만든 입력 폼이 올라올 때 하단 네비게이션 바와 겹친다. isScrollControlled: true를 써도 시트가 네비게이션 위까지 올라와 버린다. ...

2026-03-09 · 4분 소요 · Seunghan

Flutter image_picker 카메라/갤러리 바텀시트 + Riverpod 빈도 기반 카테고리 자동 정렬 삽질기

Flutter로 시민 신고 앱을 만들면서 세 가지 UX 문제를 연달아 만났다. 사진 추가 버튼이 갤러리만 열어서 카메라 촬영이 불가능한 문제 카테고리가 늘어날수록 그리드가 길어져서 스크롤이 많아지는 문제 신고 대상(일반/긴급)이 바뀌어도 버튼 색상이 바뀌지 않아서 직관성이 떨어지는 문제 각각 어떻게 풀었는지 정리한다. 문제 1: image_picker가 갤러리만 열린다 현상 사진 추가 버튼이 pickImage(source: ImageSource.gallery)만 호출해서 카메라로 찍는 게 불가능했다. 앱 자체에 카메라 권한도 있고 NSCameraUsageDescription도 있는데 UI에서 선택지를 아예 안 줬던 것. ...

2026-03-09 · 6분 소요 · Seunghan

Flutter iOS TestFlight 업로드 실패: objective_c.framework 시뮬레이터 슬라이스 오류

Flutter 앱을 flutter build ipa --release로 빌드하고 TestFlight에 업로드했더니 altool이 거절했다. 원인, 삽질 과정, Makefile 자동화까지 정리한다. 오류 메시지 UPLOAD FAILED with 3 errors Invalid executable. The "Runner.app/Frameworks/objective_c.framework/objective_c" executable references an unsupported platform in the x86_64 slice. Simulator platforms aren't permitted. Invalid executable. The "Runner.app/Frameworks/objective_c.framework/objective_c" executable references an unsupported platform in the arm64 slice. Simulator platforms aren't permitted. Unsupported Architectures. The executable for Runner.app/Frameworks/objective_c.framework contains unsupported architectures '[x86_64]'. flutter build ipa는 성공했고 IPA 파일도 정상 생성됐다. 문제는 빌드 단계가 아니라 업로드 단계에서 발생했다. 즉, Xcode 설정이나 Flutter 프로젝트 구성 자체의 문제가 아니라 Flutter가 조용히 임베드하는 서드파티 프레임워크 바이너리 안에 문제가 있다는 뜻이다. ...

2026-03-09 · 6분 소요 · Seunghan

Flutter + Web 디자인 토큰 동기화 — Storybook 기반 디자인 시스템 구축기

Flutter 앱을 개발하다 보면 항상 부딪히는 문제가 있다. 디자이너는 Figma나 웹 기반 도구로 작업하는데, 개발자는 Dart 코드에 색상을 하드코딩한다. Color(0xFF10B981) 같은 값이 app_colors.dart에만 있고, 웹 쪽 CSS에는 #10B981로 따로 있다. 두 곳을 따로 관리하다 보면 어느 순간 서로 달라져 있다. 이번에 Svelte+Storybook 기반 웹 디자인 키트와 Flutter 앱의 토큰을 하나의 기준으로 맞추는 작업을 했다. 삽질한 내용 위주로 정리한다. 문제: 두 곳에 사는 디자인 토큰 기존 상태는 이랬다. 웹 (CSS) :root { --color-primary: #0000FF; /* 기본값 그대로 */ --radius: 0px; } Flutter (Dart) ...

2026-03-08 · 4분 소요 · Seunghan

Flutter 앱에 iOS 위젯 추가하기 — pbxproj 수동 편집부터 딥링크까지

Flutter 앱에 iOS 홈 화면 위젯을 붙이는 작업을 했다. 처음엔 단순해 보였는데 생각보다 손댈 곳이 많았다. Xcode GUI를 쓰면 간단하지만 CLI 환경에서 project.pbxproj를 직접 수정해야 하는 경우를 위해 전 과정을 정리한다. 목표 홈 화면 위젯 2종: 2×2(systemSmall), 2×1(systemMedium) 위젯에서 앱의 미처리 항목 수를 실시간으로 표시 위젯 버튼 탭 → 앱 특정 화면으로 이동 (딥링크) 1. 위젯 익스텐션 파일 구성 ios/ ├── Runner/ │ ├── AppDelegate.swift │ ├── Info.plist │ └── Runner.entitlements └── ReceiptWidget/ ← 새로 추가 ├── ReceiptWidget.swift ├── Info.plist └── ReceiptWidget.entitlements ReceiptWidget.swift 하나에 Provider, View, Widget, Bundle을 모두 담았다. 사이즈별로 View를 분리하고 @Environment(\.widgetFamily)로 분기하는 패턴이 깔끔하다. ...

2026-03-08 · 5분 소요 · Seunghan

iOS 앱 배포 막히는 순간들 — Bundle ID 이전 불가·ITMS-90683·AI 아이콘 생성까지

Flutter 앱을 TestFlight에 올리는 과정에서 겪은 삽질들을 기록한다. Apple Developer 계정 전환, Bundle ID 등록, 권한 누락 에러, 그리고 AI로 아이콘과 스크린샷을 자동 생성하는 방법까지. 1. Apple Developer 계정이 다를 때 — Bundle ID 이전은 불가 앱을 A 계정(Team A)에서 개발하다가 B 계정(Team B)으로 배포하려고 했다. 기존 Bundle ID가 A 계정에 이미 등록되어 있어서 B 계정으로 등록하려 하면 409 Conflict 에러가 난다. { "errors": [{ "status": "409", "code": "ENTITY_ERROR.ATTRIBUTE.INVALID", "detail": "An App ID with Identifier 'com.xxx.yyy' is not available." }] } Bundle ID는 계정 간 이전이 불가능하다. 해결책은 두 가지다: ...

2026-03-08 · 4분 소요 · Seunghan
개인정보처리방침 이용약관 면책조항 문의