Skip to content

지금 서울 - 내 손안의 서울 : 실시간 핫플레이스 탐방 (지도 도메인 학습용)

Notifications You must be signed in to change notification settings

jeonghi/NowSeoul_iOS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

26 Commits
 
 
 
 
 
 
 
 

Repository files navigation

NowSeoul iOS

서울시 실시간 인구 데이터와 문화행사 정보를 제공하는 iOS 애플리케이션입니다.

핵심 기술 스택

  • 아키텍처: MVVM + Coordinator Pattern + Clean Architecture
  • 반응형 프로그래밍: RxSwift + RxCocoa
  • UI: UIKit, SnapKit, FSCalendar
  • 네트워킹: Alamofire + URLSession
  • 지도: MapKit + CoreLocation
  • 데이터 포맷: GeoJSON + Protocol Buffers

아키텍처 설계

1. 계층형 아키텍처

Presentation Layer (MVVM)
    ↓
Domain Layer (Use Cases)
    ↓
Data Layer (Repository)
  • Presentation Layer: MVVM 패턴으로 UI 로직과 비즈니스 로직 분리
  • Domain Layer: Use Case 패턴으로 비즈니스 로직 캡슐화
  • Data Layer: Repository 패턴으로 데이터 소스 추상화

2. 의존성 주입

protocol SeoulPublicAPIClientType {
    func fetchRealTimePopulationData(forArea areaCode: String, completion: @escaping (Result<SeoulPopulationDTO.Data?, Error>) -> Void)
    func fetchCulturalEvents(_ request: CulturalEventDTO.Request, completion: @escaping (Result<[CulturalEvent], Error>) -> Void)
}

final class SeoulPublicAPIClient: SeoulPublicAPIClientType {
    static let shared = SeoulPublicAPIClient()
    private init() {}
}
  • 프로토콜 기반 의존성 주입으로 테스트 용이성 확보
  • 싱글톤 패턴의 적절한 활용과 제한
  • 모듈 간 결합도 최소화

핵심 기술 구현

1. 반응형 아키텍처

protocol BaseViewModelType {
    associatedtype Input
    associatedtype Output

    var disposeBag: DisposeBag { get set }

    func transform(_ input: Input) -> Output
}

final class CulturalEventCalendarViewModel: BaseViewModelType {
    struct Input {
        let selectedDate: Observable<Date>
    }

    struct Output {
        let events: Driver<[CulturalEvent]>
        let isLoading: BehaviorRelay<Bool>
    }

    func transform(_ input: Input) -> Output {
        // 비즈니스 로직 구현
    }
}
  • 단방향 데이터 흐름: Input → Transform → Output
  • 메모리 관리: DisposeBag을 통한 리소스 해제
  • 에러 처리: RxSwift의 에러 처리 체인 구현

2. 지도 데이터 처리 최적화

protocol MDFDecodableFeature {
    init(feature: MKGeoJSONFeature) throws
}

protocol StylableFeature {
    var geometry: [MKShape & MKGeoJSONObject] { get }
    func configure(overlayRenderer: MKOverlayPathRenderer)
    func configure(annotationView: MKAnnotationView)
}

final class MDFDecoder {
    private let geoJSONDecoder = MKGeoJSONDecoder()

    func decodeHotspotAreaFeatures() throws -> [HotspotAreaFeature] {
        // GeoJSON 디코딩 및 최적화
    }
}
  • 메모리 최적화:
    • 지도 피처 풀링
    • 메모리 캐시 크기 제한
    • 불필요한 피처 즉시 해제
  • 성능 최적화:
    • GeoJSON 데이터 캐싱
    • 렌더링 우선순위 관리
    • 백그라운드 디코딩

3. 비동기 네트워킹

extension SeoulPublicAPIClientType {
    func fetchCulturalEventsRx(_ request: CulturalEventDTO.Request) -> Single<Result<[CulturalEvent], Error>> {
        return Single.create { single -> Disposable in
            self.fetchCulturalEvents(request) { response in
                switch response {
                case .success(let events):
                    single(.success(.success(events)))
                case .failure(let error):
                    single(.failure(error))
                }
            }
            return Disposables.create()
        }
    }
}
  • 병렬 처리:
    • DispatchGroup을 활용한 동시성 제어
    • Operation Queue를 통한 작업 우선순위 관리
  • 에러 처리:
    • 재시도 메커니즘
    • 폴백 전략
    • 에러 로깅 및 모니터링

