PROJECT

AVIRO

동아리 팀(기획, 디자인, 서버, Android) · 2023.05–2026.04

개발자로 전환한 뒤 팀으로 출시한 첫 앱입니다. 2023년부터 3년간 운영하다 2026년 4월 서비스를 정리했습니다.

누적 유저 1,300+ · App Store 평점 4.9 · 등록 비건 식당 1,300+ · 리뷰 200+

지도 · 데이터

지도와 데이터를 다루며

MVP 패턴으로 빠르게 출시해 3년을 운영했습니다. 지도와 데이터를 다루며 마주친 문제들을 코드로 풀었고, 운영이 길어질수록 손대기 어려워지는 것도 함께 겪었습니다.

  • 동기화
    변경분만 받는 동기화 전국 식당 마커를 매번 전량 내려받지 않고, 마지막 갱신 이후 바뀐 곳과 삭제된 곳만 받아 Realm에 반영했습니다. 로컬 데이터로 먼저 지도를 그린 뒤 변경분만 맞춰 시작 속도와 오프라인 대응, 트래픽을 함께 챙겼습니다.
  • 지도
    겹친 핀도 개별 선택되게 좌표가 완전히 겹친 식당들은 핀이 포개져 고를 수 없어서, 경도를 조금씩 밀어 분산시켜 하나씩 선택되게 했습니다.
  • 학습
    구조를 먼저 잡게 된 지점 화면과 데이터가 한 레이어에 뒤섞인 채로 운영하다 대규모 업데이트에서 어디를 고치면 어디가 깨지는지 알 수 없어 손대지 못한 지점이 생겼습니다. 나중에 나누는 비용이 지금 나누는 비용보다 훨씬 크다는 걸 여기서 겪었고, 다음 실무부터는 계층을 나눠 설계했습니다.
MarkerModelManager.swift
func fetchRawData() {
    // 로컬에 데이터가 있으면 Realm으로 먼저 그린다
    haveStoredData ? fetchFromRealm() : fetchFromServer()
}

// 마지막 갱신 시각을 실어 변경분만 요청
func syncDelta() {
    let dto = AVIROMapModelDTO(time: updateTime)
    api.loadPlaces(dto) { result in
        result.updatedPlace.forEach {
            realm.add($0, update: .modified)   // upsert
        }
        result.deletedPlace.forEach {
            realm.delete(placeBy: $0)          // 삭제 반영
        }
        updateTime = Date()                 // 다음 변경분 기준
    }
}