Skip to content

hooni0918/Spoony

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Thumbnail

목차


서비스 소개

Spoony는 리뷰 작성자의 신뢰도와 영향력에 기반해,
유저가 믿을 수 있는 장소 정보를 탐색하고 공유하며 나만의 찐 리스트 지도를 만들어가는 앱 서비스입니다.
🌟Spoony와 함께 새로운 장소를 발견하고 나만의 지도를 완성해보세요!🌟


🥄 Spoony 만의 특별한 사용법

1️⃣ 장소 등록하고 수저 획득하기

나만 알고 싶은 맛집, 아늑한 카페, 분위기 좋은 펍 등 찐 장소를 등록하고 수저를 획득하세요!

2️⃣신뢰도 높은 찐 리스트 떠먹기

획득한 수저로 다른 사람의 찐 리스트를 떠먹어 보세요! 원하는 유저를 팔로우하고 로컬 사용자와 지역별 랭킹을 통해 신뢰도 높은 리뷰를 확인해보세요.

3️⃣ 나만의 지도 완성하기

떠먹은 리스트 중 마음에 드는 장소를 추가해 나만의 찐 리스트 지도를 만들어보세요!

⚒️ Tech stack & Architecture

스크린샷 2025-01-07 오후 3 08 01

🍎 iOS Developer

이지훈
@hooni0918
최안용
@ChoiAnYong
최주리
@juri123123
이명진
@thingineeer
메인 지도,장소검색 등록하기 등록장소 리스트, 신고하기 등록장소 디테일뷰

시연영상

Spoony

지도 장소검색
떠먹기 네이버 길찾기
탐색 리스트 조회 지도 리스트 떠먹기 신고하기
등록 1단계 등록 2단계

🌀 Library

library description version
Moya 추상화된 네트워크 레이어를 보다 간편하게 사용 15.0.3
Kingfisher 이미지 캐싱 처리 8.1.3
NMFMaps 지도 구현 3.20.0
FlexSheet 바텀시트 라이브러리 커스텀 구현 1.2.27

✳️ Coding Convention

코딩 컨벤션 보러가기

📝 Tag & Commit Convention

Message Rule

  • 소문자로 작성
  • 한글 사용
  • 제목은 50자 이내, 명령조로 작성
  • 상세 내용은 본문에 작성

Tag Convention

태그 설명
feat 기능 구현
fix 버그/오류 수정
docs 문서 수정
setting 프로젝트 설정 변경
add 에셋/라이브러리 추가
refactor 코드 리팩토링 (생산적)
chore 경미한 수정 (비생산적)
style UI 작업
juri 주리야 도와줘

예시

feat: #1 로그인 기능 구현
add: #2 이미지 에셋 추가
juri: #3 주리야 도와줘

💿 Git Flow

우아한 형제들 Git Flow를 기반으로 진행합니다.

PR 규칙

  • 1 issue = 1 PR
  • Merge= 리드 승인 + 2인 승인
  • Squash and Merge, Rebase and Merge는 사용하지 않습니다.

📂 Foldering

📁 Project
├── App.swift
├── 📁 Source
│ ├── 🗂️ Features
│ │ ├── 🗂️ Home
│ │ │ ├── 🗂️ View
│ │ │ │ ├── MovieView.swift
│ │ │ │ └── 🗂️ Components
│ │ │ │     └── MovieCell.swift
│ │ │ ├── 🗂️ Intent
│ │ │ │ └── MovieIntent.swift
│ │ │ ├── 🗂️ State
│ │ │ │ ├── MovieState.swift
│ │ │ │ └── MovieStore.swift
│ │ │ ├── 🗂️ Model
│ │ │ │ └── MovieModel.swift
│ │ │ └── 🗂️ Service
│ │ │     └── MovieAPIService.swift
│ │ ├── 🗂️ Detail
│ │ ├── 🗂️ Quest
│ │ ├── 🗂️ Register
│ │
├── 📁 Network
│ ├── 🗂️ Network
│ │ ├── NetworkManager.swift
│ │ ├── Endpoints.swift
│ │ ├── APIError.swift
│ │
│ ├── 🗂️ Services
│ │ ├── AuthService.swift
│ │ ├── StorageService.swift
│ │
├── 📁 Resources
│ ├── 🗂️ Extensions
│ │ ├── View+.swift
│ │ ├── Color+.swift
│ │ ├── Date+.swift
│ │
│ ├── 🗂️ Helpers
│ │ ├── Constants.swift
│ │ ├── Utilities.swift
│ │
│ ├── 🗂️ Theme
│ │ ├── Colors.swift
│ │ ├── Typography.swift
│ │ ├── Spacing.swift
│ │
│ ├── 🗂️ Fonts
│ │ ├── CustomFont.ttf
│ │
│ ├── Assets.xcassets
│ ├── Info.plist

🔨 Trouble Shooting

1. 커스텀 바텀시트 라이브러리 개발 및 배포

문제상황

  • SwiftUI 내장 .sheet modifier 사용 시 탭바를 항상 덮는 UI 문제
  • 스크롤과 드래그 제스처 간의 충돌
  • 커스텀 높이 지정의 어려움

해결방안

  1. 모듈화와 접근제어
public struct FlexibleBottomSheet<Content: View>: View {
    private let content: Content
    private let sheetStyle: FlexSheetStyle
    @Binding private var currentStyle: BottomSheetStyle
    
    public init(
        currentStyle: Binding<BottomSheetStyle>,
        style: FlexSheetStyle = .defaultFlex,
        @ViewBuilder content: () -> Content
    ) {
        self._currentStyle = currentStyle
        self.sheetStyle = style
        self.content = content()
    }
}
  • public 접근제어자를 통한 모듈간 접근 제어
  • initializer도 public으로 명시하여 외부 모듈에서의 인스턴스 생성 가능하게 구현
  1. 제스처 처리 시스템
private func handleDragEnd(translation: CGFloat, velocity: CGFloat, in geometry: GeometryProxy) {
    if abs(velocity) > sheetStyle.dragSensitivity {
        handleVelocityBasedSnap(velocity: velocity)
    } else {
        let screenHeight = geometry.size.height
        let currentOffset = screenHeight - currentStyle.height(for: screenHeight) + translation
        currentStyle = getClosestSnapPoint(to: currentOffset, in: geometry)
    }
}
  • 드래그 제스처의 속도 기반 스냅 기능
  • 사용자 경험을 고려한 자연스러운 애니메이션
  1. 스타일 커스터마이징
public struct FlexSheetStyle {
    let animation: Animation
    let dragSensitivity: CGFloat
    let allowHide: Bool
    let sheetSize: BottomSheetStyle
    let fixedHeight: CGFloat
    let handleBarVisible: Bool
    
    public static let defaultFlex = FlexSheetStyle(
        animation: .spring(response: 0.3, dampingFraction: 0.7),
        dragSensitivity: 500,
        allowHide: false,
        sheetSize: .minimal,
        fixedHeight: 0,
        handleBarVisible: false
    )
}
  • 애니메이션, 드래그 감도, 시트 크기 등 다양한 커스터마이징 옵션
  • 미리 정의된 스타일 제공으로 사용 편의성 향상

결과 및 느낀점

  1. 모듈화와 은닉화

    • 모듈 간 접근 제어의 중요성 이해
  2. 확장성 있는 설계

    • 다양한 사용 케이스 대응
    • 커스터마이징 옵션 제공

라이브러리 링크

2. 지도 API 및 이미지 캐싱

3. Actor 클래스 도입으로 Data Race 해결

About

Spoony

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Swift 100.0%