4. UI 컴포넌트 설계

protocol BaseViewConfigurable {
    @objc optional func configView()
    @objc optional func configHierarchy()
    @objc optional func configLayout()
}

extension BaseViewConfigurable {
    func configBase() {
        configView?()
        configHierarchy?()
        configLayout?()
    }
}
  • 재사용성:
    • 프로토콜 기반 컴포넌트 설계
    • 컴포지션 패턴 활용
  • 성능:
    • 뷰 재사용 메커니즘
    • 레이아웃 최적화
  • 접근성:
    • VoiceOver 지원
    • Dynamic Type 대응

트러블슈팅

1. 지도 성능 최적화

문제:

  • 다수의 GeoJSON 피처 렌더링 시 메모리 사용량 급증
  • 스크롤 시 프레임 드롭 발생
  • 배터리 소모 증가

해결:

  1. 메모리 최적화

    • 피처 풀링 구현
    • 메모리 캐시 크기 제한
    • 불필요한 피처 즉시 해제
  2. 렌더링 최적화

    • LOD(Level of Detail) 시스템 구현
    • 비동기 렌더링 파이프라인 구축
    • 렌더링 우선순위 큐 도입
  3. 배터리 최적화

    • 위치 업데이트 주기 최적화
    • 백그라운드 작업 스케줄링
    • 불필요한 네트워크 요청 제거

2. 실시간 데이터 동기화

문제:

  • 여러 지역의 실시간 데이터 동시 처리
  • 네트워크 지연 및 실패 처리
  • 데이터 일관성 유지

해결:

  1. 데이터 동기화

    • 병렬 처리 최적화
    • 데이터 캐싱 전략
    • 백그라운드 업데이트
  2. 에러 처리

    • 재시도 메커니즘
    • 폴백 데이터 제공
    • 사용자 피드백
  3. 성능 모니터링

    • 메트릭 수집
    • 성능 분석
    • 사용자 경험 개선

프로젝트 구조

NowSeoul_iOS/
├── Application/
│   ├── AppDelegate.swift
│   └── SceneDelegate.swift
├── Presentation/
│   ├── Base/
│   │   ├── Protocols/
│   │   ├── BaseViewController.swift
│   │   └── BaseViewModel.swift
│   ├── HomeScene/
│   ├── MapScene/
│   ├── CulturalEventScene/
│   └── PopulationScene/
├── Domain/
│   ├── UseCases/
│   └── Models/
├── Data/
│   ├── Network/
│   ├── Repository/
│   └── DTO/
├── MDF/
│   ├── Decoder/
│   └── Features/
└── Resources/
    ├── Assets/
    └── Localization/

향후 개선 사항

  1. 테스트 도입

    • XCTest를 활용한 단위 테스트 구현
    • RxBlocking을 통한 비동기 코드 테스트
    • UI 테스트 자동화 구축
    • 테스트 커버리지 목표 설정
  2. 아키텍처 개선

    • SwiftUI 마이그레이션
    • Combine 프레임워크 도입
    • 모듈화 강화
  3. 성능 최적화

    • 메모리 사용량 최적화
    • 배터리 소모 개선
    • 네트워크 효율성 향상
  4. 모니터링 시스템

    • 크래시 리포트
    • 성능 메트릭
    • 사용자 행동 분석
  5. 보안 강화

    • 데이터 암호화
    • 보안 취약점 검사
    • 인증 시스템 개선

성능 최적화

지도 렌더링 최적화

  • 피처 풀링 시스템

    • 객체 재사용을 통한 메모리 효율성 향상
    • 메모리 캐시 크기 제한 (최대 50개)
    • 불필요한 피처 즉시 해제
  • LOD(Level of Detail) 시스템

    • 거리 기반 3단계 상세도 레벨 구현
    • 가까운 영역: 1km 이내, 100% 상세도
    • 중간 영역: 5km 이내, 50% 상세도
    • 먼 영역: 10km 이상, 20% 상세도
  • 비동기 렌더링 파이프라인

    • 백그라운드 스레드에서 피처 렌더링
    • 배치 처리로 메인 스레드 블로킹 방지
    • 우선순위 기반 렌더링 (중심점 기준 거리)

성능 모니터링

  • 메모리 사용량 모니터링
  • 렌더링 프레임 레이트 측정
  • 배터리 소모량 추적

About

지금 서울 - 내 손안의 서울 : 실시간 핫플레이스 탐방 (지도 도메인 학습용)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages