AInote

AInote AI 기반 크로스 플랫폼 스마트 노트 서비스입니다. 맥, 웹, 모바일, 텔레그램까지 어디서든 메모를 작성하고 AI의 도움을 받을 수 있습니다. Mac App macOS 네이티브 앱으로, 데스크톱 환경에 최적화된 경험을 제공합니다. 주요 기능 메뉴바 퀵 노트: 메뉴바에서 빠르게 메모 작성 글로벌 단축키: 어떤 앱에서든 단축키로 즉시 메모 Spotlight 통합: Spotlight에서 바로 노트 검색 iCloud 동기화: Apple 기기 간 자동 동기화 AI 어시스턴트: 텍스트 요약, 번역, 문법 교정 기술 스택 Swift / SwiftUI Core Data CloudKit Web App 브라우저에서 접근 가능한 웹 애플리케이션입니다. ...

2025-06-20 · 2분 소요 · Seunghan

Flutter+Rails 실시간 인프라 4대 단절 고치기 — FCM 딥링크, ActionCable JWT, 익명→회원 연결

토너먼트 앱 하나를 Flutter로 전환하고 있는데, 사용자 입장에서 제일 중요한 시나리오가 동작을 안 했다. “로그인 → 알림 수신 → 알림 탭 → 내 코트로 이동 → 대기/경기/결과 확인”. 이게 끊기면 앱이 있으나 마나다. 처음에는 코드 조각은 대부분 있는 것 같았다. FCM 토큰 등록 로직도 있고, ActionCable 클라이언트 클래스도 있고, 스코어 입력 화면도 있다. 그런데 막상 실제로 알림을 탭해도 앱이 홈으로만 열린다. 실시간 업데이트도 안 온다. 왜? 탐색해보니 연결된 것처럼 보이는 부품 사이에 네 군데가 끊겨 있었다. 이 포스트는 그 네 군데를 하루 세션에서 다 고친 기록이다. 각 단절마다 왜 그게 2026년에도 여전히 함정인지 근거도 같이 정리한다. ...

2026-04-16 · 9분 소요 · Seunghan

Flutter TestFlight 업로드 삽질 — exportArchive Failed to Use Accounts 해결

Flutter로 앱을 만들고 TestFlight에 올리려는데, 아카이브 빌드는 성공하고 IPA export에서 멈췄다. exportArchive Failed to Use Accounts라는 에러가 뜨는데, 구글링해도 명쾌한 답이 없었다. 결국 3가지 다른 에러를 연달아 만나면서 해결했고, 그 과정을 정리한다. 에러 1: exportArchive Failed to Use Accounts flutter build ipa --release --dart-define=ENV=prod --export-options-plist=ios/ExportOptions.plist 아카이브 빌드는 잘 된다: ✓ Built build/ios/archive/Runner.xcarchive (197.5MB) [✓] App Settings Validation • Version Number: 1.0.1 • Build Number: 9 • Display Name: My App • Bundle Identifier: com.example.app 근데 바로 다음 줄에서: ...

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

Hotwire Native에서 Flutter BLoC으로 — 네이티브 앱 전환 실전기

Rails 웹앱에 Hotwire Native로 iOS 앱을 감싸서 출시했는데, 접속 오류로 심사가 반복 반려됐다. WebView 기반의 한계를 느끼고 Flutter + BLoC 패턴으로 순수 네이티브 전환을 결정했다. 이 글은 실제로 웹앱을 Flutter 앱으로 전환하면서 겪은 설계, 삽질, 해결 과정을 정리한 것이다. Hotwire Native가 안 된 이유 Hotwire Native는 WKWebView 위에 얇은 네이티브 셸을 씌우는 구조다. Turbo Navigator가 URL 기반으로 네비게이션을 처리하고, Bridge Component로 네이티브 UI를 부분적으로 제어한다. 웹 개발자 입장에서는 최소 비용으로 앱을 만들 수 있어서 매력적이다. ...

2026-03-31 · 9분 소요 · Seunghan

Hotwire Native에서 Flutter로 — Rails 앱의 모바일 네이티브 전환 실전기

Rails 8 + Hotwire로 웹을 만들고, Hotwire Native로 iOS/Android를 감싸면 꽤 그럴듯한 앱이 나온다. WebView가 서버 렌더링 HTML을 그대로 보여주니 코드 한 벌로 3플랫폼을 커버할 수 있다. 실제로 이 방식으로 프로덕션에서 잘 돌아가는 앱을 운영하고 있었다. 그런데 점점 한계가 보이기 시작했다. 오프라인 지원이 안 되고, 네이티브 애니메이션도 못 쓰고, WebView 특유의 뚝뚝 끊기는 느낌이 있었다. 결국 Flutter로 풀 네이티브 전환을 결정했고, 설계부터 프로덕션 배포까지 약 2주 만에 끝냈다. 그 과정을 정리한다. ...

2026-03-31 · 9분 소요 · Seunghan

Flutter AAB 빌드 서명 오류 해결 — Play Store 업로드 시 wrong key 에러 완벽 가이드

