20220118 iOS 일일 개발일지
===
###### tags: `develop`
[TOC]
### swift keychain wrapper
id, password, access token, refresh token을 저장하기 위해서 keychain 도입이 필요하다고 판단됨.
github repository
https://github.com/jrendel/SwiftKeychainWrapper
reference document
https://baked-corn.tistory.com/69
https://medium.com/ios-os-x-development/securing-user-data-with-keychain-for-ios-e720e0f9a8e2
```swift=
//
// ItemView.swift
// Cream
//
// Created by wankikim-MN on 2022/01/19.
//
//
import UIKit
import SnapKit
final class ItemView: UIView {
lazy var ItemInfoListView: UICollectionView = {
let cv = UICollectionView(frame: .zero,
collectionViewLayout: configureCollectionViewLayout())
return cv
}()
lazy var buyButton: TradeButton = {
let button = TradeButton(tradeType: .buy)
return button
}()
lazy var sellButton: TradeButton = {
let button = TradeButton(tradeType: .sell)
return button
}()
lazy var wishButton: VerticalButton = {
let button = VerticalButton.init(frame: .zero)
button.imageView?.image = UIImage(systemName: "bookmark")
button.titleLabel?.text = "찜 목록 개수"
return button
}()
lazy var tradeStackView: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [buyButton, sellButton])
stackView.axis = .horizontal
stackView.distribution = .fillEqually
stackView.spacing = 5
return stackView
}()
lazy var containerStackView: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [wishButton, tradeStackView])
stackView.axis = .horizontal
stackView.spacing = 10
return stackView
}()
override init(frame: CGRect) {
super.init(frame: frame)
applyViewSettings()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
applyViewSettings()
}
}
// MARK: CollectionViewLayout
extension ItemView {
private func configureCollectionViewLayout() -> UICollectionViewCompositionalLayout {
return UICollectionViewCompositionalLayout { (section, env) -> NSCollectionLayoutSection? in
switch section {
case 0:
return self.configureImageSectionLayout()
case 1:
return self.configureItemInfoSectionLayout()
case 2:
return self.configureReleaseSectionLayout()
case 3:
return self.configureDeliverySectionLayout()
case 4:
return self.configureAdvertiseSectionLayout()
case 5:
return self.configurePriceChartSectionLayout()
default:
return self.configureSimilarItemSectionLayout()
}
}
}
private func configureImageSectionLayout() -> NSCollectionLayoutSection {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
heightDimension: .fractionalWidth(1))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
item.contentInsets.bottom = 15
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
heightDimension: .fractionalWidth(1))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
group.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0)
let section = NSCollectionLayoutSection(group: group)
section.orthogonalScrollingBehavior = .groupPaging
return section
}
private func configureItemInfoSectionLayout() -> NSCollectionLayoutSection {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
heightDimension: .fractionalWidth(0.52))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
item.contentInsets.bottom = 15
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
heightDimension: .fractionalWidth(0.52))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
group.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0)
let section = NSCollectionLayoutSection(group: group)
section.orthogonalScrollingBehavior = .groupPaging
return section
}
private func configureReleaseSectionLayout() -> NSCollectionLayoutSection {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.4),
heightDimension: .fractionalWidth(0.3))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
item.contentInsets.bottom = 15
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
heightDimension: .fractionalWidth(0.35))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
group.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0)
let section = NSCollectionLayoutSection(group: group)
section.orthogonalScrollingBehavior = .groupPaging
return section
}
private func configureDeliverySectionLayout() -> NSCollectionLayoutSection {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
heightDimension: .fractionalWidth(0.3))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
item.contentInsets.bottom = 0
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
heightDimension: .fractionalWidth(0.3))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
group.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0)
let section = NSCollectionLayoutSection(group: group)
section.orthogonalScrollingBehavior = .groupPaging
return section
}
private func configureAdvertiseSectionLayout() -> NSCollectionLayoutSection {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
heightDimension: .fractionalWidth(0.256))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
item.contentInsets.bottom = 0
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
heightDimension: .fractionalWidth(0.256))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
group.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0)
let section = NSCollectionLayoutSection(group: group)
section.orthogonalScrollingBehavior = .groupPaging
return section
}
private func configurePriceChartSectionLayout() -> NSCollectionLayoutSection {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
heightDimension: .fractionalWidth(1.2))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
item.contentInsets.bottom = 15
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
heightDimension: .fractionalWidth(1.2))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
group.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0)
let section = NSCollectionLayoutSection(group: group)
section.orthogonalScrollingBehavior = .groupPaging
return section
}
private func configureSimilarItemSectionLayout() -> NSCollectionLayoutSection {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.4),
heightDimension: .fractionalHeight(0.464))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
item.contentInsets = .init(top: 0, leading: 0, bottom: 5, trailing: 5)
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
heightDimension: .estimated(464))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
let section = NSCollectionLayoutSection(group: group)
section.orthogonalScrollingBehavior = .groupPaging
section.contentInsets = NSDirectionalEdgeInsets(top: 10, leading: 5, bottom: 20, trailing: 0)
section.boundarySupplementaryItems = [
NSCollectionLayoutBoundarySupplementaryItem(layoutSize: .init(widthDimension: .fractionalWidth(1),
heightDimension: .estimated(40)),
elementKind: UICollectionView.elementKindSectionHeader,
alignment: .topLeading)
]
return section
}
}
extension ItemView: ViewConfiguration {
func buildHierarchy() {
self.addSubviews(ItemInfoListView, containerStackView)
}
func setupConstraints() {
ItemInfoListView.snp.makeConstraints {
$0.top.leading.trailing.equalToSuperview()
$0.bottom.equalTo(self.containerStackView.snp.top)
}
containerStackView.snp.makeConstraints {
$0.leading.trailing.bottom.equalToSuperview()
}
}
func viewConfigure() {
collectionViewConfigure()
}
func collectionViewConfigure() {
ItemInfoListView.register(ItemInfoCell.self, forCellWithReuseIdentifier: ItemInfoCell.reuseIdentifier)
ItemInfoListView.register(ReleaseInfoCell.self, forCellWithReuseIdentifier: ReleaseInfoCell.reuseIdentifier)
ItemInfoListView.register(ShopBannerCell.self, forCellWithReuseIdentifier: ShopBannerCell.reuseIdentifier)
ItemInfoListView.register(HomeViewItemCell.self, forCellWithReuseIdentifier: HomeViewItemCell.reuseIdentifier)
}
}
```