
PawScan
반려동물 포토 저널 · AI 노트
PawScan은 반려동물의 사진을 찍어 따뜻한 일지 형태의 노트를 남기는 SwiftUI 기반 iOS 포토 저널 앱이다. 촬영한 사진은 자체 FastAPI 백엔드 프록시를 거쳐 OpenAI Vision(GPT-4o)이 분석해 저널용 관찰 노트 초안과 홈케어 팁을 만들어 주고, 매일의 컨디션(식욕·음수·활동량·배변·기분)과 체중, 사용자가 직접 설정한 예방접종·투약 일정을 한곳에서 기록한다. SwiftData 로컬 저장과 StoreKit 2 구독, 5개 언어 현지화를 갖춘 정식 제품으로, 앱에는 API 키를 두지 않고 프롬프트와 모델은 서버에서 통제한다.
반려동물의 일상 변화는 흩어진 메모와 사진첩으로는 추세를 파악하기 어렵고, 보호자가 본 것을 글로 정리하기도 번거롭다. PawScan은 사진과 매일의 기록을 한 저널에 모으고 AI가 노트 초안을 대신 써 주어, 동물병원 방문 전 상태를 차분히 돌아볼 수 있게 한다. 진단이 아닌 관찰 기록 도구로 설계됐다.
앱 미리보기
무엇을 할 수 있나요
AI 포토 노트
PhotosUI로 사진을 촬영하거나 사진첩에서 고르면 Base64로 인코딩해 백엔드 프록시(/api/v1/analyze)로 보낸다. 서버의 OpenAI Vision(GPT-4o)이 8개 카테고리(피부·눈·귀·구강·배변·구토·행동·기타) 기준 관찰 노트 초안, 우선순위(severity), 홈케어 팁, 면책 문구를 JSON으로 돌려준다. 의료 진단이 아닌 저널용 기록으로 설계됐다.
매일 건강 일지
식욕·음수량·활동량·배변·기분을 1~5단계로 매일 기록하고 타임라인과 캘린더로 추세를 확인한다. HealthLog는 SwiftData에 저장되며 주간 건강 점수 카드로 변화를 한눈에 본다. 무료 구간은 최근 7일 기록만 열람할 수 있다.
예방접종·투약 알림
사용자가 직접 설정한 접종·투약 일정을 UNCalendarNotificationTrigger로 알린다. 매일/매주/매월 반복 투약, 접종일 사전 알림(여러 일자), 매월 무료 분석 한도 리셋 알림까지 UserNotifications로 스케줄링한다.
체중 트래커
WeightRecord를 기록하고 Swift Charts로 변화 추이를 시각화한다. 홈 화면에는 미니 차트로 최근 흐름을 요약해 보여 주며, 무료 구간은 최근 30일 추이를 제공한다.
사료·알레르기 기록
현재 급여 중인 사료 브랜드(FoodRecord)와 Pet의 알레르기 태그를 관리한다. 이 맥락은 AI 포토 노트 요청 본문(active_food_brand, allergy_tags)에 함께 실려 서버 프롬프트에 반영된다.
수의사용 PDF 리포트
PDFKit의 UIGraphicsPDFRenderer로 반려동물 건강 기록을 페이지 단위 리포트로 그려 내보내고, ShareSheet로 수의사와 공유한다. 별도로 전체 데이터를 JSON으로 백업 내보내기 할 수 있다.
홈 화면 위젯
WidgetKit으로 소형·중형 두 종류 위젯을 제공한다. App Group(group.com.junsoft.PawScan)으로 메인 앱과 데이터를 공유해 오늘의 컨디션·다음 일정 같은 요약을 잠금 해제 없이 보여 준다.
구독 & 프리미엄 게이팅
StoreKit 2로 월간·연간 구독을 제공하고 Transaction.currentEntitlements로 권한을 검증한다. 무료 구간은 AI 분석 월 3회, 반려동물 1마리, 건강 일지 7일, 체중 기록 30일로 게이팅된다.
어떻게 만들었나요
iOS Core
Persistence
Apple Frameworks
Networking / AI
Backend
Localization
Tooling
Feature 단위로 폴더를 나눈 SwiftUI MV(VM) 구조로, @Observable 기반 ViewModel과 전역 AppState, SwiftData 영속 계층, actor로 격리한 네트워크/AI 계층, 그리고 OpenAI Vision을 감싼 FastAPI 백엔드 프록시를 분리했다.
- 1
AI 추론은 온디바이스가 아니라 OpenAI Vision(GPT-4o)을 호출하는 자체 FastAPI 백엔드 프록시(pawscan-api)를 경유한다. 앱에 API 키를 두지 않아 키 노출을 막고, 프롬프트·모델·max_tokens·temperature를 모두 서버 환경변수로 통제한다.
- 2
백엔드는 FastAPI + Pydantic으로 요청을 검증하고, OpenAI에 httpx로 비동기 호출하며 response_format=json_object로 구조화된 노트를 받는다. slowapi로 IP 기준 레이트 리밋(무료 10/분·프리미엄 60/분)을 걸고 Docker로 배포한다.
- 3
네트워크와 AI 서비스는 actor 싱글톤(APIClient, AIAnalysisService)으로 격리하고, AppState·StoreService는 @MainActor @Observable로 두어 Swift 6 동시성 모델에 맞춘 데이터 경합 안전성을 확보했다. 모든 모델·요청 타입은 Sendable이다.
- 4
SwiftData @Model 7종(Pet·SymptomAnalysis·HealthLog·Vaccination·Medication·WeightRecord·FoodRecord)이 Pet을 루트로 deleteRule .cascade 관계를 이루며, 열거형(species·gender·category)은 raw 문자열로 저장 후 computed 접근자로 노출하고 알레르기 태그·가능 원인 같은 복합값은 직렬화해 보관한다.
- 5
App Group(group.com.junsoft.PawScan)을 통해 메인 앱과 WidgetKit 익스텐션이 데이터를 공유하고, WidgetDataProvider가 양쪽에서 동일한 식별자로 요약 데이터를 읽고 쓴다.
- 6
StoreKit 2 구독으로 프리미엄을 게이팅한다. Transaction.updates 리스너로 갱신을 처리하고 currentEntitlements로 권한을 검증하며, AppState가 월 분석 횟수를 카운트해 무료 한도(3회/월)를 강제한다.
- 7
디자인 토큰을 PSColors·PSTypography·PSSpacing·PSComponents로 중앙화해 색·폰트·간격 하드코딩을 금지하고 일관된 UI를 강제하며, 진단이 아닌 관찰 노트라는 톤을 앱·서버 양쪽 문구에서 일관되게 유지한다.
84
Swift 소스 파일
7
SwiftData 모델
4
메인 탭
8
노트 카테고리
2
홈 위젯
5 (en, ko, ja, zh-Hans, es)
지원 언어