Flutter AAB를 Play Console에 드래그했더니 서명 에러 Flutter로 만든 앱을 Google Play Console에 업로드하려고 flutter build appbundle --release로 AAB 파일을 빌드했다. 빌드 자체는 성공했고, 51MB짜리 app-release.aab가 잘 생성됐다. 자신만만하게 Play Console에 드래그 앤 드롭했는데, 이런 에러가 떴다. Android App Bundle이 잘못된 키로 서명되었습니다. 제대로 된 서명 키로 App Bundle에 서명한 다음 다시 시도해 보세요. SHA1: 5A:2A:F8:A4:71:76:3B:CC:35:78:33:B1:98:65:8F:24:85:72:AB:87 지문이 포함된 인증서로 App Bundle에 서명해야 하지만, 업로드한 App Bundle 서명에 사용된 인증서의 지문은 SHA1: A8:E9:B6:3C:C6:9A:E9:FE:06:AA:BB:2E:E3:43:85:1A:74:96:16:48 입니다. 두 개의 SHA1 지문이 달랐다. Play Console이 기대하는 키와, 실제 AAB에 서명된 키가 다르다는 뜻이다. ...

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

Flutter에서 Gemini, OpenAI, Claude 직접 연동하기 — 멀티 AI 프로바이더 패턴 구현

시작 — 하드코딩된 API 키 문제 Flutter 앱에서 AI 기능(영수증 OCR, 이미지 번역, 블로그 자동 생성)을 넣을 때, 처음에는 BizRouter라는 AI 프록시 서비스를 썼다. 모든 요청을 하나의 엔드포인트로 보내면 내부에서 Gemini, GPT, Claude 등으로 라우팅해주는 구조였다. 문제는 API 키가 소스 코드에 하드코딩되어 있다는 것이었다. class BizRouterService { static const _apiKey = 'sk-br-v1-d6872ae8e164...'; // 이게 코드에 그대로 static const _baseUrl = 'https://api.bizrouter.ai/v1'; 지인들에게 배포하는 MVP라 처음에는 괜찮았지만, 사용자가 자기 키를 입력해서 쓸 수 있게 만들어야 했다. Gemini 키가 있는 사람은 Gemini로, OpenAI 키가 있는 사람은 GPT로, Claude 키가 있는 사람은 Claude로 — 각자 가진 키를 쓸 수 있어야 했다. ...

2026-03-26 · 9분 소요 · Seunghan

Flutter에서 iOS Live Activity 잠금화면 미리보기 만들기 — CustomPainter로 네이티브 위젯 재현

왜 Live Activity 미리보기가 필요했나 여행 앱에서 iOS Live Activity를 구현하고 나면, 사용자에게 표시 모드를 선택하게 하는 설정 화면이 필요하다. 일정 모드, 예산 모드, 자동 모드, 결합 모드 — 이렇게 네 가지 옵션이 있는데, 문제는 이 모드를 바꿨을 때 잠금화면에서 실제로 어떻게 보이는지 사용자가 알 수 없다는 점이었다. 설정 화면 하단에 Dynamic Island compact 형태의 간단한 미리보기는 있었다. 하지만 사용자가 Live Activity를 가장 많이 보는 곳은 잠금화면이다. 작은 알약 모양 미리보기로는 “이 모드를 선택하면 잠금화면이 이렇게 바뀝니다"를 전달하기 어려웠다. ...

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

앱스토어 마케팅 스크린샷 자동화 — Puppeteer + features.json 분석 주도 파이프라인

앱 출시를 앞두고 스토어 스크린샷을 만들어야 하는 상황이 됐다. Figma로 하나씩 만드는 건 너무 비효율적이고, 10가지 디자인 시안에 5개 기능 화면을 조합하면 50장인데 수작업으로 한다는 건 말이 안 된다. 그래서 HTML/CSS로 마케팅 프레임을 만들고 Puppeteer로 PNG를 뽑아내는 파이프라인을 짰다. 처음엔 대충 만들었다가 구조적으로 틀린 부분이 있다는 걸 나중에 깨달았는데, 그 과정이 의외로 중요한 교훈을 남겼다. 처음 접근 방식의 문제 처음엔 이런 식으로 기능 배열을 하드코딩했다. const FEATURES = [ { id: 'expense', title: '지출을 한번에', sub: 'AI가 영수증을 읽어드립니다', screen: '02_expense_detail' }, { id: 'camera', title: '사진 찍으면 끝', sub: 'OCR로 즉시 기록', screen: '03_camera_hub' }, // ... ]; 문제는 이 파일명들(02_expense_detail.png, 03_camera_hub.png)이 실제로 존재하지 않았다는 것이다. 캡처 스크립트가 자동으로 화면을 이동하다가 실패해서 홈 화면만 5번 찍혔는데, 파일명은 다 달랐다. 결과적으로 모든 슬롯이 placeholder(검은 화면)였다. ...

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

Flutter GoRouter ShellRoute로 바텀 네비게이션 전역 유지하기 — 삽질부터 Liquid Glass 인터랙션까지

바텀 네비가 사라지는 순간 Flutter 앱을 만들다 보면 어느 순간 이런 상황을 만난다. 메인 화면에 탭 5개짜리 바텀 네비게이션 바가 있고, 할일 수정이나 새 메모 생성 버튼을 누르면 context.push('/tasks/new')로 화면을 전환한다. 그런데 화면이 전환되는 순간 바텀 네비가 통째로 사라진다. iOS 네이티브 앱에서는 탭 안에서 push 하면 탭 바가 유지된다. Apple의 메모 앱에서 메모를 열어도, 미리 알림에서 항목을 수정해도 하단 탭 바는 그대로 있다. 그런데 Flutter에서는 기본적으로 이렇게 동작하지 않는다. 원인을 찾아보니 라우터 구조 자체의 문제였다. ...

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