Skip to content

Commit 29738f8

Browse files
zzangzzangguy0Hooni
authored andcommitted
refactor/#102: RegisterVC View와 PopUpImagesColletionView로 분리
1 parent c6f406e commit 29738f8

File tree

5 files changed

+888
-939
lines changed

5 files changed

+888
-939
lines changed

Poppool/Poppool.xcodeproj/project.pbxproj

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@
429429
4EDE57032D5E70650014D924 /* LocationPermissionBottomSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EDE57022D5E70650014D924 /* LocationPermissionBottomSheet.swift */; };
430430
4EE360FD2D91876300D2441D /* NMapsMap in Frameworks */ = {isa = PBXBuildFile; productRef = 4EE360FC2D91876300D2441D /* NMapsMap */; };
431431
4EE5A3D32D40E4A600A2469A /* MapGuideReactor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EE5A3D22D40E4A600A2469A /* MapGuideReactor.swift */; };
432+
4EEA13072DA7CDDA00775256 /* PopUpImagesCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EEA13062DA7CDDA00775256 /* PopUpImagesCollectionView.swift */; };
432433
4EEA1D8F2D352012003E7DE9 /* ImageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EEA1D8E2D352012003E7DE9 /* ImageCell.swift */; };
433434
4EEA1D912D352027003E7DE9 /* ExtendedImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EEA1D902D352027003E7DE9 /* ExtendedImage.swift */; };
434435
4EECA3942D56770B00A07CCA /* MapPopUpStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E685EBB2D12CEB6001EF91C /* MapPopUpStore.swift */; };
@@ -891,6 +892,7 @@
891892
4EDDEFB32D2D285900CFAFA5 /* DateTimePickerManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateTimePickerManager.swift; sourceTree = "<group>"; };
892893
4EDE57022D5E70650014D924 /* LocationPermissionBottomSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationPermissionBottomSheet.swift; sourceTree = "<group>"; };
893894
4EE5A3D22D40E4A600A2469A /* MapGuideReactor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapGuideReactor.swift; sourceTree = "<group>"; };
895+
4EEA13062DA7CDDA00775256 /* PopUpImagesCollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopUpImagesCollectionView.swift; sourceTree = "<group>"; };
894896
4EEA1D8E2D352012003E7DE9 /* ImageCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageCell.swift; sourceTree = "<group>"; };
895897
4EEA1D902D352027003E7DE9 /* ExtendedImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtendedImage.swift; sourceTree = "<group>"; };
896898
4EED9BAB2D22730400B288E7 /* FilterType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilterType.swift; sourceTree = "<group>"; };
@@ -2736,6 +2738,7 @@
27362738
4E9C12802D2BE0A6006744D6 /* PopUpStoreRegisterViewController.swift */,
27372739
4E643FC02D738D7F0046AF29 /* PopUpStoreRegisterReactor.swift */,
27382740
4E643FC22D738D930046AF29 /* PopUpStoreRegisterView.swift */,
2741+
4EEA13062DA7CDDA00775256 /* PopUpImagesCollectionView.swift */,
27392742
);
27402743
path = AdminRegister;
27412744
sourceTree = "<group>";
@@ -3165,6 +3168,7 @@
31653168
086DD9362D00963900B97D3B /* SearchTitleSection.swift in Sources */,
31663169
086F89D92D1E79E200CA4FC9 /* GetOtherUserCommentListRequestDTO.swift in Sources */,
31673170
083C864F2D0DD3A6003F441C /* AddCommentImageSection.swift in Sources */,
3171+
4EEA13072DA7CDDA00775256 /* PopUpImagesCollectionView.swift in Sources */,
31683172
08B191372CF366680057BC04 /* UICollectionViewCell+.swift in Sources */,
31693173
083A25B42CF362670099B58E /* Responsable.swift in Sources */,
31703174
08CBEA0D2D38ED0D00248007 /* CountButtonView.swift in Sources */,
@@ -3706,7 +3710,7 @@
37063710
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
37073711
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
37083712
CODE_SIGN_ENTITLEMENTS = Poppool/Poppool.entitlements;
3709-
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
3713+
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
37103714
CODE_SIGN_STYLE = Manual;
37113715
CURRENT_PROJECT_VERSION = 1;
37123716
DEVELOPMENT_TEAM = "";
@@ -3732,7 +3736,7 @@
37323736
PRODUCT_BUNDLE_IDENTIFIER = com.poppoolIOS.poppool;
37333737
PRODUCT_NAME = "$(TARGET_NAME)";
37343738
PROVISIONING_PROFILE_SPECIFIER = "";
3735-
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = PoppoolGitHubAction;
3739+
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = poppoolProvisioningProfile;
37363740
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
37373741
SUPPORTS_MACCATALYST = NO;
37383742
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
@@ -3751,7 +3755,7 @@
37513755
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
37523756
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
37533757
CODE_SIGN_ENTITLEMENTS = Poppool/Poppool.entitlements;
3754-
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
3758+
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
37553759
CODE_SIGN_STYLE = Manual;
37563760
CURRENT_PROJECT_VERSION = 1;
37573761
DEVELOPMENT_TEAM = "";
@@ -3777,7 +3781,7 @@
37773781
PRODUCT_BUNDLE_IDENTIFIER = com.poppoolIOS.poppool;
37783782
PRODUCT_NAME = "$(TARGET_NAME)";
37793783
PROVISIONING_PROFILE_SPECIFIER = "";
3780-
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = PoppoolGitHubAction;
3784+
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = poppoolProvisioningProfile;
37813785
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
37823786
SUPPORTS_MACCATALYST = NO;
37833787
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import UIKit
2+
3+
import SnapKit
4+
5+
final class PopUpImagesCollectionView: UICollectionView {
6+
// MARK: - Properties
7+
enum Constant {
8+
static let imageWidth: CGFloat = 80
9+
static let imageHeight: CGFloat = 120
10+
static let imageSpacing: CGFloat = 8
11+
}
12+
13+
var onImageSelected: ((Int) -> Void)?
14+
var onMainImageToggled: ((Int) -> Void)?
15+
var onImageDeleted: ((Int) -> Void)?
16+
17+
private var images: [ExtendedImage] = []
18+
19+
// MARK: - init
20+
init() {
21+
let layout = UICollectionViewFlowLayout()
22+
layout.scrollDirection = .horizontal
23+
layout.itemSize = CGSize(width: Constant.imageWidth, height: Constant.imageHeight)
24+
layout.minimumLineSpacing = Constant.imageSpacing
25+
26+
super.init(frame: .zero, collectionViewLayout: layout)
27+
28+
self.addViews()
29+
self.setupContstraints()
30+
self.configureUI()
31+
}
32+
33+
required init?(coder: NSCoder) {
34+
fatalError("\(#file), \(#function) Error")
35+
}
36+
}
37+
38+
// MARK: - Setup
39+
private extension PopUpImagesCollectionView {
40+
func addViews() { }
41+
42+
func setupContstraints() { }
43+
44+
func configureUI() {
45+
self.backgroundColor = .clear
46+
self.register(ImageCell.self, forCellWithReuseIdentifier: ImageCell.identifier)
47+
self.dataSource = self
48+
self.delegate = self
49+
self.showsHorizontalScrollIndicator = false
50+
}
51+
}
52+
53+
// MARK: - Public Methods
54+
extension PopUpImagesCollectionView {
55+
func updateImages(_ images: [ExtendedImage]) {
56+
self.images = images
57+
self.reloadData()
58+
}
59+
}
60+
61+
// MARK: - UICollectionViewDataSource
62+
extension PopUpImagesCollectionView: UICollectionViewDataSource {
63+
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
64+
return self.images.count
65+
}
66+
67+
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
68+
guard let cell = collectionView.dequeueReusableCell(
69+
withReuseIdentifier: ImageCell.identifier,
70+
for: indexPath
71+
) as? ImageCell else {
72+
return UICollectionViewCell()
73+
}
74+
75+
let item = self.images[indexPath.item]
76+
cell.configure(with: item)
77+
78+
// 대표이미지 변경
79+
cell.onMainCheckToggled = { [weak self] in
80+
self?.onMainImageToggled?(indexPath.item)
81+
}
82+
83+
// 개별 삭제
84+
cell.onDeleteTapped = { [weak self] in
85+
self?.onImageDeleted?(indexPath.item)
86+
}
87+
88+
return cell
89+
}
90+
}
91+
92+
// MARK: - UICollectionViewDelegate
93+
extension PopUpImagesCollectionView: UICollectionViewDelegate {
94+
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
95+
self.onImageSelected?(indexPath.item)
96+
}
97+
}

