From d932c532a4a688e9784b0f52c7f39dc94beccefd Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Thu, 8 Aug 2024 15:25:22 +0900 Subject: [PATCH 01/37] =?UTF-8?q?=EC=A7=80=EC=97=AD=ED=95=84=ED=84=B0?= =?UTF-8?q?=EB=A7=81=20UI=20=EC=9E=91=EC=97=85=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RegionCollectionViewCell.swift | 50 ++++++ .../RegionFilteringModalViewController.swift | 153 ++++++++++++++++++ .../RegionFilteringModalViewModel.swift | 54 +++++++ .../Utils/Extension/UIcolor+.swift | 4 + .../Contents.json | 23 +++ .../arrow-right-placeholder.png | Bin 0 -> 249 bytes .../arrow-right-placeholder@2x.png | Bin 0 -> 397 bytes .../arrow-right-placeholder@3x.png | Bin 0 -> 431 bytes .../Contents.json | 23 +++ .../arrow-right-primary.png | Bin 0 -> 183 bytes .../arrow-right-primary@2x.png | Bin 0 -> 246 bytes .../arrow-right-primary@3x.png | Bin 0 -> 258 bytes 12 files changed, 307 insertions(+) create mode 100644 StreetDrop/StreetDrop/Presentation/MyPage/View/FilterModal/RegionCollectionViewCell.swift create mode 100644 StreetDrop/StreetDrop/Presentation/MyPage/ViewModel/RegionFilteringModalViewModel.swift create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/arrow-right-placeholder.imageset/Contents.json create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/arrow-right-placeholder.imageset/arrow-right-placeholder.png create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/arrow-right-placeholder.imageset/arrow-right-placeholder@2x.png create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/arrow-right-placeholder.imageset/arrow-right-placeholder@3x.png create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/arrow-right-primary.imageset/Contents.json create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/arrow-right-primary.imageset/arrow-right-primary.png create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/arrow-right-primary.imageset/arrow-right-primary@2x.png create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/arrow-right-primary.imageset/arrow-right-primary@3x.png diff --git a/StreetDrop/StreetDrop/Presentation/MyPage/View/FilterModal/RegionCollectionViewCell.swift b/StreetDrop/StreetDrop/Presentation/MyPage/View/FilterModal/RegionCollectionViewCell.swift new file mode 100644 index 00000000..8e0d7819 --- /dev/null +++ b/StreetDrop/StreetDrop/Presentation/MyPage/View/FilterModal/RegionCollectionViewCell.swift @@ -0,0 +1,50 @@ +// +// RegionCollectionViewCell.swift +// StreetDrop +// +// Created by 차요셉 on 8/5/24. +// + +import UIKit + +import SnapKit + +final class RegionCollectionViewCell: UICollectionViewCell { + override init(frame: CGRect) { + super.init(frame: frame) + configureUI() + } + + @available(*, unavailable) + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implement") + } + + private lazy var regionNameLabel: UILabel = { + let label: UILabel = .init() + label.font = .pretendard(size: 16, weightName: .medium) + label.setLineHeight(lineHeight: 24) + label.textColor = .gray200 + label.numberOfLines = 1 + label.textAlignment = .center + + return label + }() + + func configure(regionName: String) { + regionNameLabel.text = regionName + } +} + +private extension RegionCollectionViewCell { + func configureUI() { + self.backgroundColor = .gray600 + + addSubview(regionNameLabel) + + regionNameLabel.snp.makeConstraints { + $0.centerY.equalToSuperview() + $0.horizontalEdges.equalToSuperview() + } + } +} diff --git a/StreetDrop/StreetDrop/Presentation/MyPage/View/FilterModal/RegionFilteringModalViewController.swift b/StreetDrop/StreetDrop/Presentation/MyPage/View/FilterModal/RegionFilteringModalViewController.swift index 5c978053..49f13a8f 100644 --- a/StreetDrop/StreetDrop/Presentation/MyPage/View/FilterModal/RegionFilteringModalViewController.swift +++ b/StreetDrop/StreetDrop/Presentation/MyPage/View/FilterModal/RegionFilteringModalViewController.swift @@ -9,11 +9,14 @@ import UIKit import SnapKit import RxSwift +import RxRelay final class RegionFilteringModalViewController: UIViewController, ModalPresentable { var upperMarginHeight: CGFloat = 158 var containerViewTopConstraint: Constraint? let disposeBag: DisposeBag = .init() + private let viewModel: RegionFilteringModalViewModel = .init() + private var dataSource: UICollectionViewDiffableDataSource! let modalContainerView: UIView = { let view: UIView = .init() @@ -22,15 +25,165 @@ final class RegionFilteringModalViewController: UIViewController, ModalPresentab return view }() + private let filterLabel: UILabel = { + let label: UILabel = .init() + label.text = "필터" + label.textColor = .textPrimary + label.font = .pretendard(size: 28, weight: 700) + label.setLineHeight(lineHeight: 28) + + return label + }() + + private let cityLabel: UILabel = { + let label: UILabel = .init() + label.text = "전체 지역" + label.textColor = .textPrimary + label.font = .pretendard(size: 14, weight: 400) + label.setLineHeight(lineHeight: 20) + + return label + }() + + private let arrowImageView: UIImageView = { + let imageView: UIImageView = .init(image: .init(named: "arrow-right-primary")) + + return imageView + }() + + private let districtLabel: UILabel = { + let label: UILabel = .init() + label.text = "시/군/구" + label.textColor = .textPrimary + label.font = .pretendard(size: 14, weight: 400) + label.setLineHeight(lineHeight: 20) + + return label + }() + + private lazy var collectionView: UICollectionView = { + let collectionView = UICollectionView( + frame: .zero, + collectionViewLayout: createLayout() + ) + collectionView.backgroundColor = .clear + collectionView.delegate = self + + return collectionView + }() + override func viewDidLoad() { super.viewDidLoad() setupModal() + configureDataSource() + bindViewModel() configureUI() } } private extension RegionFilteringModalViewController { + func bindViewModel() { + let input: RegionFilteringModalViewModel.Input = .init( + viewDidLoadEvent: .just(Void()) + ) + + let output = viewModel.convert(input: input, disposedBag: disposeBag) + + output.cityNames + .bind(with: self) { owner, cityNames in + owner.displayCityNames(cityNames) + } + .disposed(by: disposeBag) + } + func configureUI() { + [ + filterLabel, + cityLabel, + arrowImageView, + districtLabel, + collectionView + ].forEach { + modalContainerView.addSubview($0) + } + + filterLabel.snp.makeConstraints { + $0.height.equalTo(28) + $0.top.horizontalEdges.equalToSuperview().inset(24) + } + + cityLabel.snp.makeConstraints { + $0.height.equalTo(20) + $0.top.equalTo(filterLabel.snp.bottom).offset(12) + $0.leading.equalToSuperview().inset(24) + } + + arrowImageView.snp.makeConstraints { + $0.width.height.equalTo(20) + $0.centerY.equalTo(cityLabel) + $0.leading.equalTo(cityLabel.snp.trailing) + } + + districtLabel.snp.makeConstraints { + $0.height.equalTo(28) + $0.centerY.equalTo(cityLabel) + $0.leading.equalTo(arrowImageView.snp.trailing) + } + + collectionView.snp.makeConstraints { + $0.top.equalTo(cityLabel.snp.bottom).offset(20) + $0.horizontalEdges.equalToSuperview().inset(18) + $0.bottom.equalToSuperview() + } + } + + func displayCityNames(_ cityNames: [String]) { + var snapshot = NSDiffableDataSourceSnapshot() + snapshot.appendSections([0]) + snapshot.appendItems(cityNames, toSection: 0) + dataSource.apply(snapshot, animatingDifferences: true) + } +} + +// MARK: - Collection View + +extension RegionFilteringModalViewController: UICollectionViewDelegate { + private func createLayout() -> UICollectionViewLayout { + UICollectionViewCompositionalLayout { sectionIndex, layoutEnvironment in + let itemSize = NSCollectionLayoutSize( + widthDimension: .fractionalWidth(1.0 / 3.0), + heightDimension: .fractionalHeight(1.0) + ) + let item = NSCollectionLayoutItem(layoutSize: itemSize) + item.contentInsets = .init(top: 0, leading: 6, bottom: 0, trailing: 6) + + let groupSize = NSCollectionLayoutSize( + widthDimension: .fractionalWidth(1.0), + heightDimension: .estimated(48) + ) + let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item]) + + let section = NSCollectionLayoutSection(group: group) + section.interGroupSpacing = 12 + + return section + } + } + + private func configureDataSource() { + typealias CellRegistration = UICollectionView.CellRegistration + let cellRegistration = CellRegistration { cell, indexPath, item in + cell.configure(regionName: item) + } + dataSource = UICollectionViewDiffableDataSource( + collectionView: collectionView + ) { collectionView, indexPath, item -> UICollectionViewCell? in + collectionView.dequeueConfiguredReusableCell( + using: cellRegistration, + for: indexPath, + item: item + ) + } } } diff --git a/StreetDrop/StreetDrop/Presentation/MyPage/ViewModel/RegionFilteringModalViewModel.swift b/StreetDrop/StreetDrop/Presentation/MyPage/ViewModel/RegionFilteringModalViewModel.swift new file mode 100644 index 00000000..c8e12fc8 --- /dev/null +++ b/StreetDrop/StreetDrop/Presentation/MyPage/ViewModel/RegionFilteringModalViewModel.swift @@ -0,0 +1,54 @@ +// +// RegionFilteringModalViewModel.swift +// StreetDrop +// +// Created by 차요셉 on 7/31/24. +// + +import Foundation + +import RxSwift +import RxRelay +import OrderedCollections + +final class RegionFilteringModalViewModel: ViewModel { + private let output: Output = .init() + private let fetchingCityAndDistrictsUseCase: FetchingCityAndDistrictsUseCase + private var cityAndDistricts: OrderedDictionary = [:] + + init(fetchingCityAndDistrictsUseCase: FetchingCityAndDistrictsUseCase = DefaultFetchingCityAndDistrictsUseCase()) { + self.fetchingCityAndDistrictsUseCase = fetchingCityAndDistrictsUseCase + do { + cityAndDistricts = try fetchingCityAndDistrictsUseCase.execute() + } catch { + output.errorAlertShowRelay.accept(error.localizedDescription) + } + } + + struct Input { + let viewDidLoadEvent: Observable + } + + struct Output { + fileprivate let errorAlertShowRelay: PublishRelay = .init() + var errorAlertShow: Observable { + errorAlertShowRelay.asObservable() + } + + fileprivate let cityNamesRelay: BehaviorRelay<[String]> = .init(value: []) + var cityNames: Observable<[String]> { + cityNamesRelay.asObservable() + } + } + + func convert(input: Input, disposedBag: DisposeBag) -> Output { + input.viewDidLoadEvent + .bind(with: self) { owner, _ in + let cityNames = owner.cityAndDistricts.keys.map { String($0) } + owner.output.cityNamesRelay.accept(cityNames) + } + .disposed(by: disposedBag) + + return output + } +} diff --git a/StreetDrop/StreetDrop/Presentation/Utils/Extension/UIcolor+.swift b/StreetDrop/StreetDrop/Presentation/Utils/Extension/UIcolor+.swift index 444a7f3c..a9fbdf07 100644 --- a/StreetDrop/StreetDrop/Presentation/Utils/Extension/UIcolor+.swift +++ b/StreetDrop/StreetDrop/Presentation/Utils/Extension/UIcolor+.swift @@ -104,6 +104,10 @@ public extension UIColor { static var primaryGradation_3: UIColor { UIColor(hexString: "#68EFF7") } + + static var textPrimary: UIColor { + UIColor(hexString: "#FFFFFF") + } static var pointGradation_1: UIColor { UIColor(hexString: "#98F9FF") diff --git a/StreetDrop/StreetDrop/Resource/Assets.xcassets/arrow-right-placeholder.imageset/Contents.json b/StreetDrop/StreetDrop/Resource/Assets.xcassets/arrow-right-placeholder.imageset/Contents.json new file mode 100644 index 00000000..11823c76 --- /dev/null +++ b/StreetDrop/StreetDrop/Resource/Assets.xcassets/arrow-right-placeholder.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "arrow-right-placeholder.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "arrow-right-placeholder@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "arrow-right-placeholder@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/StreetDrop/StreetDrop/Resource/Assets.xcassets/arrow-right-placeholder.imageset/arrow-right-placeholder.png b/StreetDrop/StreetDrop/Resource/Assets.xcassets/arrow-right-placeholder.imageset/arrow-right-placeholder.png new file mode 100644 index 0000000000000000000000000000000000000000..610bdb062aaa00fc93d4a7d55bc84e5259a1e849 GIT binary patch literal 249 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VXMsm#F#`j)FbFd;%$g$s6l5$8 za(7}_cTVOdki(Mh=`}X{Et&O|AH_xoD3!0w&ZpPiatdkXQyuTl6 z!MrBhekS`p&JU9obv_ZWw_WpsQ{vX4|BD=Xwb+)fXf%2xYM@-^G%xSzOQvJ%zL;@M rNm2@EmTijavHqj!lCk8*UCZ2etAjs?Z@Om=bQy!EtDnm{r-UW|E}L1} literal 0 HcmV?d00001 diff --git a/StreetDrop/StreetDrop/Resource/Assets.xcassets/arrow-right-placeholder.imageset/arrow-right-placeholder@2x.png b/StreetDrop/StreetDrop/Resource/Assets.xcassets/arrow-right-placeholder.imageset/arrow-right-placeholder@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..0fd42f3e29317dd8b9e6dfcedb66c5a8bf4af22c GIT binary patch literal 397 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU1|)m_?Z^dEoCO|{#S9E$svykh8Km+7D9BhG z^b&`*?msgL^`g#-a|5 zlWd;zUGyBhDy3U;9A+v71*J6lFf8R}>EM)TY~y>qqr8caGxB|{==NK`o3HY0|6jZAZ59k&;4!f{ZHZNYfwC_XtM(_KDiA+hw~d+`L&m^p4p6 ztMlES(J7Q6I{kjT;prVV%x!BPf0B_%Jn}Ts;6T^u&kK(9oHkylkUnV(&-1&Dg6cl! pRMuDs>n}D)k+Ys#{O+18qrj?d8JDZxr~^Zf!PC{xWt~$(696!ook{=z literal 0 HcmV?d00001 diff --git a/StreetDrop/StreetDrop/Resource/Assets.xcassets/arrow-right-placeholder.imageset/arrow-right-placeholder@3x.png b/StreetDrop/StreetDrop/Resource/Assets.xcassets/arrow-right-placeholder.imageset/arrow-right-placeholder@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..ec38b16070ef7cebcb4048a2ae99acab6ae5d1f8 GIT binary patch literal 431 zcmeAS@N?(olHy`uVBq!ia0vp^HXzKw1|+Ti+$;i8oCO|{#S9FJ79h;%I?XTvD9BhG z7}FuNs)@H-fMU!pC<7$mT>dijgLvsCnIep>%ix@jgX2m+P|Hn^B?FJJvO zNm|~hmM40@jolvUn=@5^#k@HguP46w>d&P0*XtO1bWCqJKcCwl-2URqgSQ*1v&H7_ zYGW+y__F=-xo0=|kBKJxE@yXM{$f(X3!zvs9@$0S&5g3Lay(};ybLxh$~<_WV;P%s zsfn$G*5YUu=g^Yb2`f7M_E!ARc2PXHFTNn>jYkyg;iLSwkKOov^#9V(f;);gt(VrG zJ^N4fdYMY@wGZnz)^*v>zcoKBH0RCq)kbFD&IZd$|9+lu6#u?l*sk7*fIb_VPwS1_7SdhvjMpO};l<&YnqV z>acEgQ(idn{kyIImvSboQ(APO`@$i^^Q-sp=zjLYx%i!ti=d#Wzp$P!BH9Z3W literal 0 HcmV?d00001 diff --git a/StreetDrop/StreetDrop/Resource/Assets.xcassets/arrow-right-primary.imageset/arrow-right-primary@2x.png b/StreetDrop/StreetDrop/Resource/Assets.xcassets/arrow-right-primary.imageset/arrow-right-primary@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..61a5991eaa7a63b6a742891bd49746ac12758bf0 GIT binary patch literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU1|)m_?Z^dEoCO|{#S9E$svykh8Km+7D9BhG z>~{wa$7wWPW@K6@YugfLzRhvK{QP+wW`bGkdeIE%to1#CB=Dp6Ex!{Y6)%q zbToIeR>zhm5ABXEpN^hz($9>ar2eCGew Date: Mon, 12 Aug 2024 14:45:22 +0900 Subject: [PATCH 02/37] =?UTF-8?q?=E2=9C=A8#297:=20Share=20Extension=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- StreetDrop/ShareExtension/Info.plist | 18 ++ .../View/Base.lproj/MainInterface.storyboard | 24 +++ .../View/ShareViewController.swift | 26 +++ .../ViewModel/ShareViewModel.swift | 49 +++++ .../StreetDrop.xcodeproj/project.pbxproj | 193 +++++++++++++++++- 5 files changed, 309 insertions(+), 1 deletion(-) create mode 100644 StreetDrop/ShareExtension/Info.plist create mode 100644 StreetDrop/ShareExtension/View/Base.lproj/MainInterface.storyboard create mode 100644 StreetDrop/ShareExtension/View/ShareViewController.swift create mode 100644 StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift diff --git a/StreetDrop/ShareExtension/Info.plist b/StreetDrop/ShareExtension/Info.plist new file mode 100644 index 00000000..4b1f7e70 --- /dev/null +++ b/StreetDrop/ShareExtension/Info.plist @@ -0,0 +1,18 @@ + + + + + NSExtension + + NSExtensionAttributes + + NSExtensionActivationRule + TRUEPREDICATE + + NSExtensionMainStoryboard + MainInterface + NSExtensionPointIdentifier + com.apple.share-services + + + diff --git a/StreetDrop/ShareExtension/View/Base.lproj/MainInterface.storyboard b/StreetDrop/ShareExtension/View/Base.lproj/MainInterface.storyboard new file mode 100644 index 00000000..286a5089 --- /dev/null +++ b/StreetDrop/ShareExtension/View/Base.lproj/MainInterface.storyboard @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/StreetDrop/ShareExtension/View/ShareViewController.swift b/StreetDrop/ShareExtension/View/ShareViewController.swift new file mode 100644 index 00000000..f5431df4 --- /dev/null +++ b/StreetDrop/ShareExtension/View/ShareViewController.swift @@ -0,0 +1,26 @@ +// +// ShareViewController.swift +// ShareExtension +// +// Created by 차요셉 on 8/12/24. +// + +import UIKit +import Social + +final class ShareViewController: SLComposeServiceViewController { + + + override func isContentValid() -> Bool { + return true + } + + override func didSelectPost() { + extensionContext?.completeRequest(returningItems: [], completionHandler: nil) + } + + override func configurationItems() -> [Any]! { + return [] + } + +} diff --git a/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift b/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift new file mode 100644 index 00000000..f574040d --- /dev/null +++ b/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift @@ -0,0 +1,49 @@ +// +// ShareViewModel.swift +// ShareExtension +// +// Created by 차요셉 on 8/12/24. +// + +import CoreLocation +import Foundation + +import RxSwift +import RxRelay + +protocol ShareViewModelType { + associatedtype Input + associatedtype Output + + func convert(input: Input, disposedBag: DisposeBag) -> Output +} + +final class ShareViewModel: NSObject, ShareViewModelType { + private let output: Output = .init() + private let locationManger: CLLocationManager = .init() + + struct Input { + let viewDidLoadEvent: Observable + } + + struct Output { + + } + + func convert(input: Input, disposedBag: DisposeBag) -> Output { + input.viewDidLoadEvent + .subscribe(with: self) { owner, _ in + owner.locationManger.delegate = self + owner.locationManger.requestWhenInUseAuthorization() + owner.locationManger.startUpdatingLocation() + } + .disposed(by: disposedBag) + + + return output + } +} + +extension ShareViewModel: CLLocationManagerDelegate { + +} diff --git a/StreetDrop/StreetDrop.xcodeproj/project.pbxproj b/StreetDrop/StreetDrop.xcodeproj/project.pbxproj index 923dc07c..c270ae39 100644 --- a/StreetDrop/StreetDrop.xcodeproj/project.pbxproj +++ b/StreetDrop/StreetDrop.xcodeproj/project.pbxproj @@ -191,6 +191,10 @@ C41BD2E92A38467A0090EF2B /* UIImageView+ImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41BD2E82A38467A0090EF2B /* UIImageView+ImageCache.swift */; }; C41BD2EC2A3848880090EF2B /* UIImage+loadURLImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41BD2EB2A3848880090EF2B /* UIImage+loadURLImage.swift */; }; C41BD2ED2A3848880090EF2B /* UIImage+loadURLImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41BD2EB2A3848880090EF2B /* UIImage+loadURLImage.swift */; }; + C42182BD2C697F9700B73A99 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42182BC2C697F9700B73A99 /* ShareViewController.swift */; }; + C42182C02C697F9700B73A99 /* Base in Resources */ = {isa = PBXBuildFile; fileRef = C42182BF2C697F9700B73A99 /* Base */; }; + C42182C42C697F9700B73A99 /* ShareExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = C42182BA2C697F9700B73A99 /* ShareExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + C42182CC2C69C41800B73A99 /* ShareViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42182CB2C69C41800B73A99 /* ShareViewModel.swift */; }; C42361782B0CE8F800F61E3C /* RecommendMusic.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42361772B0CE8F800F61E3C /* RecommendMusic.swift */; }; C434A4CA2A1796E400C63526 /* SearchingMusicViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C434A4C92A1796E400C63526 /* SearchingMusicViewController.swift */; }; C434A4CC2A1796F300C63526 /* SearchingMusicViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C434A4CB2A1796F300C63526 /* SearchingMusicViewModel.swift */; }; @@ -325,9 +329,27 @@ remoteGlobalIDString = 040684FB2A01539800377094; remoteInfo = StreetDrop; }; + C42182C22C697F9700B73A99 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 040684F42A01539800377094 /* Project object */; + proxyType = 1; + remoteGlobalIDString = C42182B92C697F9700B73A99; + remoteInfo = ShareExtension; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ + C42182C52C697F9700B73A99 /* Embed Foundation Extensions */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 13; + files = ( + C42182C42C697F9700B73A99 /* ShareExtension.appex in Embed Foundation Extensions */, + ); + name = "Embed Foundation Extensions"; + runOnlyForDeploymentPostprocessing = 0; + }; C49BA7862A1BE72900A83E95 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -501,6 +523,11 @@ C41972562ABED40100211222 /* DefaultFetchingMyInfoUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultFetchingMyInfoUseCase.swift; sourceTree = ""; }; C41BD2E82A38467A0090EF2B /* UIImageView+ImageCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImageView+ImageCache.swift"; sourceTree = ""; }; C41BD2EB2A3848880090EF2B /* UIImage+loadURLImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+loadURLImage.swift"; sourceTree = ""; }; + C42182BA2C697F9700B73A99 /* ShareExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = ShareExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + C42182BC2C697F9700B73A99 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = ""; }; + C42182BF2C697F9700B73A99 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = ""; }; + C42182C12C697F9700B73A99 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + C42182CB2C69C41800B73A99 /* ShareViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewModel.swift; sourceTree = ""; }; C42361772B0CE8F800F61E3C /* RecommendMusic.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecommendMusic.swift; sourceTree = ""; }; C434A4C92A1796E400C63526 /* SearchingMusicViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchingMusicViewController.swift; sourceTree = ""; }; C434A4CB2A1796F300C63526 /* SearchingMusicViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchingMusicViewModel.swift; sourceTree = ""; }; @@ -636,6 +663,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + C42182B72C697F9700B73A99 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -644,6 +678,7 @@ children = ( 040684FE2A01539800377094 /* StreetDrop */, 41FF58FA2A06B38800ABB871 /* NetworkManagerTest */, + C42182BB2C697F9700B73A99 /* ShareExtension */, 040684FD2A01539800377094 /* Products */, DD24191EB8D98350CCDA3174 /* Pods */, 9AF428BDAA5509AEF1F4FB64 /* Frameworks */, @@ -655,6 +690,7 @@ children = ( 040684FC2A01539800377094 /* StreetDrop.app */, 41FF58F92A06B38800ABB871 /* NetworkManagerTest.xctest */, + C42182BA2C697F9700B73A99 /* ShareExtension.appex */, ); name = Products; sourceTree = ""; @@ -1510,6 +1546,33 @@ path = MyInfo; sourceTree = ""; }; + C42182BB2C697F9700B73A99 /* ShareExtension */ = { + isa = PBXGroup; + children = ( + C42182C12C697F9700B73A99 /* Info.plist */, + C42182C92C69C3FD00B73A99 /* View */, + C42182CA2C69C40300B73A99 /* ViewModel */, + ); + path = ShareExtension; + sourceTree = ""; + }; + C42182C92C69C3FD00B73A99 /* View */ = { + isa = PBXGroup; + children = ( + C42182BC2C697F9700B73A99 /* ShareViewController.swift */, + C42182BE2C697F9700B73A99 /* MainInterface.storyboard */, + ); + path = View; + sourceTree = ""; + }; + C42182CA2C69C40300B73A99 /* ViewModel */ = { + isa = PBXGroup; + children = ( + C42182CB2C69C41800B73A99 /* ShareViewModel.swift */, + ); + path = ViewModel; + sourceTree = ""; + }; C434A4C52A17962700C63526 /* SearchingMusicScene */ = { isa = PBXGroup; children = ( @@ -1931,10 +1994,12 @@ D7AAC29D93F6B0DD182BBCE1 /* [CP] Embed Pods Frameworks */, C4E25A8D2A57DD1E00E6A236 /* Firebase plist */, 086B01C72ADFFFCC00A6F1F2 /* Crashlytics */, + C42182C52C697F9700B73A99 /* Embed Foundation Extensions */, ); buildRules = ( ); dependencies = ( + C42182C32C697F9700B73A99 /* PBXTargetDependency */, ); name = StreetDrop; packageProductDependencies = ( @@ -1985,6 +2050,23 @@ productReference = 41FF58F92A06B38800ABB871 /* NetworkManagerTest.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + C42182B92C697F9700B73A99 /* ShareExtension */ = { + isa = PBXNativeTarget; + buildConfigurationList = C42182C82C697F9700B73A99 /* Build configuration list for PBXNativeTarget "ShareExtension" */; + buildPhases = ( + C42182B62C697F9700B73A99 /* Sources */, + C42182B72C697F9700B73A99 /* Frameworks */, + C42182B82C697F9700B73A99 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ShareExtension; + productName = ShareExtension; + productReference = C42182BA2C697F9700B73A99 /* ShareExtension.appex */; + productType = "com.apple.product-type.app-extension"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -1992,7 +2074,7 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = 1; - LastSwiftUpdateCheck = 1420; + LastSwiftUpdateCheck = 1540; LastUpgradeCheck = 1420; TargetAttributes = { 040684FB2A01539800377094 = { @@ -2002,6 +2084,9 @@ CreatedOnToolsVersion = 14.2; TestTargetID = 040684FB2A01539800377094; }; + C42182B92C697F9700B73A99 = { + CreatedOnToolsVersion = 15.4; + }; }; }; buildConfigurationList = 040684F72A01539800377094 /* Build configuration list for PBXProject "StreetDrop" */; @@ -2029,6 +2114,7 @@ targets = ( 040684FB2A01539800377094 /* StreetDrop */, 41FF58F82A06B38700ABB871 /* NetworkManagerTest */, + C42182B92C697F9700B73A99 /* ShareExtension */, ); }; /* End PBXProject section */ @@ -2064,6 +2150,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + C42182B82C697F9700B73A99 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C42182C02C697F9700B73A99 /* Base in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ @@ -2434,6 +2528,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + C42182B62C697F9700B73A99 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C42182CC2C69C41800B73A99 /* ShareViewModel.swift in Sources */, + C42182BD2C697F9700B73A99 /* ShareViewController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -2442,6 +2545,11 @@ target = 040684FB2A01539800377094 /* StreetDrop */; targetProxy = 41FF58FD2A06B38800ABB871 /* PBXContainerItemProxy */; }; + C42182C32C697F9700B73A99 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C42182B92C697F9700B73A99 /* ShareExtension */; + targetProxy = C42182C22C697F9700B73A99 /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ @@ -2453,6 +2561,14 @@ name = LaunchScreen.storyboard; sourceTree = ""; }; + C42182BE2C697F9700B73A99 /* MainInterface.storyboard */ = { + isa = PBXVariantGroup; + children = ( + C42182BF2C697F9700B73A99 /* Base */, + ); + name = MainInterface.storyboard; + sourceTree = ""; + }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ @@ -2574,6 +2690,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 33C6E9256EDABFB58F83B1C8 /* Pods-StreetDrop.debug.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = StreetDrop/StreetDropDebug.entitlements; @@ -2617,6 +2734,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 2611E7411DB7C5436A272A27 /* Pods-StreetDrop.release.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = StreetDrop/StreetDropRelease.entitlements; @@ -2705,6 +2823,70 @@ }; name = Release; }; + C42182C62C697F9700B73A99 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = F8M76V73YG; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = ShareExtension/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = ShareExtension; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 17.5; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.depromeet.StreetDropRelease.ShareExtension; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + C42182C72C697F9700B73A99 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CODE_SIGN_IDENTITY = "Apple Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Distribution"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = ""; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = ShareExtension/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = ShareExtension; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 17.5; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.depromeet.StreetDropRelease.ShareExtension; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -2735,6 +2917,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + C42182C82C697F9700B73A99 /* Build configuration list for PBXNativeTarget "ShareExtension" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C42182C62C697F9700B73A99 /* Debug */, + C42182C72C697F9700B73A99 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ From 8935808c6fd9b33a7e9458ff9d2e17424552c97c Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Mon, 12 Aug 2024 17:16:40 +0900 Subject: [PATCH 03/37] =?UTF-8?q?=F0=9F=9B=A0#297:=20Share=20Extension?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=82=AC=EC=9A=A9=ED=95=A0=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=EB=93=A4=20=ED=83=80=EA=B2=9F=EB=A9=A4=EB=B2=84?= =?UTF-8?q?=EC=89=BD=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=B4=EC=95=BC=ED=95=A0=20SDK=EB=93=A4=20=EC=9D=98=EC=A1=B4?= =?UTF-8?q?=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- StreetDrop/Podfile | 12 +- .../View/ShareViewController.swift | 21 +- .../StreetDrop.xcodeproj/project.pbxproj | 431 +++++++++++++++++- 3 files changed, 453 insertions(+), 11 deletions(-) diff --git a/StreetDrop/Podfile b/StreetDrop/Podfile index d105083a..8d5f7bd5 100644 --- a/StreetDrop/Podfile +++ b/StreetDrop/Podfile @@ -1,9 +1,15 @@ # Uncomment the next line to define a global platform for your project -# platform :ios, '9.0' - -target 'StreetDrop' do +# platform :ios, '14.0' +def pods pod 'NMapsMap' pod 'Google-Mobile-Ads-SDK' +end + +target 'StreetDrop' do + pods +end +target 'ShareExtension' do + pods end diff --git a/StreetDrop/ShareExtension/View/ShareViewController.swift b/StreetDrop/ShareExtension/View/ShareViewController.swift index f5431df4..281924cc 100644 --- a/StreetDrop/ShareExtension/View/ShareViewController.swift +++ b/StreetDrop/ShareExtension/View/ShareViewController.swift @@ -8,8 +8,11 @@ import UIKit import Social +import RxSwift + final class ShareViewController: SLComposeServiceViewController { - + private let viewModel: ShareViewModel = .init() + private let disposeBag: DisposeBag = .init() override func isContentValid() -> Bool { return true @@ -22,5 +25,21 @@ final class ShareViewController: SLComposeServiceViewController { override func configurationItems() -> [Any]! { return [] } + + override func viewDidLoad() { + super.viewDidLoad() + bindViewModel() + } +} +private extension ShareViewController { + func bindViewModel() { + let input: ShareViewModel.Input = .init(viewDidLoadEvent: .just(Void())) + let output: ShareViewModel.Output = viewModel.convert( + input: input, + disposedBag: disposeBag + ) + } + + } diff --git a/StreetDrop/StreetDrop.xcodeproj/project.pbxproj b/StreetDrop/StreetDrop.xcodeproj/project.pbxproj index c270ae39..17dc156d 100644 --- a/StreetDrop/StreetDrop.xcodeproj/project.pbxproj +++ b/StreetDrop/StreetDrop.xcodeproj/project.pbxproj @@ -191,11 +191,184 @@ C41BD2E92A38467A0090EF2B /* UIImageView+ImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41BD2E82A38467A0090EF2B /* UIImageView+ImageCache.swift */; }; C41BD2EC2A3848880090EF2B /* UIImage+loadURLImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41BD2EB2A3848880090EF2B /* UIImage+loadURLImage.swift */; }; C41BD2ED2A3848880090EF2B /* UIImage+loadURLImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41BD2EB2A3848880090EF2B /* UIImage+loadURLImage.swift */; }; - C42182BD2C697F9700B73A99 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42182BC2C697F9700B73A99 /* ShareViewController.swift */; }; C42182C02C697F9700B73A99 /* Base in Resources */ = {isa = PBXBuildFile; fileRef = C42182BF2C697F9700B73A99 /* Base */; }; C42182C42C697F9700B73A99 /* ShareExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = C42182BA2C697F9700B73A99 /* ShareExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - C42182CC2C69C41800B73A99 /* ShareViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42182CB2C69C41800B73A99 /* ShareViewModel.swift */; }; C42361782B0CE8F800F61E3C /* RecommendMusic.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42361772B0CE8F800F61E3C /* RecommendMusic.swift */; }; + C432DE052C69D963003DBA18 /* RxCocoa in Frameworks */ = {isa = PBXBuildFile; productRef = C432DE042C69D963003DBA18 /* RxCocoa */; }; + C432DE072C69D963003DBA18 /* RxRelay in Frameworks */ = {isa = PBXBuildFile; productRef = C432DE062C69D963003DBA18 /* RxRelay */; }; + C432DE092C69D963003DBA18 /* RxSwift in Frameworks */ = {isa = PBXBuildFile; productRef = C432DE082C69D963003DBA18 /* RxSwift */; }; + C432DEF22C69F6C4003DBA18 /* OrderedCollections in Frameworks */ = {isa = PBXBuildFile; productRef = C432DEF12C69F6C4003DBA18 /* OrderedCollections */; }; + C432DEF32C69F7F3003DBA18 /* AddressManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4143452D2A373550003FEE2A /* AddressManager.swift */; }; + C432DEF42C69F7F3003DBA18 /* DateManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4AA84E02C1F732800CADB1A /* DateManager.swift */; }; + C432DEF52C69F7F3003DBA18 /* Bundle+APIKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47583A02A5F11BD00CA7335 /* Bundle+APIKeys.swift */; }; + C432DEF62C69F7F3003DBA18 /* UIImageView+ImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41BD2E82A38467A0090EF2B /* UIImageView+ImageCache.swift */; }; + C432DEF72C69F7F3003DBA18 /* UIImage+Resizing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18D671F52A35C5D4003B1A71 /* UIImage+Resizing.swift */; }; + C432DEF82C69F7F3003DBA18 /* UIImage+loadURLImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41BD2EB2A3848880090EF2B /* UIImage+loadURLImage.swift */; }; + C432DEF92C69F7F3003DBA18 /* UILabel+LineHeight.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D16FCB2A1B98B0008B076F /* UILabel+LineHeight.swift */; }; + C432DEFA2C69F7F3003DBA18 /* UIViewController+Constant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 414345012A31F17B003FEE2A /* UIViewController+Constant.swift */; }; + C432DEFB2C69F7F3003DBA18 /* UIImage+cornerRadius.swift in Sources */ = {isa = PBXBuildFile; fileRef = 188F90C62A39FD7D003A1B4A /* UIImage+cornerRadius.swift */; }; + C432DEFC2C69F7F3003DBA18 /* UINavigation+Gesture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 082F17232ADD60BB00174D98 /* UINavigation+Gesture.swift */; }; + C432DEFD2C69F7F3003DBA18 /* String+Base64.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A1386AA2B4F8A5000E49BB5 /* String+Base64.swift */; }; + C432DEFE2C69F7F3003DBA18 /* GradientLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C49EDACD2BBD7EFE0025DB55 /* GradientLabel.swift */; }; + C432DEFF2C69F7F3003DBA18 /* Array+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4AA84DE2C1F3B0200CADB1A /* Array+Extension.swift */; }; + C432DF002C69F7F3003DBA18 /* UIViewController+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A51EC3B2C3E52FE00DEF6F3 /* UIViewController+Rx.swift */; }; + C432DF012C69F7F3003DBA18 /* Map+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A51EC3D2C3E536000DEF6F3 /* Map+Rx.swift */; }; + C432DF022C69F7F3003DBA18 /* UIFont+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D16FC82A1B9338008B076F /* UIFont+Extension.swift */; }; + C432DF032C69F7F3003DBA18 /* TestError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04FB1F312A021C330064B3C8 /* TestError.swift */; }; + C432DF042C69F7F3003DBA18 /* ImageCacheError.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45A4CAF2A3710AC00EE9C36 /* ImageCacheError.swift */; }; + C432DF052C69F7F3003DBA18 /* UserDefaultsError.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E4C6B92A5AE40900B1C84A /* UserDefaultsError.swift */; }; + C432DF062C69F7F3003DBA18 /* MyInfoError.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41972312ABDAEF200211222 /* MyInfoError.swift */; }; + C432DF072C69F7F3003DBA18 /* AsynchronousError.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E68C842C2A996000742464 /* AsynchronousError.swift */; }; + C432DF082C69F7F3003DBA18 /* JSONLoadError.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4F5D3EA2C5B43BB008AF976 /* JSONLoadError.swift */; }; + C432DF092C69F7F3003DBA18 /* UserDefaultKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45BF3962A1D0ADF00CEDE74 /* UserDefaultKey.swift */; }; + C432DF0A2C69F7F3003DBA18 /* GADUnitID.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A3AFB572B8DB399003BD144 /* GADUnitID.swift */; }; + C432DF0B2C69F7F3003DBA18 /* SettingSectionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47F02292A3869DC00F48884 /* SettingSectionType.swift */; }; + C432DF0C2C69F7F3003DBA18 /* MusicApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E4C6BC2A5AE6F500B1C84A /* MusicApp.swift */; }; + C432DF0D2C69F7F3003DBA18 /* UniviersialLinkKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08B97EA42B44303C00084F66 /* UniviersialLinkKey.swift */; }; + C432DF0E2C69F7F3003DBA18 /* RegionFilteredDropCountResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A4E3B72C64451400283C37 /* RegionFilteredDropCountResponseDTO.swift */; }; + C432DF0F2C69F7F3003DBA18 /* RegionFilteredLikeCountResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46293C82C6495DD00FF4A7A /* RegionFilteredLikeCountResponseDTO.swift */; }; + C432DF102C69F7F3003DBA18 /* CityAndDistrictsDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4F5D3E32C5B22D9008AF976 /* CityAndDistrictsDTO.swift */; }; + C432DF112C69F7F3003DBA18 /* NoticeListResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4AA84D82C1F030F00CADB1A /* NoticeListResponseDTO.swift */; }; + C432DF122C69F7F3003DBA18 /* MyLevelResponseDTO+Mapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1876F0402A66E5440064B887 /* MyLevelResponseDTO+Mapping.swift */; }; + C432DF132C69F7F3003DBA18 /* MyLevelProgressResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A806F9B2BC7A41E0003649E /* MyLevelProgressResponseDTO.swift */; }; + C432DF142C69F7F3003DBA18 /* LevelPolicyResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AAFD9A92BCE54DF001A6772 /* LevelPolicyResponseDTO.swift */; }; + C432DF152C69F7F3003DBA18 /* MyLikeListResponseDTO+Mapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1876F03E2A66E4E30064B887 /* MyLikeListResponseDTO+Mapping.swift */; }; + C432DF162C69F7F3003DBA18 /* MyDropListResponseDTO+Mapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1876F03C2A66E0330064B887 /* MyDropListResponseDTO+Mapping.swift */; }; + C432DF172C69F7F3003DBA18 /* MyInfoResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41396D862A4EFA2900B69341 /* MyInfoResponseDTO.swift */; }; + C432DF182C69F7F3003DBA18 /* UserCircleRadiusResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4685B352B725FF500F514C7 /* UserCircleRadiusResponseDTO.swift */; }; + C432DF192C69F7F3003DBA18 /* EditCommentRequestDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41396D812A4EF65B00B69341 /* EditCommentRequestDTO.swift */; }; + C432DF1A2C69F7F3003DBA18 /* ClaimCommentRequestDTO+Mapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41A9BEB62A4DC6CE00F3605C /* ClaimCommentRequestDTO+Mapping.swift */; }; + C432DF1B2C69F7F3003DBA18 /* DropMusicRequestDTO+Mapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 049F50212A122C8A001528CB /* DropMusicRequestDTO+Mapping.swift */; }; + C432DF1C2C69F7F3003DBA18 /* PoiResponseDTO+Mapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41E008CD2A1442A000F5D99C /* PoiResponseDTO+Mapping.swift */; }; + C432DF1D2C69F7F3003DBA18 /* MusicCountByDongResponseDTO+Mapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 041038962A126E7B00BC5532 /* MusicCountByDongResponseDTO+Mapping.swift */; }; + C432DF1E2C69F7F3003DBA18 /* SearchedMusicResponseDTO+Mapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41B953672A10E39D00BEC0AB /* SearchedMusicResponseDTO+Mapping.swift */; }; + C432DF1F2C69F7F3003DBA18 /* CommunityResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18AAF83D2A137349002EF441 /* CommunityResponseDTO.swift */; }; + C432DF202C69F7F3003DBA18 /* MusicWithinAreaResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18AAF8402A13CC54002EF441 /* MusicWithinAreaResponseDTO.swift */; }; + C432DF212C69F7F3003DBA18 /* RecentMusicQueryDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45BF3A02A1D133000CEDE74 /* RecentMusicQueryDTO.swift */; }; + C432DF222C69F7F3003DBA18 /* VillageNameResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E0943A2A4DF002000B4513 /* VillageNameResponseDTO.swift */; }; + C432DF232C69F7F3003DBA18 /* FCMTokenRequestDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A4458F2A5EF225008279C1 /* FCMTokenRequestDTO.swift */; }; + C432DF242C69F7F3003DBA18 /* SingleMusicResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0856524C2AFA77FD00FD9BCB /* SingleMusicResponseDTO.swift */; }; + C432DF252C69F7F3003DBA18 /* FetchingPopUpInfomationResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44A54952BBC082D00354F8F /* FetchingPopUpInfomationResponseDTO.swift */; }; + C432DF262C69F7F3003DBA18 /* PopUpUserReadingRequestDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44980792BC3AF9F0001E6C3 /* PopUpUserReadingRequestDTO.swift */; }; + C432DF272C69F7F3003DBA18 /* MyInfoRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41972502ABED0FE00211222 /* MyInfoRepository.swift */; }; + C432DF282C69F7F3003DBA18 /* FCMRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4BB15972A5EC507001BC5E8 /* FCMRepository.swift */; }; + C432DF292C69F7F3003DBA18 /* MainRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18683FDE2A348B25005A94AC /* MainRepository.swift */; }; + C432DF2A2C69F7F3003DBA18 /* SearchingMusicRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = C434A4D22A17983A00C63526 /* SearchingMusicRepository.swift */; }; + C432DF2B2C69F7F3003DBA18 /* NoticeRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4C996AC2C1EEF2500FF7B9A /* NoticeRepository.swift */; }; + C432DF2C2C69F7F3003DBA18 /* SettingsRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E4C6B12A5ADC2C00B1C84A /* SettingsRepository.swift */; }; + C432DF2D2C69F7F3003DBA18 /* MyPageRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1876F0432A66E6E00064B887 /* MyPageRepository.swift */; }; + C432DF2E2C69F7F3003DBA18 /* NicknameEditRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1816ED452A6858DE005009FC /* NicknameEditRepository.swift */; }; + C432DF2F2C69F7F3003DBA18 /* DropMusicRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41F23B4D2A1B6EE80083D2EC /* DropMusicRepository.swift */; }; + C432DF302C69F7F3003DBA18 /* LikeMusicRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 414345222A35B9A3003FEE2A /* LikeMusicRepository.swift */; }; + C432DF312C69F7F3003DBA18 /* ClaimCommentRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41A9BEB82A4DCA4A00F3605C /* ClaimCommentRepository.swift */; }; + C432DF322C69F7F3003DBA18 /* EditCommentRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41396D8A2A4EFB2500B69341 /* EditCommentRepository.swift */; }; + C432DF332C69F7F3003DBA18 /* DeleteMusicRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41396D8C2A4EFB3300B69341 /* DeleteMusicRepository.swift */; }; + C432DF342C69F7F3003DBA18 /* BlockUserRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41A3DDF52A5AD1C7004CFA2F /* BlockUserRepository.swift */; }; + C432DF352C69F7F3003DBA18 /* PopUpRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44A54902BBC076000354F8F /* PopUpRepository.swift */; }; + C432DF362C69F7F3003DBA18 /* DefaultMainRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18683FDB2A348B15005A94AC /* DefaultMainRepository.swift */; }; + C432DF372C69F7F3003DBA18 /* DefaultSearchingMusicRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = C434A4CF2A17981C00C63526 /* DefaultSearchingMusicRepository.swift */; }; + C432DF382C69F7F3003DBA18 /* DefaultFCMRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A445922A5EF265008279C1 /* DefaultFCMRepository.swift */; }; + C432DF392C69F7F3003DBA18 /* DefaultNoticeRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4C996A92C1EEF0B00FF7B9A /* DefaultNoticeRepository.swift */; }; + C432DF3A2C69F7F3003DBA18 /* DefaultSettingsRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E4C6B32A5ADC4B00B1C84A /* DefaultSettingsRepository.swift */; }; + C432DF3B2C69F7F3003DBA18 /* DefaultMyPageRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1876F04F2A66F7A30064B887 /* DefaultMyPageRepository.swift */; }; + C432DF3C2C69F7F3003DBA18 /* DefaultNicknameEditRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1816ED482A68591F005009FC /* DefaultNicknameEditRepository.swift */; }; + C432DF3D2C69F7F3003DBA18 /* DefaultDropMusicRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41F23B4A2A1B6EC20083D2EC /* DefaultDropMusicRepository.swift */; }; + C432DF3E2C69F7F3003DBA18 /* DefaultLikeMusicRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 414345242A35B9C3003FEE2A /* DefaultLikeMusicRepository.swift */; }; + C432DF3F2C69F7F3003DBA18 /* DefaultClaimCommentRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41A9BEBA2A4DCBDA00F3605C /* DefaultClaimCommentRepository.swift */; }; + C432DF402C69F7F3003DBA18 /* DefaultDeleteMusicRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41396D8E2A4EFBE800B69341 /* DefaultDeleteMusicRepository.swift */; }; + C432DF412C69F7F3003DBA18 /* DefaultEditCommentRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41396D902A4EFBF700B69341 /* DefaultEditCommentRepository.swift */; }; + C432DF422C69F7F3003DBA18 /* DefaultBlockUserRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41A3DDF72A5AD222004CFA2F /* DefaultBlockUserRepository.swift */; }; + C432DF432C69F7F3003DBA18 /* DefaultMyInfoRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41972522ABED14200211222 /* DefaultMyInfoRepository.swift */; }; + C432DF442C69F7F3003DBA18 /* DefaultPopUpRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44A54972BBC08D200354F8F /* DefaultPopUpRepository.swift */; }; + C432DF452C69F7F3003DBA18 /* RecentMusicQueriesStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45BF3A22A1D179C00CEDE74 /* RecentMusicQueriesStorage.swift */; }; + C432DF462C69F7F3003DBA18 /* MyInfoStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41396D962A4F04CB00B69341 /* MyInfoStorage.swift */; }; + C432DF472C69F7F3003DBA18 /* UserDefaultsRecentMusicSearches.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45BF39D2A1D113200CEDE74 /* UserDefaultsRecentMusicSearches.swift */; }; + C432DF482C69F7F3003DBA18 /* UserDefaultsMyInfoStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41396D982A4F04D800B69341 /* UserDefaultsMyInfoStorage.swift */; }; + C432DF492C69F7F3003DBA18 /* DroppingInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = C472B1872AC5523300482B2D /* DroppingInfo.swift */; }; + C432DF4A2C69F7F3003DBA18 /* EditInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41396DA82A51B8F700B69341 /* EditInfo.swift */; }; + C432DF4B2C69F7F3003DBA18 /* Music.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40008E92A32012B00EA7FA9 /* Music.swift */; }; + C432DF4C2C69F7F3003DBA18 /* RecommendMusic.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42361772B0CE8F800F61E3C /* RecommendMusic.swift */; }; + C432DF4D2C69F7F3003DBA18 /* ModalOption.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0856525C2B1F29FD00FD9BCB /* ModalOption.swift */; }; + C432DF4E2C69F7F3003DBA18 /* MyLevelProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A806F9D2BC7A59F0003649E /* MyLevelProgress.swift */; }; + C432DF4F2C69F7F3003DBA18 /* LevelPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AAFD9AC2BCE55A4001A6772 /* LevelPolicy.swift */; }; + C432DF502C69F7F3003DBA18 /* PopUpInfomation.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44A54922BBC07AA00354F8F /* PopUpInfomation.swift */; }; + C432DF512C69F7F3003DBA18 /* Notice.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4C996AE2C1EF6C100FF7B9A /* Notice.swift */; }; + C432DF522C69F7F3003DBA18 /* FetchingRegionFilteredLikeUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46293D32C649B7600FF4A7A /* FetchingRegionFilteredLikeUseCase.swift */; }; + C432DF532C69F7F3003DBA18 /* FetchingRegionFilteredLikeCountUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46293CF2C64971100FF4A7A /* FetchingRegionFilteredLikeCountUseCase.swift */; }; + C432DF542C69F7F3003DBA18 /* FetchingRegionFilteredDropUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A4E3C22C645A5000283C37 /* FetchingRegionFilteredDropUseCase.swift */; }; + C432DF552C69F7F3003DBA18 /* FetchingRegionFilteredDropCountUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A4E3BB2C6447AF00283C37 /* FetchingRegionFilteredDropCountUseCase.swift */; }; + C432DF562C69F7F3003DBA18 /* EditCommentUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 082F17192AB7454200174D98 /* EditCommentUseCase.swift */; }; + C432DF572C69F7F3003DBA18 /* DefaultEditCommentUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 082F171B2AB7455400174D98 /* DefaultEditCommentUseCase.swift */; }; + C432DF582C69F7F3003DBA18 /* MyInfoUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C419722D2ABD9D6F00211222 /* MyInfoUseCase.swift */; }; + C432DF592C69F7F3003DBA18 /* DefaultMyInfoUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C419722F2ABDAB0200211222 /* DefaultMyInfoUseCase.swift */; }; + C432DF5A2C69F7F3003DBA18 /* FetchingUserCircleRadiusUsecase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4685B372B72605500F514C7 /* FetchingUserCircleRadiusUsecase.swift */; }; + C432DF5B2C69F7F3003DBA18 /* DefaultFetchingUserCircleRadiusUsecase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4685B392B72610600F514C7 /* DefaultFetchingUserCircleRadiusUsecase.swift */; }; + C432DF5C2C69F7F3003DBA18 /* FetchingPOIUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41972332ABDB36600211222 /* FetchingPOIUseCase.swift */; }; + C432DF5D2C69F7F3003DBA18 /* DefaultFetchingPOIUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41972352ABDB3C000211222 /* DefaultFetchingPOIUseCase.swift */; }; + C432DF5E2C69F7F3003DBA18 /* FetchingMusicCountUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41972372ABDB49400211222 /* FetchingMusicCountUseCase.swift */; }; + C432DF5F2C69F7F3003DBA18 /* DefaultFetchingMusicCountUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41972392ABDB50B00211222 /* DefaultFetchingMusicCountUseCase.swift */; }; + C432DF602C69F7F3003DBA18 /* FetchingMusicWithinAreaUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C419723B2ABDB5AF00211222 /* FetchingMusicWithinAreaUseCase.swift */; }; + C432DF612C69F7F3003DBA18 /* DefaultFetchingMusicWithinAreaUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C419723D2ABDB5D600211222 /* DefaultFetchingMusicWithinAreaUseCase.swift */; }; + C432DF622C69F7F3003DBA18 /* LikingUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C419723F2ABDC3B000211222 /* LikingUseCase.swift */; }; + C432DF632C69F7F3003DBA18 /* DefaultLikingUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41972412ABDC3D600211222 /* DefaultLikingUseCase.swift */; }; + C432DF642C69F7F3003DBA18 /* ClaimingCommentUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41972432ABDC43C00211222 /* ClaimingCommentUseCase.swift */; }; + C432DF652C69F7F3003DBA18 /* DefaultClaimingCommentUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41972452ABDC45000211222 /* DefaultClaimingCommentUseCase.swift */; }; + C432DF662C69F7F3003DBA18 /* DeletingMusicUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41972472ABDC4C700211222 /* DeletingMusicUseCase.swift */; }; + C432DF672C69F7F3003DBA18 /* DefaultDeletingMusicUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41972492ABDC94A00211222 /* DefaultDeletingMusicUseCase.swift */; }; + C432DF682C69F7F3003DBA18 /* BlockUserUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C419724B2ABDCA6100211222 /* BlockUserUseCase.swift */; }; + C432DF692C69F7F3003DBA18 /* DefaultBlockUserUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C419724D2ABDCABD00211222 /* DefaultBlockUserUseCase.swift */; }; + C432DF6A2C69F7F3003DBA18 /* FetchingMyInfoUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41972542ABED3EC00211222 /* FetchingMyInfoUseCase.swift */; }; + C432DF6B2C69F7F3003DBA18 /* DefaultFetchingMyInfoUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41972562ABED40100211222 /* DefaultFetchingMyInfoUseCase.swift */; }; + C432DF6C2C69F7F3003DBA18 /* SearchMusicUsecase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C434A4CD2A17970A00C63526 /* SearchMusicUsecase.swift */; }; + C432DF6D2C69F7F3003DBA18 /* SettingsUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E4C6B72A5ADFDB00B1C84A /* SettingsUseCase.swift */; }; + C432DF6E2C69F7F3003DBA18 /* FetchingPopUpInfomationUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44A54992BBC097E00354F8F /* FetchingPopUpInfomationUseCase.swift */; }; + C432DF6F2C69F7F3003DBA18 /* DefaultFetchingPopUpInfomationUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44A549B2BBC099E00354F8F /* DefaultFetchingPopUpInfomationUseCase.swift */; }; + C432DF702C69F7F3003DBA18 /* PostingPopUpUserReadingUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C449807B2BC3B07E0001E6C3 /* PostingPopUpUserReadingUseCase.swift */; }; + C432DF712C69F7F3003DBA18 /* DefaultPostingPopUpUserReadingUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C449807D2BC3B09F0001E6C3 /* DefaultPostingPopUpUserReadingUseCase.swift */; }; + C432DF722C69F7F3003DBA18 /* FetchingSingleMusicUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A26BF312B33D1E40007B6B7 /* FetchingSingleMusicUseCase.swift */; }; + C432DF732C69F7F3003DBA18 /* DefaultFetchingSingleMusicUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A26BF332B33D2210007B6B7 /* DefaultFetchingSingleMusicUseCase.swift */; }; + C432DF742C69F7F3003DBA18 /* DropMusicUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 082F17052AB6DFEC00174D98 /* DropMusicUseCase.swift */; }; + C432DF752C69F7F3003DBA18 /* DefaultDropMusicUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 082F17082AB6E41100174D98 /* DefaultDropMusicUseCase.swift */; }; + C432DF762C69F7F3003DBA18 /* NoticeUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4C996A62C1EEC8600FF7B9A /* NoticeUseCase.swift */; }; + C432DF772C69F7F3003DBA18 /* FetchingLevelPolicyUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AAFD9AE2BCE567A001A6772 /* FetchingLevelPolicyUseCase.swift */; }; + C432DF782C69F7F3003DBA18 /* DefaultFetchingLevelPolicyUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AAFD9B02BCE56A6001A6772 /* DefaultFetchingLevelPolicyUseCase.swift */; }; + C432DF792C69F7F3003DBA18 /* FetchingMyLevelUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08F5745A2C4698B300635B54 /* FetchingMyLevelUseCase.swift */; }; + C432DF7A2C69F7F3003DBA18 /* DefaultFetchingMyLevelUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08F5745C2C46992500635B54 /* DefaultFetchingMyLevelUseCase.swift */; }; + C432DF7B2C69F7F3003DBA18 /* FetchingMyLikeListUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08F574552C4697E100635B54 /* FetchingMyLikeListUseCase.swift */; }; + C432DF7C2C69F7F3003DBA18 /* DefaultFetchingMyLikeListUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08F574572C46985300635B54 /* DefaultFetchingMyLikeListUseCase.swift */; }; + C432DF7D2C69F7F3003DBA18 /* FetchingMyDropListUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08F574502C4696AC00635B54 /* FetchingMyDropListUseCase.swift */; }; + C432DF7E2C69F7F3003DBA18 /* DefaultFetchingMyDropListUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08F574522C4696C600635B54 /* DefaultFetchingMyDropListUseCase.swift */; }; + C432DF7F2C69F7F3003DBA18 /* FetchingCityAndDistrictsUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4F5D3EE2C5B4830008AF976 /* FetchingCityAndDistrictsUseCase.swift */; }; + C432DF802C69F7F3003DBA18 /* DefaultFetchingCityAndDistrictsUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4F5D3F12C5B4850008AF976 /* DefaultFetchingCityAndDistrictsUseCase.swift */; }; + C432DF812C69F7F3003DBA18 /* NetworkManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F76FAA2A04FF2E006CF9EF /* NetworkManager.swift */; }; + C432DF822C69F7F3003DBA18 /* NetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F76FAC2A04FF3D006CF9EF /* NetworkService.swift */; }; + C432DF832C69F7F3003DBA18 /* ResponseSampleData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 414345202A35B92A003FEE2A /* ResponseSampleData.swift */; }; + C432DF842C69F7F3003DBA18 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42182BC2C697F9700B73A99 /* ShareViewController.swift */; }; + C432DF852C69F7F3003DBA18 /* ShareViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42182CB2C69C41800B73A99 /* ShareViewModel.swift */; }; + C432DF862C69F867003DBA18 /* MyMusic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1876F0492A66EDF10064B887 /* MyMusic.swift */; }; + C432DF872C69F867003DBA18 /* MyLevel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1876F04D2A66EE030064B887 /* MyLevel.swift */; }; + C432DF882C69F89A003DBA18 /* UIView+generateCircleGradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41D0974E2A19065B00C011A0 /* UIView+generateCircleGradientView.swift */; }; + C432DF892C69F89A003DBA18 /* UIImageView+makeCircleShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = 414139962A20B434005418A1 /* UIImageView+makeCircleShape.swift */; }; + C432DF8A2C69F89A003DBA18 /* UIcolor+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 413ABEEB2A39D1E900EA1010 /* UIcolor+.swift */; }; + C432DF8B2C69F89A003DBA18 /* UITextView+setLineSpacing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41008EB72A48891000FD4ABE /* UITextView+setLineSpacing.swift */; }; + C432DF8C2C69F89A003DBA18 /* UIView+RoundCorners.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A7D73DE2BB15826009340E3 /* UIView+RoundCorners.swift */; }; + C432DF8D2C69F89A003DBA18 /* NSMutableAttributedString+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A7D73E52BB2AE34009340E3 /* NSMutableAttributedString+.swift */; }; + C432DF8E2C69F89A003DBA18 /* UIButton+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A7D73E72BB3E62E009340E3 /* UIButton+.swift */; }; + C432DF8F2C69F89A003DBA18 /* UILabel+applyGradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08BE57152BD4C887007EA949 /* UILabel+applyGradient.swift */; }; + C432DF912C69F89A003DBA18 /* Toastable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 413ABEE72A39BBA500EA1010 /* Toastable.swift */; }; + C432DF922C69F89A003DBA18 /* AlertViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41A3DDF02A593ED4004CFA2F /* AlertViewController.swift */; }; + C432DF932C69F89A003DBA18 /* TipPopUpViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44A549D2BBC0DC500354F8F /* TipPopUpViewController.swift */; }; + C432DF942C69F89A003DBA18 /* CongratulationsLevelUpPopUpViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C49EDACB2BBD75480025DB55 /* CongratulationsLevelUpPopUpViewController.swift */; }; + C432DF952C69F89A003DBA18 /* ToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41A3DDEA2A58428F004CFA2F /* ToastView.swift */; }; + C432DF962C69F89A003DBA18 /* PaddingLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4141398E2A1FA252005418A1 /* PaddingLabel.swift */; }; + C432DF972C69F89A003DBA18 /* OptionModalViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41396D9A2A4F1C5600B69341 /* OptionModalViewController.swift */; }; + C432DF982C69F89A003DBA18 /* BubbleCommentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 085652512B00B68100FD9BCB /* BubbleCommentView.swift */; }; + C432DF992C69F89A003DBA18 /* LevelPolicyPopUpViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08810C2D2BD3FB00004FC6C1 /* LevelPolicyPopUpViewController.swift */; }; + C432DF9A2C69F89A003DBA18 /* LevelPolicySubView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08810C312BD3FC57004FC6C1 /* LevelPolicySubView.swift */; }; + C432DF9B2C69F89A003DBA18 /* MyInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41396D942A4EFF7B00B69341 /* MyInfo.swift */; }; + C432DF9C2C69F89A003DBA18 /* PoiEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18683FE02A349109005A94AC /* PoiEntity.swift */; }; + C432DF9D2C69F89A003DBA18 /* MusicCountEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1824F1362A349F3700A10320 /* MusicCountEntity.swift */; }; + C432DF9E2C69F89A003DBA18 /* MusicWithinAreaEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18CB7BEC2A359F53002B31FB /* MusicWithinAreaEntity.swift */; }; C434A4CA2A1796E400C63526 /* SearchingMusicViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C434A4C92A1796E400C63526 /* SearchingMusicViewController.swift */; }; C434A4CC2A1796F300C63526 /* SearchingMusicViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C434A4CB2A1796F300C63526 /* SearchingMusicViewModel.swift */; }; C434A4CE2A17970A00C63526 /* SearchMusicUsecase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C434A4CD2A17970A00C63526 /* SearchMusicUsecase.swift */; }; @@ -270,6 +443,12 @@ C4AA826B2C5911FB004B8934 /* ModalPresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AA826A2C5911FB004B8934 /* ModalPresentable.swift */; }; C4AA826C2C5911FB004B8934 /* ModalPresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4AA826A2C5911FB004B8934 /* ModalPresentable.swift */; }; C4BB15982A5EC507001BC5E8 /* FCMRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4BB15972A5EC507001BC5E8 /* FCMRepository.swift */; }; + C4C9D5A42C69FBCB005D90C4 /* Moya in Frameworks */ = {isa = PBXBuildFile; productRef = C4C9D5A32C69FBCB005D90C4 /* Moya */; }; + C4C9D5A62C69FBCB005D90C4 /* ReactiveMoya in Frameworks */ = {isa = PBXBuildFile; productRef = C4C9D5A52C69FBCB005D90C4 /* ReactiveMoya */; }; + C4C9D5A82C69FBCB005D90C4 /* RxMoya in Frameworks */ = {isa = PBXBuildFile; productRef = C4C9D5A72C69FBCB005D90C4 /* RxMoya */; }; + C4C9D5AA2C69FBCB005D90C4 /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = C4C9D5A92C69FBCB005D90C4 /* SnapKit */; }; + C4C9D5AC2C69FBEB005D90C4 /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = C4C9D5AB2C69FBEB005D90C4 /* Kingfisher */; }; + C4C9D5AE2C69FBF8005D90C4 /* Lottie in Frameworks */ = {isa = PBXBuildFile; productRef = C4C9D5AD2C69FBF8005D90C4 /* Lottie */; }; C4D16FBC2A1B917B008B076F /* Pretendard-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = C4D16FB32A1B917B008B076F /* Pretendard-Regular.otf */; }; C4D16FBD2A1B917B008B076F /* Pretendard-ExtraBold.otf in Resources */ = {isa = PBXBuildFile; fileRef = C4D16FB42A1B917B008B076F /* Pretendard-ExtraBold.otf */; }; C4D16FBE2A1B917B008B076F /* Pretendard-SemiBold.otf in Resources */ = {isa = PBXBuildFile; fileRef = C4D16FB52A1B917B008B076F /* Pretendard-SemiBold.otf */; }; @@ -667,6 +846,16 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + C432DE092C69D963003DBA18 /* RxSwift in Frameworks */, + C4C9D5AA2C69FBCB005D90C4 /* SnapKit in Frameworks */, + C432DE072C69D963003DBA18 /* RxRelay in Frameworks */, + C4C9D5AC2C69FBEB005D90C4 /* Kingfisher in Frameworks */, + C432DEF22C69F6C4003DBA18 /* OrderedCollections in Frameworks */, + C4C9D5AE2C69FBF8005D90C4 /* Lottie in Frameworks */, + C4C9D5A42C69FBCB005D90C4 /* Moya in Frameworks */, + C4C9D5A82C69FBCB005D90C4 /* RxMoya in Frameworks */, + C432DE052C69D963003DBA18 /* RxCocoa in Frameworks */, + C4C9D5A62C69FBCB005D90C4 /* ReactiveMoya in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2063,6 +2252,18 @@ dependencies = ( ); name = ShareExtension; + packageProductDependencies = ( + C432DE042C69D963003DBA18 /* RxCocoa */, + C432DE062C69D963003DBA18 /* RxRelay */, + C432DE082C69D963003DBA18 /* RxSwift */, + C432DEF12C69F6C4003DBA18 /* OrderedCollections */, + C4C9D5A32C69FBCB005D90C4 /* Moya */, + C4C9D5A52C69FBCB005D90C4 /* ReactiveMoya */, + C4C9D5A72C69FBCB005D90C4 /* RxMoya */, + C4C9D5A92C69FBCB005D90C4 /* SnapKit */, + C4C9D5AB2C69FBEB005D90C4 /* Kingfisher */, + C4C9D5AD2C69FBF8005D90C4 /* Lottie */, + ); productName = ShareExtension; productReference = C42182BA2C697F9700B73A99 /* ShareExtension.appex */; productType = "com.apple.product-type.app-extension"; @@ -2532,8 +2733,177 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - C42182CC2C69C41800B73A99 /* ShareViewModel.swift in Sources */, - C42182BD2C697F9700B73A99 /* ShareViewController.swift in Sources */, + C432DF882C69F89A003DBA18 /* UIView+generateCircleGradientView.swift in Sources */, + C432DF892C69F89A003DBA18 /* UIImageView+makeCircleShape.swift in Sources */, + C432DF8A2C69F89A003DBA18 /* UIcolor+.swift in Sources */, + C432DF8B2C69F89A003DBA18 /* UITextView+setLineSpacing.swift in Sources */, + C432DF8C2C69F89A003DBA18 /* UIView+RoundCorners.swift in Sources */, + C432DF8D2C69F89A003DBA18 /* NSMutableAttributedString+.swift in Sources */, + C432DF8E2C69F89A003DBA18 /* UIButton+.swift in Sources */, + C432DF8F2C69F89A003DBA18 /* UILabel+applyGradient.swift in Sources */, + C432DF912C69F89A003DBA18 /* Toastable.swift in Sources */, + C432DF922C69F89A003DBA18 /* AlertViewController.swift in Sources */, + C432DF932C69F89A003DBA18 /* TipPopUpViewController.swift in Sources */, + C432DF942C69F89A003DBA18 /* CongratulationsLevelUpPopUpViewController.swift in Sources */, + C432DF952C69F89A003DBA18 /* ToastView.swift in Sources */, + C432DF962C69F89A003DBA18 /* PaddingLabel.swift in Sources */, + C432DF972C69F89A003DBA18 /* OptionModalViewController.swift in Sources */, + C432DF982C69F89A003DBA18 /* BubbleCommentView.swift in Sources */, + C432DF992C69F89A003DBA18 /* LevelPolicyPopUpViewController.swift in Sources */, + C432DF9A2C69F89A003DBA18 /* LevelPolicySubView.swift in Sources */, + C432DF9B2C69F89A003DBA18 /* MyInfo.swift in Sources */, + C432DF9C2C69F89A003DBA18 /* PoiEntity.swift in Sources */, + C432DF9D2C69F89A003DBA18 /* MusicCountEntity.swift in Sources */, + C432DF9E2C69F89A003DBA18 /* MusicWithinAreaEntity.swift in Sources */, + C432DF862C69F867003DBA18 /* MyMusic.swift in Sources */, + C432DF872C69F867003DBA18 /* MyLevel.swift in Sources */, + C432DEF32C69F7F3003DBA18 /* AddressManager.swift in Sources */, + C432DEF42C69F7F3003DBA18 /* DateManager.swift in Sources */, + C432DEF52C69F7F3003DBA18 /* Bundle+APIKeys.swift in Sources */, + C432DEF62C69F7F3003DBA18 /* UIImageView+ImageCache.swift in Sources */, + C432DEF72C69F7F3003DBA18 /* UIImage+Resizing.swift in Sources */, + C432DEF82C69F7F3003DBA18 /* UIImage+loadURLImage.swift in Sources */, + C432DEF92C69F7F3003DBA18 /* UILabel+LineHeight.swift in Sources */, + C432DEFA2C69F7F3003DBA18 /* UIViewController+Constant.swift in Sources */, + C432DEFB2C69F7F3003DBA18 /* UIImage+cornerRadius.swift in Sources */, + C432DEFC2C69F7F3003DBA18 /* UINavigation+Gesture.swift in Sources */, + C432DEFD2C69F7F3003DBA18 /* String+Base64.swift in Sources */, + C432DEFE2C69F7F3003DBA18 /* GradientLabel.swift in Sources */, + C432DEFF2C69F7F3003DBA18 /* Array+Extension.swift in Sources */, + C432DF002C69F7F3003DBA18 /* UIViewController+Rx.swift in Sources */, + C432DF012C69F7F3003DBA18 /* Map+Rx.swift in Sources */, + C432DF022C69F7F3003DBA18 /* UIFont+Extension.swift in Sources */, + C432DF032C69F7F3003DBA18 /* TestError.swift in Sources */, + C432DF042C69F7F3003DBA18 /* ImageCacheError.swift in Sources */, + C432DF052C69F7F3003DBA18 /* UserDefaultsError.swift in Sources */, + C432DF062C69F7F3003DBA18 /* MyInfoError.swift in Sources */, + C432DF072C69F7F3003DBA18 /* AsynchronousError.swift in Sources */, + C432DF082C69F7F3003DBA18 /* JSONLoadError.swift in Sources */, + C432DF092C69F7F3003DBA18 /* UserDefaultKey.swift in Sources */, + C432DF0A2C69F7F3003DBA18 /* GADUnitID.swift in Sources */, + C432DF0B2C69F7F3003DBA18 /* SettingSectionType.swift in Sources */, + C432DF0C2C69F7F3003DBA18 /* MusicApp.swift in Sources */, + C432DF0D2C69F7F3003DBA18 /* UniviersialLinkKey.swift in Sources */, + C432DF0E2C69F7F3003DBA18 /* RegionFilteredDropCountResponseDTO.swift in Sources */, + C432DF0F2C69F7F3003DBA18 /* RegionFilteredLikeCountResponseDTO.swift in Sources */, + C432DF102C69F7F3003DBA18 /* CityAndDistrictsDTO.swift in Sources */, + C432DF112C69F7F3003DBA18 /* NoticeListResponseDTO.swift in Sources */, + C432DF122C69F7F3003DBA18 /* MyLevelResponseDTO+Mapping.swift in Sources */, + C432DF132C69F7F3003DBA18 /* MyLevelProgressResponseDTO.swift in Sources */, + C432DF142C69F7F3003DBA18 /* LevelPolicyResponseDTO.swift in Sources */, + C432DF152C69F7F3003DBA18 /* MyLikeListResponseDTO+Mapping.swift in Sources */, + C432DF162C69F7F3003DBA18 /* MyDropListResponseDTO+Mapping.swift in Sources */, + C432DF172C69F7F3003DBA18 /* MyInfoResponseDTO.swift in Sources */, + C432DF182C69F7F3003DBA18 /* UserCircleRadiusResponseDTO.swift in Sources */, + C432DF192C69F7F3003DBA18 /* EditCommentRequestDTO.swift in Sources */, + C432DF1A2C69F7F3003DBA18 /* ClaimCommentRequestDTO+Mapping.swift in Sources */, + C432DF1B2C69F7F3003DBA18 /* DropMusicRequestDTO+Mapping.swift in Sources */, + C432DF1C2C69F7F3003DBA18 /* PoiResponseDTO+Mapping.swift in Sources */, + C432DF1D2C69F7F3003DBA18 /* MusicCountByDongResponseDTO+Mapping.swift in Sources */, + C432DF1E2C69F7F3003DBA18 /* SearchedMusicResponseDTO+Mapping.swift in Sources */, + C432DF1F2C69F7F3003DBA18 /* CommunityResponseDTO.swift in Sources */, + C432DF202C69F7F3003DBA18 /* MusicWithinAreaResponseDTO.swift in Sources */, + C432DF212C69F7F3003DBA18 /* RecentMusicQueryDTO.swift in Sources */, + C432DF222C69F7F3003DBA18 /* VillageNameResponseDTO.swift in Sources */, + C432DF232C69F7F3003DBA18 /* FCMTokenRequestDTO.swift in Sources */, + C432DF242C69F7F3003DBA18 /* SingleMusicResponseDTO.swift in Sources */, + C432DF252C69F7F3003DBA18 /* FetchingPopUpInfomationResponseDTO.swift in Sources */, + C432DF262C69F7F3003DBA18 /* PopUpUserReadingRequestDTO.swift in Sources */, + C432DF272C69F7F3003DBA18 /* MyInfoRepository.swift in Sources */, + C432DF282C69F7F3003DBA18 /* FCMRepository.swift in Sources */, + C432DF292C69F7F3003DBA18 /* MainRepository.swift in Sources */, + C432DF2A2C69F7F3003DBA18 /* SearchingMusicRepository.swift in Sources */, + C432DF2B2C69F7F3003DBA18 /* NoticeRepository.swift in Sources */, + C432DF2C2C69F7F3003DBA18 /* SettingsRepository.swift in Sources */, + C432DF2D2C69F7F3003DBA18 /* MyPageRepository.swift in Sources */, + C432DF2E2C69F7F3003DBA18 /* NicknameEditRepository.swift in Sources */, + C432DF2F2C69F7F3003DBA18 /* DropMusicRepository.swift in Sources */, + C432DF302C69F7F3003DBA18 /* LikeMusicRepository.swift in Sources */, + C432DF312C69F7F3003DBA18 /* ClaimCommentRepository.swift in Sources */, + C432DF322C69F7F3003DBA18 /* EditCommentRepository.swift in Sources */, + C432DF332C69F7F3003DBA18 /* DeleteMusicRepository.swift in Sources */, + C432DF342C69F7F3003DBA18 /* BlockUserRepository.swift in Sources */, + C432DF352C69F7F3003DBA18 /* PopUpRepository.swift in Sources */, + C432DF362C69F7F3003DBA18 /* DefaultMainRepository.swift in Sources */, + C432DF372C69F7F3003DBA18 /* DefaultSearchingMusicRepository.swift in Sources */, + C432DF382C69F7F3003DBA18 /* DefaultFCMRepository.swift in Sources */, + C432DF392C69F7F3003DBA18 /* DefaultNoticeRepository.swift in Sources */, + C432DF3A2C69F7F3003DBA18 /* DefaultSettingsRepository.swift in Sources */, + C432DF3B2C69F7F3003DBA18 /* DefaultMyPageRepository.swift in Sources */, + C432DF3C2C69F7F3003DBA18 /* DefaultNicknameEditRepository.swift in Sources */, + C432DF3D2C69F7F3003DBA18 /* DefaultDropMusicRepository.swift in Sources */, + C432DF3E2C69F7F3003DBA18 /* DefaultLikeMusicRepository.swift in Sources */, + C432DF3F2C69F7F3003DBA18 /* DefaultClaimCommentRepository.swift in Sources */, + C432DF402C69F7F3003DBA18 /* DefaultDeleteMusicRepository.swift in Sources */, + C432DF412C69F7F3003DBA18 /* DefaultEditCommentRepository.swift in Sources */, + C432DF422C69F7F3003DBA18 /* DefaultBlockUserRepository.swift in Sources */, + C432DF432C69F7F3003DBA18 /* DefaultMyInfoRepository.swift in Sources */, + C432DF442C69F7F3003DBA18 /* DefaultPopUpRepository.swift in Sources */, + C432DF452C69F7F3003DBA18 /* RecentMusicQueriesStorage.swift in Sources */, + C432DF462C69F7F3003DBA18 /* MyInfoStorage.swift in Sources */, + C432DF472C69F7F3003DBA18 /* UserDefaultsRecentMusicSearches.swift in Sources */, + C432DF482C69F7F3003DBA18 /* UserDefaultsMyInfoStorage.swift in Sources */, + C432DF492C69F7F3003DBA18 /* DroppingInfo.swift in Sources */, + C432DF4A2C69F7F3003DBA18 /* EditInfo.swift in Sources */, + C432DF4B2C69F7F3003DBA18 /* Music.swift in Sources */, + C432DF4C2C69F7F3003DBA18 /* RecommendMusic.swift in Sources */, + C432DF4D2C69F7F3003DBA18 /* ModalOption.swift in Sources */, + C432DF4E2C69F7F3003DBA18 /* MyLevelProgress.swift in Sources */, + C432DF4F2C69F7F3003DBA18 /* LevelPolicy.swift in Sources */, + C432DF502C69F7F3003DBA18 /* PopUpInfomation.swift in Sources */, + C432DF512C69F7F3003DBA18 /* Notice.swift in Sources */, + C432DF522C69F7F3003DBA18 /* FetchingRegionFilteredLikeUseCase.swift in Sources */, + C432DF532C69F7F3003DBA18 /* FetchingRegionFilteredLikeCountUseCase.swift in Sources */, + C432DF542C69F7F3003DBA18 /* FetchingRegionFilteredDropUseCase.swift in Sources */, + C432DF552C69F7F3003DBA18 /* FetchingRegionFilteredDropCountUseCase.swift in Sources */, + C432DF562C69F7F3003DBA18 /* EditCommentUseCase.swift in Sources */, + C432DF572C69F7F3003DBA18 /* DefaultEditCommentUseCase.swift in Sources */, + C432DF582C69F7F3003DBA18 /* MyInfoUseCase.swift in Sources */, + C432DF592C69F7F3003DBA18 /* DefaultMyInfoUseCase.swift in Sources */, + C432DF5A2C69F7F3003DBA18 /* FetchingUserCircleRadiusUsecase.swift in Sources */, + C432DF5B2C69F7F3003DBA18 /* DefaultFetchingUserCircleRadiusUsecase.swift in Sources */, + C432DF5C2C69F7F3003DBA18 /* FetchingPOIUseCase.swift in Sources */, + C432DF5D2C69F7F3003DBA18 /* DefaultFetchingPOIUseCase.swift in Sources */, + C432DF5E2C69F7F3003DBA18 /* FetchingMusicCountUseCase.swift in Sources */, + C432DF5F2C69F7F3003DBA18 /* DefaultFetchingMusicCountUseCase.swift in Sources */, + C432DF602C69F7F3003DBA18 /* FetchingMusicWithinAreaUseCase.swift in Sources */, + C432DF612C69F7F3003DBA18 /* DefaultFetchingMusicWithinAreaUseCase.swift in Sources */, + C432DF622C69F7F3003DBA18 /* LikingUseCase.swift in Sources */, + C432DF632C69F7F3003DBA18 /* DefaultLikingUseCase.swift in Sources */, + C432DF642C69F7F3003DBA18 /* ClaimingCommentUseCase.swift in Sources */, + C432DF652C69F7F3003DBA18 /* DefaultClaimingCommentUseCase.swift in Sources */, + C432DF662C69F7F3003DBA18 /* DeletingMusicUseCase.swift in Sources */, + C432DF672C69F7F3003DBA18 /* DefaultDeletingMusicUseCase.swift in Sources */, + C432DF682C69F7F3003DBA18 /* BlockUserUseCase.swift in Sources */, + C432DF692C69F7F3003DBA18 /* DefaultBlockUserUseCase.swift in Sources */, + C432DF6A2C69F7F3003DBA18 /* FetchingMyInfoUseCase.swift in Sources */, + C432DF6B2C69F7F3003DBA18 /* DefaultFetchingMyInfoUseCase.swift in Sources */, + C432DF6C2C69F7F3003DBA18 /* SearchMusicUsecase.swift in Sources */, + C432DF6D2C69F7F3003DBA18 /* SettingsUseCase.swift in Sources */, + C432DF6E2C69F7F3003DBA18 /* FetchingPopUpInfomationUseCase.swift in Sources */, + C432DF6F2C69F7F3003DBA18 /* DefaultFetchingPopUpInfomationUseCase.swift in Sources */, + C432DF702C69F7F3003DBA18 /* PostingPopUpUserReadingUseCase.swift in Sources */, + C432DF712C69F7F3003DBA18 /* DefaultPostingPopUpUserReadingUseCase.swift in Sources */, + C432DF722C69F7F3003DBA18 /* FetchingSingleMusicUseCase.swift in Sources */, + C432DF732C69F7F3003DBA18 /* DefaultFetchingSingleMusicUseCase.swift in Sources */, + C432DF742C69F7F3003DBA18 /* DropMusicUseCase.swift in Sources */, + C432DF752C69F7F3003DBA18 /* DefaultDropMusicUseCase.swift in Sources */, + C432DF762C69F7F3003DBA18 /* NoticeUseCase.swift in Sources */, + C432DF772C69F7F3003DBA18 /* FetchingLevelPolicyUseCase.swift in Sources */, + C432DF782C69F7F3003DBA18 /* DefaultFetchingLevelPolicyUseCase.swift in Sources */, + C432DF792C69F7F3003DBA18 /* FetchingMyLevelUseCase.swift in Sources */, + C432DF7A2C69F7F3003DBA18 /* DefaultFetchingMyLevelUseCase.swift in Sources */, + C432DF7B2C69F7F3003DBA18 /* FetchingMyLikeListUseCase.swift in Sources */, + C432DF7C2C69F7F3003DBA18 /* DefaultFetchingMyLikeListUseCase.swift in Sources */, + C432DF7D2C69F7F3003DBA18 /* FetchingMyDropListUseCase.swift in Sources */, + C432DF7E2C69F7F3003DBA18 /* DefaultFetchingMyDropListUseCase.swift in Sources */, + C432DF7F2C69F7F3003DBA18 /* FetchingCityAndDistrictsUseCase.swift in Sources */, + C432DF802C69F7F3003DBA18 /* DefaultFetchingCityAndDistrictsUseCase.swift in Sources */, + C432DF812C69F7F3003DBA18 /* NetworkManager.swift in Sources */, + C432DF822C69F7F3003DBA18 /* NetworkService.swift in Sources */, + C432DF832C69F7F3003DBA18 /* ResponseSampleData.swift in Sources */, + C432DF842C69F7F3003DBA18 /* ShareViewController.swift in Sources */, + C432DF852C69F7F3003DBA18 /* ShareViewModel.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2837,7 +3207,7 @@ INFOPLIST_FILE = ShareExtension/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = ShareExtension; INFOPLIST_KEY_NSHumanReadableCopyright = ""; - IPHONEOS_DEPLOYMENT_TARGET = 17.5; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -2845,7 +3215,7 @@ ); LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.depromeet.StreetDropRelease.ShareExtension; + PRODUCT_BUNDLE_IDENTIFIER = com.depromeet.StreetDropDebug.ShareExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; @@ -2870,7 +3240,7 @@ INFOPLIST_FILE = ShareExtension/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = ShareExtension; INFOPLIST_KEY_NSHumanReadableCopyright = ""; - IPHONEOS_DEPLOYMENT_TARGET = 17.5; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -3086,6 +3456,23 @@ package = C41972582ABEDE0200211222 /* XCRemoteSwiftPackageReference "Kingfisher" */; productName = Kingfisher; }; + C432DE042C69D963003DBA18 /* RxCocoa */ = { + isa = XCSwiftPackageProductDependency; + productName = RxCocoa; + }; + C432DE062C69D963003DBA18 /* RxRelay */ = { + isa = XCSwiftPackageProductDependency; + productName = RxRelay; + }; + C432DE082C69D963003DBA18 /* RxSwift */ = { + isa = XCSwiftPackageProductDependency; + productName = RxSwift; + }; + C432DEF12C69F6C4003DBA18 /* OrderedCollections */ = { + isa = XCSwiftPackageProductDependency; + package = C4FDF55F2C60C4D700551A16 /* XCRemoteSwiftPackageReference "swift-collections" */; + productName = OrderedCollections; + }; C47C1D1A2A643B38007317EA /* Lottie */ = { isa = XCSwiftPackageProductDependency; package = C47C1D192A643B38007317EA /* XCRemoteSwiftPackageReference "lottie-ios" */; @@ -3096,6 +3483,36 @@ package = 049BC4242A02826400071A12 /* XCRemoteSwiftPackageReference "RxSwift" */; productName = "RxCocoa-Dynamic"; }; + C4C9D5A32C69FBCB005D90C4 /* Moya */ = { + isa = XCSwiftPackageProductDependency; + package = 049BC4342A02845900071A12 /* XCRemoteSwiftPackageReference "Moya" */; + productName = Moya; + }; + C4C9D5A52C69FBCB005D90C4 /* ReactiveMoya */ = { + isa = XCSwiftPackageProductDependency; + package = 049BC4342A02845900071A12 /* XCRemoteSwiftPackageReference "Moya" */; + productName = ReactiveMoya; + }; + C4C9D5A72C69FBCB005D90C4 /* RxMoya */ = { + isa = XCSwiftPackageProductDependency; + package = 049BC4342A02845900071A12 /* XCRemoteSwiftPackageReference "Moya" */; + productName = RxMoya; + }; + C4C9D5A92C69FBCB005D90C4 /* SnapKit */ = { + isa = XCSwiftPackageProductDependency; + package = 049BC4392A0284E900071A12 /* XCRemoteSwiftPackageReference "SnapKit" */; + productName = SnapKit; + }; + C4C9D5AB2C69FBEB005D90C4 /* Kingfisher */ = { + isa = XCSwiftPackageProductDependency; + package = C41972582ABEDE0200211222 /* XCRemoteSwiftPackageReference "Kingfisher" */; + productName = Kingfisher; + }; + C4C9D5AD2C69FBF8005D90C4 /* Lottie */ = { + isa = XCSwiftPackageProductDependency; + package = C47C1D192A643B38007317EA /* XCRemoteSwiftPackageReference "lottie-ios" */; + productName = Lottie; + }; C4FDF5602C60C4D700551A16 /* OrderedCollections */ = { isa = XCSwiftPackageProductDependency; package = C4FDF55F2C60C4D700551A16 /* XCRemoteSwiftPackageReference "swift-collections" */; From d976f67fb959d211ddcd1de44e8d52d12117e959 Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Tue, 13 Aug 2024 09:17:58 +0900 Subject: [PATCH 04/37] =?UTF-8?q?=E2=9C=A8#297:=20=ED=8F=B0=ED=8A=B8?= =?UTF-8?q?=EB=93=A4=20Share=20Extension=20=ED=83=80=EA=B2=9F=20=EB=A9=A4?= =?UTF-8?q?=EB=B2=84=EC=89=BD=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../StreetDrop.xcodeproj/project.pbxproj | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/StreetDrop/StreetDrop.xcodeproj/project.pbxproj b/StreetDrop/StreetDrop.xcodeproj/project.pbxproj index 17dc156d..cdcd2605 100644 --- a/StreetDrop/StreetDrop.xcodeproj/project.pbxproj +++ b/StreetDrop/StreetDrop.xcodeproj/project.pbxproj @@ -166,6 +166,16 @@ B4B9EE842ADBDFFB000A6507 /* RecommendMusicSearchCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4B9EE832ADBDFFB000A6507 /* RecommendMusicSearchCollectionView.swift */; }; B4B9EE862ADEB2AC000A6507 /* RecommendKeywordItemCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4B9EE852ADEB2AC000A6507 /* RecommendKeywordItemCell.swift */; }; C40008EA2A32012B00EA7FA9 /* Music.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40008E92A32012B00EA7FA9 /* Music.swift */; }; + C408B0302C6A5E8200338BFE /* Pretendard-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = C4D16FB32A1B917B008B076F /* Pretendard-Regular.otf */; }; + C408B0312C6A5E8200338BFE /* Pretendard-SemiBold.otf in Resources */ = {isa = PBXBuildFile; fileRef = C4D16FB52A1B917B008B076F /* Pretendard-SemiBold.otf */; }; + C408B0322C6A5E8200338BFE /* Pretendard-ExtraBold.otf in Resources */ = {isa = PBXBuildFile; fileRef = C4D16FB42A1B917B008B076F /* Pretendard-ExtraBold.otf */; }; + C408B0332C6A5E8200338BFE /* Pretendard-Black.otf in Resources */ = {isa = PBXBuildFile; fileRef = C4D16FB82A1B917B008B076F /* Pretendard-Black.otf */; }; + C408B0342C6A5E8200338BFE /* Pretendard-ExtraLight.otf in Resources */ = {isa = PBXBuildFile; fileRef = C4D16FBA2A1B917B008B076F /* Pretendard-ExtraLight.otf */; }; + C408B0352C6A5E8200338BFE /* Pretendard-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = C4D16FB92A1B917B008B076F /* Pretendard-Light.otf */; }; + C408B0362C6A5E8200338BFE /* Pretendard-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = C4D16FB72A1B917B008B076F /* Pretendard-Medium.otf */; }; + C408B0372C6A5E8200338BFE /* Pretendard-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = C4D16FBB2A1B917B008B076F /* Pretendard-Bold.otf */; }; + C408B0382C6A5E8200338BFE /* Pretendard-Thin.otf in Resources */ = {isa = PBXBuildFile; fileRef = C4D16FB62A1B917B008B076F /* Pretendard-Thin.otf */; }; + C408B03A2C6A63B500338BFE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 040685082A01539800377094 /* Assets.xcassets */; }; C419722E2ABD9D6F00211222 /* MyInfoUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C419722D2ABD9D6F00211222 /* MyInfoUseCase.swift */; }; C41972302ABDAB0200211222 /* DefaultMyInfoUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C419722F2ABDAB0200211222 /* DefaultMyInfoUseCase.swift */; }; C41972322ABDAEF200211222 /* MyInfoError.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41972312ABDAEF200211222 /* MyInfoError.swift */; }; @@ -2355,7 +2365,16 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - C42182C02C697F9700B73A99 /* Base in Resources */, + C408B0362C6A5E8200338BFE /* Pretendard-Medium.otf in Resources */, + C408B0372C6A5E8200338BFE /* Pretendard-Bold.otf in Resources */, + C408B0302C6A5E8200338BFE /* Pretendard-Regular.otf in Resources */, + C408B0382C6A5E8200338BFE /* Pretendard-Thin.otf in Resources */, + C408B03A2C6A63B500338BFE /* Assets.xcassets in Resources */, + C408B0312C6A5E8200338BFE /* Pretendard-SemiBold.otf in Resources */, + C408B0342C6A5E8200338BFE /* Pretendard-ExtraLight.otf in Resources */, + C408B0332C6A5E8200338BFE /* Pretendard-Black.otf in Resources */, + C408B0322C6A5E8200338BFE /* Pretendard-ExtraBold.otf in Resources */, + C408B0352C6A5E8200338BFE /* Pretendard-Light.otf in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; From 6dac9755fba3c257fc0169b1abe66c76fcd70b5f Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Tue, 13 Aug 2024 09:20:58 +0900 Subject: [PATCH 05/37] =?UTF-8?q?=F0=9F=9B=A0#297:=20Share=20Extension?= =?UTF-8?q?=EC=9D=98=20=EB=8F=84=EC=9E=85=EB=B6=80=20=ED=99=94=EB=A9=B4(Sh?= =?UTF-8?q?areViewController)=20=EC=BD=94=EB=93=9C=20=EB=B2=A0=EC=9D=B4?= =?UTF-8?q?=EC=8A=A4=20UI=EB=A1=9C=20=EC=A7=80=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- StreetDrop/Podfile.lock | 4 +- StreetDrop/ShareExtension/Info.plist | 18 +++++++- .../View/Base.lproj/MainInterface.storyboard | 24 ---------- .../StreetDrop.xcodeproj/project.pbxproj | 44 ++++++++++++++----- 4 files changed, 51 insertions(+), 39 deletions(-) delete mode 100644 StreetDrop/ShareExtension/View/Base.lproj/MainInterface.storyboard diff --git a/StreetDrop/Podfile.lock b/StreetDrop/Podfile.lock index 3f489f43..922103a7 100644 --- a/StreetDrop/Podfile.lock +++ b/StreetDrop/Podfile.lock @@ -23,6 +23,6 @@ SPEC CHECKSUMS: NMapsGeometry: 53c573ead66466681cf123f99f698dc8071a4b83 NMapsMap: aaa64717249b06ae82c3a3addb3a01f0e33100ab -PODFILE CHECKSUM: c1edcf3d49503875acf5f6e7bfd364191c925046 +PODFILE CHECKSUM: a8c0902adb23412ed3e2bbd632c3c7f7846b9405 -COCOAPODS: 1.15.2 +COCOAPODS: 1.12.1 diff --git a/StreetDrop/ShareExtension/Info.plist b/StreetDrop/ShareExtension/Info.plist index 4b1f7e70..058a2607 100644 --- a/StreetDrop/ShareExtension/Info.plist +++ b/StreetDrop/ShareExtension/Info.plist @@ -2,17 +2,31 @@ + GADApplicationIdentifier + ca-app-pub-7717835511859758~1784783942 NSExtension + NSExtensionPrincipalClass + $(PRODUCT_MODULE_NAME).ShareViewController NSExtensionAttributes NSExtensionActivationRule TRUEPREDICATE - NSExtensionMainStoryboard - MainInterface NSExtensionPointIdentifier com.apple.share-services + UIAppFonts + + Pretendard-Black.otf + Pretendard-Bold.otf + Pretendard-ExtraBold.otf + Pretendard-ExtraLight.otf + Pretendard-Light.otf + Pretendard-Medium.otf + Pretendard-Regular.otf + Pretendard-SemiBold.otf + Pretendard-Thin.otf + diff --git a/StreetDrop/ShareExtension/View/Base.lproj/MainInterface.storyboard b/StreetDrop/ShareExtension/View/Base.lproj/MainInterface.storyboard deleted file mode 100644 index 286a5089..00000000 --- a/StreetDrop/ShareExtension/View/Base.lproj/MainInterface.storyboard +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/StreetDrop/StreetDrop.xcodeproj/project.pbxproj b/StreetDrop/StreetDrop.xcodeproj/project.pbxproj index cdcd2605..7ad5cdb4 100644 --- a/StreetDrop/StreetDrop.xcodeproj/project.pbxproj +++ b/StreetDrop/StreetDrop.xcodeproj/project.pbxproj @@ -162,6 +162,7 @@ 6AAFD9AD2BCE55A4001A6772 /* LevelPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AAFD9AC2BCE55A4001A6772 /* LevelPolicy.swift */; }; 6AAFD9AF2BCE567A001A6772 /* FetchingLevelPolicyUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AAFD9AE2BCE567A001A6772 /* FetchingLevelPolicyUseCase.swift */; }; 6AAFD9B12BCE56A6001A6772 /* DefaultFetchingLevelPolicyUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AAFD9B02BCE56A6001A6772 /* DefaultFetchingLevelPolicyUseCase.swift */; }; + ADE9937EA437A957C3ABA1A1 /* libPods-ShareExtension.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 65CC40267A5C3004E2F36C6C /* libPods-ShareExtension.a */; }; B46578C32B00BC060024B066 /* LeftAlignedCollectionViewFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = B46578C22B00BC060024B066 /* LeftAlignedCollectionViewFlowLayout.swift */; }; B4B9EE842ADBDFFB000A6507 /* RecommendMusicSearchCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4B9EE832ADBDFFB000A6507 /* RecommendMusicSearchCollectionView.swift */; }; B4B9EE862ADEB2AC000A6507 /* RecommendKeywordItemCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4B9EE852ADEB2AC000A6507 /* RecommendKeywordItemCell.swift */; }; @@ -201,7 +202,6 @@ C41BD2E92A38467A0090EF2B /* UIImageView+ImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41BD2E82A38467A0090EF2B /* UIImageView+ImageCache.swift */; }; C41BD2EC2A3848880090EF2B /* UIImage+loadURLImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41BD2EB2A3848880090EF2B /* UIImage+loadURLImage.swift */; }; C41BD2ED2A3848880090EF2B /* UIImage+loadURLImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41BD2EB2A3848880090EF2B /* UIImage+loadURLImage.swift */; }; - C42182C02C697F9700B73A99 /* Base in Resources */ = {isa = PBXBuildFile; fileRef = C42182BF2C697F9700B73A99 /* Base */; }; C42182C42C697F9700B73A99 /* ShareExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = C42182BA2C697F9700B73A99 /* ShareExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; C42361782B0CE8F800F61E3C /* RecommendMusic.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42361772B0CE8F800F61E3C /* RecommendMusic.swift */; }; C432DE052C69D963003DBA18 /* RxCocoa in Frameworks */ = {isa = PBXBuildFile; productRef = C432DE042C69D963003DBA18 /* RxCocoa */; }; @@ -583,6 +583,7 @@ 08F574572C46985300635B54 /* DefaultFetchingMyLikeListUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultFetchingMyLikeListUseCase.swift; sourceTree = ""; }; 08F5745A2C4698B300635B54 /* FetchingMyLevelUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FetchingMyLevelUseCase.swift; sourceTree = ""; }; 08F5745C2C46992500635B54 /* DefaultFetchingMyLevelUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultFetchingMyLevelUseCase.swift; sourceTree = ""; }; + 13ACF3C8F07C1A2CFE303F4A /* Pods-ShareExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShareExtension.debug.xcconfig"; path = "Target Support Files/Pods-ShareExtension/Pods-ShareExtension.debug.xcconfig"; sourceTree = ""; }; 1816ED3B2A680608005009FC /* MusicListSectionHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MusicListSectionHeaderView.swift; sourceTree = ""; }; 1816ED3E2A68064E005009FC /* MyPageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyPageViewModel.swift; sourceTree = ""; }; 1816ED402A685704005009FC /* NicknameEditViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NicknameEditViewModel.swift; sourceTree = ""; }; @@ -664,6 +665,7 @@ 41FF58F92A06B38800ABB871 /* NetworkManagerTest.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NetworkManagerTest.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 41FF58FB2A06B38800ABB871 /* NetworkManagerTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkManagerTest.swift; sourceTree = ""; }; 642A4AE13B198B9F5F5F76E4 /* libPods-StreetDrop.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-StreetDrop.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 65CC40267A5C3004E2F36C6C /* libPods-ShareExtension.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ShareExtension.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 6A1386AA2B4F8A5000E49BB5 /* String+Base64.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Base64.swift"; sourceTree = ""; }; 6A26BF312B33D1E40007B6B7 /* FetchingSingleMusicUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FetchingSingleMusicUseCase.swift; sourceTree = ""; }; 6A26BF332B33D2210007B6B7 /* DefaultFetchingSingleMusicUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultFetchingSingleMusicUseCase.swift; sourceTree = ""; }; @@ -685,6 +687,7 @@ 6AAFD9AC2BCE55A4001A6772 /* LevelPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LevelPolicy.swift; sourceTree = ""; }; 6AAFD9AE2BCE567A001A6772 /* FetchingLevelPolicyUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FetchingLevelPolicyUseCase.swift; sourceTree = ""; }; 6AAFD9B02BCE56A6001A6772 /* DefaultFetchingLevelPolicyUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultFetchingLevelPolicyUseCase.swift; sourceTree = ""; }; + B20DBB514344BC89E684862A /* Pods-ShareExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShareExtension.release.xcconfig"; path = "Target Support Files/Pods-ShareExtension/Pods-ShareExtension.release.xcconfig"; sourceTree = ""; }; B46578C22B00BC060024B066 /* LeftAlignedCollectionViewFlowLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeftAlignedCollectionViewFlowLayout.swift; sourceTree = ""; }; B4B9EE832ADBDFFB000A6507 /* RecommendMusicSearchCollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendMusicSearchCollectionView.swift; sourceTree = ""; }; B4B9EE852ADEB2AC000A6507 /* RecommendKeywordItemCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendKeywordItemCell.swift; sourceTree = ""; }; @@ -714,7 +717,6 @@ C41BD2EB2A3848880090EF2B /* UIImage+loadURLImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+loadURLImage.swift"; sourceTree = ""; }; C42182BA2C697F9700B73A99 /* ShareExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = ShareExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; C42182BC2C697F9700B73A99 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = ""; }; - C42182BF2C697F9700B73A99 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = ""; }; C42182C12C697F9700B73A99 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; C42182CB2C69C41800B73A99 /* ShareViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewModel.swift; sourceTree = ""; }; C42361772B0CE8F800F61E3C /* RecommendMusic.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RecommendMusic.swift; sourceTree = ""; }; @@ -866,6 +868,7 @@ C4C9D5A82C69FBCB005D90C4 /* RxMoya in Frameworks */, C432DE052C69D963003DBA18 /* RxCocoa in Frameworks */, C4C9D5A62C69FBCB005D90C4 /* ReactiveMoya in Frameworks */, + ADE9937EA437A957C3ABA1A1 /* libPods-ShareExtension.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1733,6 +1736,7 @@ isa = PBXGroup; children = ( 642A4AE13B198B9F5F5F76E4 /* libPods-StreetDrop.a */, + 65CC40267A5C3004E2F36C6C /* libPods-ShareExtension.a */, ); name = Frameworks; sourceTree = ""; @@ -1759,7 +1763,6 @@ isa = PBXGroup; children = ( C42182BC2C697F9700B73A99 /* ShareViewController.swift */, - C42182BE2C697F9700B73A99 /* MainInterface.storyboard */, ); path = View; sourceTree = ""; @@ -2123,6 +2126,8 @@ children = ( 33C6E9256EDABFB58F83B1C8 /* Pods-StreetDrop.debug.xcconfig */, 2611E7411DB7C5436A272A27 /* Pods-StreetDrop.release.xcconfig */, + 13ACF3C8F07C1A2CFE303F4A /* Pods-ShareExtension.debug.xcconfig */, + B20DBB514344BC89E684862A /* Pods-ShareExtension.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -2253,6 +2258,7 @@ isa = PBXNativeTarget; buildConfigurationList = C42182C82C697F9700B73A99 /* Build configuration list for PBXNativeTarget "ShareExtension" */; buildPhases = ( + 7AC41A8E2B2F8DC531DD276C /* [CP] Check Pods Manifest.lock */, C42182B62C697F9700B73A99 /* Sources */, C42182B72C697F9700B73A99 /* Frameworks */, C42182B82C697F9700B73A99 /* Resources */, @@ -2401,6 +2407,28 @@ shellPath = /bin/sh; shellScript = "\"${BUILD_DIR%Build/*}SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/run\"\n"; }; + 7AC41A8E2B2F8DC531DD276C /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-ShareExtension-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; AAAD975E0D7F49C08E568D59 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -2950,14 +2978,6 @@ name = LaunchScreen.storyboard; sourceTree = ""; }; - C42182BE2C697F9700B73A99 /* MainInterface.storyboard */ = { - isa = PBXVariantGroup; - children = ( - C42182BF2C697F9700B73A99 /* Base */, - ); - name = MainInterface.storyboard; - sourceTree = ""; - }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ @@ -3214,6 +3234,7 @@ }; C42182C62C697F9700B73A99 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 13ACF3C8F07C1A2CFE303F4A /* Pods-ShareExtension.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CODE_SIGN_IDENTITY = "Apple Development"; @@ -3246,6 +3267,7 @@ }; C42182C72C697F9700B73A99 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = B20DBB514344BC89E684862A /* Pods-ShareExtension.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CODE_SIGN_IDENTITY = "Apple Distribution"; From 438cc57417d60591eef44257c28a54c29ca2e6ba Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Tue, 13 Aug 2024 09:24:58 +0900 Subject: [PATCH 06/37] =?UTF-8?q?=F0=9F=9B=A0#297:=20RxGesture=20SPM?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../StreetDrop.xcodeproj/project.pbxproj | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/StreetDrop/StreetDrop.xcodeproj/project.pbxproj b/StreetDrop/StreetDrop.xcodeproj/project.pbxproj index 7ad5cdb4..00ae1ed3 100644 --- a/StreetDrop/StreetDrop.xcodeproj/project.pbxproj +++ b/StreetDrop/StreetDrop.xcodeproj/project.pbxproj @@ -418,6 +418,8 @@ C46293D42C649B7600FF4A7A /* FetchingRegionFilteredLikeUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46293D32C649B7600FF4A7A /* FetchingRegionFilteredLikeUseCase.swift */; }; C46293D52C649B7600FF4A7A /* FetchingRegionFilteredLikeUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46293D32C649B7600FF4A7A /* FetchingRegionFilteredLikeUseCase.swift */; }; C46410F42A629820009DD88F /* MusicAppButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46410F32A629820009DD88F /* MusicAppButton.swift */; }; + C465BD7B2C6ADF2800C42FF1 /* RxGesture in Frameworks */ = {isa = PBXBuildFile; productRef = C465BD7A2C6ADF2800C42FF1 /* RxGesture */; }; + C465BD7D2C6ADF3700C42FF1 /* RxGesture in Frameworks */ = {isa = PBXBuildFile; productRef = C465BD7C2C6ADF3700C42FF1 /* RxGesture */; }; C4685B362B725FF500F514C7 /* UserCircleRadiusResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4685B352B725FF500F514C7 /* UserCircleRadiusResponseDTO.swift */; }; C4685B382B72605500F514C7 /* FetchingUserCircleRadiusUsecase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4685B372B72605500F514C7 /* FetchingUserCircleRadiusUsecase.swift */; }; C4685B3A2B72610600F514C7 /* DefaultFetchingUserCircleRadiusUsecase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4685B392B72610600F514C7 /* DefaultFetchingUserCircleRadiusUsecase.swift */; }; @@ -830,6 +832,7 @@ C4FDF5612C60C4D700551A16 /* OrderedCollections in Frameworks */, 0856523F2AF6A2AD00FD9BCB /* FirebaseAnalyticsSwift in Frameworks */, C47C1D1B2A643B38007317EA /* Lottie in Frameworks */, + C465BD7B2C6ADF2800C42FF1 /* RxGesture in Frameworks */, 049BC42A2A02826400071A12 /* RxSwift in Frameworks */, 049BC4282A02826400071A12 /* RxRelay in Frameworks */, 049BC43B2A0284E900071A12 /* SnapKit in Frameworks */, @@ -868,6 +871,7 @@ C4C9D5A82C69FBCB005D90C4 /* RxMoya in Frameworks */, C432DE052C69D963003DBA18 /* RxCocoa in Frameworks */, C4C9D5A62C69FBCB005D90C4 /* ReactiveMoya in Frameworks */, + C465BD7D2C6ADF3700C42FF1 /* RxGesture in Frameworks */, ADE9937EA437A957C3ABA1A1 /* libPods-ShareExtension.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2227,6 +2231,7 @@ 085652482AF6A2AD00FD9BCB /* FirebaseInAppMessagingSwift-Beta */, 0856524A2AF6A2AD00FD9BCB /* FirebaseMessaging */, C4FDF5602C60C4D700551A16 /* OrderedCollections */, + C465BD7A2C6ADF2800C42FF1 /* RxGesture */, ); productName = StreetDrop; productReference = 040684FC2A01539800377094 /* StreetDrop.app */; @@ -2279,6 +2284,7 @@ C4C9D5A92C69FBCB005D90C4 /* SnapKit */, C4C9D5AB2C69FBEB005D90C4 /* Kingfisher */, C4C9D5AD2C69FBF8005D90C4 /* Lottie */, + C465BD7C2C6ADF3700C42FF1 /* RxGesture */, ); productName = ShareExtension; productReference = C42182BA2C697F9700B73A99 /* ShareExtension.appex */; @@ -2324,6 +2330,7 @@ C41972582ABEDE0200211222 /* XCRemoteSwiftPackageReference "Kingfisher" */, 085652392AF6A2AD00FD9BCB /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, C4FDF55F2C60C4D700551A16 /* XCRemoteSwiftPackageReference "swift-collections" */, + C465BD792C6ADF2800C42FF1 /* XCRemoteSwiftPackageReference "RxGesture" */, ); productRefGroup = 040684FD2A01539800377094 /* Products */; projectDirPath = ""; @@ -3388,6 +3395,14 @@ minimumVersion = 7.0.0; }; }; + C465BD792C6ADF2800C42FF1 /* XCRemoteSwiftPackageReference "RxGesture" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/RxSwiftCommunity/RxGesture"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 4.0.4; + }; + }; C47C1D192A643B38007317EA /* XCRemoteSwiftPackageReference "lottie-ios" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/airbnb/lottie-ios"; @@ -3514,6 +3529,16 @@ package = C4FDF55F2C60C4D700551A16 /* XCRemoteSwiftPackageReference "swift-collections" */; productName = OrderedCollections; }; + C465BD7A2C6ADF2800C42FF1 /* RxGesture */ = { + isa = XCSwiftPackageProductDependency; + package = C465BD792C6ADF2800C42FF1 /* XCRemoteSwiftPackageReference "RxGesture" */; + productName = RxGesture; + }; + C465BD7C2C6ADF3700C42FF1 /* RxGesture */ = { + isa = XCSwiftPackageProductDependency; + package = C465BD792C6ADF2800C42FF1 /* XCRemoteSwiftPackageReference "RxGesture" */; + productName = RxGesture; + }; C47C1D1A2A643B38007317EA /* Lottie */ = { isa = XCSwiftPackageProductDependency; package = C47C1D192A643B38007317EA /* XCRemoteSwiftPackageReference "lottie-ios" */; From 858da9474e8745da69a60982c64421942454534a Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Wed, 14 Aug 2024 13:44:03 +0900 Subject: [PATCH 07/37] =?UTF-8?q?=E2=9C=A8#297:=20Share=20Extensuon?= =?UTF-8?q?=EC=9D=98=20ShareViewController=20viewDidLoad=EC=8B=9C=20?= =?UTF-8?q?=EA=B0=80=EC=A0=B8=EC=98=A8=20=EC=9C=84=EC=B9=98=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=EB=A5=BC=20=EA=B0=80=EC=A7=80=EA=B3=A0=20=EC=84=9C?= =?UTF-8?q?=EB=B2=84=ED=86=B5=EC=8B=A0=EC=9D=84=20=ED=86=B5=ED=95=B4=20?= =?UTF-8?q?=EC=A3=BC=EC=86=8C=20=EC=B0=8D=EC=96=B4=EC=A4=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 그 외 몇가지 UI들만 추가 --- .../View/ShareViewController.swift | 157 ++++++++++++++++++ .../ViewModel/ShareViewModel.swift | 32 +++- .../DefaultSearchingMusicRepository.swift | 5 +- .../next.imageset/Contents.json | 23 +++ .../Assets.xcassets/next.imageset/next.png | Bin 0 -> 266 bytes .../Assets.xcassets/next.imageset/next@2x.png | Bin 0 -> 393 bytes .../Assets.xcassets/next.imageset/next@3x.png | Bin 0 -> 453 bytes .../verctor.imageset/Contents.json | 23 +++ .../verctor.imageset/verctor.png | Bin 0 -> 314 bytes .../verctor.imageset/verctor@2x.png | Bin 0 -> 466 bytes .../verctor.imageset/verctor@3x.png | Bin 0 -> 546 bytes 11 files changed, 238 insertions(+), 2 deletions(-) create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/next.imageset/Contents.json create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/next.imageset/next.png create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/next.imageset/next@2x.png create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/next.imageset/next@3x.png create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/verctor.imageset/Contents.json create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/verctor.imageset/verctor.png create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/verctor.imageset/verctor@2x.png create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/verctor.imageset/verctor@3x.png diff --git a/StreetDrop/ShareExtension/View/ShareViewController.swift b/StreetDrop/ShareExtension/View/ShareViewController.swift index 281924cc..659a61d7 100644 --- a/StreetDrop/ShareExtension/View/ShareViewController.swift +++ b/StreetDrop/ShareExtension/View/ShareViewController.swift @@ -8,15 +8,106 @@ import UIKit import Social +import Kingfisher import RxSwift +import RxRelay +import SnapKit final class ShareViewController: SLComposeServiceViewController { +final class ShareViewController: UIViewController { private let viewModel: ShareViewModel = .init() private let disposeBag: DisposeBag = .init() override func isContentValid() -> Bool { return true } + private let containerView: UIView = { + let view: UIView = .init() + view.backgroundColor = .gray800 + view.layer.cornerRadius = 20 + view.layer.borderWidth = 1 + view.layer.borderColor = UIColor.gray600.cgColor + + return view + }() + + private let villageNameLabel: UILabel = { + let label: UILabel = .init() + label.text = " " + label.font = .pretendard(size: 16, weight: 700) + label.textColor = .primary400 + label.setLineHeight(lineHeight: 24) + + return label + }() + + private let changingMusicView: UIView = { + let view: UIView = .init() + view.backgroundColor = .gray600 + view.layer.cornerRadius = 12 + view.layer.borderWidth = 1 + view.layer.borderColor = UIColor(hexString: "#363840").cgColor + + let label: UILabel = .init() + label.text = "원하는 음악이 아닌가요?" + label.font = .pretendard(size: 14, weight: 500) + label.textColor = .gray150 + label.setLineHeight(lineHeight: 20) + + let imageView: UIImageView = .init(image: .init(named: "next")) + + [label, imageView].forEach { + view.addSubview($0) + } + label.snp.makeConstraints { + $0.height.equalTo(20) + $0.top.equalToSuperview().inset(4) + $0.leading.equalToSuperview().inset(10) + } + imageView.snp.makeConstraints { + $0.width.height.equalTo(20) + $0.top.equalToSuperview().inset(4) + $0.trailing.equalToSuperview().inset(12) + } + + return view + }() + + private let belowArrow: UIImageView = { + let imageView: UIImageView = .init(image: .init(named: "verctor")) + + return imageView + }() + + private let albumCoverImageView: UIImageView = { + let imageView: UIImageView = .init() + imageView.layer.cornerRadius = 20 + imageView.clipsToBounds = true + + return imageView + }() + + private let songNameLabel: UILabel = { + let label: UILabel = .init() + label.text = " " + label.font = .pretendard(size: 16, weight: 700) + label.textColor = .textPrimary + label.setLineHeight(lineHeight: 24) + label.textAlignment = .center + + return label + }() + + private let artistNameLabel: UILabel = { + let label: UILabel = .init() + label.text = " " + label.textColor = .gray400 + label.font = .pretendard(size: 12, weight: 400) + label.setLineHeight(lineHeight: 16) + label.textAlignment = .center + + return label + }() override func didSelectPost() { extensionContext?.completeRequest(returningItems: [], completionHandler: nil) @@ -29,6 +120,7 @@ final class ShareViewController: SLComposeServiceViewController { override func viewDidLoad() { super.viewDidLoad() bindViewModel() + configureUI() } } @@ -39,7 +131,72 @@ private extension ShareViewController { input: input, disposedBag: disposeBag ) + + output.showVillageName + .bind(with: self) { owner, villageName in + owner.villageNameLabel.text = villageName + } + .disposed(by: disposeBag) } + func configureUI() { + view.addSubview(containerView) + view.backgroundColor = UIColor.black.withAlphaComponent(0.5) + + containerView.snp.makeConstraints { + $0.height.equalTo(596) + $0.horizontalEdges.bottom.equalToSuperview() + } + + [ + villageNameLabel, + changingMusicView, + belowArrow, + albumCoverImageView, + songNameLabel, + artistNameLabel + ].forEach { + containerView.addSubview($0) + } + + villageNameLabel.snp.makeConstraints { + $0.height.equalTo(24) + $0.top.equalToSuperview().inset(24) + $0.centerX.equalToSuperview() + } + + changingMusicView.snp.makeConstraints { + $0.width.equalTo(174) + $0.height.equalTo(28) + $0.top.equalTo(villageNameLabel.snp.bottom).offset(25) + $0.centerX.equalToSuperview() + } + + belowArrow.snp.makeConstraints { + $0.width.equalTo(10) + $0.height.equalTo(6) + $0.top.equalTo(changingMusicView.snp.bottom) + $0.centerX.equalTo(changingMusicView) + } + + albumCoverImageView.snp.makeConstraints { + $0.width.height.equalTo(85) + $0.top.equalTo(belowArrow.snp.bottom).offset(15) + $0.centerX.equalToSuperview() + } + + songNameLabel.snp.makeConstraints { + $0.height.equalTo(24) + $0.top.equalTo(albumCoverImageView.snp.bottom).offset(16) + $0.horizontalEdges.equalToSuperview() + } + + artistNameLabel.snp.makeConstraints { + $0.height.equalTo(16) + $0.top.equalTo(songNameLabel.snp.bottom).offset(2) + $0.horizontalEdges.equalToSuperview() + } + } +} } diff --git a/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift b/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift index f574040d..a6223811 100644 --- a/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift +++ b/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift @@ -21,6 +21,12 @@ protocol ShareViewModelType { final class ShareViewModel: NSObject, ShareViewModelType { private let output: Output = .init() private let locationManger: CLLocationManager = .init() + private let searchMusicUsecase: SearchMusicUsecase + private let disposeBag: DisposeBag = .init() + + init(searchMusicUsecase: SearchMusicUsecase = DefaultSearchingMusicUsecase()) { + self.searchMusicUsecase = searchMusicUsecase + } struct Input { let viewDidLoadEvent: Observable @@ -28,11 +34,15 @@ final class ShareViewModel: NSObject, ShareViewModelType { struct Output { + fileprivate let showVillageNameRelay: PublishRelay = .init() + var showVillageName: Observable { + showVillageNameRelay.asObservable() + } } func convert(input: Input, disposedBag: DisposeBag) -> Output { input.viewDidLoadEvent - .subscribe(with: self) { owner, _ in + .bind(with: self) { owner, _ in owner.locationManger.delegate = self owner.locationManger.requestWhenInUseAuthorization() owner.locationManger.startUpdatingLocation() @@ -45,5 +55,25 @@ final class ShareViewModel: NSObject, ShareViewModelType { } extension ShareViewModel: CLLocationManagerDelegate { + func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { + guard let location = locations.last else { return } + + searchMusicUsecase.getVillageName( + latitude: location.coordinate.latitude, + longitude: location.coordinate.longitude + ) + .subscribe(with: self) { owner, villageName in + owner.output.showVillageNameRelay.accept(villageName) + } onFailure: { owner, error in + print(error.localizedDescription) + } + .disposed(by: disposeBag) + + manager.stopUpdatingLocation() + } + func locationManager(_ manager: CLLocationManager, didFailWithError error: any Error) { + // TODO: 요셉, 에러메세지 띄우기 + print("위치 정보를 가져오는데 실패했습니다: \(error.localizedDescription)") + } } diff --git a/StreetDrop/StreetDrop/Data/Repositories/SearchingMusic/DefaultSearchingMusicRepository.swift b/StreetDrop/StreetDrop/Data/Repositories/SearchingMusic/DefaultSearchingMusicRepository.swift index f171b776..95b68c60 100644 --- a/StreetDrop/StreetDrop/Data/Repositories/SearchingMusic/DefaultSearchingMusicRepository.swift +++ b/StreetDrop/StreetDrop/Data/Repositories/SearchingMusic/DefaultSearchingMusicRepository.swift @@ -77,7 +77,10 @@ final class DefaultSearchingMusicRepository: SearchingMusicRepository { longitude: longitude ) ), - responseType: String.self + responseType: VillageNameResponseDTO.self ) + .map { dto in + return dto.villageName + } } } diff --git a/StreetDrop/StreetDrop/Resource/Assets.xcassets/next.imageset/Contents.json b/StreetDrop/StreetDrop/Resource/Assets.xcassets/next.imageset/Contents.json new file mode 100644 index 00000000..33d0b5e1 --- /dev/null +++ b/StreetDrop/StreetDrop/Resource/Assets.xcassets/next.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "next.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "next@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "next@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/StreetDrop/StreetDrop/Resource/Assets.xcassets/next.imageset/next.png b/StreetDrop/StreetDrop/Resource/Assets.xcassets/next.imageset/next.png new file mode 100644 index 0000000000000000000000000000000000000000..0a64d60bff015487b0feecbc79e7a2a938b84cf0 GIT binary patch literal 266 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE-VXMsm#F#`j)FbFd;%$g$s6l5$8 za(7}_cTVOdki(Mh=5IOBSn^84FP2!+%M8`?LPxqV@1UOFrkz@H}cUPqH=cfPc1?McM zKh6D9E2};m9jbW| zci)`!J=Ar1eshoHa%G1jeU}XtHg;SNRM^mUx$r~^P;8>(Hx( lWj`3(Q+C_$`5fyK@2121zVQD2Ee#Ag22WQ%mvv4FO#pj9qhkO7 literal 0 HcmV?d00001 diff --git a/StreetDrop/StreetDrop/Resource/Assets.xcassets/next.imageset/next@3x.png b/StreetDrop/StreetDrop/Resource/Assets.xcassets/next.imageset/next@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..5f771104d660184e6e3cb787e34540885062ff71 GIT binary patch literal 453 zcmeAS@N?(olHy`uVBq!ia0vp^HXzKw1|+Ti+$;i8oCO|{#S9FJ79h;%I?XTvD9BhG z{PjTfO*2{cNXW38iH1DxbgD(!QZMiDp%ywZp@W576gHb#yd>6 z)Ku#6fE}UJ#nWUID+sspE%l!_25pKcd?U_l6kG>fA>bT64 syOg}}=gY*o#vC>01hkbvplF-_*6)&<^6R@8fuYXe>FVdQ&MBb@03sr_;s5{u literal 0 HcmV?d00001 diff --git a/StreetDrop/StreetDrop/Resource/Assets.xcassets/verctor.imageset/Contents.json b/StreetDrop/StreetDrop/Resource/Assets.xcassets/verctor.imageset/Contents.json new file mode 100644 index 00000000..09ceba4d --- /dev/null +++ b/StreetDrop/StreetDrop/Resource/Assets.xcassets/verctor.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "verctor.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "verctor@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "verctor@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/StreetDrop/StreetDrop/Resource/Assets.xcassets/verctor.imageset/verctor.png b/StreetDrop/StreetDrop/Resource/Assets.xcassets/verctor.imageset/verctor.png new file mode 100644 index 0000000000000000000000000000000000000000..a4ebf32ceeb628b8f8444628a6c93859802a6c46 GIT binary patch literal 314 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CO!3HF4Hmy+sQk(@Ik;M!Q+`=Ht$S`Y;1W=H% zILO_JVcj{Imp~3nx}&cn1H;CC?mvmFK>m487srqa#@fEUdpMCO6?R|Dd7bmu!^yh!eL^oDU&Xt-Tw6sk_RrdU6rDd5?0;|sW?>?*a zE#TMvu>37g{#Z^6mk16&ez)q=+{<4WIA2bAT2%V+<>jB;yf>XE?`+j?0D6tV)78&q Iol`;+02^v~rvLx| literal 0 HcmV?d00001 diff --git a/StreetDrop/StreetDrop/Resource/Assets.xcassets/verctor.imageset/verctor@2x.png b/StreetDrop/StreetDrop/Resource/Assets.xcassets/verctor.imageset/verctor@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..2ac5c4167d07fce3bb2cdab5aec1a808b7a31ee5 GIT binary patch literal 466 zcmV;@0WJQCP)K~#7FtyDcv z!cY`F?>$SxXZ!^M#^{QxiAi-b#zB9ABb)pLH&_1&gAgX#L716kput5aU79pa`|7(X zB~A0H6*$w&{W$0L-jlNP%bPDC+IL+Sp66i~s8lK_m&^2YI3RoUs#dEo3XFiV%6D z(E#UaDPaBA@k^KDd|eP44@!7O1+`iY{{^i$CWj;B-hC2Z3)pu5n}^|@T9re4q=urP zqpt3!$ioZbN^&e)d}dyE1m{*!XQdp2P)4UydpJwyMYiGHnSV6fN1sajmhKS*0i={# za+*3>r>f{ptzkb~BXo^LoTYP&j!P>Li{v{i&oMf1{DM4ZUrrgMxA0tJvbi|!H6#Jdw~Fe=jf1Hz4*86hM)0RR9107*qo IM6N<$fT^7Bzh0joDLK8k`~e7dfMq(Jg5x-_&6LY!D3wZaX;T8wj;l(g0)}D0 zwt{;lU?3pD6Q#cXKnM)u#agWfnx?^~gL_n~)p?B!gO_fLnr6qQo_Ebo%8EW9P_Ng4 zQVN?2!Yu7!Ap>57E2i1ATt8q7#10o(W0GEVa5NS$#MXT892r8`xardxeKnc~->l&( zz6<=)Y&HXx!67adi;D%~-@Lu{-s3VgER*qQxYs;l4-L++)^#0%AOP2OK^07Dh=JS< z`rXH5&!6d?j6clA{$Z0{o?u-l6ha{1_aRTvsN@(hquPW1^X+mUcXBn)XsI-Bl~KH2 zE|5y|vWyZ2ilEe(mt_?92C{xEuX+C&B@KjG*E|uU)&h#4 Date: Wed, 14 Aug 2024 13:51:03 +0900 Subject: [PATCH 08/37] =?UTF-8?q?=E2=9C=A8#297:=20=EC=9C=A0=ED=8A=9C?= =?UTF-8?q?=EB=B8=8C=20=EB=AE=A4=EC=A7=81=EC=95=B1=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EA=B3=B5=EC=9C=A0=ED=95=98=EA=B8=B0=EB=A1=9C=20=EA=B0=80?= =?UTF-8?q?=EC=A0=B8=EC=98=A8=20=EB=8D=B0=EC=9D=B4=ED=84=B0=EB=A5=BC=20?= =?UTF-8?q?=ED=8C=8C=EC=8B=B1=ED=95=9C=20=EB=85=B8=EB=9E=98=EC=9D=B4?= =?UTF-8?q?=EB=A6=84,=20=EC=95=84=ED=8B=B0=EC=8A=A4=ED=8A=B8=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=EC=9C=BC=EB=A1=9C=20=EC=9D=8C=EC=95=85=EA=B2=80?= =?UTF-8?q?=EC=83=89=20=EB=B9=84=EC=A6=88=EB=8B=88=EC=8A=A4=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=8B=A4=ED=96=89=20=EB=B0=8F=20Music=20Array=20?= =?UTF-8?q?=EC=B2=AB=EB=B2=88=EC=A7=B8=20=EC=9D=B8=EB=8D=B1=EC=8A=A4?= =?UTF-8?q?=EA=B0=92=20=EC=95=A8=EB=B2=94=EC=BB=A4=EB=B2=84,=20=EB=85=B8?= =?UTF-8?q?=EB=9E=98=EC=9D=B4=EB=A6=84,=20=EC=95=84=ED=8B=B0=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EC=9D=B4=EB=A6=84=20UI=EC=97=90=20=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/ShareViewController.swift | 70 ++++++++++++++++++- .../ViewModel/ShareViewModel.swift | 21 +++++- 2 files changed, 89 insertions(+), 2 deletions(-) diff --git a/StreetDrop/ShareExtension/View/ShareViewController.swift b/StreetDrop/ShareExtension/View/ShareViewController.swift index 659a61d7..1c6d23f8 100644 --- a/StreetDrop/ShareExtension/View/ShareViewController.swift +++ b/StreetDrop/ShareExtension/View/ShareViewController.swift @@ -17,6 +17,7 @@ final class ShareViewController: SLComposeServiceViewController { final class ShareViewController: UIViewController { private let viewModel: ShareViewModel = .init() private let disposeBag: DisposeBag = .init() + private let sharedMusicKeyWordEvent: PublishRelay = .init() override func isContentValid() -> Bool { return true @@ -121,12 +122,20 @@ final class ShareViewController: UIViewController { super.viewDidLoad() bindViewModel() configureUI() + + // 공유된 데이터 가져오기 + guard let extensionItem = extensionContext?.inputItems.first as? NSExtensionItem else { return } + handleExtensionItem(extensionItem) + } } } private extension ShareViewController { func bindViewModel() { - let input: ShareViewModel.Input = .init(viewDidLoadEvent: .just(Void())) + let input: ShareViewModel.Input = .init( + viewDidLoadEvent: .just(Void()), + sharedMusicKeyWordEvent: sharedMusicKeyWordEvent.asObservable() + ) let output: ShareViewModel.Output = viewModel.convert( input: input, disposedBag: disposeBag @@ -137,6 +146,14 @@ private extension ShareViewController { owner.villageNameLabel.text = villageName } .disposed(by: disposeBag) + + output.showSearchedMusic + .bind(with: self) { owner, music in + owner.albumCoverImageView.kf.setImage(with: URL(string: music.albumImage)) + owner.songNameLabel.text = music.songName + owner.artistNameLabel.text = music.artistName + } + .disposed(by: disposeBag) } func configureUI() { @@ -198,5 +215,56 @@ private extension ShareViewController { } } } + +// MARK: - Handle Shared Data +private extension ShareViewController { + func handleExtensionItem(_ extensionItem: NSExtensionItem) { + // ExtensionItem에서 ContentText 추출 + guard let sharedTextItem = extensionItem.attributedContentText, + let videoID = extractVideoID(from: sharedTextItem.string) else { return } + + fetchVideoDetails(videoID: videoID) { [weak self] songName, artistName in + self?.sharedMusicKeyWordEvent.accept("\(songName ?? "")-\(artistName ?? "")") + } + } + func fetchVideoDetails(videoID: String, completion: @escaping (String?, String?) -> Void) { + let apiKey = "AIzaSyDHsdIcuAK98-EW9UueCeF6g4iYiap7bmA" // YouTube Data API 키를 여기에 입력하세요 + let urlString = "https://www.googleapis.com/youtube/v3/videos?id=\(videoID)&key=\(apiKey)&part=snippet" + + guard let url = URL(string: urlString) else { + completion(nil, nil) + return + } + + let task = URLSession.shared.dataTask(with: url) { data, response, error in + guard let data = data, error == nil else { + completion(nil, nil) + return + } + + do { + if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any], + let items = json["items"] as? [[String: Any]], + let snippet = items.first?["snippet"] as? [String: Any] { + let title = snippet["title"] as? String + let channelTitle = snippet["channelTitle"] as? String + completion(title, channelTitle) + } else { + completion(nil, nil) + } + } catch { + completion(nil, nil) + } + } + task.resume() + } + + func extractVideoID(from url: String) -> String? { + guard let urlComponents = URLComponents(string: url), + let queryItems = urlComponents.queryItems else { + return nil + } + return queryItems.first(where: { $0.name == "v" })?.value + } } diff --git a/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift b/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift index a6223811..b089775d 100644 --- a/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift +++ b/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift @@ -30,14 +30,18 @@ final class ShareViewModel: NSObject, ShareViewModelType { struct Input { let viewDidLoadEvent: Observable + let sharedMusicKeyWordEvent: Observable } struct Output { - fileprivate let showVillageNameRelay: PublishRelay = .init() var showVillageName: Observable { showVillageNameRelay.asObservable() } + fileprivate let showSearchedMusicRelay: PublishRelay = .init() + var showSearchedMusic: Observable { + showSearchedMusicRelay.asObservable() + } } func convert(input: Input, disposedBag: DisposeBag) -> Output { @@ -49,6 +53,21 @@ final class ShareViewModel: NSObject, ShareViewModelType { } .disposed(by: disposedBag) + input.sharedMusicKeyWordEvent + .bind(with: self) { owner, sharedMusicKeyWord in + owner.searchMusicUsecase.searchMusic(keyword: sharedMusicKeyWord) + .subscribe(with: self) { owner, musicList in + guard let firstMusic = musicList.first else { + // TODO: 요셉, 검색된 음악 없다는 이벤트 view에 전달 + return + } + owner.output.showSearchedMusicRelay.accept(firstMusic) + } onFailure: { owner, error in + + } + .disposed(by: disposedBag) + } + .disposed(by: disposedBag) return output } From 6f2c6e1c5b7dcc5bdb6677333136de561bef6060 Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Wed, 14 Aug 2024 14:27:38 +0900 Subject: [PATCH 09/37] =?UTF-8?q?=E2=9C=A8#297:=20ShareViewController?= =?UTF-8?q?=EC=9D=98=20=EC=BD=94=EB=A9=98=ED=8A=B8=20=EC=9E=85=EB=A0=A5?= =?UTF-8?q?=EC=B0=BD=20UI/UX,=20MusicDropViewController=EC=99=80=20?= =?UTF-8?q?=EB=8F=99=EC=9D=BC=ED=95=98=EA=B2=8C=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/ShareViewController.swift | 231 +++++++++++++++++- 1 file changed, 220 insertions(+), 11 deletions(-) diff --git a/StreetDrop/ShareExtension/View/ShareViewController.swift b/StreetDrop/ShareExtension/View/ShareViewController.swift index 1c6d23f8..4bf993d3 100644 --- a/StreetDrop/ShareExtension/View/ShareViewController.swift +++ b/StreetDrop/ShareExtension/View/ShareViewController.swift @@ -13,15 +13,16 @@ import RxSwift import RxRelay import SnapKit -final class ShareViewController: SLComposeServiceViewController { final class ShareViewController: UIViewController { + enum Constant { + static let commentPlaceHolder: String = "노래, 현재 감정, 상황, 관련 에피소드, 거리, 가수 등 떠오르는 말을 적어보세요." + static let communityButtonTitle: String = "커뮤니티 가이드" + static let defaultCommentCount: String = "0/40" + } private let viewModel: ShareViewModel = .init() private let disposeBag: DisposeBag = .init() private let sharedMusicKeyWordEvent: PublishRelay = .init() - override func isContentValid() -> Bool { - return true - } private let containerView: UIView = { let view: UIView = .init() view.backgroundColor = .gray800 @@ -109,17 +110,80 @@ final class ShareViewController: UIViewController { return label }() + + private lazy var commentView: UIView = { + let view = UIView() + view.backgroundColor = .gray700 + view.layer.cornerRadius = 12 + view.layer.borderWidth = 1 + view.layer.borderColor = UIColor.gray700.cgColor + view.clipsToBounds = true + return view + }() + + lazy var commentTextView: UITextView = { + let textView = UITextView() + textView.textColor = .white + textView.font = .pretendard(size: 14, weight: 500) + textView.backgroundColor = .gray700 + textView.keyboardAppearance = .dark + textView.keyboardDismissMode = .interactive + textView.showsVerticalScrollIndicator = false + textView.returnKeyType = .done + textView.delegate = self - override func didSelectPost() { - extensionContext?.completeRequest(returningItems: [], completionHandler: nil) - } + return textView + }() + + private lazy var commentClearButton: UIButton = { + let icon = UIImage(named: "cancleButton") + let button = UIButton() + button.setImage(icon, for: .normal) + button.isHidden = true + button.isEnabled = false - override func configurationItems() -> [Any]! { - return [] - } + return button + }() + + private lazy var commentCountLabel: UILabel = { + let label = UILabel() + label.text = Constant.defaultCommentCount + label.textColor = .gray300 + label.font = .pretendard(size: 14, weightName: .medium) + label.isHidden = true + + return label + }() + + private lazy var communityGuideButton: UIButton = { + let icon = UIImage(named: "infoIcon") + let button = UIButton(frame: .zero) + button.setImage(icon, for: .normal) + button.setTitle(Constant.communityButtonTitle, for: .normal) + button.setTitleColor(.gray200, for: .normal) + button.titleLabel?.font = .pretendard(size: 12, weightName: .semiBold) + button.backgroundColor = .gray700 + button.layer.cornerRadius = 15 + button.clipsToBounds = false + + return button + }() + + private let dropButton: UIButton = { + let button = UIButton(type: .system) + button.setTitle("드랍하기", for: .normal) + button.setTitleColor(.gray400, for: .normal) + button.titleLabel?.font = .pretendard(size: 16, weightName: .bold) + button.layer.cornerRadius = 10 + button.backgroundColor = .gray300 + button.isEnabled = false + + return button + }() override func viewDidLoad() { super.viewDidLoad() + bindAction() bindViewModel() configureUI() @@ -127,10 +191,66 @@ final class ShareViewController: UIViewController { guard let extensionItem = extensionContext?.inputItems.first as? NSExtensionItem else { return } handleExtensionItem(extensionItem) } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + setupPlaceHolder() } } private extension ShareViewController { + func bindAction() { + // 코멘트 플레이스홀더, 글자수라벨 설치, 줄 수 제한, 커멘트있을때만 드랍가능 + commentTextView.rx.didBeginEditing + .subscribe { [weak self] element in + self?.removePlaceHolder() + self?.commentCountLabel.isHidden = false + self?.commentClearButton.isHidden = false + self?.commentClearButton.isEnabled = true + self?.commentView.layer.borderColor = UIColor.darkPrimary_25.cgColor + }.disposed(by: disposeBag) + + commentTextView.rx.didEndEditing + .subscribe { [weak self] element in + self?.setupPlaceHolder() + self?.commentClearButton.isHidden = true + self?.commentClearButton.isEnabled = false + self?.commentView.layer.borderColor = UIColor.gray700.cgColor + }.disposed(by: disposeBag) + + commentTextView.rx.didChange + .subscribe { [weak self] _ in + self?.checkMaxCount(max: 40) + self?.checkAvailableToDrop() + }.disposed(by: disposeBag) + + commentTextView.rx.willBeginDragging + .subscribe { [weak self] _ in + self?.commentView.layer.borderColor = UIColor.darkPrimary_25.cgColor + }.disposed(by: disposeBag) + + commentTextView.rx.didEndDragging + .subscribe { [weak self] _ in + self?.commentView.layer.borderColor = UIColor.gray700.cgColor + }.disposed(by: disposeBag) + + commentTextView.rx.text.orEmpty + .asObservable() + .bind { [weak self] text in + guard text != Constant.commentPlaceHolder, + !text.isEmpty else { return } + self?.commentCountLabel.text = "\(text.count)/40" + self?.commentView.layer.borderColor = text.count < 40 + ? UIColor.darkPrimary_25.cgColor + : UIColor.systemCritical.cgColor + }.disposed(by: disposeBag) + + commentClearButton.rx.tap + .bind { [weak self] in + self?.commentTextView.text = nil + }.disposed(by: disposeBag) + } + func bindViewModel() { let input: ShareViewModel.Input = .init( viewDidLoadEvent: .just(Void()), @@ -171,11 +291,20 @@ private extension ShareViewController { belowArrow, albumCoverImageView, songNameLabel, - artistNameLabel + artistNameLabel, + commentView ].forEach { containerView.addSubview($0) } + [ + commentTextView, + commentCountLabel, + commentClearButton + ].forEach { + commentView.addSubview($0) + } + villageNameLabel.snp.makeConstraints { $0.height.equalTo(24) $0.top.equalToSuperview().inset(24) @@ -213,6 +342,28 @@ private extension ShareViewController { $0.top.equalTo(songNameLabel.snp.bottom).offset(2) $0.horizontalEdges.equalToSuperview() } + + commentView.snp.makeConstraints { + $0.top.equalTo(artistNameLabel.snp.bottom).offset(24) + $0.leading.trailing.equalToSuperview().inset(24) + $0.height.equalTo(112) + } + + commentTextView.snp.makeConstraints { + $0.top.bottom.equalToSuperview().inset(12) + $0.leading.equalToSuperview().inset(16) + $0.trailing.equalToSuperview().inset(16+40+4) // inset+countLabel+spacing + } + + commentClearButton.snp.makeConstraints { + $0.top.trailing.equalToSuperview().inset(16) + $0.width.height.equalTo(20) + } + + commentCountLabel.snp.makeConstraints { + $0.trailing.equalTo(commentView.snp.trailing).inset(16) + $0.bottom.equalTo(commentView.snp.bottom).inset(16) + } } } @@ -267,4 +418,62 @@ private extension ShareViewController { } return queryItems.first(where: { $0.name == "v" })?.value } + + func setupPlaceHolder() { + let placeHolder: String = Constant.commentPlaceHolder + + if(commentTextView.text == nil || commentTextView.text == "") { + commentTextView.text = placeHolder + commentTextView.textColor = .gray300 + } + } + + func removePlaceHolder() { + let placeHolder: String = Constant.commentPlaceHolder + + if(commentTextView.text == placeHolder) { + commentTextView.text = nil + commentTextView.textColor = .gray100 + } + } + + func checkMaxCount(max: Int) { + let count = commentTextView.text.count + + if count > max { + commentTextView.text = String(commentTextView.text.prefix(40)) + } + } + + func checkAvailableToDrop() { + let placeHolder: String = Constant.commentPlaceHolder + + if(commentTextView.text != nil + && commentTextView.text != "" + && commentTextView.text != placeHolder + ) { + dropButton.isEnabled = true + dropButton.backgroundColor = .primary500 + dropButton.setTitleColor(.gray900, for: .normal) + } else { + dropButton.isEnabled = false + dropButton.setTitleColor( + .gray400, + for: .normal + ) + dropButton.backgroundColor = .gray300 + } + } +} + +// MARK: - UITextViewDelegate +extension ShareViewController: UITextViewDelegate { + func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { + if text == "\n" { + view.endEditing(true) + return false + } + + return true + } } From 98fa46dda6ed7b00ce71bb243fb9a4ef3647f83b Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Wed, 14 Aug 2024 14:45:44 +0900 Subject: [PATCH 10/37] =?UTF-8?q?=E2=9C=A8#297:=20ShareViewController=20?= =?UTF-8?q?=ED=85=8D=EC=8A=A4=ED=8A=B8=EB=B7=B0=20=ED=81=B4=EB=A6=AD?= =?UTF-8?q?=ED=95=B4=EC=84=9C=20=ED=82=A4=EB=B3=B4=EB=93=9C=20=EC=98=AC?= =?UTF-8?q?=EB=9D=BC=EC=98=A4=EA=B3=A0=20=EB=82=B4=EB=A0=A4=EA=B0=88?= =?UTF-8?q?=EB=95=8C=20=EB=B7=B0=20=EB=86=92=EC=9D=B4=20=EC=A1=B0=EC=A0=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/ShareViewController.swift | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/StreetDrop/ShareExtension/View/ShareViewController.swift b/StreetDrop/ShareExtension/View/ShareViewController.swift index 4bf993d3..56300893 100644 --- a/StreetDrop/ShareExtension/View/ShareViewController.swift +++ b/StreetDrop/ShareExtension/View/ShareViewController.swift @@ -186,6 +186,7 @@ final class ShareViewController: UIViewController { bindAction() bindViewModel() configureUI() + registerKeyboardNotification() // 공유된 데이터 가져오기 guard let extensionItem = extensionContext?.inputItems.first as? NSExtensionItem else { return } @@ -477,3 +478,41 @@ extension ShareViewController: UITextViewDelegate { return true } } + +// MARK: - KeyBoard +private extension ShareViewController { + func registerKeyboardNotification() { + NotificationCenter.default.addObserver( + self, + selector: #selector(keyboardWillShow), + name: UIResponder.keyboardWillShowNotification, + object: nil) + NotificationCenter.default.addObserver( + self, + selector: #selector(keyboardWillHide), + name: UIResponder.keyboardWillHideNotification, + object: nil) + } + + @objc func keyboardWillShow(_ notification: Notification) { + UIView.animate(withDuration: 0.3) { [weak self] in + guard let self = self else { return } + containerView.snp.updateConstraints { [weak self] in + guard let self = self else { return } + + $0.height.equalTo(view.bounds.height) + } + view.layoutIfNeeded() + } + } + + @objc func keyboardWillHide() { + UIView.animate(withDuration: 0.3) { [weak self] in + self?.containerView.snp.updateConstraints { + let screenHeight = UIScreen.main.bounds.height + $0.height.equalTo(596) + } + self?.view.layoutIfNeeded() + } + } +} From 81830f3cba708ddf655174c7fc24f2a81db63e59 Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Wed, 14 Aug 2024 14:57:08 +0900 Subject: [PATCH 11/37] =?UTF-8?q?=F0=9F=9B=A0#297:=20Share=20Extension=20?= =?UTF-8?q?=EC=95=B1=EB=B2=84=EC=A0=84,=20=EC=95=B1=ED=83=80=EA=B2=9F?= =?UTF-8?q?=EA=B3=BC=20=EB=8F=99=EA=B8=B0=ED=99=94=20=EB=B0=8F=20Community?= =?UTF-8?q?GuideDetailView.swift=20Share=20Extension=20=EC=95=B1=ED=83=80?= =?UTF-8?q?=EA=B2=9F=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- StreetDrop/StreetDrop.xcodeproj/project.pbxproj | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/StreetDrop/StreetDrop.xcodeproj/project.pbxproj b/StreetDrop/StreetDrop.xcodeproj/project.pbxproj index 00ae1ed3..e00b97ea 100644 --- a/StreetDrop/StreetDrop.xcodeproj/project.pbxproj +++ b/StreetDrop/StreetDrop.xcodeproj/project.pbxproj @@ -389,6 +389,7 @@ C434A4D82A17AAAB00C63526 /* SearchingMusicViewModelTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C434A4D72A17AAAB00C63526 /* SearchingMusicViewModelTest.swift */; }; C434A4DC2A19CA6F00C63526 /* SearchingMusicTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C434A4DB2A19CA6F00C63526 /* SearchingMusicTableViewCell.swift */; }; C434A4DD2A19CA6F00C63526 /* SearchingMusicTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C434A4DB2A19CA6F00C63526 /* SearchingMusicTableViewCell.swift */; }; + C44442F32C6C7CA700CA93EA /* CommunityGuideDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41589AB92A474B3D0029A2EE /* CommunityGuideDetailView.swift */; }; C44980782BC37CB70001E6C3 /* NaverMaps.plist in Resources */ = {isa = PBXBuildFile; fileRef = C44980772BC37CB70001E6C3 /* NaverMaps.plist */; }; C449807A2BC3AF9F0001E6C3 /* PopUpUserReadingRequestDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44980792BC3AF9F0001E6C3 /* PopUpUserReadingRequestDTO.swift */; }; C449807C2BC3B07E0001E6C3 /* PostingPopUpUserReadingUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C449807B2BC3B07E0001E6C3 /* PostingPopUpUserReadingUseCase.swift */; }; @@ -2881,6 +2882,7 @@ C432DF362C69F7F3003DBA18 /* DefaultMainRepository.swift in Sources */, C432DF372C69F7F3003DBA18 /* DefaultSearchingMusicRepository.swift in Sources */, C432DF382C69F7F3003DBA18 /* DefaultFCMRepository.swift in Sources */, + C44442F32C6C7CA700CA93EA /* CommunityGuideDetailView.swift in Sources */, C432DF392C69F7F3003DBA18 /* DefaultNoticeRepository.swift in Sources */, C432DF3A2C69F7F3003DBA18 /* DefaultSettingsRepository.swift in Sources */, C432DF3B2C69F7F3003DBA18 /* DefaultMyPageRepository.swift in Sources */, @@ -3261,7 +3263,7 @@ "@executable_path/../../Frameworks", ); LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MARKETING_VERSION = 1.0; + MARKETING_VERSION = 1.2.1; PRODUCT_BUNDLE_IDENTIFIER = com.depromeet.StreetDropDebug.ShareExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -3295,7 +3297,7 @@ "@executable_path/../../Frameworks", ); LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MARKETING_VERSION = 1.0; + MARKETING_VERSION = 1.2.1; PRODUCT_BUNDLE_IDENTIFIER = com.depromeet.StreetDropRelease.ShareExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; From d1372903a7c6f1ea9c3ecc96a343d637b3f25b44 Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Wed, 14 Aug 2024 15:19:58 +0900 Subject: [PATCH 12/37] =?UTF-8?q?=F0=9F=9B=A0#297:=20=EC=95=B1=20=ED=83=80?= =?UTF-8?q?=EA=B2=9F,=20Share=20Extension=20=ED=83=80=EA=B2=9F=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EB=B6=84=EA=B8=B0=20=ED=94=8C=EB=9E=98=EA=B7=B8=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- StreetDrop/StreetDrop.xcodeproj/project.pbxproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/StreetDrop/StreetDrop.xcodeproj/project.pbxproj b/StreetDrop/StreetDrop.xcodeproj/project.pbxproj index e00b97ea..a4faacfd 100644 --- a/StreetDrop/StreetDrop.xcodeproj/project.pbxproj +++ b/StreetDrop/StreetDrop.xcodeproj/project.pbxproj @@ -3135,6 +3135,7 @@ "@executable_path/Frameworks", ); MARKETING_VERSION = 1.2.1; + OTHER_SWIFT_FLAGS = "-DAPP_TARGET"; PRODUCT_BUNDLE_IDENTIFIER = com.depromeet.StreetDropDebug; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -3180,6 +3181,7 @@ "@executable_path/Frameworks", ); MARKETING_VERSION = 1.2.1; + OTHER_SWIFT_FLAGS = "-DAPP_TARGET"; PRODUCT_BUNDLE_IDENTIFIER = com.depromeet.StreetDropRelease; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = "StreetDrop Release"; @@ -3264,6 +3266,7 @@ ); LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MARKETING_VERSION = 1.2.1; + OTHER_SWIFT_FLAGS = "-DSHARE_EXTENSION_TARGET"; PRODUCT_BUNDLE_IDENTIFIER = com.depromeet.StreetDropDebug.ShareExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -3298,6 +3301,7 @@ ); LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MARKETING_VERSION = 1.2.1; + OTHER_SWIFT_FLAGS = "-DSHARE_EXTENSION_TARGET"; PRODUCT_BUNDLE_IDENTIFIER = com.depromeet.StreetDropRelease.ShareExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; From f56a53853a4a6c099289a97623882c05acb7f797 Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Wed, 14 Aug 2024 15:22:37 +0900 Subject: [PATCH 13/37] =?UTF-8?q?=E2=9C=A8#297:=20Share=20Extension?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=BB=A4=EB=AE=A4=EB=8B=88=ED=8B=B0=20?= =?UTF-8?q?=EA=B0=80=EC=9D=B4=EB=93=9C=20UIUX=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Share Extension에서는 UIApplication.shared.open(url) 사용 불가능해서 SFSafariViewController로 노션페이지 띄움 --- .../View/ShareViewController.swift | 47 ++++++++++++++++++- .../View/CommunityGuideDetailView.swift | 12 ++++- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/StreetDrop/ShareExtension/View/ShareViewController.swift b/StreetDrop/ShareExtension/View/ShareViewController.swift index 56300893..10f3af1a 100644 --- a/StreetDrop/ShareExtension/View/ShareViewController.swift +++ b/StreetDrop/ShareExtension/View/ShareViewController.swift @@ -7,6 +7,7 @@ import UIKit import Social +import SafariServices import Kingfisher import RxSwift @@ -169,6 +170,8 @@ final class ShareViewController: UIViewController { return button }() + private lazy var communityGuideDetailView: CommunityGuideDetailView = .init() + private let dropButton: UIButton = { let button = UIButton(type: .system) button.setTitle("드랍하기", for: .normal) @@ -250,6 +253,26 @@ private extension ShareViewController { .bind { [weak self] in self?.commentTextView.text = nil }.disposed(by: disposeBag) + + communityGuideButton.rx.tap + .bind { [weak self] in + guard let self = self else { return } + self.endEditing() + + UIView.animate(withDuration: 0.3) { + let isHidden: Bool = (self.communityGuideDetailView.alpha == 0) + self.communityGuideDetailView.alpha = isHidden ? 1 : 0 + self.communityGuideDetailView.isUserInteractionEnabled = isHidden ? true : false + } + }.disposed(by: disposeBag) + + communityGuideDetailView.shareExtensionCompletionEvent + .bind(with: self) { owner, url in + let safariVC = SFSafariViewController(url: url) + owner.present(safariVC, animated: true, completion: nil) + } + .disposed(by: disposeBag) + } func bindViewModel() { @@ -293,7 +316,9 @@ private extension ShareViewController { albumCoverImageView, songNameLabel, artistNameLabel, - commentView + commentView, + communityGuideButton, + communityGuideDetailView ].forEach { containerView.addSubview($0) } @@ -365,6 +390,18 @@ private extension ShareViewController { $0.trailing.equalTo(commentView.snp.trailing).inset(16) $0.bottom.equalTo(commentView.snp.bottom).inset(16) } + + communityGuideButton.snp.makeConstraints { + $0.width.equalTo(120) + $0.height.equalTo(32) + $0.leading.equalToSuperview().inset(24) + $0.top.equalTo(commentView.snp.bottom).offset(16) + } + + communityGuideDetailView.snp.makeConstraints { + $0.leading.equalTo(communityGuideButton) + $0.top.equalTo(communityGuideButton.snp.bottom).offset(8+8) // spacing + 말풍선꼬리높이 + } } } @@ -502,6 +539,10 @@ private extension ShareViewController { $0.height.equalTo(view.bounds.height) } + + communityGuideDetailView.alpha = 0 + communityGuideDetailView.isUserInteractionEnabled = false + view.layoutIfNeeded() } } @@ -515,4 +556,8 @@ private extension ShareViewController { self?.view.layoutIfNeeded() } } + + @objc func endEditing() { + self.view.endEditing(true) + } } diff --git a/StreetDrop/StreetDrop/Presentation/MusicDropView/View/CommunityGuideDetailView.swift b/StreetDrop/StreetDrop/Presentation/MusicDropView/View/CommunityGuideDetailView.swift index 9f4ae3e1..aba42cc1 100644 --- a/StreetDrop/StreetDrop/Presentation/MusicDropView/View/CommunityGuideDetailView.swift +++ b/StreetDrop/StreetDrop/Presentation/MusicDropView/View/CommunityGuideDetailView.swift @@ -6,8 +6,10 @@ // import UIKit +import Social import RxSwift +import RxRelay class CommunityGuideDetailView: UIView { @@ -17,6 +19,7 @@ class CommunityGuideDetailView: UIView { } let disposeBag: DisposeBag = DisposeBag() + let shareExtensionCompletionEvent: PublishRelay = .init() //MARK: - UI 요소 @@ -69,14 +72,19 @@ private extension CommunityGuideDetailView { func bindAction() { detailGuideLinkButton.rx.tap - .bind { + .bind(with: self) { owner, _ in guard let url = URL( string: "https://unruly-case-46b.notion.site/4244aa9e3aff4977a2c076d2f1d78df8" ) else { return } - +#if SHARE_EXTENSION_TARGET + owner.shareExtensionCompletionEvent.accept(url) +#else + // 기본 동작 또는 다른 타겟의 경우 UIApplication.shared.open(url) +#endif + }.disposed(by: disposeBag) } From 494c973eadd97aa271817bc14b04b3cd51c42d24 Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Wed, 14 Aug 2024 16:07:07 +0900 Subject: [PATCH 14/37] =?UTF-8?q?=E2=9C=A8#297:=20Share=20Extension?= =?UTF-8?q?=EC=97=90=20=EB=93=9C=EB=9E=8D=ED=95=98=EA=B8=B0=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20UI=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 기존 드랍하기 버튼 이외에, 텍스트뷰 클릭해서 키보드 올라올때, 키보드 바로위에 드랍하기 버튼 추가 --- .../View/ShareViewController.swift | 64 +++++++++++++++---- 1 file changed, 53 insertions(+), 11 deletions(-) diff --git a/StreetDrop/ShareExtension/View/ShareViewController.swift b/StreetDrop/ShareExtension/View/ShareViewController.swift index 10f3af1a..a4a3cc64 100644 --- a/StreetDrop/ShareExtension/View/ShareViewController.swift +++ b/StreetDrop/ShareExtension/View/ShareViewController.swift @@ -184,6 +184,18 @@ final class ShareViewController: UIViewController { return button }() + private let dropButtonOnKeyBoard: UIButton = { + let button: UIButton = .init(type: .system) + button.setTitle("드랍하기", for: .normal) + button.setTitleColor(.gray900, for: .normal) + button.titleLabel?.font = .pretendard(size: 16, weight: 700) + button.backgroundColor = .primary500 + button.isEnabled = false + button.isHidden = true + + return button + }() + override func viewDidLoad() { super.viewDidLoad() bindAction() @@ -252,6 +264,7 @@ private extension ShareViewController { commentClearButton.rx.tap .bind { [weak self] in self?.commentTextView.text = nil + self?.checkAvailableToDrop() }.disposed(by: disposeBag) communityGuideButton.rx.tap @@ -318,7 +331,9 @@ private extension ShareViewController { artistNameLabel, commentView, communityGuideButton, - communityGuideDetailView + communityGuideDetailView, + dropButton, + dropButtonOnKeyBoard ].forEach { containerView.addSubview($0) } @@ -402,6 +417,17 @@ private extension ShareViewController { $0.leading.equalTo(communityGuideButton) $0.top.equalTo(communityGuideButton.snp.bottom).offset(8+8) // spacing + 말풍선꼬리높이 } + + dropButton.snp.makeConstraints { + $0.height.equalTo(56) + $0.horizontalEdges.equalToSuperview().inset(24) + $0.bottom.equalTo(self.view.safeAreaLayoutGuide).inset(16) + } + + dropButtonOnKeyBoard.snp.makeConstraints { + $0.height.equalTo(56) + $0.horizontalEdges.equalToSuperview() + } } } @@ -490,16 +516,20 @@ private extension ShareViewController { && commentTextView.text != "" && commentTextView.text != placeHolder ) { - dropButton.isEnabled = true - dropButton.backgroundColor = .primary500 - dropButton.setTitleColor(.gray900, for: .normal) + [dropButton, dropButtonOnKeyBoard].forEach { + $0.isEnabled = true + $0.backgroundColor = .primary500 + $0.setTitleColor(.gray900, for: .normal) + } } else { - dropButton.isEnabled = false - dropButton.setTitleColor( - .gray400, - for: .normal - ) - dropButton.backgroundColor = .gray300 + [dropButton, dropButtonOnKeyBoard].forEach { + $0.isEnabled = false + $0.setTitleColor( + .gray400, + for: .normal + ) + $0.backgroundColor = .gray300 + } } } } @@ -545,14 +575,26 @@ private extension ShareViewController { view.layoutIfNeeded() } + + DispatchQueue.main.asyncAfter(deadline: .now() + 0.35, execute: { [weak self] in + guard let self = self, + let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue + else { return } + // 키보드의 위치에 맞게 버튼 위치 조정 + let keyboardHeight = keyboardFrame.cgRectValue.height + dropButtonOnKeyBoard.isHidden = false + checkAvailableToDrop() + dropButtonOnKeyBoard.frame.origin.y = view.frame.height - keyboardHeight - 56 + }) + } @objc func keyboardWillHide() { UIView.animate(withDuration: 0.3) { [weak self] in self?.containerView.snp.updateConstraints { - let screenHeight = UIScreen.main.bounds.height $0.height.equalTo(596) } + self?.dropButtonOnKeyBoard.isHidden = true self?.view.layoutIfNeeded() } } From d992f6b309afb5132b69582064b065bc82778bab Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Wed, 14 Aug 2024 16:09:25 +0900 Subject: [PATCH 15/37] =?UTF-8?q?=F0=9F=9B=A0#297:=20Share=20Extension=20i?= =?UTF-8?q?nfo.plist=20NSExtensionActivationSupportsWebURLWithMaxCount=20?= =?UTF-8?q?=ED=82=A4=EA=B0=92=201=EB=A1=9C=20=EC=84=A4=EC=A0=95=ED=95=B4?= =?UTF-8?q?=EC=84=9C=20=20=ED=95=9C=20=EB=B2=88=EC=97=90=20=ED=95=98?= =?UTF-8?q?=EB=82=98=EC=9D=98=20=EC=9B=B9=20URL=EB=A7=8C=20=EC=88=98?= =?UTF-8?q?=EB=9D=BD=ED=95=98=EB=8F=84=EB=A1=9D=20=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - NSExtensionActivationSupportsWebURLWithMaxCount: 이 키는 확장이 웹 URL을 수락하고 처리할 수 있다는 것을 나타냄. 값은 최대 몇 개의 웹 URL을 한 번에 지원할 수 있는지를 나타내는 정수로 설정 --- StreetDrop/ShareExtension/Info.plist | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/StreetDrop/ShareExtension/Info.plist b/StreetDrop/ShareExtension/Info.plist index 058a2607..3868e2e2 100644 --- a/StreetDrop/ShareExtension/Info.plist +++ b/StreetDrop/ShareExtension/Info.plist @@ -10,8 +10,11 @@ $(PRODUCT_MODULE_NAME).ShareViewController NSExtensionAttributes - NSExtensionActivationRule - TRUEPREDICATE + NSExtensionActivationRule + + NSExtensionActivationSupportsWebURLWithMaxCount + 1 + NSExtensionPointIdentifier com.apple.share-services From 8590a2651c79958cbfe08258eee4a8dc3fd3d671 Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Fri, 16 Aug 2024 09:53:10 +0900 Subject: [PATCH 16/37] =?UTF-8?q?=F0=9F=90=9B#297:=20ShareViewController?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=BB=A4=EB=AE=A4=EB=8B=88=ED=8B=B0=20?= =?UTF-8?q?=EA=B0=80=EC=9D=B4=EB=93=9C=20=ED=88=B4=ED=8C=81=20=ED=81=B4?= =?UTF-8?q?=EB=A6=AD=20=EC=8B=9C,=20=EB=93=9C=EB=9E=8D=ED=95=98=EA=B8=B0?= =?UTF-8?q?=20=EB=B2=84=ED=8A=BC=EC=97=90=20=EA=B0=80=EB=A0=A4=EC=A7=80?= =?UTF-8?q?=EB=8A=94=20=ED=98=84=EC=83=81=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- StreetDrop/ShareExtension/View/ShareViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/StreetDrop/ShareExtension/View/ShareViewController.swift b/StreetDrop/ShareExtension/View/ShareViewController.swift index a4a3cc64..98d253c4 100644 --- a/StreetDrop/ShareExtension/View/ShareViewController.swift +++ b/StreetDrop/ShareExtension/View/ShareViewController.swift @@ -323,6 +323,7 @@ private extension ShareViewController { } [ + dropButton, villageNameLabel, changingMusicView, belowArrow, @@ -332,7 +333,6 @@ private extension ShareViewController { commentView, communityGuideButton, communityGuideDetailView, - dropButton, dropButtonOnKeyBoard ].forEach { containerView.addSubview($0) From a903076dcf9c7cf1fa861f3a6a50884070135d31 Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Fri, 16 Aug 2024 15:04:52 +0900 Subject: [PATCH 17/37] =?UTF-8?q?=E2=9C=A8#297:=20Share=20Extension,=20?= =?UTF-8?q?=EC=9D=8C=EC=95=85=20=EC=9E=AC=EA=B2=80=EC=83=89=20UI=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReSearchingMusicForSharingView.swift | 173 ++++++++++++++++++ .../ReSearchingMusicTableViewCell.swift | 122 ++++++++++++ .../StreetDrop.xcodeproj/project.pbxproj | 16 ++ .../exit.imageset/Contents.json | 23 +++ .../Assets.xcassets/exit.imageset/exit.png | Bin 0 -> 238 bytes .../Assets.xcassets/exit.imageset/exit@2x.png | Bin 0 -> 407 bytes .../Assets.xcassets/exit.imageset/exit@3x.png | Bin 0 -> 579 bytes 7 files changed, 334 insertions(+) create mode 100644 StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicForSharingView.swift create mode 100644 StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicTableViewCell.swift create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/exit.imageset/Contents.json create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/exit.imageset/exit.png create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/exit.imageset/exit@2x.png create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/exit.imageset/exit@3x.png diff --git a/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicForSharingView.swift b/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicForSharingView.swift new file mode 100644 index 00000000..9699b73f --- /dev/null +++ b/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicForSharingView.swift @@ -0,0 +1,173 @@ +// +// ReSearchingMusicForSharingView.swift +// ShareExtension +// +// Created by 차요셉 on 8/16/24. +// + +import UIKit + +import RxSwift +import RxRelay +import SnapKit + +final class ReSearchingMusicForSharingView: UIView { + private let reSearchingEventRelay: PublishRelay = .init() + // View -> ViewController + var reSearchingEvent: Observable { + reSearchingEventRelay.asObservable() + } + // ViewController -> View + let settingMusicDataRelay: PublishRelay<[Music]> = .init() + private let disposeBag: DisposeBag = .init() + + override init(frame: CGRect) { + super.init(frame: frame) + bindData() + configureUI() + } + + @available(*, unavailable) + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private let backbutton: UIButton = { + let button: UIButton = .init() + button.setImage(.init(named: "backButton"), for: .normal) + + return button + }() + + private let titleLabel: UILabel = { + let label: UILabel = .init() + label.text = "직접 검색" + label.textColor = .textPrimary + label.font = .pretendard(size: 16, weight: 700) + label.setLineHeight(lineHeight: 24) + + return label + }() + + private let exitButton: UIButton = { + let button: UIButton = .init() + button.setImage(.init(named: "exit"), for: .normal) + + return button + }() + + private lazy var searchTextField: UITextField = { + let textField: UITextField = UITextField() + textField.backgroundColor = UIColor.gray700 + textField.attributedPlaceholder = NSAttributedString( + string: "드랍할 음악 검색", + attributes: [ + .foregroundColor: UIColor.gray400 + ] + ) + textField.textColor = .textPrimary + textField.layer.cornerRadius = 12.0 + + textField.returnKeyType = .search + + let leftPaddingView = UIView( + frame: CGRect( + x: 0, + y: 0, + width: 16, + height: 44 + ) + ) + textField.leftView = leftPaddingView + textField.leftViewMode = .always + + textField.rightView = searchCancelView + textField.rightViewMode = .whileEditing + return textField + }() + + private lazy var searchCancelView: UIView = { + let view: UIView = .init() + + return view + }() + + private lazy var searchCancelButton: UIButton = { + let button: UIButton = .init() + button.setImage(UIImage(named: "cancleButton"), for: .normal) + + return button + }() + + private lazy var tableView: UITableView = { + let tableView: UITableView = .init() + tableView.backgroundColor = .clear + tableView.register( + ReSearchingMusicTableViewCell.self, + forCellReuseIdentifier: ReSearchingMusicTableViewCell.identifier + ) + tableView.rowHeight = 80 + tableView.keyboardDismissMode = .onDrag + + return tableView + }() +} + +private extension ReSearchingMusicForSharingView { + func bindData() { + settingMusicDataRelay + .bind( + to: tableView.rx.items( + cellIdentifier: ReSearchingMusicTableViewCell.identifier, + cellType: ReSearchingMusicTableViewCell.self + ) + ) { (row, music, reSearchingMusicTableViewCell) in + reSearchingMusicTableViewCell.setData(music: music) + } + .disposed(by: disposeBag) + } + + func configureUI() { + [ + backbutton, + titleLabel, + searchTextField, + exitButton, + tableView + ].forEach { + addSubview($0) + } + + searchCancelView.addSubview(searchCancelButton) + + backbutton.snp.makeConstraints { + $0.width.height.equalTo(32) + $0.top.equalToSuperview().inset(14) + $0.leading.equalToSuperview().inset(24) + } + + titleLabel.snp.makeConstraints { + $0.height.equalTo(18) + $0.top.equalToSuperview().inset(18) + $0.centerX.equalToSuperview() + } + + exitButton.snp.makeConstraints { + $0.width.equalTo(44) + $0.height.equalTo(32) + $0.top.equalToSuperview().inset(14) + $0.trailing.equalToSuperview().inset(24) + } + + searchTextField.snp.makeConstraints { + $0.height.equalTo(44) + $0.top.equalTo(titleLabel.snp.bottom).offset(26) + $0.horizontalEdges.equalToSuperview().inset(24) + } + + tableView.snp.makeConstraints { + $0.top.equalTo(searchTextField.snp.bottom).offset(12) + $0.horizontalEdges.bottom.equalToSuperview() + } + } +} diff --git a/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicTableViewCell.swift b/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicTableViewCell.swift new file mode 100644 index 00000000..7475d931 --- /dev/null +++ b/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicTableViewCell.swift @@ -0,0 +1,122 @@ +// +// ReSearchingMusicTableViewCell.swift +// ShareExtension +// +// Created by 차요셉 on 8/16/24. +// + +import UIKit + +import RxSwift +import SnapKit +import Kingfisher + +final class ReSearchingMusicTableViewCell: UITableViewCell { + static let identifier = "SearchingMusicTableViewCell" + private var disposeBag: DisposeBag = DisposeBag() + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + self.backgroundColor = .clear + self.selectionStyle = .none + self.configureUI() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been impl") + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + } + + override func prepareForReuse() { + super.prepareForReuse() + self.albumImageView.image = nil + self.disposeBag = DisposeBag() + } + + func setData(music: Music) { + albumImageView.setImage(with: music.albumImage) + songNameLabel.text = music.songName + artistNameLabel.text = music.artistName + durationTimeLabel.text = music.durationTime + } + + private lazy var albumImageView: UIImageView = { + let imageView: UIImageView = .init() + imageView.layer.cornerRadius = 12.0 + imageView.contentMode = .scaleAspectFill + imageView.clipsToBounds = true + return imageView + }() + + private lazy var songNameLabel: UILabel = { + let label: UILabel = .init() + label.font = .pretendard(size: 16, weight: 600) + label.setLineHeight(lineHeight: 24) + label.textColor = UIColor.white + label.numberOfLines = 1 + return label + }() + + private lazy var artistNameLabel: UILabel = { + let label: UILabel = .init() + label.font = .pretendard(size: 12, weight: 400) + label.setLineHeight(lineHeight: 16) + label.numberOfLines = 1 + label.textColor = UIColor.gray200 + return label + }() + + private lazy var durationTimeLabel: UILabel = { + let label: UILabel = .init() + label.font = .pretendard(size: 12, weight: 400) + label.setLineHeight(lineHeight: 16) + label.numberOfLines = 1 + label.textColor = UIColor.gray200 + label.adjustsFontSizeToFitWidth = true + + return label + }() +} + +private extension ReSearchingMusicTableViewCell { + func configureUI() { + [ + albumImageView, + songNameLabel, + artistNameLabel, + durationTimeLabel + ].forEach { + addSubview($0) + } + + albumImageView.snp.makeConstraints { + $0.width.height.equalTo(56) + $0.centerY.equalToSuperview() + $0.leading.equalToSuperview().offset(24) + } + + songNameLabel.snp.makeConstraints { + $0.height.equalTo(24) + $0.top.equalToSuperview().inset(19) + $0.leading.equalTo(albumImageView.snp.trailing).offset(12) + $0.trailing.equalToSuperview().inset(60) + } + + artistNameLabel.snp.makeConstraints { + $0.top.equalTo(songNameLabel.snp.bottom).offset(2) + $0.leading.equalTo(albumImageView.snp.trailing).offset(12) + $0.trailing.equalTo(durationTimeLabel.snp.leading) + } + + durationTimeLabel.snp.makeConstraints { + $0.width.equalTo(36) + $0.height.equalTo(16) + $0.bottom.equalTo(artistNameLabel.snp.bottom) + $0.trailing.equalToSuperview().inset(24) + } + } +} + diff --git a/StreetDrop/StreetDrop.xcodeproj/project.pbxproj b/StreetDrop/StreetDrop.xcodeproj/project.pbxproj index a4faacfd..973acb4f 100644 --- a/StreetDrop/StreetDrop.xcodeproj/project.pbxproj +++ b/StreetDrop/StreetDrop.xcodeproj/project.pbxproj @@ -401,6 +401,8 @@ C44A549A2BBC097E00354F8F /* FetchingPopUpInfomationUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44A54992BBC097E00354F8F /* FetchingPopUpInfomationUseCase.swift */; }; C44A549C2BBC099E00354F8F /* DefaultFetchingPopUpInfomationUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44A549B2BBC099E00354F8F /* DefaultFetchingPopUpInfomationUseCase.swift */; }; C44A549E2BBC0DC500354F8F /* TipPopUpViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44A549D2BBC0DC500354F8F /* TipPopUpViewController.swift */; }; + C44DE1F92C6EDC04004F211C /* ReSearchingMusicForSharingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44DE1F82C6EDC04004F211C /* ReSearchingMusicForSharingView.swift */; }; + C44DE1FB2C6EE07D004F211C /* ReSearchingMusicTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44DE1FA2C6EE07D004F211C /* ReSearchingMusicTableViewCell.swift */; }; C45A4CB02A3710AC00EE9C36 /* ImageCacheError.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45A4CAF2A3710AC00EE9C36 /* ImageCacheError.swift */; }; C45BF3972A1D0ADF00CEDE74 /* UserDefaultKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45BF3962A1D0ADF00CEDE74 /* UserDefaultKey.swift */; }; C45BF39E2A1D113200CEDE74 /* UserDefaultsRecentMusicSearches.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45BF39D2A1D113200CEDE74 /* UserDefaultsRecentMusicSearches.swift */; }; @@ -741,6 +743,8 @@ C44A54992BBC097E00354F8F /* FetchingPopUpInfomationUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FetchingPopUpInfomationUseCase.swift; sourceTree = ""; }; C44A549B2BBC099E00354F8F /* DefaultFetchingPopUpInfomationUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultFetchingPopUpInfomationUseCase.swift; sourceTree = ""; }; C44A549D2BBC0DC500354F8F /* TipPopUpViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TipPopUpViewController.swift; sourceTree = ""; }; + C44DE1F82C6EDC04004F211C /* ReSearchingMusicForSharingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReSearchingMusicForSharingView.swift; sourceTree = ""; }; + C44DE1FA2C6EE07D004F211C /* ReSearchingMusicTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReSearchingMusicTableViewCell.swift; sourceTree = ""; }; C45A4CAF2A3710AC00EE9C36 /* ImageCacheError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageCacheError.swift; sourceTree = ""; }; C45BF3962A1D0ADF00CEDE74 /* UserDefaultKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultKey.swift; sourceTree = ""; }; C45BF39D2A1D113200CEDE74 /* UserDefaultsRecentMusicSearches.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsRecentMusicSearches.swift; sourceTree = ""; }; @@ -1768,6 +1772,7 @@ isa = PBXGroup; children = ( C42182BC2C697F9700B73A99 /* ShareViewController.swift */, + C44DE1FC2C6EE089004F211C /* ReSearchingMusic */, ); path = View; sourceTree = ""; @@ -1836,6 +1841,15 @@ path = PopUp; sourceTree = ""; }; + C44DE1FC2C6EE089004F211C /* ReSearchingMusic */ = { + isa = PBXGroup; + children = ( + C44DE1F82C6EDC04004F211C /* ReSearchingMusicForSharingView.swift */, + C44DE1FA2C6EE07D004F211C /* ReSearchingMusicTableViewCell.swift */, + ); + path = ReSearchingMusic; + sourceTree = ""; + }; C45BF3982A1D0AE200CEDE74 /* Constant */ = { isa = PBXGroup; children = ( @@ -2904,6 +2918,7 @@ C432DF4B2C69F7F3003DBA18 /* Music.swift in Sources */, C432DF4C2C69F7F3003DBA18 /* RecommendMusic.swift in Sources */, C432DF4D2C69F7F3003DBA18 /* ModalOption.swift in Sources */, + C44DE1F92C6EDC04004F211C /* ReSearchingMusicForSharingView.swift in Sources */, C432DF4E2C69F7F3003DBA18 /* MyLevelProgress.swift in Sources */, C432DF4F2C69F7F3003DBA18 /* LevelPolicy.swift in Sources */, C432DF502C69F7F3003DBA18 /* PopUpInfomation.swift in Sources */, @@ -2930,6 +2945,7 @@ C432DF652C69F7F3003DBA18 /* DefaultClaimingCommentUseCase.swift in Sources */, C432DF662C69F7F3003DBA18 /* DeletingMusicUseCase.swift in Sources */, C432DF672C69F7F3003DBA18 /* DefaultDeletingMusicUseCase.swift in Sources */, + C44DE1FB2C6EE07D004F211C /* ReSearchingMusicTableViewCell.swift in Sources */, C432DF682C69F7F3003DBA18 /* BlockUserUseCase.swift in Sources */, C432DF692C69F7F3003DBA18 /* DefaultBlockUserUseCase.swift in Sources */, C432DF6A2C69F7F3003DBA18 /* FetchingMyInfoUseCase.swift in Sources */, diff --git a/StreetDrop/StreetDrop/Resource/Assets.xcassets/exit.imageset/Contents.json b/StreetDrop/StreetDrop/Resource/Assets.xcassets/exit.imageset/Contents.json new file mode 100644 index 00000000..f23258b1 --- /dev/null +++ b/StreetDrop/StreetDrop/Resource/Assets.xcassets/exit.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "exit.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "exit@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "exit@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/StreetDrop/StreetDrop/Resource/Assets.xcassets/exit.imageset/exit.png b/StreetDrop/StreetDrop/Resource/Assets.xcassets/exit.imageset/exit.png new file mode 100644 index 0000000000000000000000000000000000000000..39facb15f3a0504de20bb2a8aa6a63d95e1f6432 GIT binary patch literal 238 zcmeAS@N?(olHy`uVBq!ia0vp^IzX(z!3HEV-DXt*Db50q$YKTtZeb8+WSBKa0w~B> z9OUlAui~bwMH#ftglU6%#zq-|o$*Xyr!=a0E4jQ+18!*kEe)acs gfsYO8JsW@cwe6Fu=adY!06K@k)78&qol`;+0H{V&=Kufz literal 0 HcmV?d00001 diff --git a/StreetDrop/StreetDrop/Resource/Assets.xcassets/exit.imageset/exit@2x.png b/StreetDrop/StreetDrop/Resource/Assets.xcassets/exit.imageset/exit@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..c187614c0b7ced9611ed06152622e88064fc0d80 GIT binary patch literal 407 zcmeAS@N?(olHy`uVBq!ia0vp^5kTy~!3HGf32Zn7q&N#aB8wRq#8g3;(KATp15l8$ zILO_JVcj{Imp~3nx}&cn1H;CC?mvmFKsg;x7srqa#<#b4xta}l93F1yUT6NDLryU` zfMd4()@>6_-!mr~7<@6jVWrIk)D8p>&aZq`z3bRZsb|+8y?OcbtS6=t98nZxqbPf5M-+oXRP534PT zKeVQO{r=;)b6Skjbc>GJUmDewV=wmH-|3>aMBGf!WuFIkS%%BGCFa}qyVxxh{THq9 zsZXl#?B0%?t3BE8JfB2%?|61^qw@Bi?6f02Zv?NO=@PwZyl$qX`lf&L`17Q$pSjy5 w^QfjkNL_m3Zd-X9orRMvs;lfE{uVgTey@J*&8+LMAAkfrUHx3vIVCg!01#`c&;S4c literal 0 HcmV?d00001 diff --git a/StreetDrop/StreetDrop/Resource/Assets.xcassets/exit.imageset/exit@3x.png b/StreetDrop/StreetDrop/Resource/Assets.xcassets/exit.imageset/exit@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..1f98e89afacc5cbcdc92405ddc390f12950c9e1d GIT binary patch literal 579 zcmeAS@N?(olHy`uVBq!ia0vp^EkK;W!3HGnOuS_bq&N#aB8wRq6fHoQ(RG?(0#J~# zILO_JVcj{Imp~3nx}&cn1H;CC?mvmFK)D;9E{-7;jBoG8W<53#X$Ulwp8qBxjs3A~ z8RsmiD6NcF7N73#J!Sb|dqV7)=?*zPUW`CPpdc=I?bq+WKYlCxqj@rAzWtP+OxNE3 zo2v3G^8J~5?Jqxngk9|k{3CGq&Dsm;iX9gMb&e=>=suf&eV0y*2!GOyzq((l_csJj z(+E3aAiC|eK&ynGm?f8Cj7pM7(vFBF8b<_NT7blvsev7eE3_90I2WY5DYmJc>u};Z zDI?h`G094a%TQ%|x=5155xKyQM1$x>0*4n=0f`6mI-Pj*lYB)&dDf@8iX>H-&JFZw zEwq(98X|H3l*Y12C)OVlD_wqmLTv4y{6$lrZFRJ=k!;p*y9Oe*D7CFrt8(t)eI;D3 z;A*(zR-tv2Nb@S`dA=P<2Bq!np^Jdl8Jav7a!so~c41Dih@`Bbb8%i^N>K{WS*b-Q z9`s1e+Ug>BbEct5c9+s3?WBxrVy-IT$1a>v=;Ba1a^Z|pm$qxy!kL~T;T;mr#bP0l+XkK Di2>lq literal 0 HcmV?d00001 From f147371961010207b74759e94c785da564c947e4 Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Fri, 16 Aug 2024 15:44:49 +0900 Subject: [PATCH 18/37] =?UTF-8?q?=E2=9C=A8#297:=20Share=20ViewController?= =?UTF-8?q?=EC=9D=98=20'=EC=9B=90=ED=95=98=EB=8A=94=20=EC=9D=8C=EC=95=85?= =?UTF-8?q?=EC=9D=B4=20=EC=95=84=EB=8B=8C=EA=B0=80=EC=9A=94'=20=ED=81=B4?= =?UTF-8?q?=EB=A6=AD=20=EC=8B=9C,=20=EC=9E=AC=EA=B2=80=EC=83=89=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EB=82=98=ED=83=80=EB=82=B4=EA=B3=A0=20?= =?UTF-8?q?=EC=9C=A0=ED=8A=9C=EB=B8=8C=EB=AE=A4=EC=A7=81=EC=97=90=EC=84=9C?= =?UTF-8?q?=20=EA=B3=B5=EC=9C=A0=EB=90=9C=20=EA=B3=A1=EC=9D=B4=EB=A6=84=20?= =?UTF-8?q?=ED=86=B5=ED=95=B4=20=EA=B2=80=EC=83=89=20=EB=B0=8F=20=ED=85=8C?= =?UTF-8?q?=EC=9D=B4=EB=B8=94=20=EB=B7=B0=20=EB=8D=B0=EC=9D=B4=ED=84=B0?= =?UTF-8?q?=EB=93=A4=20=EB=82=98=ED=83=80=EB=83=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/ShareViewController.swift | 33 ++++++++++++++++++- .../ViewModel/ShareViewModel.swift | 19 +++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/StreetDrop/ShareExtension/View/ShareViewController.swift b/StreetDrop/ShareExtension/View/ShareViewController.swift index 98d253c4..0816b666 100644 --- a/StreetDrop/ShareExtension/View/ShareViewController.swift +++ b/StreetDrop/ShareExtension/View/ShareViewController.swift @@ -12,6 +12,7 @@ import SafariServices import Kingfisher import RxSwift import RxRelay +import RxGesture import SnapKit final class ShareViewController: UIViewController { @@ -196,6 +197,17 @@ final class ShareViewController: UIViewController { return button }() + private let reSearchingMusicForSharingView: ReSearchingMusicForSharingView = { + let reSearchingMusicForSharingView: ReSearchingMusicForSharingView = .init() + reSearchingMusicForSharingView.isHidden = true + reSearchingMusicForSharingView.backgroundColor = .gray800 + reSearchingMusicForSharingView.layer.cornerRadius = 20 + reSearchingMusicForSharingView.layer.borderWidth = 1 + reSearchingMusicForSharingView.layer.borderColor = UIColor.gray600.cgColor + + return reSearchingMusicForSharingView + }() + override func viewDidLoad() { super.viewDidLoad() bindAction() @@ -291,7 +303,8 @@ private extension ShareViewController { func bindViewModel() { let input: ShareViewModel.Input = .init( viewDidLoadEvent: .just(Void()), - sharedMusicKeyWordEvent: sharedMusicKeyWordEvent.asObservable() + sharedMusicKeyWordEvent: sharedMusicKeyWordEvent.asObservable(), + changingMusicViewClickEvent: changingMusicView.rx.tapGesture().asObservable().mapVoid() ) let output: ShareViewModel.Output = viewModel.convert( input: input, @@ -311,10 +324,23 @@ private extension ShareViewController { owner.artistNameLabel.text = music.artistName } .disposed(by: disposeBag) + + output.showReSearchedMusicList + .bind(with: self) { owner, musicList in + DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: { [weak self] in + guard let self = self else { return } + containerView.isHidden = true + reSearchingMusicForSharingView.isHidden = false + view.layoutIfNeeded() + }) + owner.reSearchingMusicForSharingView.settingMusicDataRelay.accept(musicList) + } + .disposed(by: disposeBag) } func configureUI() { view.addSubview(containerView) + view.addSubview(reSearchingMusicForSharingView) view.backgroundColor = UIColor.black.withAlphaComponent(0.5) containerView.snp.makeConstraints { @@ -322,6 +348,10 @@ private extension ShareViewController { $0.horizontalEdges.bottom.equalToSuperview() } + reSearchingMusicForSharingView.snp.makeConstraints { + $0.edges.equalToSuperview() + } + [ dropButton, villageNameLabel, @@ -440,6 +470,7 @@ private extension ShareViewController { fetchVideoDetails(videoID: videoID) { [weak self] songName, artistName in self?.sharedMusicKeyWordEvent.accept("\(songName ?? "")-\(artistName ?? "")") + self?.viewModel.sharedSongName = songName ?? "" } } diff --git a/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift b/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift index b089775d..031b3b93 100644 --- a/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift +++ b/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift @@ -23,6 +23,7 @@ final class ShareViewModel: NSObject, ShareViewModelType { private let locationManger: CLLocationManager = .init() private let searchMusicUsecase: SearchMusicUsecase private let disposeBag: DisposeBag = .init() + var sharedSongName: String = "" init(searchMusicUsecase: SearchMusicUsecase = DefaultSearchingMusicUsecase()) { self.searchMusicUsecase = searchMusicUsecase @@ -31,6 +32,7 @@ final class ShareViewModel: NSObject, ShareViewModelType { struct Input { let viewDidLoadEvent: Observable let sharedMusicKeyWordEvent: Observable + let changingMusicViewClickEvent: Observable } struct Output { @@ -42,6 +44,10 @@ final class ShareViewModel: NSObject, ShareViewModelType { var showSearchedMusic: Observable { showSearchedMusicRelay.asObservable() } + fileprivate let showReSearchedMusicListRelay: PublishRelay<[Music]> = .init() + var showReSearchedMusicList: Observable<[Music]> { + showReSearchedMusicListRelay.asObservable() + } } func convert(input: Input, disposedBag: DisposeBag) -> Output { @@ -69,6 +75,19 @@ final class ShareViewModel: NSObject, ShareViewModelType { } .disposed(by: disposedBag) + input.changingMusicViewClickEvent + .bind(with: self) { owner, _ in + owner.searchMusicUsecase.searchMusic(keyword: owner.sharedSongName) + .subscribe(with: self) { owner, musicList in + owner.output.showReSearchedMusicListRelay.accept(musicList) + } onFailure: { owner, error in + // TODO: 요셉, 실패 팝업 띄우기 + } + .disposed(by: disposedBag) + + } + .disposed(by: disposedBag) + return output } } From f3e63677ff83ddc68ce600ed6f9271422bfe4fd0 Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Fri, 16 Aug 2024 16:07:19 +0900 Subject: [PATCH 19/37] =?UTF-8?q?=E2=9C=A8#297:=20Share=20Extension?= =?UTF-8?q?=EC=9D=98=20=EC=9D=8C=EC=95=85=20=EC=9E=AC=EA=B2=80=EC=83=89=20?= =?UTF-8?q?=EC=8B=9C,=20=EC=9D=8C=EC=95=85=20=EA=B2=80=EC=83=89=20?= =?UTF-8?q?=EB=B9=84=EC=A6=88=EB=8B=88=EC=8A=A4=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=88=98=ED=96=89=20=EB=B0=8F=20=EA=B2=B0=EA=B3=BC=EA=B0=92=20?= =?UTF-8?q?=EC=9E=AC=EA=B2=80=EC=83=89=20=ED=85=8C=EC=9D=B4=EB=B8=94=20?= =?UTF-8?q?=EB=B7=B0=EC=97=90=20=EB=82=98=ED=83=80=EB=83=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReSearchingMusicForSharingView.swift | 16 +++++++++++ .../View/ShareViewController.swift | 3 +- .../ViewModel/ShareViewModel.swift | 28 +++++++++++++------ 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicForSharingView.swift b/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicForSharingView.swift index 9699b73f..92b4e70c 100644 --- a/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicForSharingView.swift +++ b/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicForSharingView.swift @@ -23,6 +23,7 @@ final class ReSearchingMusicForSharingView: UIView { override init(frame: CGRect) { super.init(frame: frame) + bindAction() bindData() configureUI() } @@ -114,6 +115,21 @@ final class ReSearchingMusicForSharingView: UIView { } private extension ReSearchingMusicForSharingView { + func bindAction() { + searchTextField.rx.text.orEmpty + .filter { $0.isEmpty } + .map { _ in } + .bind(with: self) { owner, _ in + owner.settingMusicDataRelay.accept([]) + } + .disposed(by: disposeBag) + + searchTextField.rx.controlEvent(.editingDidEndOnExit) + .compactMap { [weak self] in self?.searchTextField.text ?? "" } + .bind(to: reSearchingEventRelay) + .disposed(by: disposeBag) + } + func bindData() { settingMusicDataRelay .bind( diff --git a/StreetDrop/ShareExtension/View/ShareViewController.swift b/StreetDrop/ShareExtension/View/ShareViewController.swift index 0816b666..dabc9224 100644 --- a/StreetDrop/ShareExtension/View/ShareViewController.swift +++ b/StreetDrop/ShareExtension/View/ShareViewController.swift @@ -304,7 +304,8 @@ private extension ShareViewController { let input: ShareViewModel.Input = .init( viewDidLoadEvent: .just(Void()), sharedMusicKeyWordEvent: sharedMusicKeyWordEvent.asObservable(), - changingMusicViewClickEvent: changingMusicView.rx.tapGesture().asObservable().mapVoid() + changingMusicViewClickEvent: changingMusicView.rx.tapGesture().asObservable().mapVoid(), + reSearchingEvent: reSearchingMusicForSharingView.reSearchingEvent ) let output: ShareViewModel.Output = viewModel.convert( input: input, diff --git a/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift b/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift index 031b3b93..5cf881d4 100644 --- a/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift +++ b/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift @@ -33,6 +33,7 @@ final class ShareViewModel: NSObject, ShareViewModelType { let viewDidLoadEvent: Observable let sharedMusicKeyWordEvent: Observable let changingMusicViewClickEvent: Observable + let reSearchingEvent: Observable } struct Output { @@ -77,14 +78,13 @@ final class ShareViewModel: NSObject, ShareViewModelType { input.changingMusicViewClickEvent .bind(with: self) { owner, _ in - owner.searchMusicUsecase.searchMusic(keyword: owner.sharedSongName) - .subscribe(with: self) { owner, musicList in - owner.output.showReSearchedMusicListRelay.accept(musicList) - } onFailure: { owner, error in - // TODO: 요셉, 실패 팝업 띄우기 - } - .disposed(by: disposedBag) - + owner.reSearchMusic(keyword: owner.sharedSongName, disposeBag: disposedBag) + } + .disposed(by: disposedBag) + + input.reSearchingEvent + .bind(with: self) { owner, reSearchingKeyword in + owner.reSearchMusic(keyword: reSearchingKeyword, disposeBag: disposedBag) } .disposed(by: disposedBag) @@ -92,6 +92,18 @@ final class ShareViewModel: NSObject, ShareViewModelType { } } +private extension ShareViewModel { + func reSearchMusic(keyword: String, disposeBag: DisposeBag) { + searchMusicUsecase.searchMusic(keyword: keyword) + .subscribe(with: self) { owner, musicList in + owner.output.showReSearchedMusicListRelay.accept(musicList) + } onFailure: { owner, error in + // TODO: 요셉, 실패 팝업 띄우기 + } + .disposed(by: disposeBag) + } +} + extension ShareViewModel: CLLocationManagerDelegate { func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { guard let location = locations.last else { return } From c7f72b0d1b6a5e56a5f7f948a2268e9f20319b98 Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Mon, 19 Aug 2024 13:20:53 +0900 Subject: [PATCH 20/37] =?UTF-8?q?=E2=9C=A8#297:=20Share=20Extension?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=9E=AC=EA=B2=80=EC=83=89=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=EC=9D=98=20=EC=9B=90=ED=95=98=EB=8A=94=20=ED=85=8C?= =?UTF-8?q?=EC=9D=B4=EB=B8=94=EB=B7=B0=20=EC=85=80=20=ED=81=B4=EB=A6=AD=20?= =?UTF-8?q?=EC=8B=9C,=20=ED=81=B4=EB=A6=AD=ED=95=9C=20=EC=85=80=EC=9D=98?= =?UTF-8?q?=20=EC=9D=8C=EC=95=85=20=EC=A0=95=EB=B3=B4=20=EC=9D=B4=EC=A0=84?= =?UTF-8?q?=20=ED=99=94=EB=A9=B4=EC=9D=98=20=EC=A0=95=EB=B3=B4=EB=A1=9C=20?= =?UTF-8?q?=EA=B8=B0=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReSearchingMusicForSharingView.swift | 11 ++++++++++- .../ShareExtension/View/ShareViewController.swift | 14 ++++++++++++++ .../ShareExtension/ViewModel/ShareViewModel.swift | 2 ++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicForSharingView.swift b/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicForSharingView.swift index 92b4e70c..2db63a58 100644 --- a/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicForSharingView.swift +++ b/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicForSharingView.swift @@ -12,11 +12,16 @@ import RxRelay import SnapKit final class ReSearchingMusicForSharingView: UIView { - private let reSearchingEventRelay: PublishRelay = .init() // View -> ViewController + private let reSearchingEventRelay: PublishRelay = .init() var reSearchingEvent: Observable { reSearchingEventRelay.asObservable() } + private let selectedMusicEventRelay: PublishRelay = .init() + var selectedMusicEvent: Observable { + selectedMusicEventRelay.asObservable() + } + // ViewController -> View let settingMusicDataRelay: PublishRelay<[Music]> = .init() private let disposeBag: DisposeBag = .init() @@ -128,6 +133,10 @@ private extension ReSearchingMusicForSharingView { .compactMap { [weak self] in self?.searchTextField.text ?? "" } .bind(to: reSearchingEventRelay) .disposed(by: disposeBag) + + tableView.rx.modelSelected(Music.self) + .bind(to: selectedMusicEventRelay) + .disposed(by: disposeBag) } func bindData() { diff --git a/StreetDrop/ShareExtension/View/ShareViewController.swift b/StreetDrop/ShareExtension/View/ShareViewController.swift index dabc9224..8bc18a9e 100644 --- a/StreetDrop/ShareExtension/View/ShareViewController.swift +++ b/StreetDrop/ShareExtension/View/ShareViewController.swift @@ -298,6 +298,20 @@ private extension ShareViewController { } .disposed(by: disposeBag) + reSearchingMusicForSharingView.selectedMusicEvent + .bind(with: self) { owner, music in + owner.viewModel.selectedMusic = music + owner.albumCoverImageView.kf.setImage(with: URL(string: music.albumImage)) + owner.songNameLabel.text = music.songName + owner.artistNameLabel.text = music.artistName + DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: { [weak self] in + guard let self = self else { return } + containerView.isHidden = false + reSearchingMusicForSharingView.isHidden = true + view.layoutIfNeeded() + }) + } + .disposed(by: disposeBag) } func bindViewModel() { diff --git a/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift b/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift index 5cf881d4..8d69d85c 100644 --- a/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift +++ b/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift @@ -24,6 +24,7 @@ final class ShareViewModel: NSObject, ShareViewModelType { private let searchMusicUsecase: SearchMusicUsecase private let disposeBag: DisposeBag = .init() var sharedSongName: String = "" + var selectedMusic: Music? init(searchMusicUsecase: SearchMusicUsecase = DefaultSearchingMusicUsecase()) { self.searchMusicUsecase = searchMusicUsecase @@ -69,6 +70,7 @@ final class ShareViewModel: NSObject, ShareViewModelType { return } owner.output.showSearchedMusicRelay.accept(firstMusic) + owner.selectedMusic = firstMusic } onFailure: { owner, error in } From c8c2f4330b6974e77e17a14ef6aeb4d4ec9e7aa4 Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Mon, 19 Aug 2024 14:39:46 +0900 Subject: [PATCH 21/37] =?UTF-8?q?=E2=9C=A8#297:=20=EB=91=90=EA=B0=80?= =?UTF-8?q?=EC=A7=80=EC=9D=98=20=EB=93=9C=EB=9E=8D=ED=95=98=EA=B8=B0=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=ED=81=B4=EB=A6=AD=20=EC=8B=9C,=20?= =?UTF-8?q?=EB=93=9C=EB=9E=8D=ED=95=98=EA=B8=B0=20=EB=B9=84=EC=A6=88?= =?UTF-8?q?=EB=8B=88=EC=8A=A4=20=EB=A1=9C=EC=A7=81=20=EC=88=98=ED=96=89(?= =?UTF-8?q?=EC=84=B1=EA=B3=B5/=EC=8B=A4=ED=8C=A8=20=EC=8B=9C=20UI=EC=9E=91?= =?UTF-8?q?=EC=97=85=EC=9D=80=20=EC=B6=94=ED=9B=84=EC=97=90=20=EC=BB=A4?= =?UTF-8?q?=EB=B0=8B)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/ShareViewController.swift | 20 ++++++-- .../ViewModel/ShareViewModel.swift | 49 ++++++++++++++++++- 2 files changed, 64 insertions(+), 5 deletions(-) diff --git a/StreetDrop/ShareExtension/View/ShareViewController.swift b/StreetDrop/ShareExtension/View/ShareViewController.swift index 8bc18a9e..d809b717 100644 --- a/StreetDrop/ShareExtension/View/ShareViewController.swift +++ b/StreetDrop/ShareExtension/View/ShareViewController.swift @@ -24,6 +24,7 @@ final class ShareViewController: UIViewController { private let viewModel: ShareViewModel = .init() private let disposeBag: DisposeBag = .init() private let sharedMusicKeyWordEvent: PublishRelay = .init() + private let dropButtonClickEvent: PublishRelay = .init() private let containerView: UIView = { let view: UIView = .init() @@ -264,11 +265,12 @@ private extension ShareViewController { commentTextView.rx.text.orEmpty .asObservable() - .bind { [weak self] text in + .bind(with: self) { owner, text in guard text != Constant.commentPlaceHolder, !text.isEmpty else { return } - self?.commentCountLabel.text = "\(text.count)/40" - self?.commentView.layer.borderColor = text.count < 40 + owner.viewModel.comment = text + owner.commentCountLabel.text = "\(text.count)/40" + owner.commentView.layer.borderColor = text.count < 40 ? UIColor.darkPrimary_25.cgColor : UIColor.systemCritical.cgColor }.disposed(by: disposeBag) @@ -312,6 +314,15 @@ private extension ShareViewController { }) } .disposed(by: disposeBag) + + Observable.merge( + [ + dropButton.rx.tap.asObservable(), + dropButtonOnKeyBoard.rx.tap.asObservable() + ] + ) + .bind(to: dropButtonClickEvent) + .disposed(by: disposeBag) } func bindViewModel() { @@ -319,7 +330,8 @@ private extension ShareViewController { viewDidLoadEvent: .just(Void()), sharedMusicKeyWordEvent: sharedMusicKeyWordEvent.asObservable(), changingMusicViewClickEvent: changingMusicView.rx.tapGesture().asObservable().mapVoid(), - reSearchingEvent: reSearchingMusicForSharingView.reSearchingEvent + reSearchingEvent: reSearchingMusicForSharingView.reSearchingEvent, + dropButtonClickEvent: dropButtonClickEvent.asObservable() ) let output: ShareViewModel.Output = viewModel.convert( input: input, diff --git a/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift b/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift index 8d69d85c..d9eb94e1 100644 --- a/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift +++ b/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift @@ -22,12 +22,19 @@ final class ShareViewModel: NSObject, ShareViewModelType { private let output: Output = .init() private let locationManger: CLLocationManager = .init() private let searchMusicUsecase: SearchMusicUsecase + private let dropMusicUseCase: DropMusicUseCase private let disposeBag: DisposeBag = .init() + private var currentLocation: DroppingInfo.Location? var sharedSongName: String = "" var selectedMusic: Music? + var comment: String? - init(searchMusicUsecase: SearchMusicUsecase = DefaultSearchingMusicUsecase()) { + init( + searchMusicUsecase: SearchMusicUsecase = DefaultSearchingMusicUsecase(), + dropMusicUseCase: DropMusicUseCase = DefaultDropMusicUseCase() + ) { self.searchMusicUsecase = searchMusicUsecase + self.dropMusicUseCase = dropMusicUseCase } struct Input { @@ -35,6 +42,7 @@ final class ShareViewModel: NSObject, ShareViewModelType { let sharedMusicKeyWordEvent: Observable let changingMusicViewClickEvent: Observable let reSearchingEvent: Observable + let dropButtonClickEvent: Observable } struct Output { @@ -90,6 +98,40 @@ final class ShareViewModel: NSObject, ShareViewModelType { } .disposed(by: disposedBag) + input.dropButtonClickEvent + .bind(with: self) { owner, _ in + guard let selectedMusic = owner.selectedMusic else { + // TODO: 요셉, 선택한 음악정보 없다는 에러팝업 + return + } + + guard let comment = owner.comment else { + // TODO: 코멘트 없다는 에러팝업 + return + } + + guard let currentLocation = owner.currentLocation else { + // TODO: 현재 위치정보 없다는 에러팝업 + return + } + + owner.dropMusicUseCase.drop( + droppingInfo: .init( + location: currentLocation, + music: selectedMusic + ), + content: comment + ) + .subscribe { statusCode in + print("성공") + } onFailure: { error in + print(error.localizedDescription) + } + .disposed(by: disposedBag) + + } + .disposed(by: disposedBag) + return output } } @@ -116,6 +158,11 @@ extension ShareViewModel: CLLocationManagerDelegate { ) .subscribe(with: self) { owner, villageName in owner.output.showVillageNameRelay.accept(villageName) + owner.currentLocation = .init( + latitude: location.coordinate.latitude, + longitude: location.coordinate.longitude, + address: villageName + ) } onFailure: { owner, error in print(error.localizedDescription) } From dbf363e9c7b2698deaf741383a56c98e27ff34c6 Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Tue, 20 Aug 2024 09:38:28 +0900 Subject: [PATCH 22/37] =?UTF-8?q?=E2=9C=A8#297:=20Share=20Extension?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EB=93=9C=EB=9E=8D=ED=95=98=EA=B8=B0=20?= =?UTF-8?q?=EC=84=B1=EA=B3=B5=20=EC=8B=9C,=20=EB=93=9C=EB=9E=8D=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C=20=ED=99=94=EB=A9=B4=20=EB=A0=8C=EB=8D=94?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/DropDone/DropDoneView.swift | 245 ++++++++++++++++++ .../View/ShareViewController.swift | 22 ++ .../ViewModel/ShareViewModel.swift | 12 +- .../StreetDrop.xcodeproj/project.pbxproj | 18 ++ .../Contents.json | 23 ++ .../share-extension-location.png | Bin 0 -> 400 bytes .../share-extension-location@2x.png | Bin 0 -> 615 bytes .../share-extension-location@3x.png | Bin 0 -> 922 bytes .../UILabel+actualNumberOfLines.swift | 52 ++++ 9 files changed, 369 insertions(+), 3 deletions(-) create mode 100644 StreetDrop/ShareExtension/View/DropDone/DropDoneView.swift create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/share-extension-location.imageset/Contents.json create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/share-extension-location.imageset/share-extension-location.png create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/share-extension-location.imageset/share-extension-location@2x.png create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/share-extension-location.imageset/share-extension-location@3x.png create mode 100644 StreetDrop/StreetDrop/Util/Extensions/UILabel+actualNumberOfLines.swift diff --git a/StreetDrop/ShareExtension/View/DropDone/DropDoneView.swift b/StreetDrop/ShareExtension/View/DropDone/DropDoneView.swift new file mode 100644 index 00000000..439db02c --- /dev/null +++ b/StreetDrop/ShareExtension/View/DropDone/DropDoneView.swift @@ -0,0 +1,245 @@ +// +// DropDoneView.swift +// ShareExtension +// +// Created by 차요셉 on 8/19/24. +// + +import UIKit + +import Kingfisher +import SnapKit + +final class DropDoneView: UIView { + private let droppedMusic: Music + private let droppedAddress: String + private let droppedComment: String + + init( + droppedMusic: Music, + droppedAddress: String, + droppedComment: String + ) { + self.droppedMusic = droppedMusic + self.droppedAddress = droppedAddress + self.droppedComment = droppedComment + super.init(frame: .zero) + configureUI() + } + + @available(*, unavailable) + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private let dropDoneTitleLabel: UILabel = { + let label: UILabel = .init() + label.text = "드랍 완료!" + label.font = .pretendard(size: 18, weight: 700) + label.textColor = .white + label.setLineHeight(lineHeight: 28) + + return label + }() + + private let exitButton: UIButton = { + let button: UIButton = .init() + button.setImage(.init(named: "exit"), for: .normal) + + return button + }() + + private let contentContainerView: UIView = { + let view: UIView = .init() + view.backgroundColor = .gray700 + view.layer.cornerRadius = 20 + + return view + }() + + private lazy var albumImageView: UIImageView = { + let imageView: UIImageView = .init() + imageView.layer.cornerRadius = 8 + imageView.layer.borderWidth = 1 + imageView.layer.borderColor = UIColor.white.withAlphaComponent(0.05).cgColor + imageView.layer.masksToBounds = true + + imageView.kf.setImage(with: URL(string: droppedMusic.albumImage)) + + return imageView + }() + + private lazy var songNameLabel: UILabel = { + let label: UILabel = .init() + label.text = droppedMusic.songName + label.font = .pretendard(size: 14, weight: 500) + label.textColor = .white + label.setLineHeight(lineHeight: 20) + + return label + }() + + private lazy var artistNameLabel: UILabel = { + let label: UILabel = .init() + label.text = droppedMusic.artistName + label.textColor = .gray200 + label.font = .pretendard(size: 12, weight: 400) + label.setLineHeight(lineHeight: 16) + + return label + }() + + private let middleLine: UIView = { + let view: UIView = .init() + view.backgroundColor = .gray600 + + return view + }() + + private lazy var commentLabel: UILabel = { + let label: UILabel = .init() + label.text = droppedComment + label.font = .pretendard(size: 14, weight: 400) + label.textColor = .white + label.numberOfLines = 0 + label.setLineHeight(lineHeight: 20) + + return label + }() + + private let locationImageView: UIImageView = { + let imageView: UIImageView = .init(image: .init(named: "share-extension-location")) + + return imageView + }() + + private lazy var addressLabel: UILabel = { + let label: UILabel = .init() + label.text = droppedAddress + label.font = .pretendard(size: 12, weight: 400) + label.textColor = .primary400 + label.setLineHeight(lineHeight: 16) + + return label + }() + + private let viewOnAppButton: UIButton = { + let button = UIButton(type: .system) + button.setTitle("앱에서 보기", for: .normal) + button.setTitleColor(.gray900, for: .normal) + button.titleLabel?.font = .pretendard(size: 16, weight: 700) + button.layer.cornerRadius = 12 + button.backgroundColor = .primary400 + + return button + }() +} + +private extension DropDoneView { + func configureUI() { + layer.cornerRadius = 20 + layer.borderWidth = 1 + layer.borderColor = UIColor.gray600.cgColor + backgroundColor = .gray800 + + [ + dropDoneTitleLabel, + exitButton, + contentContainerView, + viewOnAppButton + ].forEach { + addSubview($0) + } + + [ + albumImageView, + songNameLabel, + artistNameLabel, + middleLine, + commentLabel, + locationImageView, + addressLabel + ].forEach { + contentContainerView.addSubview($0) + } + + dropDoneTitleLabel.snp.makeConstraints { + $0.top.equalToSuperview().inset(22) + $0.leading.equalToSuperview().inset(24) + $0.height.equalTo(28) + } + + exitButton.snp.makeConstraints { + $0.width.equalTo(44) + $0.height.equalTo(32) + $0.top.equalToSuperview().inset(20) + $0.trailing.equalToSuperview().inset(24) + } + + var contentContainerViewHeightConstraint: Constraint? + contentContainerView.snp.makeConstraints { + contentContainerViewHeightConstraint = $0.height.equalTo(0).constraint + $0.top.equalTo(dropDoneTitleLabel.snp.bottom).offset(10) + $0.horizontalEdges.equalToSuperview().inset(24) + } + + albumImageView.snp.makeConstraints { + $0.width.height.equalTo(48) + $0.top.equalToSuperview().inset(16) + $0.leading.equalToSuperview().inset(20) + } + + songNameLabel.snp.makeConstraints { + $0.height.equalTo(20) + $0.top.equalToSuperview().inset(20) + $0.leading.equalTo(albumImageView.snp.trailing).offset(8) + } + + artistNameLabel.snp.makeConstraints { + $0.height.equalTo(16) + $0.top.equalTo(songNameLabel.snp.bottom).offset(2) + $0.leading.equalTo(albumImageView.snp.trailing).offset(8) + } + + middleLine.snp.makeConstraints { + $0.height.equalTo(1) + $0.top.equalTo(albumImageView.snp.bottom).offset(16) + $0.horizontalEdges.equalToSuperview().inset(20) + } + + commentLabel.snp.makeConstraints { + $0.top.equalTo(middleLine.snp.bottom).offset(16) + $0.horizontalEdges.equalToSuperview().inset(20) + } + + locationImageView.snp.makeConstraints { + $0.width.equalTo(13) + $0.height.equalTo(16) + $0.top.equalTo(commentLabel.snp.bottom).offset(10) + $0.leading.equalToSuperview().inset(20) + } + + addressLabel.snp.makeConstraints { + $0.height.equalTo(16) + $0.top.equalTo(locationImageView) + $0.leading.equalTo(locationImageView.snp.trailing) + } + + viewOnAppButton.snp.makeConstraints { + $0.height.equalTo(56) + $0.horizontalEdges.equalToSuperview().inset(24) + $0.bottom.equalToSuperview().inset(48) + } + + layoutIfNeeded() + + let contentContainerHeight = 16 + 48 + 33 + commentLabel.actualNumberOfLines() * 20 + 46 + contentContainerViewHeightConstraint?.update( + offset: contentContainerHeight + ) + + snp.makeConstraints { + $0.height.equalTo(60 + contentContainerHeight + 132) + } + } +} diff --git a/StreetDrop/ShareExtension/View/ShareViewController.swift b/StreetDrop/ShareExtension/View/ShareViewController.swift index d809b717..20cb1b80 100644 --- a/StreetDrop/ShareExtension/View/ShareViewController.swift +++ b/StreetDrop/ShareExtension/View/ShareViewController.swift @@ -363,6 +363,28 @@ private extension ShareViewController { owner.reSearchingMusicForSharingView.settingMusicDataRelay.accept(musicList) } .disposed(by: disposeBag) + + output.goDropDoneView + .bind(onNext: { (droppedMusic, droppedAddress, droppedComment) in + DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: { [weak self] in + guard let self = self else { return } + containerView.isHidden = true + reSearchingMusicForSharingView.isHidden = true + + let dropDoneView: DropDoneView = .init( + droppedMusic: droppedMusic, + droppedAddress: droppedAddress, + droppedComment: droppedComment + ) + view.addSubview(dropDoneView) + dropDoneView.snp.makeConstraints { + $0.horizontalEdges.bottom.equalToSuperview() + } + + view.layoutIfNeeded() + }) + }) + .disposed(by: disposeBag) } func configureUI() { diff --git a/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift b/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift index d9eb94e1..d003ac00 100644 --- a/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift +++ b/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift @@ -58,6 +58,10 @@ final class ShareViewModel: NSObject, ShareViewModelType { var showReSearchedMusicList: Observable<[Music]> { showReSearchedMusicListRelay.asObservable() } + fileprivate let goDropDoneViewRelay: PublishRelay<(Music, String, String)> = .init() + var goDropDoneView: Observable<(Music, String, String)> { + goDropDoneViewRelay.asObservable() + } } func convert(input: Input, disposedBag: DisposeBag) -> Output { @@ -122,9 +126,11 @@ final class ShareViewModel: NSObject, ShareViewModelType { ), content: comment ) - .subscribe { statusCode in - print("성공") - } onFailure: { error in + .subscribe(with: self) { owner, statusCode in + owner.output.goDropDoneViewRelay.accept( + (selectedMusic, currentLocation.address, comment) + ) + } onFailure: { owner, error in print(error.localizedDescription) } .disposed(by: disposedBag) diff --git a/StreetDrop/StreetDrop.xcodeproj/project.pbxproj b/StreetDrop/StreetDrop.xcodeproj/project.pbxproj index 973acb4f..d6e87c4f 100644 --- a/StreetDrop/StreetDrop.xcodeproj/project.pbxproj +++ b/StreetDrop/StreetDrop.xcodeproj/project.pbxproj @@ -437,6 +437,9 @@ C47F02242A38633C00F48884 /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47F02232A38633C00F48884 /* SettingsViewModel.swift */; }; C47F02282A3864A500F48884 /* SettingElementCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47F02272A3864A500F48884 /* SettingElementCell.swift */; }; C47F022A2A3869DC00F48884 /* SettingSectionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47F02292A3869DC00F48884 /* SettingSectionType.swift */; }; + C48B76F52C73151B0003BC3C /* DropDoneView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48B76F42C73151B0003BC3C /* DropDoneView.swift */; }; + C48B76F72C7339DA0003BC3C /* UILabel+actualNumberOfLines.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48B76F62C7339DA0003BC3C /* UILabel+actualNumberOfLines.swift */; }; + C48B76F82C7339EB0003BC3C /* UILabel+actualNumberOfLines.swift in Sources */ = {isa = PBXBuildFile; fileRef = C48B76F62C7339DA0003BC3C /* UILabel+actualNumberOfLines.swift */; }; C49BA7612A1BDFC900A83E95 /* UIFont+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D16FC82A1B9338008B076F /* UIFont+Extension.swift */; }; C49BA7622A1BDFCC00A83E95 /* UILabel+LineHeight.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D16FCB2A1B98B0008B076F /* UILabel+LineHeight.swift */; }; C49BA7832A1BE71700A83E95 /* SearchingMusicViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C434A4CB2A1796F300C63526 /* SearchingMusicViewModel.swift */; }; @@ -769,6 +772,8 @@ C47F02232A38633C00F48884 /* SettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewModel.swift; sourceTree = ""; }; C47F02272A3864A500F48884 /* SettingElementCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingElementCell.swift; sourceTree = ""; }; C47F02292A3869DC00F48884 /* SettingSectionType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingSectionType.swift; sourceTree = ""; }; + C48B76F42C73151B0003BC3C /* DropDoneView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DropDoneView.swift; sourceTree = ""; }; + C48B76F62C7339DA0003BC3C /* UILabel+actualNumberOfLines.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UILabel+actualNumberOfLines.swift"; sourceTree = ""; }; C49EDACB2BBD75480025DB55 /* CongratulationsLevelUpPopUpViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CongratulationsLevelUpPopUpViewController.swift; sourceTree = ""; }; C49EDACD2BBD7EFE0025DB55 /* GradientLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientLabel.swift; sourceTree = ""; }; C4A0567A2A631D6E00AE2F0B /* CustomSwitch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomSwitch.swift; sourceTree = ""; }; @@ -1773,6 +1778,7 @@ children = ( C42182BC2C697F9700B73A99 /* ShareViewController.swift */, C44DE1FC2C6EE089004F211C /* ReSearchingMusic */, + C48B76F32C7314F20003BC3C /* DropDone */, ); path = View; sourceTree = ""; @@ -1978,6 +1984,14 @@ path = ViewModel; sourceTree = ""; }; + C48B76F32C7314F20003BC3C /* DropDone */ = { + isa = PBXGroup; + children = ( + C48B76F42C73151B0003BC3C /* DropDoneView.swift */, + ); + path = DropDone; + sourceTree = ""; + }; C4A4458E2A5EF203008279C1 /* FCM */ = { isa = PBXGroup; children = ( @@ -2093,6 +2107,7 @@ F4AA84DE2C1F3B0200CADB1A /* Array+Extension.swift */, 6A51EC3B2C3E52FE00DEF6F3 /* UIViewController+Rx.swift */, 6A51EC3D2C3E536000DEF6F3 /* Map+Rx.swift */, + C48B76F62C7339DA0003BC3C /* UILabel+actualNumberOfLines.swift */, ); path = Extensions; sourceTree = ""; @@ -2623,6 +2638,7 @@ 41396D912A4EFBF700B69341 /* DefaultEditCommentRepository.swift in Sources */, C419722E2ABD9D6F00211222 /* MyInfoUseCase.swift in Sources */, C4A4E3BC2C6447AF00283C37 /* FetchingRegionFilteredDropCountUseCase.swift in Sources */, + C48B76F72C7339DA0003BC3C /* UILabel+actualNumberOfLines.swift in Sources */, C4A0567B2A631D6E00AE2F0B /* CustomSwitch.swift in Sources */, 6A26BF342B33D2210007B6B7 /* DefaultFetchingSingleMusicUseCase.swift in Sources */, 1876F04E2A66EE030064B887 /* MyLevel.swift in Sources */, @@ -2842,6 +2858,7 @@ C432DF002C69F7F3003DBA18 /* UIViewController+Rx.swift in Sources */, C432DF012C69F7F3003DBA18 /* Map+Rx.swift in Sources */, C432DF022C69F7F3003DBA18 /* UIFont+Extension.swift in Sources */, + C48B76F82C7339EB0003BC3C /* UILabel+actualNumberOfLines.swift in Sources */, C432DF032C69F7F3003DBA18 /* TestError.swift in Sources */, C432DF042C69F7F3003DBA18 /* ImageCacheError.swift in Sources */, C432DF052C69F7F3003DBA18 /* UserDefaultsError.swift in Sources */, @@ -2892,6 +2909,7 @@ C432DF322C69F7F3003DBA18 /* EditCommentRepository.swift in Sources */, C432DF332C69F7F3003DBA18 /* DeleteMusicRepository.swift in Sources */, C432DF342C69F7F3003DBA18 /* BlockUserRepository.swift in Sources */, + C48B76F52C73151B0003BC3C /* DropDoneView.swift in Sources */, C432DF352C69F7F3003DBA18 /* PopUpRepository.swift in Sources */, C432DF362C69F7F3003DBA18 /* DefaultMainRepository.swift in Sources */, C432DF372C69F7F3003DBA18 /* DefaultSearchingMusicRepository.swift in Sources */, diff --git a/StreetDrop/StreetDrop/Resource/Assets.xcassets/share-extension-location.imageset/Contents.json b/StreetDrop/StreetDrop/Resource/Assets.xcassets/share-extension-location.imageset/Contents.json new file mode 100644 index 00000000..0656e6c4 --- /dev/null +++ b/StreetDrop/StreetDrop/Resource/Assets.xcassets/share-extension-location.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "share-extension-location.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "share-extension-location@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "share-extension-location@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/StreetDrop/StreetDrop/Resource/Assets.xcassets/share-extension-location.imageset/share-extension-location.png b/StreetDrop/StreetDrop/Resource/Assets.xcassets/share-extension-location.imageset/share-extension-location.png new file mode 100644 index 0000000000000000000000000000000000000000..8670f97bd696eedbe14767c5fcea45b0f9b8acd4 GIT binary patch literal 400 zcmV;B0dM|^P)C1~EflGcX2IWKt^v-XQA!E;Ml$@ZoElfaP@uI4H=tr_VNyiTK9m;SL_OALrGGy@n7R3F$9C<)Z zNZbZmzf74k8{eFArm6gBIJ@S1pfIvJCvss$s>Nb;)>Qfe@#7lNHYh*c8yS?Dcximn z77MHfZFOZw2~SNyRebJ&fP<0LbDZbpJGgmot7J7fQG>sy;sPylX=!?pingTGVKvZF uF+V4DVC(I^>(_MJY*UQQY}eM)QQ0q1#ey5k5)IM-0000MQ+n=NWY_M)XY2t=?C+LmNK&e9p+y~(L)Fig!m&|uH-d7+C2c`|g zEk@XZZ1Wfqo-YG^3uVdNZng*J)eeuK6fj~`CwaTXG!cEykE<*&`VLg%2C*xxP_scW zp!V`a4!l3{kr9r2+zq&nY`(k;7`g=fq-^A*xQhmkt!SE3V2pZCI?l@2Az49qrGhaj z)%a)JvB5nmGM`=nnWSZ(EuS|v*`AZOFG{}kMLGV4VCD~y z0vtPKc(KYl_8NnFxbG*;nG+kpAt&ZYa>xp$yPOL?>^Uj>g;E?CU)A)UH2WtIQgi_; z!lg>qd@7a0e)7uTKh6T^T-7R#tOY6QZ~f?VSDv6GoQ*A0=XvW=WEZ>Gwe{}=%EDHY zB29E5sjq`-$11N-Gjw3$r_0*bW0AGuZ$Yv9!^o=d0184ZSCjk0NH)dTb!R96%$l6^ zIeK60U1Op~nV+3pGC$#RM1{!Ggf4NHBidj+@eA3T+$u#@JSYGF002ovPDHLkV1ko8 B4$%Mr literal 0 HcmV?d00001 diff --git a/StreetDrop/StreetDrop/Resource/Assets.xcassets/share-extension-location.imageset/share-extension-location@3x.png b/StreetDrop/StreetDrop/Resource/Assets.xcassets/share-extension-location.imageset/share-extension-location@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..a28d889a9ec5da649613b4ca48ee31190c5261db GIT binary patch literal 922 zcmV;L17-Y)P)D3 zB0&&_t9nKR^ne*)25bas1{#4Ff$L>myewW8-HRB3nt>U}WFQxPtPk&HP^!CYs;j@M24KmOCI2_*W8CQUwhfpqAgT~x1%S%`Ocn9p5fS|c1Fc$N zr3D$FaX0#rSU)ZVr(R>;|6@_kO&0WYGUi~TBik|f0}F-^+m1FT zV>yUq@4y2jc#uOddisnr7h2nigCZsB1A%aDLi^=-E!_BC3^wIS7;F;R8`XHA%K1}& zS7RAY)(l`D$UT4%STa6pTdg2M4b`8|-8PH4GeSJiAwOfqivDY5Xb zt<+t1ji+9n4}()yUJAhm8z!d5aEo8^eP@N>H+gt1hD}hA?}klHUKXAQ+b)}-gNEEC zjCa57dfPEa8~8v5+D=2XWtYj&K}%S28FC0C@Ietl&AJAZphb^HL8JuBkO3nHX?Ow? zkxu4Ux2tke1YgzpDApZqan8E)MeO=If#qs+rLlv6BIjJ=4=kMbtWD0G-~qQ5gQGXy zi%};k@yWd6c@!dyk%+v@Y9iFEaW`Da4_yQJH1BdrteiddTV!ZhImlv(8`>>=9#l0i zIr5KMDzov2QFDr3wRj$+G)~)v_e@T)bQk(sIwxGqHO>h!naOuozWR11X&}(|gE0rC z0$89+SR@|N6FvyFGy|NAD%tUeFHqpu@=vWKtYZhT09d?FeWE8!b@1DIu5G~{L5A=h z`Eptx>0)LrJ}Ks!oG&fN1dLwS!aAfNv031JIT-z?cfkdt40nAS2W*|CoGF>h-KjgY8Zs$W-LLBPhr{x|_3i@wOh@ wFNO4SGK*9W3U8NvY3+Bj-qs~cmV74u0!$rFJ{PF3#Q*>R07*qoM6N<$g00DwE&u=k literal 0 HcmV?d00001 diff --git a/StreetDrop/StreetDrop/Util/Extensions/UILabel+actualNumberOfLines.swift b/StreetDrop/StreetDrop/Util/Extensions/UILabel+actualNumberOfLines.swift new file mode 100644 index 00000000..74de0693 --- /dev/null +++ b/StreetDrop/StreetDrop/Util/Extensions/UILabel+actualNumberOfLines.swift @@ -0,0 +1,52 @@ +// +// UILabel+actualNumberOfLines.swift +// StreetDrop +// +// Created by 차요셉 on 8/19/24. +// + +import UIKit + +extension UILabel { + func actualNumberOfLines() -> Int { + // 레이아웃이 완료된 이후에만 프레임을 사용 + layoutIfNeeded() + + guard let text = self.text, let font = self.font else { + return 0 + } + + // UILabel의 textContainer로 계산 + let textStorage = NSTextStorage(string: text) + let textContainer = NSTextContainer(size: CGSize(width: frame.size.width, height: CGFloat.greatestFiniteMagnitude)) + let layoutManager = NSLayoutManager() + + layoutManager.addTextContainer(textContainer) + textStorage.addLayoutManager(layoutManager) + + textStorage.addAttribute(.font, value: font, range: NSRange(location: 0, length: textStorage.length)) + textContainer.lineFragmentPadding = 0.0 + textContainer.lineBreakMode = lineBreakMode + + layoutManager.glyphRange(for: textContainer) + + let numberOfLines = layoutManager.numberOfLines(in: textContainer) + return numberOfLines + } +} + +extension NSLayoutManager { + func numberOfLines(in textContainer: NSTextContainer) -> Int { + var numberOfLines = 0 + var index = 0 + var lineRange: NSRange = NSRange() + + while index < numberOfGlyphs { + self.lineFragmentRect(forGlyphAt: index, effectiveRange: &lineRange) + index = NSMaxRange(lineRange) + numberOfLines += 1 + } + + return numberOfLines + } +} From 01b88886335dcd2f0358374a8bd8bf9ea3962ccb Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Tue, 20 Aug 2024 09:49:39 +0900 Subject: [PATCH 23/37] =?UTF-8?q?=E2=99=BB=EF=B8=8F#297:=20Share=20Extensi?= =?UTF-8?q?on=EC=9D=98=20=EC=9C=A0=ED=8A=9C=EB=B8=8C=20=EB=AE=A4=EC=A7=81?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=95=84=ED=8B=B0=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EB=AA=85=20=EB=8B=A4=EB=A5=B8=20=EB=8D=B0=EC=9D=B4=ED=84=B0?= =?UTF-8?q?=EB=A1=9C=20=EB=8C=80=EC=B2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 기존 데이터는 뒤에 "- TOPIC' 접미어가 붙어 검색 정확도가 떨어졌음 --- StreetDrop/ShareExtension/View/ShareViewController.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/StreetDrop/ShareExtension/View/ShareViewController.swift b/StreetDrop/ShareExtension/View/ShareViewController.swift index 20cb1b80..1801e0cf 100644 --- a/StreetDrop/ShareExtension/View/ShareViewController.swift +++ b/StreetDrop/ShareExtension/View/ShareViewController.swift @@ -543,8 +543,8 @@ private extension ShareViewController { let items = json["items"] as? [[String: Any]], let snippet = items.first?["snippet"] as? [String: Any] { let title = snippet["title"] as? String - let channelTitle = snippet["channelTitle"] as? String - completion(title, channelTitle) + let tags = snippet["tags"] as? [String] + completion(title, tags?.first ?? "") } else { completion(nil, nil) } From 506b8901b278a9a55f9e66c487413ee72d3c1acd Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Tue, 20 Aug 2024 10:09:50 +0900 Subject: [PATCH 24/37] =?UTF-8?q?=E2=9C=A8#297:=20Share=20Extension=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=EB=93=A4=EC=9D=98=20"X"=20=EC=A2=85=EB=A3=8C?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=ED=81=B4=EB=A6=AD=20=EC=8B=9C,=20Share=20?= =?UTF-8?q?Extension=20=EC=A2=85=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/DropDone/DropDoneView.swift | 16 ++++++++ .../ReSearchingMusicForSharingView.swift | 8 ++++ .../View/ShareViewController.swift | 41 ++++++++++++++++++- 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/StreetDrop/ShareExtension/View/DropDone/DropDoneView.swift b/StreetDrop/ShareExtension/View/DropDone/DropDoneView.swift index 439db02c..6259eda0 100644 --- a/StreetDrop/ShareExtension/View/DropDone/DropDoneView.swift +++ b/StreetDrop/ShareExtension/View/DropDone/DropDoneView.swift @@ -7,13 +7,22 @@ import UIKit +import RxSwift +import RxRelay import Kingfisher import SnapKit final class DropDoneView: UIView { + // View -> ViewController + private let exitButtonEventRelay: PublishRelay = .init() + var exitButtonEvent: Observable { + exitButtonEventRelay.asObservable() + } + private let droppedMusic: Music private let droppedAddress: String private let droppedComment: String + private let disposeBag: DisposeBag = .init() init( droppedMusic: Music, @@ -24,6 +33,7 @@ final class DropDoneView: UIView { self.droppedAddress = droppedAddress self.droppedComment = droppedComment super.init(frame: .zero) + bindAction() configureUI() } @@ -136,6 +146,12 @@ final class DropDoneView: UIView { } private extension DropDoneView { + func bindAction() { + exitButton.rx.tap + .bind(to: exitButtonEventRelay) + .disposed(by: disposeBag) + } + func configureUI() { layer.cornerRadius = 20 layer.borderWidth = 1 diff --git a/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicForSharingView.swift b/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicForSharingView.swift index 2db63a58..60f4e199 100644 --- a/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicForSharingView.swift +++ b/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicForSharingView.swift @@ -21,6 +21,10 @@ final class ReSearchingMusicForSharingView: UIView { var selectedMusicEvent: Observable { selectedMusicEventRelay.asObservable() } + private let exitButtonEventRelay: PublishRelay = .init() + var exitButtonEvent: Observable { + exitButtonEventRelay.asObservable() + } // ViewController -> View let settingMusicDataRelay: PublishRelay<[Music]> = .init() @@ -137,6 +141,10 @@ private extension ReSearchingMusicForSharingView { tableView.rx.modelSelected(Music.self) .bind(to: selectedMusicEventRelay) .disposed(by: disposeBag) + + exitButton.rx.tap + .bind(to: exitButtonEventRelay) + .disposed(by: disposeBag) } func bindData() { diff --git a/StreetDrop/ShareExtension/View/ShareViewController.swift b/StreetDrop/ShareExtension/View/ShareViewController.swift index 1801e0cf..4c5a1827 100644 --- a/StreetDrop/ShareExtension/View/ShareViewController.swift +++ b/StreetDrop/ShareExtension/View/ShareViewController.swift @@ -46,6 +46,13 @@ final class ShareViewController: UIViewController { return label }() + private let exitButton: UIButton = { + let button: UIButton = .init() + button.setImage(.init(named: "exit"), for: .normal) + + return button + }() + private let changingMusicView: UIView = { let view: UIView = .init() view.backgroundColor = .gray600 @@ -209,6 +216,8 @@ final class ShareViewController: UIViewController { return reSearchingMusicForSharingView }() + private var dropDoneView: DropDoneView? + override func viewDidLoad() { super.viewDidLoad() bindAction() @@ -229,6 +238,18 @@ final class ShareViewController: UIViewController { private extension ShareViewController { func bindAction() { + Observable.merge([ + exitButton.rx.tap.asObservable(), + reSearchingMusicForSharingView.exitButtonEvent.asObservable() + ]) + .bind(with: self) { owner, _ in + owner.extensionContext?.completeRequest( + returningItems: nil, + completionHandler: nil + ) + } + .disposed(by: disposeBag) + // 코멘트 플레이스홀더, 글자수라벨 설치, 줄 수 제한, 커멘트있을때만 드랍가능 commentTextView.rx.didBeginEditing .subscribe { [weak self] element in @@ -371,16 +392,26 @@ private extension ShareViewController { containerView.isHidden = true reSearchingMusicForSharingView.isHidden = true - let dropDoneView: DropDoneView = .init( + dropDoneView = .init( droppedMusic: droppedMusic, droppedAddress: droppedAddress, droppedComment: droppedComment ) + guard let dropDoneView = dropDoneView else { return } view.addSubview(dropDoneView) dropDoneView.snp.makeConstraints { $0.horizontalEdges.bottom.equalToSuperview() } + dropDoneView.exitButtonEvent + .bind(with: self) { owner, _ in + owner.extensionContext?.completeRequest( + returningItems: nil, + completionHandler: nil + ) + } + .disposed(by: disposeBag) + view.layoutIfNeeded() }) }) @@ -404,6 +435,7 @@ private extension ShareViewController { [ dropButton, villageNameLabel, + exitButton, changingMusicView, belowArrow, albumCoverImageView, @@ -431,6 +463,13 @@ private extension ShareViewController { $0.centerX.equalToSuperview() } + exitButton.snp.makeConstraints { + $0.width.equalTo(44) + $0.height.equalTo(32) + $0.top.equalToSuperview().inset(20) + $0.trailing.equalToSuperview().inset(24) + } + changingMusicView.snp.makeConstraints { $0.width.equalTo(174) $0.height.equalTo(28) From 581983ad2a0bf2a1243d098aeeeb3082d86c0908 Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Tue, 20 Aug 2024 10:32:01 +0900 Subject: [PATCH 25/37] =?UTF-8?q?=E2=9C=A8#297:=20Share=20Extension?= =?UTF-8?q?=EC=9D=98=20=EC=9E=AC=EA=B2=80=EC=83=89=20=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=EB=B0=B1=EB=B2=84=ED=8A=BC=20=EB=8F=99=EC=9E=91=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReSearchingMusicForSharingView.swift | 12 ++++++++++++ .../ShareExtension/View/ShareViewController.swift | 11 +++++++++++ 2 files changed, 23 insertions(+) diff --git a/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicForSharingView.swift b/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicForSharingView.swift index 60f4e199..9eb47aa6 100644 --- a/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicForSharingView.swift +++ b/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicForSharingView.swift @@ -25,6 +25,10 @@ final class ReSearchingMusicForSharingView: UIView { var exitButtonEvent: Observable { exitButtonEventRelay.asObservable() } + private let backbuttonEventRelay: PublishRelay = .init() + var backbuttonEvent: Observable { + backbuttonEventRelay.asObservable() + } // ViewController -> View let settingMusicDataRelay: PublishRelay<[Music]> = .init() @@ -145,6 +149,14 @@ private extension ReSearchingMusicForSharingView { exitButton.rx.tap .bind(to: exitButtonEventRelay) .disposed(by: disposeBag) + + backbutton.rx.tap + .do(onNext: { [weak self] _ in + self?.searchTextField.text = nil + self?.endEditing(true) + }) + .bind(to: backbuttonEventRelay) + .disposed(by: disposeBag) } func bindData() { diff --git a/StreetDrop/ShareExtension/View/ShareViewController.swift b/StreetDrop/ShareExtension/View/ShareViewController.swift index 4c5a1827..967a7268 100644 --- a/StreetDrop/ShareExtension/View/ShareViewController.swift +++ b/StreetDrop/ShareExtension/View/ShareViewController.swift @@ -344,6 +344,17 @@ private extension ShareViewController { ) .bind(to: dropButtonClickEvent) .disposed(by: disposeBag) + + reSearchingMusicForSharingView.backbuttonEvent + .bind(with: self) { owner, _ in + DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: { [weak self] in + guard let self = self else { return } + containerView.isHidden = false + reSearchingMusicForSharingView.isHidden = true + view.layoutIfNeeded() + }) + } + .disposed(by: disposeBag) } func bindViewModel() { From 7f9d9e60d77a108daecd82f24e2bee6e2a08437b Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Tue, 20 Aug 2024 10:33:38 +0900 Subject: [PATCH 26/37] =?UTF-8?q?=E2=9C=A8#297:=20Share=20ViewController?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EB=8B=A4=EB=A5=B8=20=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=EA=B0=88=EB=95=8C,=20=ED=82=A4=EB=B3=B4=EB=93=9C=20=EB=82=B4?= =?UTF-8?q?=EB=A6=AC=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- StreetDrop/ShareExtension/View/ShareViewController.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/StreetDrop/ShareExtension/View/ShareViewController.swift b/StreetDrop/ShareExtension/View/ShareViewController.swift index 967a7268..187b3866 100644 --- a/StreetDrop/ShareExtension/View/ShareViewController.swift +++ b/StreetDrop/ShareExtension/View/ShareViewController.swift @@ -386,6 +386,7 @@ private extension ShareViewController { output.showReSearchedMusicList .bind(with: self) { owner, musicList in + owner.endEditing() DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: { [weak self] in guard let self = self else { return } containerView.isHidden = true @@ -397,7 +398,8 @@ private extension ShareViewController { .disposed(by: disposeBag) output.goDropDoneView - .bind(onNext: { (droppedMusic, droppedAddress, droppedComment) in + .bind(onNext: { [weak self] (droppedMusic, droppedAddress, droppedComment) in + self?.endEditing() DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: { [weak self] in guard let self = self else { return } containerView.isHidden = true From 5eae16db6ab892350f6573592a833d90a3bc0fc9 Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Tue, 20 Aug 2024 16:27:50 +0900 Subject: [PATCH 27/37] =?UTF-8?q?=E2=9C=A8#297:=20=EB=8B=A4=EB=A5=B8=20?= =?UTF-8?q?=EC=95=B1=EC=97=90=EC=84=9C=20Share=20Extension=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EA=B0=80=EC=A0=B8=EC=98=A8=20ExtensionItem?= =?UTF-8?q?=EA=B0=92=EC=9D=B4=20=EC=97=86=EB=8A=94=20=EA=B2=BD=EC=9A=B0,?= =?UTF-8?q?=20=EC=9D=8C=EC=95=85=20=EC=A0=95=EB=B3=B4=20=EB=B6=88=EB=9F=AC?= =?UTF-8?q?=EC=98=A4=EC=A7=80=20=EB=AA=BB=ED=96=88=EB=8B=A4=EB=8A=94=20UI?= =?UTF-8?q?=20=EB=A0=8C=EB=8D=94=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- StreetDrop/Podfile.lock | 2 +- .../FailedLoadingMusicView.swift | 105 ++++++++++++++++++ .../View/ShareViewController.swift | 40 ++++++- .../ViewModel/ShareViewModel.swift | 18 +-- .../StreetDrop.xcodeproj/project.pbxproj | 12 ++ .../warning.imageset/Contents.json | 23 ++++ .../warning.imageset/warning.png | Bin 0 -> 632 bytes .../warning.imageset/warning@2x.png | Bin 0 -> 1106 bytes .../warning.imageset/warning@3x.png | Bin 0 -> 1550 bytes 9 files changed, 188 insertions(+), 12 deletions(-) create mode 100644 StreetDrop/ShareExtension/View/FailedLoadingMusicView/FailedLoadingMusicView.swift create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/warning.imageset/Contents.json create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/warning.imageset/warning.png create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/warning.imageset/warning@2x.png create mode 100644 StreetDrop/StreetDrop/Resource/Assets.xcassets/warning.imageset/warning@3x.png diff --git a/StreetDrop/Podfile.lock b/StreetDrop/Podfile.lock index 922103a7..42739630 100644 --- a/StreetDrop/Podfile.lock +++ b/StreetDrop/Podfile.lock @@ -25,4 +25,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: a8c0902adb23412ed3e2bbd632c3c7f7846b9405 -COCOAPODS: 1.12.1 +COCOAPODS: 1.15.2 diff --git a/StreetDrop/ShareExtension/View/FailedLoadingMusicView/FailedLoadingMusicView.swift b/StreetDrop/ShareExtension/View/FailedLoadingMusicView/FailedLoadingMusicView.swift new file mode 100644 index 00000000..03c3d70e --- /dev/null +++ b/StreetDrop/ShareExtension/View/FailedLoadingMusicView/FailedLoadingMusicView.swift @@ -0,0 +1,105 @@ +// +// FailedLoadingMusicView.swift +// ShareExtension +// +// Created by 차요셉 on 8/20/24. +// + +import UIKit + +import RxSwift +import RxRelay +import SnapKit + +final class FailedLoadingMusicView: UIView { + private let searchingMusicButtonEventRelay: PublishRelay = .init() + var searchingMusicButtonEvent: Observable { + searchingMusicButtonEventRelay.asObservable() + } + + private let disposeBag: DisposeBag = .init() + + override init(frame: CGRect) { + super.init(frame: frame) + bindAction() + configureUI() + } + + @available(*, unavailable) + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private let warningImageView: UIImageView = { + let imageView: UIImageView = .init(image: .init(named: "warning")) + + return imageView + }() + + private let guidingLabel: UILabel = { + let label: UILabel = .init() + label.text = "음악 정보를 불러오지 못했어요" + label.font = .pretendard(size: 18, weight: 700) + label.textColor = .white + label.setLineHeight(lineHeight: 28) + + return label + }() + + private let searchingMusicButton: UIButton = { + let button = UIButton(type: .system) + button.setTitle("음악 검색하기", for: .normal) + button.setTitleColor(.gray900, for: .normal) + button.titleLabel?.font = .pretendard(size: 16, weight: 700) + button.layer.cornerRadius = 12 + button.backgroundColor = .primary400 + + return button + }() +} + +private extension FailedLoadingMusicView { + func bindAction() { + searchingMusicButton.rx.tap + .bind(to: searchingMusicButtonEventRelay) + .disposed(by: disposeBag) + } + + func configureUI() { + layer.cornerRadius = 20 + layer.borderWidth = 1 + layer.borderColor = UIColor.gray600.cgColor + + backgroundColor = .gray800 + + snp.makeConstraints { + $0.height.equalTo(192) + } + + [ + warningImageView, + guidingLabel, + searchingMusicButton + ].forEach { + addSubview($0) + } + + warningImageView.snp.makeConstraints { + $0.width.height.equalTo(32) + $0.top.equalToSuperview().inset(20) + $0.leading.equalToSuperview().inset(24) + } + + guidingLabel.snp.makeConstraints { + $0.height.equalTo(32) + $0.top.equalToSuperview().inset(20) + $0.leading.equalTo(warningImageView.snp.trailing) + } + + searchingMusicButton.snp.makeConstraints { + $0.height.equalTo(56) + $0.horizontalEdges.equalToSuperview().inset(24) + $0.bottom.equalToSuperview().inset(48) + } + } +} diff --git a/StreetDrop/ShareExtension/View/ShareViewController.swift b/StreetDrop/ShareExtension/View/ShareViewController.swift index 187b3866..b77f19b2 100644 --- a/StreetDrop/ShareExtension/View/ShareViewController.swift +++ b/StreetDrop/ShareExtension/View/ShareViewController.swift @@ -23,7 +23,7 @@ final class ShareViewController: UIViewController { } private let viewModel: ShareViewModel = .init() private let disposeBag: DisposeBag = .init() - private let sharedMusicKeyWordEvent: PublishRelay = .init() + private let sharedMusicKeyWordEvent: PublishRelay = .init() private let dropButtonClickEvent: PublishRelay = .init() private let containerView: UIView = { @@ -218,6 +218,13 @@ final class ShareViewController: UIViewController { private var dropDoneView: DropDoneView? + private let failedLoadingMusicView: FailedLoadingMusicView = { + let failedLoadingMusicView: FailedLoadingMusicView = .init() + failedLoadingMusicView.isHidden = true + + return failedLoadingMusicView + }() + override func viewDidLoad() { super.viewDidLoad() bindAction() @@ -429,11 +436,28 @@ private extension ShareViewController { }) }) .disposed(by: disposeBag) + + output.goFailedLoadingMusicView + .bind(with: self) { owner, _ in + DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: { [weak self] in + guard let self = self else { return } + containerView.isHidden = true + reSearchingMusicForSharingView.isHidden = true + failedLoadingMusicView.isHidden = false + view.layoutIfNeeded() + }) + } + .disposed(by: disposeBag) } func configureUI() { - view.addSubview(containerView) - view.addSubview(reSearchingMusicForSharingView) + [ + containerView, + reSearchingMusicForSharingView, + failedLoadingMusicView + ].forEach { + view.addSubview($0) + } view.backgroundColor = UIColor.black.withAlphaComponent(0.5) containerView.snp.makeConstraints { @@ -559,6 +583,11 @@ private extension ShareViewController { $0.height.equalTo(56) $0.horizontalEdges.equalToSuperview() } + + failedLoadingMusicView.snp.makeConstraints { + $0.height.equalTo(192) + $0.horizontalEdges.bottom.equalToSuperview() + } } } @@ -567,7 +596,10 @@ private extension ShareViewController { func handleExtensionItem(_ extensionItem: NSExtensionItem) { // ExtensionItem에서 ContentText 추출 guard let sharedTextItem = extensionItem.attributedContentText, - let videoID = extractVideoID(from: sharedTextItem.string) else { return } + let videoID = extractVideoID(from: sharedTextItem.string) else { + sharedMusicKeyWordEvent.accept(nil) + return + } fetchVideoDetails(videoID: videoID) { [weak self] songName, artistName in self?.sharedMusicKeyWordEvent.accept("\(songName ?? "")-\(artistName ?? "")") diff --git a/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift b/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift index d003ac00..02e08633 100644 --- a/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift +++ b/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift @@ -39,7 +39,7 @@ final class ShareViewModel: NSObject, ShareViewModelType { struct Input { let viewDidLoadEvent: Observable - let sharedMusicKeyWordEvent: Observable + let sharedMusicKeyWordEvent: Observable let changingMusicViewClickEvent: Observable let reSearchingEvent: Observable let dropButtonClickEvent: Observable @@ -62,6 +62,10 @@ final class ShareViewModel: NSObject, ShareViewModelType { var goDropDoneView: Observable<(Music, String, String)> { goDropDoneViewRelay.asObservable() } + fileprivate let goFailedLoadingMusicViewRelay: PublishRelay = .init() + var goFailedLoadingMusicView: Observable { + goFailedLoadingMusicViewRelay.asObservable() + } } func convert(input: Input, disposedBag: DisposeBag) -> Output { @@ -75,10 +79,14 @@ final class ShareViewModel: NSObject, ShareViewModelType { input.sharedMusicKeyWordEvent .bind(with: self) { owner, sharedMusicKeyWord in + guard let sharedMusicKeyWord = sharedMusicKeyWord else { + owner.output.goFailedLoadingMusicViewRelay.accept(Void()) + return + } owner.searchMusicUsecase.searchMusic(keyword: sharedMusicKeyWord) .subscribe(with: self) { owner, musicList in guard let firstMusic = musicList.first else { - // TODO: 요셉, 검색된 음악 없다는 이벤트 view에 전달 + owner.output.goFailedLoadingMusicViewRelay.accept(Void()) return } owner.output.showSearchedMusicRelay.accept(firstMusic) @@ -131,6 +139,7 @@ final class ShareViewModel: NSObject, ShareViewModelType { (selectedMusic, currentLocation.address, comment) ) } onFailure: { owner, error in + // TODO: 드랍 실패 팝업 print(error.localizedDescription) } .disposed(by: disposedBag) @@ -176,9 +185,4 @@ extension ShareViewModel: CLLocationManagerDelegate { manager.stopUpdatingLocation() } - - func locationManager(_ manager: CLLocationManager, didFailWithError error: any Error) { - // TODO: 요셉, 에러메세지 띄우기 - print("위치 정보를 가져오는데 실패했습니다: \(error.localizedDescription)") - } } diff --git a/StreetDrop/StreetDrop.xcodeproj/project.pbxproj b/StreetDrop/StreetDrop.xcodeproj/project.pbxproj index d6e87c4f..12fcc25f 100644 --- a/StreetDrop/StreetDrop.xcodeproj/project.pbxproj +++ b/StreetDrop/StreetDrop.xcodeproj/project.pbxproj @@ -389,6 +389,7 @@ C434A4D82A17AAAB00C63526 /* SearchingMusicViewModelTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C434A4D72A17AAAB00C63526 /* SearchingMusicViewModelTest.swift */; }; C434A4DC2A19CA6F00C63526 /* SearchingMusicTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C434A4DB2A19CA6F00C63526 /* SearchingMusicTableViewCell.swift */; }; C434A4DD2A19CA6F00C63526 /* SearchingMusicTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C434A4DB2A19CA6F00C63526 /* SearchingMusicTableViewCell.swift */; }; + C4429C002C74515B00DC8C36 /* FailedLoadingMusicView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4429BFF2C74515B00DC8C36 /* FailedLoadingMusicView.swift */; }; C44442F32C6C7CA700CA93EA /* CommunityGuideDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41589AB92A474B3D0029A2EE /* CommunityGuideDetailView.swift */; }; C44980782BC37CB70001E6C3 /* NaverMaps.plist in Resources */ = {isa = PBXBuildFile; fileRef = C44980772BC37CB70001E6C3 /* NaverMaps.plist */; }; C449807A2BC3AF9F0001E6C3 /* PopUpUserReadingRequestDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44980792BC3AF9F0001E6C3 /* PopUpUserReadingRequestDTO.swift */; }; @@ -735,6 +736,7 @@ C434A4D22A17983A00C63526 /* SearchingMusicRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchingMusicRepository.swift; sourceTree = ""; }; C434A4D72A17AAAB00C63526 /* SearchingMusicViewModelTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchingMusicViewModelTest.swift; sourceTree = ""; }; C434A4DB2A19CA6F00C63526 /* SearchingMusicTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchingMusicTableViewCell.swift; sourceTree = ""; }; + C4429BFF2C74515B00DC8C36 /* FailedLoadingMusicView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FailedLoadingMusicView.swift; sourceTree = ""; }; C44980772BC37CB70001E6C3 /* NaverMaps.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = NaverMaps.plist; sourceTree = ""; }; C44980792BC3AF9F0001E6C3 /* PopUpUserReadingRequestDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopUpUserReadingRequestDTO.swift; sourceTree = ""; }; C449807B2BC3B07E0001E6C3 /* PostingPopUpUserReadingUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostingPopUpUserReadingUseCase.swift; sourceTree = ""; }; @@ -1779,6 +1781,7 @@ C42182BC2C697F9700B73A99 /* ShareViewController.swift */, C44DE1FC2C6EE089004F211C /* ReSearchingMusic */, C48B76F32C7314F20003BC3C /* DropDone */, + C4429BFE2C74514300DC8C36 /* FailedLoadingMusicView */, ); path = View; sourceTree = ""; @@ -1838,6 +1841,14 @@ path = SearchingMusic; sourceTree = ""; }; + C4429BFE2C74514300DC8C36 /* FailedLoadingMusicView */ = { + isa = PBXGroup; + children = ( + C4429BFF2C74515B00DC8C36 /* FailedLoadingMusicView.swift */, + ); + path = FailedLoadingMusicView; + sourceTree = ""; + }; C44A54942BBC080700354F8F /* PopUp */ = { isa = PBXGroup; children = ( @@ -2985,6 +2996,7 @@ C432DF7A2C69F7F3003DBA18 /* DefaultFetchingMyLevelUseCase.swift in Sources */, C432DF7B2C69F7F3003DBA18 /* FetchingMyLikeListUseCase.swift in Sources */, C432DF7C2C69F7F3003DBA18 /* DefaultFetchingMyLikeListUseCase.swift in Sources */, + C4429C002C74515B00DC8C36 /* FailedLoadingMusicView.swift in Sources */, C432DF7D2C69F7F3003DBA18 /* FetchingMyDropListUseCase.swift in Sources */, C432DF7E2C69F7F3003DBA18 /* DefaultFetchingMyDropListUseCase.swift in Sources */, C432DF7F2C69F7F3003DBA18 /* FetchingCityAndDistrictsUseCase.swift in Sources */, diff --git a/StreetDrop/StreetDrop/Resource/Assets.xcassets/warning.imageset/Contents.json b/StreetDrop/StreetDrop/Resource/Assets.xcassets/warning.imageset/Contents.json new file mode 100644 index 00000000..acb42565 --- /dev/null +++ b/StreetDrop/StreetDrop/Resource/Assets.xcassets/warning.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "warning.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "warning@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "warning@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/StreetDrop/StreetDrop/Resource/Assets.xcassets/warning.imageset/warning.png b/StreetDrop/StreetDrop/Resource/Assets.xcassets/warning.imageset/warning.png new file mode 100644 index 0000000000000000000000000000000000000000..b9050404809c0f89b56429530371be4167bb8c55 GIT binary patch literal 632 zcmV-;0*C#HP)BgqE`Oj$T~@6%Ab$5G9H)6hk1on}c_|pn^`C zoT*5>A05;O8V#P@yJigqbnF@XZahD*J>a=%O> z-($F6P)#Dua43hU$85dkBmpK!k2XZd@YQ9gAx`6QIJV7@Na91*)<{xX6*|5;SCj2} zDEW8%i9U+dpUa0zoF^lRPl&RaMEyIHf%N=|66#?X%71L^wRIdbIqFZco^Lebpk Se(wqUd05jVRQ(!O9$KsW*BsdV~4I6=b+YED3Ug1RRt(}oEp z#Of+G#8wipEybiW`er2!>8kTR?3)(61d}3Zt?d>oIxwx?W27B)^%^75$#F{=RNyM1FlZ_i3bFi zblqFQiqE1yBox=hU6moA`>btDpE`aC*wX1Qv??J~0KQ?e`L}5B$7u&I+Uf&MEA%BY zS{0#93E>pDyT-Tzd|VD}U2h$bHI(;l{>6jW8G!goMQ0crw8R5TWju_2L*Ilg8W4MRh0Lk znE{qXwDIFICMiD;%9b$63dm`#r*T@n!w-88Ja8#%yeTo(ET4S3cv6uJ>a|Xg$qz(*zwa~7IAOWM{2(iWqB>+V1a56 zNlD-%CrXw;ncG!T!fPmqu=o<|8SE!=qGSmc0($CJEM?`QB9toq735hv#CqS3f1@@$ zsM?9?Y)Q)Yu58hEp*L8$Q*@Wv| z=VLY9t=XePWCeApol_{FtFrV1$rO5664RYLO{ru06lK<-fR<#5@^-n3WG~|G1e)oh zH)$g$Q+_cCZPjMlZ6Ys^gJk2ZeUGJmRf~u$Kq$4IkOQYwUv!{|wzQcRPt9=ea0Jcu z9kPgPm4b&Tr$tksE?uHJrsz|hx!!zqv{MgP^4tx=TR5w|sQQ%7& zqBPG_CQ(m#bX@$`FKNh(Ue{rp!II>pBL5!C){L3eJl9T>bxr)*V&v-udOixdb07X$0MNt$*Q4~c{6h%=KMNt$*Q4~c{ zmIi|*!Nzg>18z4Xm{-*3j)i?qpSFQ%Ki&g7Fo^o}*MNRnF9R-DV0)h>Cw(-SMvK55 z{}H!)7U&}XEQsmRw;i{Dw26W=QiKojPL~??4y8KY%PEO**d#F;CBjX-(-{KqA=CL! zX^a>V8p6l@@AmFte?=Gpm@N|g_v?7)9crd_O9=e*`$)+uw(GKrT16-XxS&5fGyY4T zCh1@3(~B_dwa^-jcN~A;J$)B@PvjYO$;`i*=etRW^*V&8O@yoXTXHd@i*Xmzh0Wc~ zGy3!VWpa{YfqF8uVgtJ|tuCsE>snt+e&`_}wTLi_07d5?uVFPYNisl53M<(vysim^ z7b3U_GY&ywWAu!3P|%?%s0h6Hy2dSgKppQrTK2RR4YJ63SJ0ms8auJj&RLn1Xvi(A4ZDkwJEh5|9YLxiwhl z5IKa|gaE?BQRFmXj)bDYSc+MBN<@YvVG($;bkayG7$bFGHm@Oomm?dyZy1OLmU^(czE*eCY&pBcu~o$|`h!|AnXsg}a!#%BJUp)&Og>FXjXNMyJ*%QKM(@d>4g7f8fkk$83(qSEwH~3JMTopp3@yN-<3)mV z`Fk?VhDEkzW~wW!0L;=ICPy9yx#Z0iTIBSf9wr|mYIAN7zmkW#b#tEY{@)!YAEB>R zXn+VKW;oJXImJt=4*9qgYNRnDFl-ff`D7eo;a2O@KTe}W7$Gc1S{ztU(GVIb!iZwN z=;C1~u2hx=cl>2l@5!i|MvE{`ZXM>ef#p}Ty<*pv+|JJP7ZDoz*j@(n2fvc%C05Uy z*zt;@D2k#eilQirq9}@@D2k#eilQirqAV%@061-CEy}dm$p8QV07*qoM6N<$f?;pF A$p8QV literal 0 HcmV?d00001 From bdbd55d49cd7b66b498493d970aacf3bd496a939 Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Tue, 20 Aug 2024 16:50:12 +0900 Subject: [PATCH 28/37] =?UTF-8?q?=E2=9C=A8#297:=20Share=20Extension?= =?UTF-8?q?=EC=97=90=EC=84=9C=20ShareViewController=20->=20=EC=9E=AC?= =?UTF-8?q?=EA=B2=80=EC=83=89=ED=99=94=EB=A9=B4=20=EC=9D=B4=EB=8F=99?= =?UTF-8?q?=ED=95=A0=EB=95=8C=20=EC=9E=AC=EA=B2=80=EC=83=89=20=ED=86=B5?= =?UTF-8?q?=EC=8B=A0=20=EC=8B=A4=ED=8C=A8=20=EC=8B=9C,=20=ED=85=8C?= =?UTF-8?q?=EC=9D=B4=EB=B8=94=EB=B7=B0=EC=97=90=20=EB=B9=88=EB=B0=B0?= =?UTF-8?q?=EC=97=B4(=EB=B9=88=ED=99=94=EB=A9=B4)=20=EB=B3=B4=EC=97=AC?= =?UTF-8?q?=EC=A4=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift b/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift index 02e08633..61b8e565 100644 --- a/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift +++ b/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift @@ -157,7 +157,7 @@ private extension ShareViewModel { .subscribe(with: self) { owner, musicList in owner.output.showReSearchedMusicListRelay.accept(musicList) } onFailure: { owner, error in - // TODO: 요셉, 실패 팝업 띄우기 + owner.output.showReSearchedMusicListRelay.accept([]) } .disposed(by: disposeBag) } From 1ddc88905322155fbc98b379172f959f6910c224 Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Tue, 20 Aug 2024 16:54:18 +0900 Subject: [PATCH 29/37] =?UTF-8?q?=F0=9F=90=9B#297:=20Share=20Extension=20i?= =?UTF-8?q?nit=EC=8B=9C=20changingMusicViewClickEvent=20=ED=98=B8=EC=B6=9C?= =?UTF-8?q?=EB=90=98=EB=8A=94=20=ED=98=84=EC=83=81=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 원래 changingMusicView 클릭 할때만 이벤트 발생해야함 --- StreetDrop/ShareExtension/View/ShareViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/StreetDrop/ShareExtension/View/ShareViewController.swift b/StreetDrop/ShareExtension/View/ShareViewController.swift index b77f19b2..ff08893b 100644 --- a/StreetDrop/ShareExtension/View/ShareViewController.swift +++ b/StreetDrop/ShareExtension/View/ShareViewController.swift @@ -368,7 +368,7 @@ private extension ShareViewController { let input: ShareViewModel.Input = .init( viewDidLoadEvent: .just(Void()), sharedMusicKeyWordEvent: sharedMusicKeyWordEvent.asObservable(), - changingMusicViewClickEvent: changingMusicView.rx.tapGesture().asObservable().mapVoid(), + changingMusicViewClickEvent: changingMusicView.rx.tapGesture().when(.recognized).asObservable().mapVoid(), reSearchingEvent: reSearchingMusicForSharingView.reSearchingEvent, dropButtonClickEvent: dropButtonClickEvent.asObservable() ) From 7fde765deead33b0d0904c16391624da822112f3 Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Tue, 20 Aug 2024 16:58:37 +0900 Subject: [PATCH 30/37] =?UTF-8?q?=E2=9C=A8#297:=20Share=20Extension,=20?= =?UTF-8?q?=EC=9D=8C=EC=95=85=20=EC=A0=95=EB=B3=B4=20=EB=B6=88=EB=9F=AC?= =?UTF-8?q?=EC=98=A4=EC=A7=80=20=EB=AA=BB=ED=96=88=EB=8B=A4=EB=8A=94=20UI?= =?UTF-8?q?=EC=9D=98=20'=EC=9D=8C=EC=95=85=20=EA=B2=80=EC=83=89=ED=95=98?= =?UTF-8?q?=EA=B8=B0'=EB=B2=84=ED=8A=BC=20=EB=8F=99=EC=9E=91=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - '음악 검색하기'버튼 클릭 시, 빈 테이블뷰의 재검색 화면으로 이동 --- .../ShareExtension/View/ShareViewController.swift | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/StreetDrop/ShareExtension/View/ShareViewController.swift b/StreetDrop/ShareExtension/View/ShareViewController.swift index ff08893b..b1f77307 100644 --- a/StreetDrop/ShareExtension/View/ShareViewController.swift +++ b/StreetDrop/ShareExtension/View/ShareViewController.swift @@ -362,6 +362,18 @@ private extension ShareViewController { }) } .disposed(by: disposeBag) + + failedLoadingMusicView.searchingMusicButtonEvent + .bind(with: self) { owner, _ in + DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: { [weak self] in + guard let self = self else { return } + containerView.isHidden = true + reSearchingMusicForSharingView.isHidden = false + failedLoadingMusicView.isHidden = true + view.layoutIfNeeded() + }) + } + .disposed(by: disposeBag) } func bindViewModel() { From 9815fca10ab54ece57df93ef30befa750d28d549 Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Tue, 20 Aug 2024 17:19:26 +0900 Subject: [PATCH 31/37] =?UTF-8?q?=E2=9C=A8#297:=20Share=20Extension=20?= =?UTF-8?q?=ED=86=B5=EC=8B=A0=20=EC=97=90=EB=9F=AC=20=EB=B0=9C=EC=83=9D?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=97=90=EB=9F=AC=20=ED=8C=9D?= =?UTF-8?q?=EC=97=85=20=EB=A0=8C=EB=8D=94=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 정상 동작을 위한 재기동을 위해 팝업 확인 버튼 클릭 시, Share Extension 종료 --- .../View/ShareViewController.swift | 19 ++++++++++++++++++- .../ViewModel/ShareViewModel.swift | 13 ++++++++----- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/StreetDrop/ShareExtension/View/ShareViewController.swift b/StreetDrop/ShareExtension/View/ShareViewController.swift index b1f77307..051057bb 100644 --- a/StreetDrop/ShareExtension/View/ShareViewController.swift +++ b/StreetDrop/ShareExtension/View/ShareViewController.swift @@ -15,7 +15,7 @@ import RxRelay import RxGesture import SnapKit -final class ShareViewController: UIViewController { +final class ShareViewController: UIViewController, Alertable { enum Constant { static let commentPlaceHolder: String = "노래, 현재 감정, 상황, 관련 에피소드, 거리, 가수 등 떠오르는 말을 적어보세요." static let communityButtonTitle: String = "커뮤니티 가이드" @@ -458,6 +458,23 @@ private extension ShareViewController { failedLoadingMusicView.isHidden = false view.layoutIfNeeded() }) + + output.errorAlertShow + .bind(with: self) { owner, errorMessage in + owner.showAlert( + type: .alert( + onConfirm: { [weak self] in + self?.extensionContext?.completeRequest( + returningItems: nil, + completionHandler: nil + ) + } + ), + state: .primary, + title: "에러 발생", + subText: errorMessage, + buttonTitle: "확인" + ) } .disposed(by: disposeBag) } diff --git a/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift b/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift index 61b8e565..a052472c 100644 --- a/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift +++ b/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift @@ -66,6 +66,10 @@ final class ShareViewModel: NSObject, ShareViewModelType { var goFailedLoadingMusicView: Observable { goFailedLoadingMusicViewRelay.asObservable() } + fileprivate let errorAlertShowRelay: PublishRelay = .init() + var errorAlertShow: Observable { + errorAlertShowRelay.asObservable() + } } func convert(input: Input, disposedBag: DisposeBag) -> Output { @@ -113,17 +117,17 @@ final class ShareViewModel: NSObject, ShareViewModelType { input.dropButtonClickEvent .bind(with: self) { owner, _ in guard let selectedMusic = owner.selectedMusic else { - // TODO: 요셉, 선택한 음악정보 없다는 에러팝업 + owner.output.errorAlertShowRelay.accept("선택한 음악 정보가 없습니다.") return } guard let comment = owner.comment else { - // TODO: 코멘트 없다는 에러팝업 + owner.output.errorAlertShowRelay.accept("코멘트가 없습니다.") return } guard let currentLocation = owner.currentLocation else { - // TODO: 현재 위치정보 없다는 에러팝업 + owner.output.errorAlertShowRelay.accept("현재 위치정보가 없습니다.") return } @@ -139,8 +143,7 @@ final class ShareViewModel: NSObject, ShareViewModelType { (selectedMusic, currentLocation.address, comment) ) } onFailure: { owner, error in - // TODO: 드랍 실패 팝업 - print(error.localizedDescription) + owner.output.errorAlertShowRelay.accept("드랍에 실패 했습니다.") } .disposed(by: disposedBag) From 05566a4b2709fe6cb5adf650596dacc01e0ab35a Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Tue, 20 Aug 2024 17:20:51 +0900 Subject: [PATCH 32/37] =?UTF-8?q?=E2=9C=A8#297:=20Share=20Extension,=20?= =?UTF-8?q?=EB=8B=A4=EB=A5=B8=20=EC=95=B1=EC=97=90=EC=84=9C=20Share=20Exte?= =?UTF-8?q?nsion=EC=9C=BC=EB=A1=9C=20=EA=B0=80=EC=A0=B8=EC=98=A8=20Extensi?= =?UTF-8?q?onItem=EA=B0=92=EC=9D=B4=20=EC=97=86=EB=8A=94=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0(=EC=9D=8C=EC=95=85=20=EC=A0=95=EB=B3=B4=20=EB=AA=BB?= =?UTF-8?q?=EA=B0=80=EC=A0=B8=EC=98=A8=20=EA=B2=BD=EC=9A=B0)=20=EB=94=9C?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=97=86=EC=9D=B4=20=EB=B9=A0=EB=A5=B4?= =?UTF-8?q?=EA=B2=8C=20=EA=B4=80=EB=A0=A8=20UI=20=EB=A0=8C=EB=8D=94?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ShareExtension/View/ShareViewController.swift | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/StreetDrop/ShareExtension/View/ShareViewController.swift b/StreetDrop/ShareExtension/View/ShareViewController.swift index 051057bb..fa88b711 100644 --- a/StreetDrop/ShareExtension/View/ShareViewController.swift +++ b/StreetDrop/ShareExtension/View/ShareViewController.swift @@ -451,13 +451,11 @@ private extension ShareViewController { output.goFailedLoadingMusicView .bind(with: self) { owner, _ in - DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: { [weak self] in - guard let self = self else { return } - containerView.isHidden = true - reSearchingMusicForSharingView.isHidden = true - failedLoadingMusicView.isHidden = false - view.layoutIfNeeded() - }) + owner.containerView.isHidden = true + owner.reSearchingMusicForSharingView.isHidden = true + owner.failedLoadingMusicView.isHidden = false + } + .disposed(by: disposeBag) output.errorAlertShow .bind(with: self) { owner, errorMessage in From 7f4012e8ad5679bfa26f8560b19e59e224f88c47 Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Tue, 20 Aug 2024 17:21:55 +0900 Subject: [PATCH 33/37] =?UTF-8?q?=E2=9C=A8#297:=20Share=20Extension=20Aler?= =?UTF-8?q?table=20=EC=A3=BC=EC=9E=85=EC=97=90=20=EB=94=B0=EB=9D=BC,=20Sha?= =?UTF-8?q?re=20Extension=EC=97=90=EC=84=9C=20=EB=8F=99=EC=9E=91=ED=95=A0?= =?UTF-8?q?=20=EC=88=98=20=EC=97=86=EB=8A=94=20=EB=A1=9C=EC=A7=81=EC=97=90?= =?UTF-8?q?=20=EB=8C=80=ED=95=9C=20=EC=BD=94=EB=93=9C=20=EB=B6=84=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- StreetDrop/StreetDrop.xcodeproj/project.pbxproj | 2 ++ StreetDrop/StreetDrop/Presentation/Utils/Alertable.swift | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/StreetDrop/StreetDrop.xcodeproj/project.pbxproj b/StreetDrop/StreetDrop.xcodeproj/project.pbxproj index 12fcc25f..d06d1e77 100644 --- a/StreetDrop/StreetDrop.xcodeproj/project.pbxproj +++ b/StreetDrop/StreetDrop.xcodeproj/project.pbxproj @@ -390,6 +390,7 @@ C434A4DC2A19CA6F00C63526 /* SearchingMusicTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C434A4DB2A19CA6F00C63526 /* SearchingMusicTableViewCell.swift */; }; C434A4DD2A19CA6F00C63526 /* SearchingMusicTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C434A4DB2A19CA6F00C63526 /* SearchingMusicTableViewCell.swift */; }; C4429C002C74515B00DC8C36 /* FailedLoadingMusicView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4429BFF2C74515B00DC8C36 /* FailedLoadingMusicView.swift */; }; + C4429C032C74860B00DC8C36 /* Alertable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41BCFD442A38C099001D3E5F /* Alertable.swift */; }; C44442F32C6C7CA700CA93EA /* CommunityGuideDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41589AB92A474B3D0029A2EE /* CommunityGuideDetailView.swift */; }; C44980782BC37CB70001E6C3 /* NaverMaps.plist in Resources */ = {isa = PBXBuildFile; fileRef = C44980772BC37CB70001E6C3 /* NaverMaps.plist */; }; C449807A2BC3AF9F0001E6C3 /* PopUpUserReadingRequestDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44980792BC3AF9F0001E6C3 /* PopUpUserReadingRequestDTO.swift */; }; @@ -2975,6 +2976,7 @@ C432DF662C69F7F3003DBA18 /* DeletingMusicUseCase.swift in Sources */, C432DF672C69F7F3003DBA18 /* DefaultDeletingMusicUseCase.swift in Sources */, C44DE1FB2C6EE07D004F211C /* ReSearchingMusicTableViewCell.swift in Sources */, + C4429C032C74860B00DC8C36 /* Alertable.swift in Sources */, C432DF682C69F7F3003DBA18 /* BlockUserUseCase.swift in Sources */, C432DF692C69F7F3003DBA18 /* DefaultBlockUserUseCase.swift in Sources */, C432DF6A2C69F7F3003DBA18 /* FetchingMyInfoUseCase.swift in Sources */, diff --git a/StreetDrop/StreetDrop/Presentation/Utils/Alertable.swift b/StreetDrop/StreetDrop/Presentation/Utils/Alertable.swift index c524e555..d01e3369 100644 --- a/StreetDrop/StreetDrop/Presentation/Utils/Alertable.swift +++ b/StreetDrop/StreetDrop/Presentation/Utils/Alertable.swift @@ -22,7 +22,11 @@ extension Alertable where Self: UIViewController { let goSetting = UIAlertAction(title: "설정으로 이동", style: .default) { _ in if let appSetting = URL(string: UIApplication.openSettingsURLString) { +#if SHARE_EXTENSION_TARGET +#else + // 기본 동작 또는 다른 타겟의 경우 UIApplication.shared.open(appSetting) +#endif } } From 296d7b834c1b2676e8ef1059d964fbc7fc88dd44 Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Thu, 22 Aug 2024 09:51:02 +0900 Subject: [PATCH 34/37] =?UTF-8?q?=F0=9F=9B=A0#297:=20Share=20Extension?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=95=B1=EC=9C=BC=EB=A1=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=20=EC=8B=9C,=20=EA=B3=B5=EC=9C=A0=ED=95=A0=20?= =?UTF-8?q?=EB=93=9C=EB=9E=8D=EB=90=9C=20=EC=95=84=EC=9D=B4=ED=85=9C=20ID?= =?UTF-8?q?=20=EA=B3=B5=EC=9C=A0=EB=A5=BC=20=EC=9C=84=ED=95=B4=20Share=20E?= =?UTF-8?q?xtension=EA=B3=BC=20App=EA=B0=84=EC=9D=98=20App=20Groups?= =?UTF-8?q?=EB=A5=BC=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- StreetDrop/ShareExtension/ShareExtension.entitlements | 10 ++++++++++ StreetDrop/StreetDrop.xcodeproj/project.pbxproj | 4 ++++ StreetDrop/StreetDrop/StreetDropDebug.entitlements | 4 ++++ StreetDrop/StreetDrop/StreetDropRelease.entitlements | 4 ++++ 4 files changed, 22 insertions(+) create mode 100644 StreetDrop/ShareExtension/ShareExtension.entitlements diff --git a/StreetDrop/ShareExtension/ShareExtension.entitlements b/StreetDrop/ShareExtension/ShareExtension.entitlements new file mode 100644 index 00000000..548c32da --- /dev/null +++ b/StreetDrop/ShareExtension/ShareExtension.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.application-groups + + group.com.depromeet.StreetDrop + + + diff --git a/StreetDrop/StreetDrop.xcodeproj/project.pbxproj b/StreetDrop/StreetDrop.xcodeproj/project.pbxproj index d06d1e77..0a2faf95 100644 --- a/StreetDrop/StreetDrop.xcodeproj/project.pbxproj +++ b/StreetDrop/StreetDrop.xcodeproj/project.pbxproj @@ -801,6 +801,7 @@ C4D16FCB2A1B98B0008B076F /* UILabel+LineHeight.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UILabel+LineHeight.swift"; sourceTree = ""; }; C4D32A192C5A1F1E00E74BE8 /* RegionFilteringModalViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegionFilteringModalViewModel.swift; sourceTree = ""; }; C4E0943A2A4DF002000B4513 /* VillageNameResponseDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VillageNameResponseDTO.swift; sourceTree = ""; }; + C4E0E98D2C76BFC200977346 /* ShareExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ShareExtension.entitlements; sourceTree = ""; }; C4E25A9A2A57F8FF00E6A236 /* StreetDropDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = StreetDropDebug.entitlements; sourceTree = ""; }; C4E25A9B2A580B0D00E6A236 /* StreetDropRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = StreetDropRelease.entitlements; sourceTree = ""; }; C4E4C6B12A5ADC2C00B1C84A /* SettingsRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsRepository.swift; sourceTree = ""; }; @@ -1769,6 +1770,7 @@ C42182BB2C697F9700B73A99 /* ShareExtension */ = { isa = PBXGroup; children = ( + C4E0E98D2C76BFC200977346 /* ShareExtension.entitlements */, C42182C12C697F9700B73A99 /* Info.plist */, C42182C92C69C3FD00B73A99 /* View */, C42182CA2C69C40300B73A99 /* ViewModel */, @@ -3296,6 +3298,7 @@ baseConfigurationReference = 13ACF3C8F07C1A2CFE303F4A /* Pods-ShareExtension.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; @@ -3330,6 +3333,7 @@ baseConfigurationReference = B20DBB514344BC89E684862A /* Pods-ShareExtension.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Distribution"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Distribution"; CODE_SIGN_STYLE = Automatic; diff --git a/StreetDrop/StreetDrop/StreetDropDebug.entitlements b/StreetDrop/StreetDrop/StreetDropDebug.entitlements index 2f59161a..7d0032eb 100644 --- a/StreetDrop/StreetDrop/StreetDropDebug.entitlements +++ b/StreetDrop/StreetDrop/StreetDropDebug.entitlements @@ -9,5 +9,9 @@ applinks:test-open.street-drop.com webcredentials:test-open.street-drop.com + com.apple.security.application-groups + + group.com.depromeet.StreetDrop + diff --git a/StreetDrop/StreetDrop/StreetDropRelease.entitlements b/StreetDrop/StreetDrop/StreetDropRelease.entitlements index 07fca7ff..304b59f9 100644 --- a/StreetDrop/StreetDrop/StreetDropRelease.entitlements +++ b/StreetDrop/StreetDrop/StreetDropRelease.entitlements @@ -9,5 +9,9 @@ applinks:open.street-drop.com webcredentials:open.street-drop.com + com.apple.security.application-groups + + group.com.depromeet.StreetDrop + From bbfe4db303e68c68ff87c4b38c87a488c1fbc1be Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Thu, 22 Aug 2024 09:56:55 +0900 Subject: [PATCH 35/37] =?UTF-8?q?=E2=9C=A8#297:=20Share=20Extension?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=95=84=EC=9D=B4=ED=85=9C=20=EB=93=9C?= =?UTF-8?q?=EB=9E=8D=ED=95=98=EA=B8=B0=20API=ED=98=B8=EC=B6=9C=20=EC=8B=9C?= =?UTF-8?q?,=20ResponseDTO=EC=A4=91=20itemID=EB=A5=BC=20=EC=95=B1=EC=A0=84?= =?UTF-8?q?=ED=99=98=20=EC=8B=9C=20=ED=95=84=EC=9A=94=ED=95=98=EA=B8=B0=20?= =?UTF-8?q?=EB=95=8C=EB=AC=B8=EC=97=90=20=EC=95=B1=EC=9D=98=20=EB=93=9C?= =?UTF-8?q?=EB=9E=8D=ED=95=98=EA=B8=B0=20=EB=A1=9C=EC=A7=81=EA=B3=BC=20?= =?UTF-8?q?=EB=B6=84=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../StreetDrop.xcodeproj/project.pbxproj | 6 ++++ .../DropMusic/DropMusicReponseDTO.swift | 13 ++++++++ .../DefaultDropMusicRepository.swift | 30 ++++++++++++++++++- .../Protocol/DropMusicRepository.swift | 3 +- .../DropMusic/DefaultDropMusicUseCase.swift | 8 +++-- .../UseCase/DropMusic/DropMusicUseCase.swift | 3 +- .../ViewModel/MusicDropViewModel.swift | 2 +- 7 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 StreetDrop/StreetDrop/Data/DataMapping/DropMusic/DropMusicReponseDTO.swift diff --git a/StreetDrop/StreetDrop.xcodeproj/project.pbxproj b/StreetDrop/StreetDrop.xcodeproj/project.pbxproj index 0a2faf95..774d0cc5 100644 --- a/StreetDrop/StreetDrop.xcodeproj/project.pbxproj +++ b/StreetDrop/StreetDrop.xcodeproj/project.pbxproj @@ -177,6 +177,8 @@ C408B0372C6A5E8200338BFE /* Pretendard-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = C4D16FBB2A1B917B008B076F /* Pretendard-Bold.otf */; }; C408B0382C6A5E8200338BFE /* Pretendard-Thin.otf in Resources */ = {isa = PBXBuildFile; fileRef = C4D16FB62A1B917B008B076F /* Pretendard-Thin.otf */; }; C408B03A2C6A63B500338BFE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 040685082A01539800377094 /* Assets.xcassets */; }; + C40F09022C761ACB0034D7E3 /* DropMusicReponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40F09012C761ACB0034D7E3 /* DropMusicReponseDTO.swift */; }; + C40F09032C761ACB0034D7E3 /* DropMusicReponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40F09012C761ACB0034D7E3 /* DropMusicReponseDTO.swift */; }; C419722E2ABD9D6F00211222 /* MyInfoUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C419722D2ABD9D6F00211222 /* MyInfoUseCase.swift */; }; C41972302ABDAB0200211222 /* DefaultMyInfoUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C419722F2ABDAB0200211222 /* DefaultMyInfoUseCase.swift */; }; C41972322ABDAEF200211222 /* MyInfoError.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41972312ABDAEF200211222 /* MyInfoError.swift */; }; @@ -702,6 +704,7 @@ B4B9EE832ADBDFFB000A6507 /* RecommendMusicSearchCollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendMusicSearchCollectionView.swift; sourceTree = ""; }; B4B9EE852ADEB2AC000A6507 /* RecommendKeywordItemCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendKeywordItemCell.swift; sourceTree = ""; }; C40008E92A32012B00EA7FA9 /* Music.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Music.swift; sourceTree = ""; }; + C40F09012C761ACB0034D7E3 /* DropMusicReponseDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DropMusicReponseDTO.swift; sourceTree = ""; }; C419722D2ABD9D6F00211222 /* MyInfoUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyInfoUseCase.swift; sourceTree = ""; }; C419722F2ABDAB0200211222 /* DefaultMyInfoUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultMyInfoUseCase.swift; sourceTree = ""; }; C41972312ABDAEF200211222 /* MyInfoError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyInfoError.swift; sourceTree = ""; }; @@ -943,6 +946,7 @@ isa = PBXGroup; children = ( 049F50212A122C8A001528CB /* DropMusicRequestDTO+Mapping.swift */, + C40F09012C761ACB0034D7E3 /* DropMusicReponseDTO.swift */, ); path = DropMusic; sourceTree = ""; @@ -2621,6 +2625,7 @@ C449807E2BC3B09F0001E6C3 /* DefaultPostingPopUpUserReadingUseCase.swift in Sources */, C41972302ABDAB0200211222 /* DefaultMyInfoUseCase.swift in Sources */, 41396D8F2A4EFBE800B69341 /* DefaultDeleteMusicRepository.swift in Sources */, + C40F09022C761ACB0034D7E3 /* DropMusicReponseDTO.swift in Sources */, 41396D822A4EF65B00B69341 /* EditCommentRequestDTO.swift in Sources */, C434A4D32A17983A00C63526 /* SearchingMusicRepository.swift in Sources */, 41A3DDF82A5AD222004CFA2F /* DefaultBlockUserRepository.swift in Sources */, @@ -2854,6 +2859,7 @@ C432DF9C2C69F89A003DBA18 /* PoiEntity.swift in Sources */, C432DF9D2C69F89A003DBA18 /* MusicCountEntity.swift in Sources */, C432DF9E2C69F89A003DBA18 /* MusicWithinAreaEntity.swift in Sources */, + C40F09032C761ACB0034D7E3 /* DropMusicReponseDTO.swift in Sources */, C432DF862C69F867003DBA18 /* MyMusic.swift in Sources */, C432DF872C69F867003DBA18 /* MyLevel.swift in Sources */, C432DEF32C69F7F3003DBA18 /* AddressManager.swift in Sources */, diff --git a/StreetDrop/StreetDrop/Data/DataMapping/DropMusic/DropMusicReponseDTO.swift b/StreetDrop/StreetDrop/Data/DataMapping/DropMusic/DropMusicReponseDTO.swift new file mode 100644 index 00000000..c6b7e0e4 --- /dev/null +++ b/StreetDrop/StreetDrop/Data/DataMapping/DropMusic/DropMusicReponseDTO.swift @@ -0,0 +1,13 @@ +// +// DropMusicReponseDTO.swift +// StreetDrop +// +// Created by 차요셉 on 8/21/24. +// + +import Foundation + +struct DropMusicReponseDTO: Decodable { + let itemId: Int + // 프로퍼티 더 있는데 일단 필요한 것만 사용 +} diff --git a/StreetDrop/StreetDrop/Data/Repositories/DefaultDropMusicRepository.swift b/StreetDrop/StreetDrop/Data/Repositories/DefaultDropMusicRepository.swift index da64d43f..44431baf 100644 --- a/StreetDrop/StreetDrop/Data/Repositories/DefaultDropMusicRepository.swift +++ b/StreetDrop/StreetDrop/Data/Repositories/DefaultDropMusicRepository.swift @@ -17,7 +17,7 @@ final class DefaultDropMusicRepository { } extension DefaultDropMusicRepository: DropMusicRepository { - func dropMusic(droppingInfo: DroppingInfo, content: String) -> Single { + func dropMusicResponsingOnlyStatusCode(droppingInfo: DroppingInfo, content: String) -> Single { return networkManager.requestStatusCode( target: .init( NetworkService.dropMusic( @@ -40,4 +40,32 @@ extension DefaultDropMusicRepository: DropMusicRepository { ) ) } + + func dropMusicResponsingOnlyItemID(droppingInfo: DroppingInfo, content: String) -> Single { + return networkManager.request( + target: .init( + NetworkService.dropMusic( + requestDTO: .init( + location: DropMusicRequestDTO.Location( + latitude: droppingInfo.location.latitude, + longitude: droppingInfo.location.longitude, + address: droppingInfo.location.address + ), + music: DropMusicRequestDTO.Music( + title: droppingInfo.music.songName, + artist: droppingInfo.music.artistName, + albumName: droppingInfo.music.albumName, + albumImage: droppingInfo.music.albumImage, + genre: droppingInfo.music.genre + ), + content: content + ) + ) + ), + responseType: DropMusicReponseDTO.self + ) + .map { dto in + return dto.itemId + } + } } diff --git a/StreetDrop/StreetDrop/Data/Repositories/Protocol/DropMusicRepository.swift b/StreetDrop/StreetDrop/Data/Repositories/Protocol/DropMusicRepository.swift index 29ffd6ff..7a857b21 100644 --- a/StreetDrop/StreetDrop/Data/Repositories/Protocol/DropMusicRepository.swift +++ b/StreetDrop/StreetDrop/Data/Repositories/Protocol/DropMusicRepository.swift @@ -10,5 +10,6 @@ import Foundation import RxSwift protocol DropMusicRepository { - func dropMusic(droppingInfo: DroppingInfo, content: String) -> Single + func dropMusicResponsingOnlyStatusCode(droppingInfo: DroppingInfo, content: String) -> Single + func dropMusicResponsingOnlyItemID(droppingInfo: DroppingInfo, content: String) -> Single } diff --git a/StreetDrop/StreetDrop/Domain/UseCase/DropMusic/DefaultDropMusicUseCase.swift b/StreetDrop/StreetDrop/Domain/UseCase/DropMusic/DefaultDropMusicUseCase.swift index e00355f2..9f370c40 100644 --- a/StreetDrop/StreetDrop/Domain/UseCase/DropMusic/DefaultDropMusicUseCase.swift +++ b/StreetDrop/StreetDrop/Domain/UseCase/DropMusic/DefaultDropMusicUseCase.swift @@ -16,7 +16,11 @@ final class DefaultDropMusicUseCase: DropMusicUseCase { self.dropMusicRepository = dropMusicRepository } - func drop(droppingInfo: DroppingInfo, content: String) -> Single { - return dropMusicRepository.dropMusic(droppingInfo: droppingInfo, content: content) + func dropMusicResponsingOnlyStatusCode(droppingInfo: DroppingInfo, content: String) -> Single { + return dropMusicRepository.dropMusicResponsingOnlyStatusCode(droppingInfo: droppingInfo, content: content) + } + + func dropMusicResponsingOnlyItemID(droppingInfo: DroppingInfo, content: String) -> Single { + return dropMusicRepository.dropMusicResponsingOnlyItemID(droppingInfo: droppingInfo, content: content) } } diff --git a/StreetDrop/StreetDrop/Domain/UseCase/DropMusic/DropMusicUseCase.swift b/StreetDrop/StreetDrop/Domain/UseCase/DropMusic/DropMusicUseCase.swift index bbcfea53..da5504e5 100644 --- a/StreetDrop/StreetDrop/Domain/UseCase/DropMusic/DropMusicUseCase.swift +++ b/StreetDrop/StreetDrop/Domain/UseCase/DropMusic/DropMusicUseCase.swift @@ -10,5 +10,6 @@ import Foundation import RxSwift protocol DropMusicUseCase { - func drop(droppingInfo: DroppingInfo, content: String) -> Single + func dropMusicResponsingOnlyStatusCode(droppingInfo: DroppingInfo, content: String) -> Single + func dropMusicResponsingOnlyItemID(droppingInfo: DroppingInfo, content: String) -> Single } diff --git a/StreetDrop/StreetDrop/Presentation/MusicDropView/ViewModel/MusicDropViewModel.swift b/StreetDrop/StreetDrop/Presentation/MusicDropView/ViewModel/MusicDropViewModel.swift index 9ae2d85b..c57cbb28 100644 --- a/StreetDrop/StreetDrop/Presentation/MusicDropView/ViewModel/MusicDropViewModel.swift +++ b/StreetDrop/StreetDrop/Presentation/MusicDropView/ViewModel/MusicDropViewModel.swift @@ -93,7 +93,7 @@ class MusicDropViewModel: ViewModel { var comment = "" input.comment.bind { comment = $0 }.disposed(by: DisposeBag()) - self.dropMusicUseCase.drop(droppingInfo: self.droppingInfo, content: comment) + self.dropMusicUseCase.dropMusicResponsingOnlyStatusCode(droppingInfo: self.droppingInfo, content: comment) .subscribe(onSuccess: { response in if !(200...299).contains(response) { output.isSuccessDrop.accept( From 98efeaad6bed76542104398b7f50401200650c8c Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Thu, 22 Aug 2024 10:07:13 +0900 Subject: [PATCH 36/37] =?UTF-8?q?=E2=9C=A8#297:=20Share=20Extension?= =?UTF-8?q?=EC=9D=98=20'=EC=95=B1=EC=97=90=EC=84=9C=20=EB=B3=B4=EA=B8=B0'?= =?UTF-8?q?=20=EB=B2=84=ED=8A=BC=20=ED=81=B4=EB=A6=AD=20=EC=8B=9C,=20?= =?UTF-8?q?=EC=95=B1=EC=9C=BC=EB=A1=9C=20=EC=9D=B4=EB=8F=99=ED=95=B4=20Sha?= =?UTF-8?q?re=20Extension=EC=97=90=EC=84=9C=20=EB=93=9C=EB=9E=8D=ED=95=9C?= =?UTF-8?q?=20=EC=95=84=EC=9D=B4=ED=85=9C=EC=97=90=20=EB=8C=80=ED=95=9C=20?= =?UTF-8?q?=EC=BB=A4=EB=AE=A4=EB=8B=88=ED=8B=B0=20Scene=EC=97=90=EC=84=9C?= =?UTF-8?q?=20=EB=A0=8C=EB=8D=94=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Share Extension에서 드랍한 아이템 ID, UserDefaults에 저장 및 메인 Scene ViewDidAppear 또는 Bakcground -> Foreground 전환 시 커뮤니티 Scene 렌더링 --- .../View/DropDone/DropDoneView.swift | 8 +++ .../View/ShareViewController.swift | 58 +++++++++++++++++-- .../ViewModel/ShareViewModel.swift | 6 +- .../Application/SceneDelegate.swift | 36 ++++++------ .../MainScene/View/MainViewController.swift | 34 +++++++++++ 5 files changed, 118 insertions(+), 24 deletions(-) diff --git a/StreetDrop/ShareExtension/View/DropDone/DropDoneView.swift b/StreetDrop/ShareExtension/View/DropDone/DropDoneView.swift index 6259eda0..f7317d3b 100644 --- a/StreetDrop/ShareExtension/View/DropDone/DropDoneView.swift +++ b/StreetDrop/ShareExtension/View/DropDone/DropDoneView.swift @@ -18,6 +18,10 @@ final class DropDoneView: UIView { var exitButtonEvent: Observable { exitButtonEventRelay.asObservable() } + private let viewOnAppButtonEventRelay: PublishRelay = .init() + var viewOnAppButtonEvent: Observable { + viewOnAppButtonEventRelay.asObservable() + } private let droppedMusic: Music private let droppedAddress: String @@ -150,6 +154,10 @@ private extension DropDoneView { exitButton.rx.tap .bind(to: exitButtonEventRelay) .disposed(by: disposeBag) + + viewOnAppButton.rx.tap + .bind(to: viewOnAppButtonEventRelay) + .disposed(by: disposeBag) } func configureUI() { diff --git a/StreetDrop/ShareExtension/View/ShareViewController.swift b/StreetDrop/ShareExtension/View/ShareViewController.swift index fa88b711..bc751a90 100644 --- a/StreetDrop/ShareExtension/View/ShareViewController.swift +++ b/StreetDrop/ShareExtension/View/ShareViewController.swift @@ -216,8 +216,6 @@ final class ShareViewController: UIViewController, Alertable { return reSearchingMusicForSharingView }() - private var dropDoneView: DropDoneView? - private let failedLoadingMusicView: FailedLoadingMusicView = { let failedLoadingMusicView: FailedLoadingMusicView = .init() failedLoadingMusicView.isHidden = true @@ -424,13 +422,13 @@ private extension ShareViewController { containerView.isHidden = true reSearchingMusicForSharingView.isHidden = true - dropDoneView = .init( + let dropDoneView: DropDoneView = .init( droppedMusic: droppedMusic, droppedAddress: droppedAddress, droppedComment: droppedComment ) - guard let dropDoneView = dropDoneView else { return } view.addSubview(dropDoneView) + dropDoneView.snp.makeConstraints { $0.horizontalEdges.bottom.equalToSuperview() } @@ -444,6 +442,58 @@ private extension ShareViewController { } .disposed(by: disposeBag) + dropDoneView.viewOnAppButtonEvent + .bind(with: self) { owner, _ in + guard let droppedItemID = owner.viewModel.itemID else { + owner.showAlert( + type: .alert( + onConfirm: { [weak self] in + self?.extensionContext?.completeRequest( + returningItems: nil, + completionHandler: nil + ) + } + ), + state: .primary, + title: "에러 발생", + subText: "드랍된 ID를 찾을 수 없습니다.", + buttonTitle: "확인" + ) + return + } + + guard let url = URL(string: "streetdrop://") else { return } + var responder = self as UIResponder? + while responder != nil { + if let application = responder as? UIApplication { + guard let sharedDefaults = UserDefaults(suiteName: "group.com.depromeet.StreetDrop") else { + owner.showAlert( + type: .alert( + onConfirm: { [weak self] in + self?.extensionContext?.completeRequest( + returningItems: nil, + completionHandler: nil + ) + } + ), + state: .primary, + title: "에러 발생", + subText: "드랍 아이템 ID 내부 데이터 저장 실패", + buttonTitle: "확인" + ) + return + } + sharedDefaults.set(droppedItemID, forKey: "ShareExtensionDroppedItemID") + sharedDefaults.synchronize() + + application.open(url, options: [:], completionHandler: nil) + break + } + responder = responder?.next + } + } + .disposed(by: disposeBag) + view.layoutIfNeeded() }) }) diff --git a/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift b/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift index a052472c..617ef5ce 100644 --- a/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift +++ b/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift @@ -28,6 +28,7 @@ final class ShareViewModel: NSObject, ShareViewModelType { var sharedSongName: String = "" var selectedMusic: Music? var comment: String? + var itemID: Int? init( searchMusicUsecase: SearchMusicUsecase = DefaultSearchingMusicUsecase(), @@ -131,14 +132,15 @@ final class ShareViewModel: NSObject, ShareViewModelType { return } - owner.dropMusicUseCase.drop( + owner.dropMusicUseCase.dropMusicResponsingOnlyItemID( droppingInfo: .init( location: currentLocation, music: selectedMusic ), content: comment ) - .subscribe(with: self) { owner, statusCode in + .subscribe(with: self) { owner, itemID in + owner.itemID = itemID owner.output.goDropDoneViewRelay.accept( (selectedMusic, currentLocation.address, comment) ) diff --git a/StreetDrop/StreetDrop/Application/SceneDelegate.swift b/StreetDrop/StreetDrop/Application/SceneDelegate.swift index a29923af..1e88a846 100644 --- a/StreetDrop/StreetDrop/Application/SceneDelegate.swift +++ b/StreetDrop/StreetDrop/Application/SceneDelegate.swift @@ -33,6 +33,24 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { guard let url = URLContexts.first?.url else { return } handleDeepLink(isLaunched: false, url: url) } + + func navigateToCommunity(with itemID: Int) { + let sceneDelegate = UIApplication.shared.connectedScenes + .first!.delegate as? SceneDelegate + + if let navigationView = topViewController(base: sceneDelegate?.window!.rootViewController)? + .navigationController as? UINavigationController{ + + let communityViewModel = CommunityViewModel( + communityInfos: [], + index: 0 + ) + communityViewModel.itemID = itemID + + let communityView = CommunityViewController(viewModel: communityViewModel) + navigationView.pushViewController(communityView, animated: true) + } + } } // MARK: - Private Methods @@ -89,24 +107,6 @@ private extension SceneDelegate { } } - func navigateToCommunity(with itemID: Int) { - let sceneDelegate = UIApplication.shared.connectedScenes - .first!.delegate as? SceneDelegate - - if let navigationView = topViewController(base: sceneDelegate?.window!.rootViewController)? - .navigationController as? UINavigationController{ - - let communityViewModel = CommunityViewModel( - communityInfos: [], - index: 0 - ) - communityViewModel.itemID = itemID - - let communityView = CommunityViewController(viewModel: communityViewModel) - navigationView.pushViewController(communityView, animated: true) - } - } - func topViewController(base: UIViewController?) -> UIViewController? { if let nav = base as? UINavigationController { return topViewController(base: nav.visibleViewController) diff --git a/StreetDrop/StreetDrop/Presentation/MainScene/View/MainViewController.swift b/StreetDrop/StreetDrop/Presentation/MainScene/View/MainViewController.swift index 516677f7..30323bea 100644 --- a/StreetDrop/StreetDrop/Presentation/MainScene/View/MainViewController.swift +++ b/StreetDrop/StreetDrop/Presentation/MainScene/View/MainViewController.swift @@ -41,6 +41,14 @@ final class MainViewController: UIViewController, Toastable, Alertable { required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } + + deinit { + NotificationCenter.default.removeObserver( + self, + name: UIApplication.willEnterForegroundNotification, + object: nil + ) + } override func viewDidLoad() { super.viewDidLoad() @@ -64,6 +72,13 @@ final class MainViewController: UIViewController, Toastable, Alertable { override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) viewDidAppearEvent.accept(Void()) + NotificationCenter.default.addObserver( + self, + selector: #selector(configureShareExtensionViewOnAppButton), + name: UIApplication.willEnterForegroundNotification, + object: nil + ) + configureShareExtensionViewOnAppButton() } // MARK: - UI @@ -977,3 +992,22 @@ extension MainViewController: NMFMapViewCameraDelegate { self.locationOverlay.circleRadius = viewModel.userCircleRadius / naverMapView.projection.metersPerPixel() } } + +// MARK: - Share Extension + +private extension MainViewController { + @objc func configureShareExtensionViewOnAppButton() { + guard let sharedDefaults = UserDefaults(suiteName: "group.com.depromeet.StreetDrop") else { + print("Failed to access shared UserDefaults.") + return + } + + guard let shareExtensionDroppedItemID = sharedDefaults.object(forKey: "ShareExtensionDroppedItemID") as? Int, + let scene = view.window?.windowScene, + let sceneDelegate = scene.delegate as? SceneDelegate else { return } + + sceneDelegate.navigateToCommunity(with: shareExtensionDroppedItemID) + sharedDefaults.removeObject(forKey: "ShareExtensionDroppedItemID") + sharedDefaults.synchronize() + } +} From 14e2f1a5a47efe854082ba0628f4913f83f81d8d Mon Sep 17 00:00:00 2001 From: Joseph Cha Date: Mon, 7 Oct 2024 13:37:41 +0900 Subject: [PATCH 37/37] =?UTF-8?q?refactor:=20=EC=BD=94=EB=93=9C=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FailedLoadingMusicView.swift | 6 +----- .../ReSearchingMusicForSharingView.swift | 7 +------ .../ReSearchingMusicTableViewCell.swift | 4 ---- .../View/ShareViewController.swift | 17 +++++++++-------- .../ViewModel/ShareViewModel.swift | 2 -- .../StreetDrop/Application/SceneDelegate.swift | 4 ++-- .../MainScene/View/MainViewController.swift | 1 - 7 files changed, 13 insertions(+), 28 deletions(-) diff --git a/StreetDrop/ShareExtension/View/FailedLoadingMusicView/FailedLoadingMusicView.swift b/StreetDrop/ShareExtension/View/FailedLoadingMusicView/FailedLoadingMusicView.swift index 03c3d70e..d9537dbb 100644 --- a/StreetDrop/ShareExtension/View/FailedLoadingMusicView/FailedLoadingMusicView.swift +++ b/StreetDrop/ShareExtension/View/FailedLoadingMusicView/FailedLoadingMusicView.swift @@ -30,11 +30,7 @@ final class FailedLoadingMusicView: UIView { fatalError("init(coder:) has not been implemented") } - private let warningImageView: UIImageView = { - let imageView: UIImageView = .init(image: .init(named: "warning")) - - return imageView - }() + private let warningImageView: UIImageView = .init(image: .init(named: "warning")) private let guidingLabel: UILabel = { let label: UILabel = .init() diff --git a/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicForSharingView.swift b/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicForSharingView.swift index 9eb47aa6..60381f9a 100644 --- a/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicForSharingView.swift +++ b/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicForSharingView.swift @@ -100,11 +100,7 @@ final class ReSearchingMusicForSharingView: UIView { return textField }() - private lazy var searchCancelView: UIView = { - let view: UIView = .init() - - return view - }() + private let searchCancelView: UIView = .init() private lazy var searchCancelButton: UIButton = { let button: UIButton = .init() @@ -131,7 +127,6 @@ private extension ReSearchingMusicForSharingView { func bindAction() { searchTextField.rx.text.orEmpty .filter { $0.isEmpty } - .map { _ in } .bind(with: self) { owner, _ in owner.settingMusicDataRelay.accept([]) } diff --git a/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicTableViewCell.swift b/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicTableViewCell.swift index 7475d931..5b647c77 100644 --- a/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicTableViewCell.swift +++ b/StreetDrop/ShareExtension/View/ReSearchingMusic/ReSearchingMusicTableViewCell.swift @@ -25,10 +25,6 @@ final class ReSearchingMusicTableViewCell: UITableViewCell { required init?(coder: NSCoder) { fatalError("init(coder:) has not been impl") } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - } override func prepareForReuse() { super.prepareForReuse() diff --git a/StreetDrop/ShareExtension/View/ShareViewController.swift b/StreetDrop/ShareExtension/View/ShareViewController.swift index bc751a90..234e593d 100644 --- a/StreetDrop/ShareExtension/View/ShareViewController.swift +++ b/StreetDrop/ShareExtension/View/ShareViewController.swift @@ -308,16 +308,17 @@ private extension ShareViewController { }.disposed(by: disposeBag) communityGuideButton.rx.tap - .bind { [weak self] in - guard let self = self else { return } - self.endEditing() + .bind(with: self, onNext: { owner, _ in + owner.endEditing() - UIView.animate(withDuration: 0.3) { - let isHidden: Bool = (self.communityGuideDetailView.alpha == 0) - self.communityGuideDetailView.alpha = isHidden ? 1 : 0 - self.communityGuideDetailView.isUserInteractionEnabled = isHidden ? true : false + UIView.animate(withDuration: 0.3) { [weak self] in + guard let self else { return } + let isHidden: Bool = (communityGuideDetailView.alpha == 0) + communityGuideDetailView.alpha = isHidden ? 1 : 0 + communityGuideDetailView.isUserInteractionEnabled = isHidden ? true : false } - }.disposed(by: disposeBag) + }) + .disposed(by: disposeBag) communityGuideDetailView.shareExtensionCompletionEvent .bind(with: self) { owner, url in diff --git a/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift b/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift index 617ef5ce..70d10cbe 100644 --- a/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift +++ b/StreetDrop/ShareExtension/ViewModel/ShareViewModel.swift @@ -96,8 +96,6 @@ final class ShareViewModel: NSObject, ShareViewModelType { } owner.output.showSearchedMusicRelay.accept(firstMusic) owner.selectedMusic = firstMusic - } onFailure: { owner, error in - } .disposed(by: disposedBag) } diff --git a/StreetDrop/StreetDrop/Application/SceneDelegate.swift b/StreetDrop/StreetDrop/Application/SceneDelegate.swift index 1e88a846..c924fe64 100644 --- a/StreetDrop/StreetDrop/Application/SceneDelegate.swift +++ b/StreetDrop/StreetDrop/Application/SceneDelegate.swift @@ -36,9 +36,9 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { func navigateToCommunity(with itemID: Int) { let sceneDelegate = UIApplication.shared.connectedScenes - .first!.delegate as? SceneDelegate + .first?.delegate as? SceneDelegate - if let navigationView = topViewController(base: sceneDelegate?.window!.rootViewController)? + if let navigationView = topViewController(base: sceneDelegate?.window?.rootViewController)? .navigationController as? UINavigationController{ let communityViewModel = CommunityViewModel( diff --git a/StreetDrop/StreetDrop/Presentation/MainScene/View/MainViewController.swift b/StreetDrop/StreetDrop/Presentation/MainScene/View/MainViewController.swift index 30323bea..9e7f8373 100644 --- a/StreetDrop/StreetDrop/Presentation/MainScene/View/MainViewController.swift +++ b/StreetDrop/StreetDrop/Presentation/MainScene/View/MainViewController.swift @@ -1008,6 +1008,5 @@ private extension MainViewController { sceneDelegate.navigateToCommunity(with: shareExtensionDroppedItemID) sharedDefaults.removeObject(forKey: "ShareExtensionDroppedItemID") - sharedDefaults.synchronize() } }