Skip to content

davis-chad/ThriftScan

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ThriftScan

ThriftScan is a SwiftUI MVP for evaluating thrifted clothing/shoes before purchase.

What the app does

  • Capture or select 2-4 photos of an item.
  • Enter the thrift store purchase price.
  • Upload photos + price to POST /analyze-item using multipart/form-data.
  • Show a structured analysis and a prominent Buy / Maybe / Pass recommendation.
  • Save successful analyses locally with SwiftData for scan history.
  • Support a mock mode for offline testing.

Architecture

  • UI: SwiftUI
  • Pattern: MVVM
  • Persistence: SwiftData (ScanRecord)
  • Networking: URLSession async/await, multipart upload
  • Settings: UserDefaults via AppSettings (backendBaseURLString, useMockAPI)

Current source layout

ThriftScan/
├── ThriftScanApp.swift
├── Models/
│   ├── AnalyzeItemRequest.swift
│   ├── AnalysisResponse.swift
│   └── ScanRecord.swift
├── ViewModels/
│   ├── NewScanFlowViewModel.swift
│   └── ScanHistoryViewModel.swift
├── Services/
│   ├── AnalysisAPIClient.swift
│   ├── AppSettings.swift
│   ├── ItemAnalysisService.swift
│   ├── MockAnalysisProvider.swift
│   └── PhotoStorageService.swift
├── Persistence/
│   └── PersistenceController.swift
├── Navigation/
│   └── ScanRoute.swift
├── Views/
│   ├── MainTabView.swift
│   ├── NewScanFlowRootView.swift
│   ├── PhotoPickerScreen.swift
│   ├── PriceInputScreen.swift
│   ├── AnalysisResultScreen.swift
│   ├── AnalysisSummaryContent.swift
│   ├── HistoryScreen.swift
│   ├── HistoryDetailScreen.swift
│   ├── SettingsScreen.swift
│   ├── CameraImagePicker.swift
│   └── Components/
│       └── RecommendationBanner.swift
└── Resources/
    └── MockResponse.json

Build and run

  1. Open ThriftScan.xcodeproj in Xcode 15+.
  2. Select an iOS 17+ simulator or device.
  3. Build and run.
  4. In Settings, configure:
    • Backend base URL (for example http://localhost:8080 in simulator).
    • Use mock responses toggle for local testing.

Required iOS permissions

Ensure these are present in Info.plist:

  • NSCameraUsageDescription
  • NSPhotoLibraryUsageDescription

Backend contract

Endpoint

  • POST {baseURL}/analyze-item
  • Content type: multipart/form-data

Multipart fields sent by app

  • images: repeated JPEG files (photo0.jpg, photo1.jpg, ...)
  • thrift_price: decimal number as text

Response JSON expected

{
  "brand": "Patagonia",
  "category": "Outerwear",
  "item_type": "Nano Puff jacket",
  "gender": "Men",
  "color": "Forge Grey",
  "material": "Recycled polyester ripstop",
  "pattern": "Solid",
  "style_keywords": ["outdoor", "lightweight insulation"],
  "suggested_search_queries": ["patagonia nano puff men's forge grey medium"],
  "condition_checklist": ["Verify zipper pulls and teeth"],
  "estimated_resale_low": 85,
  "estimated_resale_high": 140,
  "suggested_list_price": 119,
  "expected_sale_price": 105,
  "estimated_net_profit": 62,
  "recommendation": "Buy",
  "reasoning": "Strong brand velocity and healthy margin."
}

recommendation should be one of: Buy, Maybe, Pass (case-insensitive is normalized by the app).

Mock mode

When Use mock responses is enabled:

  • The app loads Resources/MockResponse.json.
  • If that file fails to load, it falls back to a deterministic synthetic mock response.

This mode avoids any backend dependency for UI/flow testing.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors