From efaecd0c1267cc6f5ac89abf73d114335c51dcb6 Mon Sep 17 00:00:00 2001 From: Hanwe Lee Date: Tue, 14 Dec 2021 22:23:09 +0900 Subject: [PATCH 01/10] =?UTF-8?q?RedeMe=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ffec3d6..565547d 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,62 @@ -# Archive -"상자 속 가지런히 모아둔 티켓" 전시 관람 후 감정을 오래 기억하고 소장하세요:) +# Archive 🎨🖌 + +## 소개 + - "상자 속 가지런히 모아둔 티켓" 전시 관람 후 감정을 오래 기억하고 소장하세요:) + - [Archive Repository](https://github.com/depromeet/Archive_iOS) + - [Archive AppStore](https://apps.apple.com/kr/app/archive/id1599941822) + +## 컨트리뷰터 (가나다 순) +- 👨🏻‍💻[이한위](https://github.com/HanweeeeLee) ✉️: mobiledev@kakao.com +- 🧑‍💻[홍동현](https://github.com/TTOzzi) + +## 다른 플랫폼 + - [서버](https://github.com/depromeet/Archive_Backend) + +## 아키텍쳐 +> ReactorKit + +## 사용기술 + - 객체지향 프로그래밍 + - 프로토콜지향 프로그래밍 + - ReactorKit + - RxFlow + +## 의존성 +> 서드파티 프레임워크 및 라이브러리는 Swift Package Manager와 CocoaPods을 사용해 관리합니다. + + - [RxSwift](https://github.com/ReactiveX/RxSwift) + - [RxCocoa](https://github.com/ReactiveX/RxSwift) + - [RxDataSources](https://github.com/RxSwiftCommunity/RxDataSources) + - [ReactorKit](https://github.com/ReactorKit/ReactorKit) + - [SwiftLint](https://github.com/realm/SwiftLint) + - [SwiftGen](https://github.com/SwiftGen/SwiftGen) + - [Moya](https://github.com/Moya/Moya) + - [SwiftyJson](https://github.com/SwiftyJSON/SwiftyJSON) + - [Snapkit](https://github.com/SnapKit/SnapKit) + - [Kingfisher](https://github.com/onevcat/Kingfisher) + - [GrowingTextView](https://github.com/KennethTsang/GrowingTextView) + - [CropViewController](https://github.com/TimOliver/TOCropViewController) + - [UIImageColors](https://github.com/jathu/UIImageColors) + - [lottie-ios](https://github.com/airbnb/lottie-ios) + +## 코드 컨벤션 관리 + > 코드 컨벤션은 SwiftLint로 관리됩니다. + +## 협업 도구 + - Github + - Notion + - Figma + - Gather Town + +## 스크린샷 +![merge_from_ofoct](https://user-images.githubusercontent.com/60125719/146006348-806d7994-cd60-4cb9-955c-b05393c65602.jpg) + +## 릴리즈 + +[v 1.0.1](https://github.com/depromeet/Archive_iOS/releases/tag/1.0.1 ) + +## 라이센스 + +Archive is released under the MIT license. [See LICENSE](https://github.com/depromeet/Archive_iOS/blob/development/LICENSE) for details. + + From d107f13c69ada993433830818987ce3477b5d026 Mon Sep 17 00:00:00 2001 From: Hanwe Lee Date: Sat, 18 Dec 2021 21:25:06 +0900 Subject: [PATCH 02/10] RemadMe.md Update --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 565547d..cd19014 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ - [RxCocoa](https://github.com/ReactiveX/RxSwift) - [RxDataSources](https://github.com/RxSwiftCommunity/RxDataSources) - [ReactorKit](https://github.com/ReactorKit/ReactorKit) + - [RxFlow](https://github.com/RxSwiftCommunity/RxFlow) - [SwiftLint](https://github.com/realm/SwiftLint) - [SwiftGen](https://github.com/SwiftGen/SwiftGen) - [Moya](https://github.com/Moya/Moya) From 4a1ec9cddf5b1292c02cbc1a06f4d665ad69d558 Mon Sep 17 00:00:00 2001 From: Hanwe Lee Date: Thu, 23 Dec 2021 20:29:33 +0900 Subject: [PATCH 03/10] =?UTF-8?q?=EC=BD=94=EB=93=9C=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Archive.xcodeproj/project.pbxproj | 4 - Archive/Flows/AppFlow.swift | 16 --- Archive/Flows/OnboardingFlow.swift | 8 -- Archive/Flows/RecordFlow.swift | 143 ----------------------- Archive/Onboarding/Onboarding.storyboard | 4 +- 5 files changed, 2 insertions(+), 173 deletions(-) delete mode 100644 Archive/Flows/RecordFlow.swift diff --git a/Archive.xcodeproj/project.pbxproj b/Archive.xcodeproj/project.pbxproj index e750909..2039f50 100644 --- a/Archive.xcodeproj/project.pbxproj +++ b/Archive.xcodeproj/project.pbxproj @@ -99,7 +99,6 @@ 789E61992725550A00D6E18F /* RecordViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 789E61982725550A00D6E18F /* RecordViewController.swift */; }; 789E619B2725551400D6E18F /* RecordReactor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 789E619A2725551400D6E18F /* RecordReactor.swift */; }; 789E619D2725551C00D6E18F /* RecordModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 789E619C2725551C00D6E18F /* RecordModel.swift */; }; - 789E61A727255F8500D6E18F /* RecordFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 789E61A627255F8500D6E18F /* RecordFlow.swift */; }; 789E61B027257BCB00D6E18F /* ImageRecordReactor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 789E61AF27257BCB00D6E18F /* ImageRecordReactor.swift */; }; 789E61B227257BD400D6E18F /* ImageRecordModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 789E61B127257BD400D6E18F /* ImageRecordModel.swift */; }; 789E61B92725817900D6E18F /* NibIdentifiable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 789E61B82725817900D6E18F /* NibIdentifiable.swift */; }; @@ -241,7 +240,6 @@ 789E61982725550A00D6E18F /* RecordViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordViewController.swift; sourceTree = ""; }; 789E619A2725551400D6E18F /* RecordReactor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordReactor.swift; sourceTree = ""; }; 789E619C2725551C00D6E18F /* RecordModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordModel.swift; sourceTree = ""; }; - 789E61A627255F8500D6E18F /* RecordFlow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordFlow.swift; sourceTree = ""; }; 789E61AF27257BCB00D6E18F /* ImageRecordReactor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageRecordReactor.swift; sourceTree = ""; }; 789E61B127257BD400D6E18F /* ImageRecordModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageRecordModel.swift; sourceTree = ""; }; 789E61B82725817900D6E18F /* NibIdentifiable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NibIdentifiable.swift; sourceTree = ""; }; @@ -405,7 +403,6 @@ 44FB09FE271832AD006E1048 /* AppFlow.swift */, 44FB0A2827186E33006E1048 /* AppStepper.swift */, 44FB0A08271832E9006E1048 /* OnboardingFlow.swift */, - 789E61A627255F8500D6E18F /* RecordFlow.swift */, 78599DE4276379AE003FD959 /* HomeFlow.swift */, ); path = Flows; @@ -1108,7 +1105,6 @@ 44FB0A1727183C22006E1048 /* PasswordInputViewController.swift in Sources */, 783A61DF273BEB02004D848F /* InstagramStoryShareManager.swift in Sources */, 78A3217F275BBEB20078650D /* UIColorExtension.swift in Sources */, - 789E61A727255F8500D6E18F /* RecordFlow.swift in Sources */, 78BA1549272197250078B88E /* MyPageModel.swift in Sources */, 78C4B32D2724292D0006EBAD /* WithdrawalReactor.swift in Sources */, 780478242723E84900FAA1CF /* LoginInformationModel.swift in Sources */, diff --git a/Archive/Flows/AppFlow.swift b/Archive/Flows/AppFlow.swift index a0ecda4..b5ee9b0 100644 --- a/Archive/Flows/AppFlow.swift +++ b/Archive/Flows/AppFlow.swift @@ -36,8 +36,6 @@ final class AppFlow: Flow { switch step { case .onboardingIsRequired: return navigationToOnboardingScreen() - case .recordIsRequired: - return navigationToRecordScreen() case .homeIsRequired: return navigationToHomeScreen() case .onboardingIsComplete: @@ -62,20 +60,6 @@ final class AppFlow: Flow { allowStepWhenDismissed: false)) } - private func navigationToRecordScreen() -> FlowContributors { - let recordFlow = RecordFlow() - - Flows.use(recordFlow, when: .created) { [weak self] root in - DispatchQueue.main.async { - root.modalPresentationStyle = .fullScreen - self?.rootViewController.present(root, animated: false) - } - } - - return .one(flowContributor: .contribute(withNextPresentable: recordFlow, - withNextStepper: OneStepper(withSingleStep: ArchiveStep.recordIsRequired))) - } - private func navigationToHomeScreen() -> FlowContributors { let homeFlow = HomeFlow() diff --git a/Archive/Flows/OnboardingFlow.swift b/Archive/Flows/OnboardingFlow.swift index bfbf880..31789a4 100644 --- a/Archive/Flows/OnboardingFlow.swift +++ b/Archive/Flows/OnboardingFlow.swift @@ -95,18 +95,10 @@ final class OnboardingFlow: Flow { } private func navigationToSignUpCompletionScreen() -> FlowContributors { -// guard let = onboardingStoryBoard -// .instantiateViewController(identifier: .identifier) as? SignUpCompletionViewController else { -// return .none -// } -// rootViewController.pushViewController(signUpCompletionViewController, animated: true) -// return .one(flowContributor: .contribute(withNext: signUpCompletionViewController)) - let signUpCompletionViewController = onboardingStoryBoard .instantiateViewController(identifier: SignUpCompletionViewController.identifier) { coder in return SignUpCompletionViewController(coder: coder, reactor: self.signUpReactor) } -// signUpCompletionViewController.title = Constants.signUpNavigationTitle rootViewController.pushViewController(signUpCompletionViewController, animated: true) return .one(flowContributor: .contribute(withNextPresentable: signUpCompletionViewController, withNextStepper: signUpReactor)) diff --git a/Archive/Flows/RecordFlow.swift b/Archive/Flows/RecordFlow.swift deleted file mode 100644 index b224668..0000000 --- a/Archive/Flows/RecordFlow.swift +++ /dev/null @@ -1,143 +0,0 @@ -// -// RecordFlow.swift -// Archive -// -// Created by hanwe on 2021/10/24. -// - -import UIKit -import RxFlow - -class RecordFlow: Flow { - private enum Constants { - static let RecordStoryBoardName = "Record" - static let RecordNavigationTitle = "전시기록" - } - - var root: Presentable { - return rootViewController - } - - private lazy var rootViewController: UINavigationController = { - let viewController = UINavigationController() - return viewController - }() - - private let recordStoryBoard = UIStoryboard(name: Constants.RecordStoryBoardName, bundle: nil) - - weak var recordViewController: RecordViewController? - weak var editEmotionViewController: EmotionSelectViewController? - weak var imageSelectViewControllerNavi: UINavigationController? - - func navigate(to step: Step) -> FlowContributors { - guard let step = step as? ArchiveStep else { return .none } - switch step { - case .recordIsRequired: - return navigationToRecordScreen() - case .recordEmotionEditIsRequired(let emotion): - return navigationToEditEmotion(currentEmotion: emotion) - case .recordEmotionEditIsComplete(let emotion): - dismissEditEmotion(emotion: emotion) - return .none - case .recordImageSelectIsRequired(let emotion): - return navigationToImageSelect(emotion: emotion) - case .recordImageSelectIsComplete(let thumbnailImage, let images): - self.recordViewController?.reactor?.action.onNext(.setImages(images)) - self.recordViewController?.reactor?.action.onNext(.setThumbnailImage(thumbnailImage)) - dismissImageSelect() - return .none - case .recordUploadIsRequired(let contents, let thumbnail, let emotion, let imageInfos): - return navigationToRecordUpload(contents: contents, thumbnail: thumbnail, emotion: emotion, imageInfos: imageInfos) - case .recordUploadIsComplete(let thumbnail, let emotion, let contentsInfo): - rootViewController.dismiss(animated: false, completion: nil) - return navigationToRecordUploadComplete(thumbnail: thumbnail, emotion: emotion, conetentsInfo: contentsInfo) - case .recordComplete: - rootViewController.dismiss(animated: true, completion: { [weak self] in - self?.rootViewController.dismiss(animated: true, completion: nil) - }) - return .none - default: - return .none - } - } - - private func navigationToRecordScreen() -> FlowContributors { - let model: RecordModel = RecordModel() - let reactor = RecordReactor(model: model) - let recordViewController: RecordViewController = recordStoryBoard.instantiateViewController(identifier: RecordViewController.identifier) { corder in - return RecordViewController(coder: corder, reactor: reactor) - } - recordViewController.title = Constants.RecordNavigationTitle - self.recordViewController = recordViewController - rootViewController.pushViewController(recordViewController, animated: false) - return .one(flowContributor: .contribute(withNextPresentable: recordViewController, - withNextStepper: reactor)) - } - - private func navigationToEditEmotion(currentEmotion: Emotion?) -> FlowContributors { - let model: EmotionSelectModel = EmotionSelectModel() - let reactor = EmotionSelectReactor(model: model, currentEmotion: currentEmotion) - let emotionSelectViewController: EmotionSelectViewController = recordStoryBoard.instantiateViewController(identifier: EmotionSelectViewController.identifier) { corder in - return EmotionSelectViewController(coder: corder, reactor: reactor) - } - emotionSelectViewController.title = "" - emotionSelectViewController.modalPresentationStyle = .overFullScreen - self.editEmotionViewController = emotionSelectViewController - rootViewController.present(emotionSelectViewController, animated: false, completion: { - emotionSelectViewController.fadeInAnimation() - }) - return .one(flowContributor: .contribute(withNextPresentable: emotionSelectViewController, - withNextStepper: reactor)) - } - - private func dismissEditEmotion(emotion: Emotion) { - self.editEmotionViewController?.dismiss(animated: false, completion: nil) - self.recordViewController?.reactor?.action.onNext(.setEmotion(emotion)) - } - - private func navigationToImageSelect(emotion: Emotion) -> FlowContributors { - let model: ImageSelectModel = ImageSelectModel() - let reactor = ImageSelectReactor(model: model, emotion: emotion) - let imageSelectViewController: ImageSelectViewController = recordStoryBoard.instantiateViewController(identifier: ImageSelectViewController.identifier) { corder in - return ImageSelectViewController(coder: corder, reactor: reactor) - } - imageSelectViewController.title = "" - let navi: UINavigationController = UINavigationController(rootViewController: imageSelectViewController) - navi.modalPresentationStyle = .fullScreen - self.imageSelectViewControllerNavi = navi - rootViewController.present(navi, animated: true, completion: nil) - return .one(flowContributor: .contribute(withNextPresentable: imageSelectViewController, - withNextStepper: reactor)) - } - - private func dismissImageSelect() { - self.imageSelectViewControllerNavi?.dismiss(animated: true, completion: { - self.imageSelectViewControllerNavi?.viewControllers = [] - }) - } - - private func navigationToRecordUpload(contents: ContentsRecordModelData, thumbnail: UIImage, emotion: Emotion, imageInfos: [ImageInfo]?) -> FlowContributors { - let model: RecordUploadModel = RecordUploadModel(contents: contents, thumbnailImage: thumbnail, emotion: emotion, imageInfos: imageInfos) - let reactor = RecordUploadReactor(model: model) - let recordUploadViewController: RecordUploadViewController = recordStoryBoard.instantiateViewController(identifier: RecordUploadViewController.identifier) { corder in - return RecordUploadViewController(coder: corder, reactor: reactor) - } - recordUploadViewController.modalPresentationStyle = .fullScreen - rootViewController.present(recordUploadViewController, animated: true, completion: nil) - return .one(flowContributor: .contribute(withNextPresentable: recordUploadViewController, - withNextStepper: reactor)) - } - - private func navigationToRecordUploadComplete(thumbnail: UIImage, emotion: Emotion, conetentsInfo: ContentsRecordModelData) -> FlowContributors { - let model: RecordUploadCompleteModel = RecordUploadCompleteModel(thumbnail: thumbnail, emotion: emotion, contentsInfo: conetentsInfo) - let reactor = RecordUploadCompleteReactor(model: model) - let recordUploadCompleteViewController: RecordUploadCompleteViewController = recordStoryBoard.instantiateViewController(identifier: RecordUploadCompleteViewController.identifier) { corder in - return RecordUploadCompleteViewController(coder: corder, reactor: reactor) - } - recordUploadCompleteViewController.modalPresentationStyle = .fullScreen - rootViewController.present(recordUploadCompleteViewController, animated: false, completion: nil) - return .one(flowContributor: .contribute(withNextPresentable: recordUploadCompleteViewController, - withNextStepper: reactor)) - } - -} diff --git a/Archive/Onboarding/Onboarding.storyboard b/Archive/Onboarding/Onboarding.storyboard index 1cb1211..4661991 100644 --- a/Archive/Onboarding/Onboarding.storyboard +++ b/Archive/Onboarding/Onboarding.storyboard @@ -1,9 +1,9 @@ - + - + From 069603f0ee6570979c4aeef707a25a00c584044d Mon Sep 17 00:00:00 2001 From: Hanwe Lee Date: Thu, 23 Dec 2021 21:49:11 +0900 Subject: [PATCH 04/10] =?UTF-8?q?=EC=88=98=EC=A0=95=EC=82=AC=ED=95=AD=20?= =?UTF-8?q?=20-=20=EC=8A=A4=EC=9C=84=EC=B9=98=20=EC=83=89=EC=83=81=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20=20-=20pageControl=20=EB=94=94=ED=85=8C?= =?UTF-8?q?=EC=9D=BC/=EB=A0=88=EC=BD=94=EB=93=9C=20=EB=B2=84=EA=B7=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=20-=20=EB=A1=9C=EA=B7=B8=EC=95=84?= =?UTF-8?q?=EC=9B=83=20=EC=96=BC=EB=9F=BF=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Archive/Detail/DetailViewController.swift | 19 ++++++++++-- Archive/Home/HomeViewController.swift | 1 + Archive/MyPage/MyPage.storyboard | 14 ++++----- Archive/MyPage/MyPageViewController.swift | 2 +- .../LoginInformationViewController.swift | 11 +++++-- .../ImageRecordViewController.swift | 31 ++++++++++++++----- 6 files changed, 57 insertions(+), 21 deletions(-) diff --git a/Archive/Detail/DetailViewController.swift b/Archive/Detail/DetailViewController.swift index cc90dd4..cd17ab3 100644 --- a/Archive/Detail/DetailViewController.swift +++ b/Archive/Detail/DetailViewController.swift @@ -44,6 +44,7 @@ class DetailViewController: UIViewController, StoryboardView, ActivityIndicatora private let photoContentsView: DetailPhotoContentsView? = DetailPhotoContentsView.instance() private let modalShareViewController: ModalShareViewController = ModalShareViewController.init(nibName: "ModalShareViewController", bundle: nil) + private var willDisplayIndex: Int = 0 weak var delegate: DetailViewControllerDelegate? @@ -111,13 +112,25 @@ class DetailViewController: UIViewController, StoryboardView, ActivityIndicatora }) .disposed(by: self.disposeBag) - self.collectionView.rx.willDisplayCell + self.collectionView.rx.didEndDisplayingCell .asDriver() .drive(onNext: { [weak self] info in + var index: Int = 0 + if info.at.section != 0 { + index = info.at.item + 1 + } + if index != (self?.willDisplayIndex ?? 0) { + self?.pageControl.currentPage = self?.willDisplayIndex ?? 0 + } + }) + .disposed(by: self.disposeBag) + + self.collectionView.rx.willDisplayCell + .subscribe(onNext: { [weak self] info in if info.at.section == 0 { - self?.pageControl.currentPage = 0 + self?.willDisplayIndex = 0 } else { - self?.pageControl.currentPage = info.at.item + 1 + self?.willDisplayIndex = info.at.item + 1 } }) .disposed(by: self.disposeBag) diff --git a/Archive/Home/HomeViewController.swift b/Archive/Home/HomeViewController.swift index ac25790..de2a1ff 100644 --- a/Archive/Home/HomeViewController.swift +++ b/Archive/Home/HomeViewController.swift @@ -34,6 +34,7 @@ final class HomeViewController: UIViewController, StoryboardView, ActivityIndica // MARK: private property private let shimmerView: HomeShimmerView? = HomeShimmerView.instance() + private var willDisplayIndex: Int = 0 // MARK: internal property diff --git a/Archive/MyPage/MyPage.storyboard b/Archive/MyPage/MyPage.storyboard index 42bbdb3..08af35b 100644 --- a/Archive/MyPage/MyPage.storyboard +++ b/Archive/MyPage/MyPage.storyboard @@ -1,9 +1,9 @@ - + - + @@ -78,16 +78,16 @@