- 앱 설계
- View
- Manager
| 이병훈 (1인 개발) |
|---|
- 오픈 API (Google Book)를 이용하여 책 검색어에 대한 데이터를 받아와 나타냄.
totalItems: 878
▿ items: 10 elements
▿ BookFinder.BookList
- id: "PIVQ6PANsikC"
▿ bookInfo: BookFinder.BookInfo
- title: "American Red Cross Sports Safety Training Im"
▿ authors: Optional(["Granada Learning Limited"])
▿ some: 1 element
- "Granada Learning Limited"
▿ publishedDate: Optional("1997-12")
- some: "1997-12"
▿ imageLinks: Optional(BookFinder.BookImage(thumbnail: "http://books.google.com/books/content?id=PIVQ6PANsikC&printsec=frontcover&img=1&zoom=1&source=gbs_api"))
▿ some: BookFinder.BookImage
- thumbnail: "http://books.google.com/books/content?id=PIVQ6PANsikC&printsec=frontcover&img=1&zoom=1&source=gbs_api"
- infoLink: "http://books.google.co.kr/books?id=PIVQ6PANsikC&dq=Red&hl=&source=gbs_api"MVVM 아키텍처사용infinite scroll(무한스크롤) 구현- 리스트에서 책을 터치하면
상세페이지를 webView로 띄움. - 데이터 호출 되는동안
로딩 애니메이션 UnitTest- 이미지 캐싱
| 검색, 무한스크롤, 오픈API (GET) |
상세페이지 (WebView) |
|---|---|
![]() |
![]() |
| class / struct | 역할 |
|---|---|
SearchBookCollectionViewCell |
- BookList 데이터를 표시하는 Cell |
SearchBookViewController |
- SearchController를 사용하여 검색기능 사용가능 - 키워드 입력 후 검색을 누르면 GET 메서드로 데이터를 불러옴 - BookList의 item(cell)을 누르면 BookDetailViewController로 이동 - BookDetailViewController 선택된 item의 데이터 전달 |
BookDetailViewController |
- SearchBookViewController에서 전달받은 데이터를 webView로 표현 - load가 되기 전까진 로딩 인디케이터 표현 |
| class / struct | 역할 |
|---|---|
EndPointType |
- URLRequest를 반환하는데 필요한 정보를 정의하는 Protocol |
BookListEndPoint |
- EndPointType채택, URLRequest를 반환하는데 필요한 정보를 담고있는 객체 |
NetworkRequester |
- EndPointType 혹은 URLString를 매개변수로 전달받아, 통신을 수행하는 객체 |
BookListAPIProvider |
- BookListEndPoint, NetworkRequester를 사용하여 API통신을 수행하는 객체 - 반환된 data를 Decode함. |
BookImageProvider |
- 이미지의 URL -> Image data를 얻어오는 객체. - image caching기능을 수행. |
검색결과가 없을때 `spinner` 가 계속 돌게됨
검색결과가 없을때 로딩 인디케이터 (spinner)가 계속 돌게됨
아래와 같이 JSON 의 키 값중 items가 데이터가 없는경우에 해당 값이 없음.
BookListResults 의 items에 Optional 처리를 해주었고,
struct BookListResults: Decodable {
let totalItems: Int
let items: [BookList]? // Optional
}items가 없을시 옵셔널 바인딩 (guard let) 에서 예외처리 부분에 코드를 추가해줌.
// SearchBookViewModel
func fetchBookList(
with searchText: String
) {
isLoading.value = true
bookListAPIProvider.fetchBooks(
with: searchText,
from: startIndex.value,
completion: { [weak self] result in
guard let self = self else { return }
switch result {
case .success(let data):
guard let items = data.items else {
self.noResult.value = true // 예외 처리
return
}
self.searchedBookTotalCount.value = data.totalItems
self.bookList.value = items
self.startIndex.value += 10
self.searchedTitle.value = searchText
self.isLoading.value = false
case .failure(let error):
print(error.localizedDescription)
self.isLoading.value = false
}
})
}+추가로
검색결과가 없다는걸 사용자가 알 수 있게 Alert 띄워줌
CollectionView 깜빡임 현상
이번 프로젝트로 정말 많은걸 배웠다. MVVM도 학습해서 적용해보았으며, UnitTest도 해볼 수 있었던 좋은 경험이었다. 이전 프로젝트와는 다른방식으로 무한스크롤(infiniteScroll)도 구현해보았고 짧았지만 여러가지로 많은 경험을 할 수 있었던 것 같아 너무 좋았다. 먼저 피드백 받은것을 반영해보고 고도화 시켜봐야겠다.





