Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions Poppool/Poppool.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,7 @@
4EDE57032D5E70650014D924 /* LocationPermissionBottomSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EDE57022D5E70650014D924 /* LocationPermissionBottomSheet.swift */; };
4EE360FD2D91876300D2441D /* NMapsMap in Frameworks */ = {isa = PBXBuildFile; productRef = 4EE360FC2D91876300D2441D /* NMapsMap */; };
4EE5A3D32D40E4A600A2469A /* MapGuideReactor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EE5A3D22D40E4A600A2469A /* MapGuideReactor.swift */; };
4EEA13072DA7CDDA00775256 /* PopUpImagesCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EEA13062DA7CDDA00775256 /* PopUpImagesCollectionView.swift */; };
4EEA1D8F2D352012003E7DE9 /* ImageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EEA1D8E2D352012003E7DE9 /* ImageCell.swift */; };
4EEA1D912D352027003E7DE9 /* ExtendedImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EEA1D902D352027003E7DE9 /* ExtendedImage.swift */; };
4EECA3942D56770B00A07CCA /* MapPopUpStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E685EBB2D12CEB6001EF91C /* MapPopUpStore.swift */; };
Expand Down Expand Up @@ -891,6 +892,7 @@
4EDDEFB32D2D285900CFAFA5 /* DateTimePickerManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateTimePickerManager.swift; sourceTree = "<group>"; };
4EDE57022D5E70650014D924 /* LocationPermissionBottomSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationPermissionBottomSheet.swift; sourceTree = "<group>"; };
4EE5A3D22D40E4A600A2469A /* MapGuideReactor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapGuideReactor.swift; sourceTree = "<group>"; };
4EEA13062DA7CDDA00775256 /* PopUpImagesCollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopUpImagesCollectionView.swift; sourceTree = "<group>"; };
4EEA1D8E2D352012003E7DE9 /* ImageCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageCell.swift; sourceTree = "<group>"; };
4EEA1D902D352027003E7DE9 /* ExtendedImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtendedImage.swift; sourceTree = "<group>"; };
4EED9BAB2D22730400B288E7 /* FilterType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilterType.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2736,6 +2738,7 @@
4E9C12802D2BE0A6006744D6 /* PopUpStoreRegisterViewController.swift */,
4E643FC02D738D7F0046AF29 /* PopUpStoreRegisterReactor.swift */,
4E643FC22D738D930046AF29 /* PopUpStoreRegisterView.swift */,
4EEA13062DA7CDDA00775256 /* PopUpImagesCollectionView.swift */,
);
path = AdminRegister;
sourceTree = "<group>";
Expand Down Expand Up @@ -3165,6 +3168,7 @@
086DD9362D00963900B97D3B /* SearchTitleSection.swift in Sources */,
086F89D92D1E79E200CA4FC9 /* GetOtherUserCommentListRequestDTO.swift in Sources */,
083C864F2D0DD3A6003F441C /* AddCommentImageSection.swift in Sources */,
4EEA13072DA7CDDA00775256 /* PopUpImagesCollectionView.swift in Sources */,
08B191372CF366680057BC04 /* UICollectionViewCell+.swift in Sources */,
083A25B42CF362670099B58E /* Responsable.swift in Sources */,
08CBEA0D2D38ED0D00248007 /* CountButtonView.swift in Sources */,
Expand Down Expand Up @@ -3706,7 +3710,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = Poppool/Poppool.entitlements;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = "";
Expand All @@ -3732,7 +3736,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.poppoolIOS.poppool;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = PoppoolGitHubAction;
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = poppoolProvisioningProfile;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
Expand All @@ -3751,7 +3755,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = Poppool/Poppool.entitlements;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = "";
Expand All @@ -3777,7 +3781,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.poppoolIOS.poppool;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = PoppoolGitHubAction;
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = poppoolProvisioningProfile;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import UIKit

import SnapKit

final class PopUpImagesCollectionView: UICollectionView {
// MARK: - Properties
enum Constant {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저희가 맞추기로 하였던 상수값을 빼는 부분을 적용해 주셨군요 좋습니다 :>

static let imageWidth: CGFloat = 80
static let imageHeight: CGFloat = 120
static let imageSpacing: CGFloat = 8
}

var onImageSelected: ((Int) -> Void)?
var onMainImageToggled: ((Int) -> Void)?
var onImageDeleted: ((Int) -> Void)?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rx가 아니라 클로저로 스트림을 연결한 이유가 따로 있을까요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

단순이벤트라 판단되어 연산자체인에 오버헤드인지 .. 빌드에서 무한빌드가 되는케이스가 있었습니다
우선적으로 빌드확인을위해 빼뒀었지만 더나은 방법이 있다면 고려해보고 수정해도 좋을것 같습니다
매서운 리뷰 ..


private var images: [ExtendedImage] = []

// MARK: - init
init() {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.itemSize = CGSize(width: Constant.imageWidth, height: Constant.imageHeight)
layout.minimumLineSpacing = Constant.imageSpacing

super.init(frame: .zero, collectionViewLayout: layout)

self.addViews()
self.setupContstraints()
self.configureUI()
}

required init?(coder: NSCoder) {
fatalError("\(#file), \(#function) Error")
}
}

// MARK: - Setup
private extension PopUpImagesCollectionView {
func addViews() { }

func setupContstraints() { }

func configureUI() {
self.backgroundColor = .clear
self.register(ImageCell.self, forCellWithReuseIdentifier: ImageCell.identifier)
self.dataSource = self
self.delegate = self
self.showsHorizontalScrollIndicator = false
}
}