Poppool/Poppool/Presentation/Admin/AdminRegister/PopUpStoreRegisterReactor.swift

Lines changed: 76 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ final class PopUpStoreRegisterReactor: Reactor {
1515
private let isEditMode: Bool
1616
private let editingStoreId: Int64?
1717

18+
private var disposeBag = DisposeBag()
19+
20+
1821
init(adminUseCase: AdminUseCase, presignedService: PreSignedService, editingStore: GetAdminPopUpStoreListResponseDTO.PopUpStore? = nil) {
1922
self.adminUseCase = adminUseCase
2023
self.presignedService = presignedService
@@ -142,6 +145,8 @@ final class PopUpStoreRegisterReactor: Reactor {
142145
case let .updateName(name):
143146
return .just(.setName(name))
144147

148+
149+
145150
case let .updateAddress(address):
146151
return .just(.setAddress(address))
147152

@@ -396,39 +401,96 @@ final class PopUpStoreRegisterReactor: Reactor {
396401

397402
// 폼 유효성 검사
398403
private func validateForm(state: State) -> Bool {
399-
// 필수 필드 검사
400-
guard !state.name.isEmpty,
401-
!state.address.isEmpty,
402-
!state.lat.isEmpty,
403-
!state.lon.isEmpty,
404-
!state.description.isEmpty,
405-
!state.category.isEmpty,
406-
!state.images.isEmpty,
407-
state.images.contains(where: { $0.isMain }),
408-
state.selectedStartDate != nil,
409-
state.selectedEndDate != nil else {
404+
Logger.log(message: "폼 유효성 검사 시작", category: .debug)
405+
406+
// 이름 필드 검사
407+
guard !state.name.isEmpty else {
408+
Logger.log(message: "유효성 검사 실패: 이름 비어있음", category: .debug)
409+
return false
410+
}
411+
412+
// 주소 필드 검사
413+
guard !state.address.isEmpty else {
414+
Logger.log(message: "유효성 검사 실패: 주소 비어있음", category: .debug)
415+
return false
416+
}
417+
418+
// 위도/경도 필드 검사
419+
guard !state.lat.isEmpty else {
420+
Logger.log(message: "유효성 검사 실패: 위도 비어있음", category: .debug)
421+
return false
422+
}
423+
424+
guard !state.lon.isEmpty else {
425+
Logger.log(message: "유효성 검사 실패: 경도 비어있음", category: .debug)
426+
return false
427+
}
428+
429+
// 설명 필드 검사
430+
guard !state.description.isEmpty else {
431+
Logger.log(message: "유효성 검사 실패: 설명 비어있음", category: .debug)
432+
return false
433+
}
434+
435+
// 카테고리 필드 검사
436+
guard !state.category.isEmpty else {
437+
Logger.log(message: "유효성 검사 실패: 카테고리 비어있음", category: .debug)
438+
return false
439+
}
440+
441+
// 이미지 검사
442+
guard !state.images.isEmpty else {
443+
Logger.log(message: "유효성 검사 실패: 이미지 없음", category: .debug)
444+
return false
445+
}
446+
447+
// 대표 이미지 검사
448+
guard state.images.contains(where: { $0.isMain }) else {
449+
Logger.log(message: "유효성 검사 실패: 대표 이미지 없음", category: .debug)
450+
return false
451+
}
452+
453+
// 날짜 검사
454+
guard state.selectedStartDate != nil else {
455+
Logger.log(message: "유효성 검사 실패: 시작 날짜 없음", category: .debug)
456+
return false
457+
}
458+
459+
guard state.selectedEndDate != nil else {
460+
Logger.log(message: "유효성 검사 실패: 종료 날짜 없음", category: .debug)
410461
return false
411462
}
412463

413464
// 위도/경도 유효성 검사
414465
guard let latVal = Double(state.lat),
415-
let lonVal = Double(state.lon),
416-
latVal != 0 || lonVal != 0 else {
466+
let lonVal = Double(state.lon) else {
467+
Logger.log(message: "유효성 검사 실패: 위도/경도 형식 오류", category: .debug)
468+
return false
469+
}
470+
471+
// 위도/경도 값이 유효한지 검사
472+
guard latVal != 0 || lonVal != 0 else {
473+
Logger.log(message: "유효성 검사 실패: 위도/경도 값이 모두 0", category: .debug)
417474
return false
418475
}
419476

420477
// 날짜 순서 검사
421478
if let startDate = state.selectedStartDate,
422479
let endDate = state.selectedEndDate,
423480
startDate > endDate {
481+
Logger.log(message: "유효성 검사 실패: 시작일이 종료일보다 늦음", category: .debug)
424482
return false
425483
}
426484

485+
Logger.log(message: "유효성 검사 성공", category: .debug)
427486
return true
428487
}
429488

489+
430490
// 주소 지오코딩
431491
private func geocodeAddress(address: String) -> Observable<CLLocation?> {
492+
Logger.log(message: "지오코딩 함수 호출: \(address)", category: .debug)
493+
432494
return Observable.create { observer in
433495
let geocoder = CLGeocoder()
434496
let fullAddress = "\(address), Korea"
@@ -470,7 +532,7 @@ final class PopUpStoreRegisterReactor: Reactor {
470532
Logger.log(message: "S3에서 이미지 삭제 실패: \(error.localizedDescription)", category: .error)
471533
}
472534
)
473-
.disposed(by: DisposeBag())
535+
.disposed(by: disposeBag)
474536
}
475537

476538
// 카테고리 ID 매핑

0 commit comments

Comments
 (0)