- 국립중앙도서관 API를 활용한 발행일 기반
도서 검색
- 알라딘 API를 통한 도서 검색 및
베스트셀러 제공
- Realm 데이터베이스를 활용한
북마크 기능
구현
앱스토어(링크)
2024년 3월 7일 ~ 24일 (약 2주, 업데이트 진행중)
최신 버전 : 1.0.9 - 2024년 7월 3일
- 최소 버전: iOS 17.2
- iPhone SE ~ iPhone 15 Pro Max 기기 대응
UIKit(Code Base)
MVVM
Custom Observable
FlowLayout
FSCalendar
Kingfisher
Alamofire
Realm
Then
국립중앙도서관 API
알라딘 API
- 클로저 내부에 약한 참조와 캡쳐 리스트를 활용한 메모리 누수 방지 및 안전성 강화
- ViewModel을 통해 MVVM 패턴을 적용하여 UI 로직과 비즈니스 로직의 명확한 분리 및 유지보수성 향상
- 공통 로직 메서드 분리를 통한 API 호출 코드 중복 최소화 및 재사용성 강화
- 네트워크 요청 캐싱 전략을 통해 중복된 API 호출 방지 및 네트워크 자원 효율성 개선
- Input/Output 패턴 설계로 데이터의 흐름 명확성 증대
- 접근 제어자를 활용한 객체 캡슐화 강화 및 데이터 은닉화
- final 클래스로 상속 및 재정의 방지 및 Static Dispatch를 통한 앱 성능 최적화
❌ 문제 상황
국립중앙도서관 API에서 제공하는 책 이미지 데이터가 부족하여, 책 이미지 범위가 제한되는 문제가 발생
⭕️ 해결 방법
- 국립중앙도서관 API에서 책 정보를 검색할 때 ISBN 정보만 추출
- 추출한 ISBN 정보를 알라딘 API에서 재검색
- 이를 통해 책 제목, 저자, 이미지 등 풍부한 정보로 인해 검색 결과 구현
self.inputDate.bind { [weak self] bookDate in
guard let self else { return }
// Indicator Start animating
self.inputIndicatorTrigger.value = true
APIManager.shared.nationalLibraryCallRequest(api: .dateLibrary(date: bookDate)) {
[weak self] result in
guard let self else { return }
// Indicator stop animating
self.inputIndicatorTrigger.value = false
switch result {
case .success(let success):
for isbn in success.docs {
if !isbn.isbn.isEmpty {
self.outputNationalLibraryAPIResult.append(isbn.isbn)
}
}
self.inputISBNTrigger.value = ()
case .failure(let failure):
if !failure.isResponseSerializationError {
self.outputErrorMessage.value = "잠시 후 다시 시도해주세요"
}
}
}
}
self.inputISBNTrigger.bind { [weak self] _ in
guard let self else { return }
let isbnSlice = self.outputNationalLibraryAPIResult.prefix(15)
var aladinSuccessItem: [Item] = []
var failureCount = 0
for isbn in isbnSlice {
APIManager.shared.aladinCallRequest(api: .isbnAladin(isbn: isbn)) {
[weak self] result in
guard let self else { return }
switch result {
case .success(let success):
aladinSuccessItem.append(contentsOf: success.item)
if aladinSuccessItem.count + failureCount == isbnSlice.count {
self.outputAladinAPIResult.value.append(contentsOf: aladinSuccessItem)
}
❌ 문제 상황
뷰에 보여지는 날짜와 클릭한 날짜가 같을 경우 네트워크 중복 호출이 발생하는 문제
⭕️ 해결 방법
didSelect
와 shouldSelect
메소드를 활용하여 문제 해결
didSelect
: 날짜가 선택될 때 선택된 날짜를 저장shouldSelect
: 다른 날짜를 선택할 때 기존 날짜를 초기화하고, 같은 날짜를 선택할 경우 선택 방지
func calendar(_ calendar: FSCalendar,
didSelect date: Date,
at monthPosition: FSCalendarMonthPosition) {
selectedDate = date
birthdayDate(date: date)
viewModel.inputIndicatorTrigger.value = true
}
func calendar(_ calendar: FSCalendar,
shouldSelect date: Date,
at monthPosition: FSCalendarMonthPosition) -> Bool {
if date != selectedDate {
collectionView.scrollsToTop = true
APIManager.shared.bookISBNArray.removeAll()
viewModel.outputAladinAPIResult.value.removeAll()
} else {
return false
}
return true
}
- Realm Notification Token
- Network StatusCode Error Handling
- DTO 적용
- Memory Leak 확인
- Launch Screen 설정
- 본인 생일 입력 → Push Notification
- Realm PK Key 수정
- adult 연령의 책 제한
프로젝트를 시작하기 전 API 사전 조사의 중요성을 깨달았다. 날짜를 기준으로 책 정보를 검색할 수 있는 API는 국립중앙도서관이 유일했기 때문에 이를 통해 프로젝트를 시작했다. 하지만 국립중앙도서관 API를 사용하면서 책 이미지 데이터의 부족함을 느꼈고, 이로 인해 사용자에게 보여줄 수 있는 책 이미지 범위가 제한되는 문제를 직면했다. 국립중앙도서관 API에서 제공하는 책 정보 중 책 이미지 URL을 포함하고 있는 데이터가 많지 않았기 때문이다. 이로 인해 이미지가 있는 책들만 배열에 넣고 보여주는 방식으로 진행했지만 검색화면(SearchView)을 구현하는 과정 중에 데이터의 양이 크게 제한되는 결과를 초래했다.
국립중앙도서관 API의 한계를 극복하기 위해, 날짜를 클릭 시 국립중앙도서관 API에서 ISBN만을 추출하여 이를 알라딘 API에서 재검색하는 방식으로 전환했고, 알라딘 API로 책 제목, 저자, 이미지 등 풍부한 정보로 인해 더 만족스러운 검색 결과를 구현할 수 있었다.