// MARK: - Public Methods
extension PopUpImagesCollectionView {
func updateImages(_ images: [ExtendedImage]) {
self.images = images
self.reloadData()
}
}

// MARK: - UICollectionViewDataSource
extension PopUpImagesCollectionView: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.images.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(
withReuseIdentifier: ImageCell.identifier,
for: indexPath
) as? ImageCell else {
return UICollectionViewCell()
}

let item = self.images[indexPath.item]
cell.configure(with: item)

// 대표이미지 변경
cell.onMainCheckToggled = { [weak self] in
self?.onMainImageToggled?(indexPath.item)
}

// 개별 삭제
cell.onDeleteTapped = { [weak self] in
self?.onImageDeleted?(indexPath.item)
}

return cell
}
}

// MARK: - UICollectionViewDelegate
extension PopUpImagesCollectionView: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.onImageSelected?(indexPath.item)
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

분리를 했는데도 많이 아직도 많네요 🥲

이번에 리팩토링때 클린아키텍처 구조로 더 분리를 해보죠 👍🏻

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

스트림이 길어지는 부분이 있어서 제가 내용을 정확히 확인하는 것에는 조금 난이도가 있습니다 ㅎㅎ. ㅠ 해당 작업 내용은 다시 한 번 확인해 보겠습니다!!

Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ final class PopUpStoreRegisterReactor: Reactor {
private let isEditMode: Bool
private let editingStoreId: Int64?

private var disposeBag = DisposeBag()


init(adminUseCase: AdminUseCase, presignedService: PreSignedService, editingStore: GetAdminPopUpStoreListResponseDTO.PopUpStore? = nil) {
self.adminUseCase = adminUseCase
self.presignedService = presignedService
Expand Down Expand Up @@ -142,6 +145,8 @@ final class PopUpStoreRegisterReactor: Reactor {
case let .updateName(name):
return .just(.setName(name))



case let .updateAddress(address):
return .just(.setAddress(address))

Expand Down Expand Up @@ -396,39 +401,96 @@ final class PopUpStoreRegisterReactor: Reactor {

// 폼 유효성 검사
private func validateForm(state: State) -> Bool {
// 필수 필드 검사
guard !state.name.isEmpty,
!state.address.isEmpty,
!state.lat.isEmpty,
!state.lon.isEmpty,
!state.description.isEmpty,
!state.category.isEmpty,
!state.images.isEmpty,
state.images.contains(where: { $0.isMain }),
state.selectedStartDate != nil,
state.selectedEndDate != nil else {
Logger.log(message: "폼 유효성 검사 시작", category: .debug)

// 이름 필드 검사
guard !state.name.isEmpty else {
Logger.log(message: "유효성 검사 실패: 이름 비어있음", category: .debug)
return false
}

// 주소 필드 검사
guard !state.address.isEmpty else {
Logger.log(message: "유효성 검사 실패: 주소 비어있음", category: .debug)
return false
}

// 위도/경도 필드 검사
guard !state.lat.isEmpty else {
Logger.log(message: "유효성 검사 실패: 위도 비어있음", category: .debug)
return false
}

guard !state.lon.isEmpty else {
Logger.log(message: "유효성 검사 실패: 경도 비어있음", category: .debug)
return false
}

// 설명 필드 검사
guard !state.description.isEmpty else {
Logger.log(message: "유효성 검사 실패: 설명 비어있음", category: .debug)
return false
}

// 카테고리 필드 검사
guard !state.category.isEmpty else {
Logger.log(message: "유효성 검사 실패: 카테고리 비어있음", category: .debug)
return false
}

// 이미지 검사
guard !state.images.isEmpty else {
Logger.log(message: "유효성 검사 실패: 이미지 없음", category: .debug)
return false
}

// 대표 이미지 검사
guard state.images.contains(where: { $0.isMain }) else {
Logger.log(message: "유효성 검사 실패: 대표 이미지 없음", category: .debug)
return false
}

// 날짜 검사
guard state.selectedStartDate != nil else {
Logger.log(message: "유효성 검사 실패: 시작 날짜 없음", category: .debug)
return false
}

guard state.selectedEndDate != nil else {
Logger.log(message: "유효성 검사 실패: 종료 날짜 없음", category: .debug)
return false
}

// 위도/경도 유효성 검사
guard let latVal = Double(state.lat),
let lonVal = Double(state.lon),
latVal != 0 || lonVal != 0 else {
let lonVal = Double(state.lon) else {
Logger.log(message: "유효성 검사 실패: 위도/경도 형식 오류", category: .debug)
return false
}

// 위도/경도 값이 유효한지 검사
guard latVal != 0 || lonVal != 0 else {
Logger.log(message: "유효성 검사 실패: 위도/경도 값이 모두 0", category: .debug)
return false
}

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

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


// 주소 지오코딩
private func geocodeAddress(address: String) -> Observable<CLLocation?> {
Logger.log(message: "지오코딩 함수 호출: \(address)", category: .debug)

return Observable.create { observer in
let geocoder = CLGeocoder()
let fullAddress = "\(address), Korea"
Expand Down Expand Up @@ -470,7 +532,7 @@ final class PopUpStoreRegisterReactor: Reactor {
Logger.log(message: "S3에서 이미지 삭제 실패: \(error.localizedDescription)", category: .error)
}
)
.disposed(by: DisposeBag())
.disposed(by: disposeBag)
}

// 카테고리 ID 매핑
Expand Down
Loading