diff --git a/iOS/SideDish/SideDish.xcodeproj/project.pbxproj b/iOS/SideDish/SideDish.xcodeproj/project.pbxproj index 189cf9dfe..dc208b87b 100644 --- a/iOS/SideDish/SideDish.xcodeproj/project.pbxproj +++ b/iOS/SideDish/SideDish.xcodeproj/project.pbxproj @@ -26,12 +26,12 @@ D4BFBB36262EB89800D68297 /* BanchanCustomCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D4BFBB34262EB89800D68297 /* BanchanCustomCell.xib */; }; D4BFBB3C262EC8DB00D68297 /* BanchanCustomCellHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4BFBB3A262EC8DB00D68297 /* BanchanCustomCellHeader.swift */; }; D4BFBB3D262EC8DB00D68297 /* BanchanCustomCellHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = D4BFBB3B262EC8DB00D68297 /* BanchanCustomCellHeader.xib */; }; - D4BFBB5626301B6B00D68297 /* Section.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4BFBB5526301B6B00D68297 /* Section.swift */; }; FFA10EB1262FC6CD00D584B6 /* BanchanCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFA10EB0262FC6CD00D584B6 /* BanchanCollectionView.swift */; }; FFEF70F926310FB400189376 /* NetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFEF70F826310FB400189376 /* NetworkService.swift */; }; FFEF70FF2631104B00189376 /* BanchanListDTO+Mapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFEF70FE2631104B00189376 /* BanchanListDTO+Mapping.swift */; }; FFEF71042631107200189376 /* FetchBanchanListUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFEF71032631107200189376 /* FetchBanchanListUseCase.swift */; }; FFEF71092631128900189376 /* FetchImageUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFEF71082631128900189376 /* FetchImageUseCase.swift */; }; + FFEF7123263119C500189376 /* BanchanListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFEF7122263119C500189376 /* BanchanListViewModel.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -81,7 +81,6 @@ D4BFBB34262EB89800D68297 /* BanchanCustomCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = BanchanCustomCell.xib; sourceTree = ""; }; D4BFBB3A262EC8DB00D68297 /* BanchanCustomCellHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BanchanCustomCellHeader.swift; sourceTree = ""; }; D4BFBB3B262EC8DB00D68297 /* BanchanCustomCellHeader.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = BanchanCustomCellHeader.xib; sourceTree = ""; }; - D4BFBB5526301B6B00D68297 /* Section.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Section.swift; sourceTree = ""; }; D7433C6120AE2C2B5B290532 /* Pods_SideDishTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SideDishTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; E5121CE39396F4ECB1937C15 /* Pods-SideDish-SideDishUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SideDish-SideDishUITests.debug.xcconfig"; path = "Target Support Files/Pods-SideDish-SideDishUITests/Pods-SideDish-SideDishUITests.debug.xcconfig"; sourceTree = ""; }; FFA10EB0262FC6CD00D584B6 /* BanchanCollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BanchanCollectionView.swift; sourceTree = ""; }; @@ -89,6 +88,7 @@ FFEF70FE2631104B00189376 /* BanchanListDTO+Mapping.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BanchanListDTO+Mapping.swift"; sourceTree = ""; }; FFEF71032631107200189376 /* FetchBanchanListUseCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchBanchanListUseCase.swift; sourceTree = ""; }; FFEF71082631128900189376 /* FetchImageUseCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchImageUseCase.swift; sourceTree = ""; }; + FFEF7122263119C500189376 /* BanchanListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BanchanListViewModel.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -255,7 +255,7 @@ D4BFBB21262EA7BC00D68297 /* ViewModel */ = { isa = PBXGroup; children = ( - D4BFBB5526301B6B00D68297 /* Section.swift */, + FFEF7122263119C500189376 /* BanchanListViewModel.swift */, D4BFBB20262EA7B600D68297 /* View */, ); path = ViewModel; @@ -575,7 +575,6 @@ D4BFBAD7262E989000D68297 /* BanchanListViewController.swift in Sources */, D4BFBAD3262E989000D68297 /* AppDelegate.swift in Sources */, D4BFBAD5262E989000D68297 /* SceneDelegate.swift in Sources */, - D4BFBB5626301B6B00D68297 /* Section.swift in Sources */, FFA10EB1262FC6CD00D584B6 /* BanchanCollectionView.swift in Sources */, D4BFBB0A262E9A8200D68297 /* DetailBanchanViewController.swift in Sources */, D4BFBB2F262EAD1C00D68297 /* DetailBanchan.swift in Sources */, @@ -584,6 +583,7 @@ D4BFBB35262EB89800D68297 /* BanchanCustomCell.swift in Sources */, D4BFBB2A262EA93700D68297 /* Banchan.swift in Sources */, FFEF71092631128900189376 /* FetchImageUseCase.swift in Sources */, + FFEF7123263119C500189376 /* BanchanListViewModel.swift in Sources */, D4BFBB3C262EC8DB00D68297 /* BanchanCustomCellHeader.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/iOS/SideDish/SideDish.xcworkspace/xcuserdata/jibook.xcuserdatad/UserInterfaceState.xcuserstate b/iOS/SideDish/SideDish.xcworkspace/xcuserdata/jibook.xcuserdatad/UserInterfaceState.xcuserstate index 7d00cc447..14146f759 100644 Binary files a/iOS/SideDish/SideDish.xcworkspace/xcuserdata/jibook.xcuserdatad/UserInterfaceState.xcuserstate and b/iOS/SideDish/SideDish.xcworkspace/xcuserdata/jibook.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/iOS/SideDish/SideDish/Data/Network/DataMapping/BanchanListDTO+Mapping.swift b/iOS/SideDish/SideDish/Data/Network/DataMapping/BanchanListDTO+Mapping.swift index 22376e3ca..60256d3cb 100644 --- a/iOS/SideDish/SideDish/Data/Network/DataMapping/BanchanListDTO+Mapping.swift +++ b/iOS/SideDish/SideDish/Data/Network/DataMapping/BanchanListDTO+Mapping.swift @@ -48,6 +48,12 @@ extension BanchanListDTO { extension BanchanListDTO.BanchanListItemDTO { func toDomain() -> Banchan { - return .init(hash: hash, image: image, alt: alt, title: title, description: description, netPrice: normalPrice, salePrice: salePrice, badge: badge, deliveryType: deliveryType) + var newData: Data? + FetchImageUseCase.fetch(network: NetworkSerivce.shared, imgURL: image) { data in + DispatchQueue.main.async { + newData = data + } + } + return .init(hash: hash, image: newData, alt: alt, title: title, description: description, netPrice: normalPrice, salePrice: salePrice, badge: badge, delivery_type: deliveryType) } } diff --git a/iOS/SideDish/SideDish/Data/Network/NetworkService.swift b/iOS/SideDish/SideDish/Data/Network/NetworkService.swift index bc4c8b786..d032e8c98 100644 --- a/iOS/SideDish/SideDish/Data/Network/NetworkService.swift +++ b/iOS/SideDish/SideDish/Data/Network/NetworkService.swift @@ -14,6 +14,11 @@ protocol NetworkRequest { class NetworkSerivce: NetworkRequest { + static let shared = NetworkSerivce() + + private init() { + } + func request(url strUrl: String, httpMethod: HTTPMethod, completion: @escaping (AFDataResponse) -> Void) { guard let url = URL(string: strUrl) else { return } diff --git a/iOS/SideDish/SideDish/Domain/Entities/Banchan.swift b/iOS/SideDish/SideDish/Domain/Entities/Banchan.swift index 0fa58821b..9ad7f751b 100644 --- a/iOS/SideDish/SideDish/Domain/Entities/Banchan.swift +++ b/iOS/SideDish/SideDish/Domain/Entities/Banchan.swift @@ -19,14 +19,14 @@ enum PriceType { struct Banchan: Hashable { private (set) var hash: String - private (set) var image: String + private (set) var image: Data? private (set) var alt: String private (set) var title: String private (set) var description: String private (set) var netPrice: String? private (set) var salePrice: String - private (set) var badge: [PriceType] - private (set) var delivery_type: [Delivery] + private (set) var badge: [String]? + private (set) var delivery_type: [String] func hash(into hasher: inout Hasher) { hasher.combine(hash) diff --git a/iOS/SideDish/SideDish/Domain/UseCases/FetchBanchanListUseCase.swift b/iOS/SideDish/SideDish/Domain/UseCases/FetchBanchanListUseCase.swift index 44de4ced6..9a687aa01 100644 --- a/iOS/SideDish/SideDish/Domain/UseCases/FetchBanchanListUseCase.swift +++ b/iOS/SideDish/SideDish/Domain/UseCases/FetchBanchanListUseCase.swift @@ -8,10 +8,11 @@ import Foundation struct FetchBanchanListUseCase { - private static let url: String = "https://h3rb9c0ugl.execute-api.ap-northeast-2.amazonaws.com/develop/baminchan/side" + private static let baseURL: String = "https://h3rb9c0ugl.execute-api.ap-northeast-2.amazonaws.com/develop/baminchan/" - static func fetchBanchanList(network: NetworkRequest, completion: @escaping ([Banchan]?) -> Void) { - network.request(url: self.url, httpMethod: .get) { dataDummy in + static func fetchBanchanList(network: NetworkRequest,section: String, completion: @escaping ([Banchan]?) -> Void) { + let url = baseURL+section + network.request(url: url, httpMethod: .get) { dataDummy in guard let data = dataDummy.data else { return } guard let banchans = try? JSONDecoder().decode(BanchanListDTO.self, from: data) else { return } diff --git a/iOS/SideDish/SideDish/Info.plist b/iOS/SideDish/SideDish/Info.plist index 5b531f7b2..53c6efd04 100644 --- a/iOS/SideDish/SideDish/Info.plist +++ b/iOS/SideDish/SideDish/Info.plist @@ -2,6 +2,11 @@ + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleExecutable diff --git a/iOS/SideDish/SideDish/Presentaion/BanchanList/ViewModel/BanchanListViewModel.swift b/iOS/SideDish/SideDish/Presentaion/BanchanList/ViewModel/BanchanListViewModel.swift index 577363082..edd048c72 100644 --- a/iOS/SideDish/SideDish/Presentaion/BanchanList/ViewModel/BanchanListViewModel.swift +++ b/iOS/SideDish/SideDish/Presentaion/BanchanList/ViewModel/BanchanListViewModel.swift @@ -2,30 +2,53 @@ // BanchanListViewModel.swift // SideDish // -// Created by 지북 on 2021/04/20. +// Created by 지북 on 2021/04/22. // import Foundation -import UIKit -//class BanchanListViewModel { -//// enum Section: String, CaseIterable { -//// case soup = "정성이 담긴 뜨끈뜨끈 국물요리" -//// case side = "식탁을 풍성하게 하는 정갈한 밑반찬" -//// case main = "모두가 좋아하는 든든한 메인요리" -//// } -// -// var menu: Dictionary -// -// init() { -// self.menu = [:] -// } -// -// func sectionCount() -> Int { -// return Section.allCases.count -// } -// -// func getBanchans(section: Section) -> [Banchan]? { -// return menu[section] -// } -//} +class BanchanListViewModel { + enum Section: String, CaseIterable { + case soup = "정성이 담긴 뜨끈뜨끈 국물요리" + case side = "식탁을 풍성하게 하는 정갈한 밑반찬" + case main = "모두가 좋아하는 든든한 메인요리" + } + + var menu: Dictionary { + didSet { + NotificationCenter.default.post(name: Notification.Name("updateMenu"), object: self) + } + } + var network = NetworkSerivce.shared + + init() { + self.menu = [:] + fetchMenu() + } + + func fetchMenu() { + FetchBanchanListUseCase.fetchBanchanList(network: network, section: "main", completion: { banchans in + guard let banchans = banchans else { return } + self.menu[.main] = banchans + }) + + FetchBanchanListUseCase.fetchBanchanList(network: network, section: "soup", completion: { banchans in + guard let banchans = banchans else { return } + self.menu[.soup] = banchans + }) + + FetchBanchanListUseCase.fetchBanchanList(network: network, section: "side", completion: { banchans in + guard let banchans = banchans else { return } + self.menu[.side] = banchans + }) + } + + func sectionCount() -> Int { + return Section.allCases.count + } + + func getBanchans(section: Section) -> [Banchan]? { + return menu[section] + } +} + diff --git a/iOS/SideDish/SideDish/Presentaion/BanchanList/ViewModel/Section.swift b/iOS/SideDish/SideDish/Presentaion/BanchanList/ViewModel/Section.swift deleted file mode 100644 index ed5346172..000000000 --- a/iOS/SideDish/SideDish/Presentaion/BanchanList/ViewModel/Section.swift +++ /dev/null @@ -1,40 +0,0 @@ -// -// Section.swift -// SideDish -// -// Created by 심영민 on 2021/04/21. -// - -import UIKit - -class Section: Hashable { - enum SectionTitle: String { - case main = "모두가 좋아하는 든든한 메인요리" - case soup = "정성이 담긴 뜨끈뜨끈 국물요리" - case side = "식탁을 풍성하게 하는 정갈한 밑반찬" - } - var id = UUID() - var banchans: [Banchan] - var title: SectionTitle - - init(title: SectionTitle, banchans: [Banchan]) { - self.title = title - self.banchans = banchans - } - static func == (lhs: Section, rhs: Section) -> Bool { - return lhs.id == rhs.id - } - - func hash(into hasher: inout Hasher) { - hasher.combine(id) - } -} - -extension Section { - static var allSections: [Section] = [ - - Section(title: .main, banchans: [Banchan(hash: "1", image: "https://pbs.twimg.com/profile_images/770139154898382848/ndFg-IDH.jpg", alt: "alt", title: "타이틀", description: "데스크립션", netPrice: "1000", salePrice: "1000", badge: [], delivery_type: [])]), - Section(title: .soup, banchans: [Banchan(hash: "2", image: "https://pbs.twimg.com/profile_images/770139154898382848/ndFg-IDH.jpg", alt: "alt", title: "타이틀", description: "데스크립션", netPrice: "1000", salePrice: "1000", badge: [], delivery_type: [])]), - Section(title: .side, banchans: [Banchan(hash: "3", image: "https://pbs.twimg.com/profile_images/770139154898382848/ndFg-IDH.jpg", alt: "alt", title: "타이틀", description: "데스크립션", netPrice: "1000", salePrice: "1000", badge: [], delivery_type: [])]) - ] -} diff --git a/iOS/SideDish/SideDish/Presentaion/BanchanList/ViewModel/View/BanchanCustomCell.swift b/iOS/SideDish/SideDish/Presentaion/BanchanList/ViewModel/View/BanchanCustomCell.swift index a426520a4..26b926c83 100644 --- a/iOS/SideDish/SideDish/Presentaion/BanchanList/ViewModel/View/BanchanCustomCell.swift +++ b/iOS/SideDish/SideDish/Presentaion/BanchanList/ViewModel/View/BanchanCustomCell.swift @@ -8,7 +8,7 @@ import UIKit class BanchanCustomCell: UICollectionViewCell { - + @IBOutlet weak var imageView: UIImageView! @IBOutlet weak var titleLabel: UILabel! @IBOutlet weak var descriptionLabel: UILabel! @@ -28,18 +28,12 @@ class BanchanCustomCell: UICollectionViewCell { var banchan: Banchan? { didSet{ - guard let url = URL(string: "\(banchan!.image)"), - let data = try? Data(contentsOf: url) else { - return - } - - imageView.image = UIImage(data: data) + imageView.image = UIImage(data: banchan!.image ?? Data()) titleLabel.text = banchan?.title descriptionLabel.text = banchan?.description - netPriceLabel.text = "\(banchan?.netPrice ?? "")" - salePriceLabel.text = "\(banchan?.salePrice ?? "")" - priceTypeLabel.text = "\(banchan?.badge ?? [])" + netPriceLabel.text = "1000" + salePriceLabel.text = "2000" + priceTypeLabel.text = "3000" } } - } diff --git a/iOS/SideDish/SideDish/Presentaion/BanchanList/ViewModel/View/BanchanListViewController.swift b/iOS/SideDish/SideDish/Presentaion/BanchanList/ViewModel/View/BanchanListViewController.swift index 9fb62f7ee..b1a5a3315 100644 --- a/iOS/SideDish/SideDish/Presentaion/BanchanList/ViewModel/View/BanchanListViewController.swift +++ b/iOS/SideDish/SideDish/Presentaion/BanchanList/ViewModel/View/BanchanListViewController.swift @@ -11,19 +11,21 @@ class BanchanListViewController: UIViewController { @IBOutlet weak var banchanCollectionView: BanchanCollectionView! - //var viewModel = BanchanListViewModel() - private var sections = Section.allSections + var viewModel = BanchanListViewModel() lazy var dataSource = configureDataSource() typealias DataSource = UICollectionViewDiffableDataSource typealias Snapshot = NSDiffableDataSourceSnapshot + typealias Section = BanchanListViewModel.Section override func viewDidLoad() { super.viewDidLoad() - - applySnapshot(animatingDifferences: false) + + applySnapshot(animatingDifferences: true) banchanCollectionView.dataSource = self.dataSource banchanCollectionView.delegate = self + + NotificationCenter.default.addObserver(self, selector: #selector(applySnapshot(animatingDifferences:)), name: Notification.Name("updateMenu"), object: viewModel) } } @@ -31,40 +33,32 @@ class BanchanListViewController: UIViewController { extension BanchanListViewController { func configureDataSource() -> DataSource { let dataSource = DataSource(collectionView: banchanCollectionView) { (collectionView, indexPath, banchan) -> UICollectionViewCell? in - guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: BanchanCustomCell.identifer, for: indexPath) as? BanchanCustomCell else { - return nil - } - cell.banchan = banchan - return cell + guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: BanchanCustomCell.identifer, for: indexPath) as? BanchanCustomCell else { return nil } + cell.banchan = banchan + return cell } - dataSource.supplementaryViewProvider = { (collectionView, kind, indexPath) in - guard kind == UICollectionView.elementKindSectionHeader else { - return nil - } - - guard let view = collectionView.dequeueReusableSupplementaryView( - ofKind: kind, - withReuseIdentifier: BanchanCustomCellHeader.identifier, - for: indexPath) as? BanchanCustomCellHeader else { - return nil - } + guard kind == UICollectionView.elementKindSectionHeader else { return nil } let section = self.dataSource.snapshot().sectionIdentifiers[indexPath.section] - view.titleLabel.text = section.title.rawValue + guard let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: BanchanCustomCellHeader.identifier, for: indexPath) as? BanchanCustomCellHeader else { return nil } + view.titleLabel.text = section.rawValue return view } return dataSource } + @objc func applySnapshot(animatingDifferences: Bool = true) { var snapshot = Snapshot() - - snapshot.appendSections(sections) - sections.forEach { section in - snapshot.appendItems(section.banchans, toSection: section) + snapshot.appendSections(Section.allCases) + + Section.allCases.forEach { section in + guard let banchans = viewModel.getBanchans(section: section) else { return } + snapshot.appendItems(banchans, toSection: section) } + dataSource.apply(snapshot, animatingDifferences: animatingDifferences) } }