안녕하세요 요즘 블로그 활동이 뜸했는데요...^^ 그동안 이것저것 프로젝트 하면서 살았답니다 ㅎㅎ
제가 스위프 앱 1기에서 진행한 near 앱을 소개하겠습니다!
바쁜 현대 사회에서 소중한 친구들과의 관계를 놓치지 않고 더 가깝게 이어갈 수 있도록 돕는 것을 목표로 iOS 앱 'near'를 개발했습니다.
이번 포스팅에서는 'near' 앱 개발에 사용된 핵심 기술 스택, 아키텍처 결정 과정, 그리고 개발 중 겪었던 도전과 배움의 순간들을 공유하고자 합니다.
1. 왜 'near'인가? : 앱 개발 배경 및 목표
"연락해야 하는데..." 생각만 하고 놓쳐버린 친구, 있지 않으신가요? 'near'는 이런 아쉬움을 해결하기 위해 탄생했습니다. 저희는 사용자가 친구들의 생일, 기념일, 설정한 연락 주기 등을 놓치지 않고 관리하며, 꾸준하고 의미 있는 관계를 유지할 수 있도록 돕는 것을 목표로 삼았습니다.
주요 기능은 다음과 같습니다.
- 연락처 및 카카오톡 친구 연동: 손쉽게 친구 목록을 가져와 관리합니다.
- 맞춤 연락 주기 설정: 친구별로 원하는 연락 주기를 설정하고 리마인더를 받습니다.
- 챙김 기록 및 관리: 친구를 챙긴 기록을 남기고, 관계 유지 현황을 파악합니다.
- 홈 화면 대시보드: 이번 달 챙겨야 할 친구와 전체 친구 목록을 한눈에 확인합니다.
2. 기술 스택 Deep Dive: 'near'를 구성하는 핵심 기술들
안정적이면서도 확장 가능하고, 효율적인 개발 경험을 위해 신중하게 기술 스택을 선택했습니다.
2.1. 프로젝트 관리 및 구조화: Tuist
- 선택 이유: Xcode 프로젝트 파일(.xcodeproj, .xcworkspace)의 복잡성과 충돌 가능성을 줄이고, 프로젝트 설정을 코드로 명확하게 관리하기 위해 Tuist를 도입했습니다.
- Project.swift 파일을 통해 앱 타겟, 테스트 타겟, 설정, 종속성, 리소스 등을 정의했습니다.
- 모듈화된 구조를 쉽게 구현하고, 팀원 간 설정 일관성을 유지하며 빌드 시간을 단축하는 효과를 얻었습니다.
- .xcconfig 파일을 활용하여 Debug/Release 환경별 설정을 분리하고, KAKAO_APP_KEY, DEV_BASE_URL 등 민감 정보를 안전하게 관리했습니다.
// Project.swift
settings: .settings(
base: [:],
configurations: [
.debug(name: "Debug", xcconfig: "Tuist/Config/Config.xcconfig"),
.release(name: "Release", xcconfig: "Tuist/Config/Config.xcconfig"),
]
),
targets: [
.target(
name: "SwypApp2nd",
// ...
infoPlist: .extendingDefault(with: [
"KAKAO_APP_KEY": "$(KAKAO_APP_KEY)",
"DEV_BASE_URL": "$(DEV_BASE_URL)",
// ...
]),
dependencies: [
.external(name: "Alamofire"),
.external(name: "Kingfisher"),
.external(name: "KakaoSDKCommon"),
// ... Kakao SDKs
],
// ...
),
// ...
]
2.2. 아키텍처: MVVM (Model-View-ViewModel)
- 선택 이유: View의 역할(UI 표시 및 사용자 입력)과 Business Logic(데이터 처리, 상태 관리)을 명확히 분리하여 코드의 가독성, 테스트 용이성, 유지보수성을 높이기 위해 MVVM 패턴을 채택했습니다.
- 구현: 각 View에 대응하는 ViewModel을 만들어 데이터 흐름과 상태 변화를 관리했습니다. SwiftUI와의 조합을 통해 데이터 바인딩을 효과적으로 활용했습니다.
2.3. UI 프레임워크: SwiftUI
- 선택 이유: iOS 17.0을 타겟으로 하고 MVVM 패턴을 사용하는 점, 그리고 선언적이고 현대적인 UI 개발 방식의 이점을 고려하여 SwiftUI를 주력 UI 프레임워크로 사용했습니다.
- 장점: 코드의 양을 줄이고, 실시간 프리뷰를 통해 UI 개발 생산성을 크게 향상시킬 수 있었습니다. MVVM 패턴과의 자연스러운 통합도 장점입니다.
2.4. 네트워킹: Alamofire & Backend API
- Alamofire: 백엔드 서버와의 안정적이고 편리한 HTTP 통신을 위해 검증된 라이브러리인 Alamofire를 사용했습니다. (dependencies: [.external(name: "Alamofire")])
- Backend API 연동: 자체 백엔드 서버와 RESTful API 통신을 통해 로그인, 친구 목록 조회/추가/수정/삭제, 프로필 관리, 챙김 기록 등 앱의 핵심 기능을 구현했습니다.
2.5. 사용자 인증: Kakao SDK, Sign in with Apple, Token Management
- Kakao SDK: 핵심 로그인 방식으로 카카오 로그인을 사용하며, 사용자 정보 및 친구 목록(동의 시)을 가져오는 데 활용했습니다. (KakaoSDKCommon, Auth, User, Friend 등 다수 모듈 사용)
- Sign in with Apple: Apple 사용자를 위한 간편 로그인 옵션을 제공합니다. (entitlements: "Tuist/SignInWithApple.entitlements")
- Token 기반 인증: 백엔드와의 안전한 통신을 위해 Access Token과 Refresh Token을 관리하고, Keychain에 안전하게 저장하며 자동 로그인 및 토큰 갱신 로직을 구현했습니다.
2.6. 비동기 이미지 처리: Kingfisher & Presigned URL
- Kingfisher: 서버로부터 받은 친구 프로필 이미지 URL 등을 비동기적으로 다운로드하고 캐싱하여 UI에 효율적으로 표시하기 위해 Kingfisher를 사용했습니다. (dependencies: [.external(name: "Kingfisher")])
- Presigned URL: 친구 프로필 이미지 업로드/다운로드 시 AWS S3 Presigned URL 방식을 사용하여 서버 부하를 줄이고 효율성을 높였습니다.
2.7. 로컬 데이터 관리: Core Data
- 활용: 알림(Notification) 관련 데이터를 로컬에 저장하고 관리하는 데 Core Data를 사용했습니다. (coreDataModels 설정: NotificationContainer.xcdatamodeld) 향후 오프라인 지원 강화 등 로컬 데이터 활용 범위를 넓힐 가능성을 염두에 두었습니다.
2.8. 시스템 연동: Contacts Framework
- 사용자의 주소록에 접근하여 친구를 가져오는 기능을 구현하기 위해 Contacts Framework를 사용했습니다. 사용자에게 명확한 권한 요청 안내를 제공합니다.
2.9. UI/UX 커스터마이징
- Custom Fonts (Pretendard): 앱 전체 디자인의 일관성을 위해 Pretendard 폰트를 적용했습니다.
- Light Mode 고정: 초기 버전에서는 디자인 리소스 및 개발 집중도를 고려하여 Light 모드만 지원하도록 설정했습니다.
- LaunchScreen: 앱 시작 시 브랜드 로고 등을 보여주는 LaunchScreen 스토리보드를 사용합니다.
3. 주요 기능 구현 하이라이트
기술 스택을 바탕으로 다음과 같은 주요 기능들을 구현했습니다.
- 로그인 및 온보딩: 카카오/애플 SDK를 이용한 간편 로그인 후, 서비스 이용 약관 동의, 연락처/카카오 친구 가져오기, 연락 주기 설정으로 이어지는 자연스러운 온보딩 플로우를 설계했습니다.
- 친구 관리: 연락처 및 카카오톡에서 가져온 친구를 '챙길 친구'로 등록하고, 맞춤 연락 주기를 설정합니다. Alamofire를 통해 백엔드 API와 연동하여 친구 정보를 생성, 조회, 수정, 삭제합니다.
- 홈 화면: '이번 달 챙길 친구'와 '내 사람들' 목록을 보여주며, 친구를 챙겼음을 기록하는 기능을 제공합니다.
- 프로필 상세 및 수정: 친구의 상세 정보(연락처, 기념일, 메모 등)를 확인하고 수정하는 기능을 구현했습니다.
4. 개발 과정에서의 도전과 배움 (Challenges & Learnings)
개발 과정은 순탄하지만은 않았습니다. 몇 가지 기술적 어려움에 직면했고, 이를 해결하며 값진 경험을 얻었습니다.
- Tuist와 Kakao SDK 리소스 번들: Kakao SDK 중 친구 목록 관련 기능을 사용할 때, SDK 내부 리소스 번들을 Tuist 프로젝트에 올바르게 포함시키는 과정에서 어려움을 겪었습니다. Tuist의 리소스 처리 방식과 Kakao SDK 문서 검토를 통해 해결했습니다.
- 데이터 동기화 및 상태 관리: 친구 추가/수정 후 홈 화면 등 다른 View에 변경 사항이 즉시 반영되지 않는 문제가 있었습니다. SwiftUI의 @State, @ObservedObject, @EnvironmentObject 등을 활용한 상태 관리 로직을 개선하고, 데이터 흐름을 명확히 하여 해결했습니다.
- 비동기 처리: 여러 친구의 프로필 이미지를 동시에 업로드하거나, 다수의 API 호출 후 UI를 업데이트하는 과정에서 DispatchGroup 등을 활용하여 비동기 코드를 안정적이고 효율적으로 관리했습니다.
- Tuist와 Core Data 연동: 초기 설정 시 Core Data 모델 파일(.xcdatamodeld) 경로를 Tuist 프로젝트 설정(Project.swift)에 정확히 명시하여 인식시키는 데 약간의 시행착오가 있었습니다.
- API 명세 변경 대응: 개발 중 백엔드 API 명세가 변경되는 경우가 있었고, 이에 맞춰 모델과 네트워킹 코드를 신속하게 수정하며 백엔드 팀과의 긴밀한 소통의 중요성을 다시 한번 느꼈습니다.
5. 마무리하며
'near' 앱은 Tuist를 통한 효율적인 프로젝트 관리, MVVM 아키텍처 기반의 구조화된 코드, SwiftUI를 활용한 현대적인 UI 구현, 그리고 Alamofire, Kingfisher, Kakao SDK 등 검증된 라이브러리 및 Core Data, Contacts 등 시스템 프레임워크를 적극적으로 활용하여 개발되었습니다.
개발 과정에서의 도전들은 저희 팀을 더욱 성장시키는 계기가 되었습니다. 앞으로도 사용자분들이 친구들과의 소중한 관계를 'near'를 통해 더 쉽고 의미 있게 가꿔나갈 수 있도록, 꾸준히 기능을 개선하고 안정화해 나갈 예정입니다.
긴 글 읽어주셔서 감사합니다! 'near' 앱 개발 과정이나 사용된 기술에 대해 궁금한 점이 있다면 언제든지 댓글로 남겨주세요.
'iOS' 카테고리의 다른 글
SwiftUI) previewLayout이 안돼요.. (0) | 2023.12.21 |
---|---|
Swift - Alamofire Uikit(사자성어 앱 개발을 위한 공부) (0) | 2023.02.05 |