From 5610a6d6ae390e88664478a06d0734fd6389ec20 Mon Sep 17 00:00:00 2001 From: sanghee Date: Sat, 11 Jun 2022 09:55:10 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=9C=84=EC=8B=9C=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=8B=A4=EC=A0=9C=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=EB=B0=98=EC=98=81=20(ios-h/airbnb#41)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- iOS/airbnb.xcodeproj/project.pbxproj | 12 +++++ iOS/airbnb/Common/Model/Constant.swift | 1 + .../WishList/Model/WishListResponseData.swift | 2 +- .../View/WishListCollectionViewCell.swift | 14 +++++- .../WishListCollectionViewDataSource.swift | 15 +++++- .../WishList/WishListViewController.swift | 24 ++++++--- .../Present/WishList/WishListViewModel.swift | 50 +++++++++++++++++++ 7 files changed, 108 insertions(+), 10 deletions(-) create mode 100644 iOS/airbnb/Present/WishList/WishListViewModel.swift diff --git a/iOS/airbnb.xcodeproj/project.pbxproj b/iOS/airbnb.xcodeproj/project.pbxproj index 716811012..7fb5567bb 100644 --- a/iOS/airbnb.xcodeproj/project.pbxproj +++ b/iOS/airbnb.xcodeproj/project.pbxproj @@ -30,6 +30,7 @@ D00B74652852503800B31424 /* WishListResponseData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00B74642852503800B31424 /* WishListResponseData.swift */; }; D00B74692852526200B31424 /* SearchLocationResponseData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00B74682852526200B31424 /* SearchLocationResponseData.swift */; }; D00B746D2852BBBE00B31424 /* Constant.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00B746C2852BBBE00B31424 /* Constant.swift */; }; + D00B7486285332E500B31424 /* WishListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00B7485285332E500B31424 /* WishListViewModel.swift */; }; D01D65EF283C70710067B5E1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01D65EE283C70710067B5E1 /* AppDelegate.swift */; }; D01D65F1283C70710067B5E1 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01D65F0283C70710067B5E1 /* SceneDelegate.swift */; }; D01D65F3283C70710067B5E1 /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01D65F2283C70710067B5E1 /* MainViewController.swift */; }; @@ -128,6 +129,7 @@ D00B74642852503800B31424 /* WishListResponseData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WishListResponseData.swift; sourceTree = ""; }; D00B74682852526200B31424 /* SearchLocationResponseData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchLocationResponseData.swift; sourceTree = ""; }; D00B746C2852BBBE00B31424 /* Constant.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constant.swift; sourceTree = ""; }; + D00B7485285332E500B31424 /* WishListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WishListViewModel.swift; sourceTree = ""; }; D01D65EB283C70710067B5E1 /* airbnb.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = airbnb.app; sourceTree = BUILT_PRODUCTS_DIR; }; D01D65EE283C70710067B5E1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; D01D65F0283C70710067B5E1 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -297,6 +299,13 @@ path = Model; sourceTree = ""; }; + D00B747A2852E72F00B31424 /* Network */ = { + isa = PBXGroup; + children = ( + ); + path = Network; + sourceTree = ""; + }; D01D65E2283C70710067B5E1 = { isa = PBXGroup; children = ( @@ -323,6 +332,7 @@ D01D65ED283C70710067B5E1 /* airbnb */ = { isa = PBXGroup; children = ( + D00B747A2852E72F00B31424 /* Network */, D068BCF528406D7700EF783E /* App */, D01D662E283D3A050067B5E1 /* Common */, D01D6624283CB50E0067B5E1 /* Present */, @@ -514,6 +524,7 @@ D0D29A1E284F4300009D1608 /* WishListCollectionViewDataSource.swift */, D0D299F0284F1D4D009D1608 /* WishListFlowCoordinator.swift */, D01D6627283CB5550067B5E1 /* WishListViewController.swift */, + D00B7485285332E500B31424 /* WishListViewModel.swift */, ); path = WishList; sourceTree = ""; @@ -815,6 +826,7 @@ D00B742E285059C900B31424 /* CalendarCollectionViewDataSource.swift in Sources */, D0D299DC284CB88A009D1608 /* CommonCollectionViewCell.swift in Sources */, D089E80528460B4C0000AE78 /* MainSectionDiffableDataSource.swift in Sources */, + D00B7486285332E500B31424 /* WishListViewModel.swift in Sources */, D0D299FD284F2498009D1608 /* WishListCollectionViewCell.swift in Sources */, D089E80B284621770000AE78 /* SearchDiffableDataSource.swift in Sources */, D087289D283F0DB9009983A5 /* CustomButton.swift in Sources */, diff --git a/iOS/airbnb/Common/Model/Constant.swift b/iOS/airbnb/Common/Model/Constant.swift index 6ae608534..e94c63342 100644 --- a/iOS/airbnb/Common/Model/Constant.swift +++ b/iOS/airbnb/Common/Model/Constant.swift @@ -9,4 +9,5 @@ import Foundation struct Constant { static let urlString = "http://52.79.106.69:8080" + static let tempToken = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOiJteWJsb29tIn0.16uZEJLejIvHUuYrUtcbiu6RbtFluK0mW837R0a9BP0" } diff --git a/iOS/airbnb/Present/WishList/Model/WishListResponseData.swift b/iOS/airbnb/Present/WishList/Model/WishListResponseData.swift index 44dfd32df..9e344b8c0 100644 --- a/iOS/airbnb/Present/WishList/Model/WishListResponseData.swift +++ b/iOS/airbnb/Present/WishList/Model/WishListResponseData.swift @@ -15,7 +15,7 @@ struct WishListData: Codable { let accommodationId: Int let name: String let price: Int - let imageUrls: [String] + let imagesUrls: [String] let wishId: Int let isWish: Bool } diff --git a/iOS/airbnb/Present/WishList/View/WishListCollectionViewCell.swift b/iOS/airbnb/Present/WishList/View/WishListCollectionViewCell.swift index d9a780fd1..7dc5217e7 100644 --- a/iOS/airbnb/Present/WishList/View/WishListCollectionViewCell.swift +++ b/iOS/airbnb/Present/WishList/View/WishListCollectionViewCell.swift @@ -10,7 +10,19 @@ import UIKit class WishListCollectionViewCell: CommonCollectionViewCell { func configure(with cell: WishListModel) { - self.accomodationImageView.image = cell.image + let imgUrl = cell.imageUrls?.randomElement() ?? "" + + if imgUrl.count > 0 { + DispatchQueue.global().async { + if let data = try? Data(contentsOf: URL(string: imgUrl)!) { + let img = UIImage(data: data) + + DispatchQueue.main.async { + self.accomodationImageView.image = img + } + } + } + } self.ratingLabel.text = "\(cell.rating ?? 0)" self.reviewCountingLabel.text = "(후기 \(cell.reviewCount ?? 0)개)" self.accomodationNameLabel.text = cell.accomodationName diff --git a/iOS/airbnb/Present/WishList/WishListCollectionViewDataSource.swift b/iOS/airbnb/Present/WishList/WishListCollectionViewDataSource.swift index 25be91020..d39573a06 100644 --- a/iOS/airbnb/Present/WishList/WishListCollectionViewDataSource.swift +++ b/iOS/airbnb/Present/WishList/WishListCollectionViewDataSource.swift @@ -5,12 +5,13 @@ // Created by 안상희 on 2022/06/07. // +import Alamofire import UIKit final class WishListCollectionViewDataSource: NSObject, UICollectionViewDataSource { func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { - return MockDataModel.mockWishListItems.count + return !wishListItems.isEmpty ? wishListItems.count: MockDataModel.mockWishListItems.count } func collectionView(_ collectionView: UICollectionView, @@ -21,8 +22,20 @@ final class WishListCollectionViewDataSource: NSObject, UICollectionViewDataSour return UICollectionViewCell() } + if !wishListItems.isEmpty { + let item = wishListItems[indexPath.item] + cell.configure(with: item) + return cell + } + let item = MockDataModel.mockWishListItems[indexPath.item] cell.configure(with: item) return cell } + + init(wishListItems: [WishListModel]) { + self.wishListItems = wishListItems + } + + private var wishListItems: [WishListModel] } diff --git a/iOS/airbnb/Present/WishList/WishListViewController.swift b/iOS/airbnb/Present/WishList/WishListViewController.swift index 4326429ee..989b3d370 100644 --- a/iOS/airbnb/Present/WishList/WishListViewController.swift +++ b/iOS/airbnb/Present/WishList/WishListViewController.swift @@ -13,19 +13,29 @@ final class WishListViewController: UIViewController { var coordinate: WishListFlow? private var wishListCollectionView: UICollectionView! = nil - private var dataSource = WishListCollectionViewDataSource() + private lazy var dataSource: WishListCollectionViewDataSource = { + let dataSource = + WishListCollectionViewDataSource(wishListItems: + wishListItems ?? MockDataModel.mockWishListItems) + return dataSource + }() + + private let viewModel = WishListViewModel() + private var wishListItems: [WishListModel]? override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white - configureCollectionView() - configureDataSource() - - configure() - - getWishList() + viewModel.getWishList { + self.wishListItems = self.viewModel.wishListItems + + self.configureCollectionView() + self.configureDataSource() + + self.configure() + } } private func configure() { diff --git a/iOS/airbnb/Present/WishList/WishListViewModel.swift b/iOS/airbnb/Present/WishList/WishListViewModel.swift new file mode 100644 index 000000000..ac8f3e6a0 --- /dev/null +++ b/iOS/airbnb/Present/WishList/WishListViewModel.swift @@ -0,0 +1,50 @@ +// +// WishListViewModel.swift +// airbnb +// +// Created by 안상희 on 2022/06/10. +// + +import Alamofire +import Foundation + +class WishListViewModel { + var wishListItems = [WishListModel]() + + private func dataToModel(responseData: WishListResponseData) { + for data in responseData.data { + let rating = Double.random(in: 3.00...5.00) + let reviewCount = Int.random(in: 1...100) + let model = WishListModel(id: data.wishId, + imageUrls: data.imagesUrls, + rating: round(rating * 100) / 100, + reviewCount: reviewCount, + accomodationName: data.name, + price: data.price) + wishListItems.append(model) + } + } + + func getWishList(completion: @escaping () -> Void) { + let url = "\(Constant.urlString)/api/wishlist?customerId=1" + AF.request(url, + method: .get, + parameters: nil, + encoding: URLEncoding.default, + headers: [ + "Authorization": Constant.tempToken, + "Content-Type": "application/json", + "Accept": "application/json"]) + .validate(statusCode: 200..<300) + .responseDecodable(of: WishListResponseData.self) { response in + switch response.result { + case .success(let response): + self.dataToModel(responseData: response) + completion() + case .failure(let error): + print(error.localizedDescription) + } + } + + } +}