From 63c4b11f7a99d7cc479dd6fd54b5281d649b4d73 Mon Sep 17 00:00:00 2001 From: BaeRoNuI Date: Tue, 29 Nov 2022 16:09:35 +0900 Subject: [PATCH 01/17] =?UTF-8?q?fix:=20image=20data=20=EC=A0=84=EC=86=A1?= =?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=9C=20Endpoint=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Segno/Segno/Data/Network/Endpoint.swift | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Segno/Segno/Data/Network/Endpoint.swift b/Segno/Segno/Data/Network/Endpoint.swift index b524300..e390bf2 100644 --- a/Segno/Segno/Data/Network/Endpoint.swift +++ b/Segno/Segno/Data/Network/Endpoint.swift @@ -20,6 +20,7 @@ enum HTTPMethod: String { enum HTTPRequestParameter { case queries(Queries) case body(Body) + case data(Data) } // MARK: Endpoint 본체 @@ -35,7 +36,12 @@ protocol Endpoint { extension Endpoint { var headers: Headers { - return ["Content-Type": "application/json"] + switch self.parameters { + case .data(_): + return ["Content-Type": "multipart/form-data; boundary=SEGNO"] + default: + return ["Content-Type": "application/json"] + } } func toURLRequest() throws -> URLRequest { From 9b4104a78774713b58ae82bbaabca9fa34230c2e Mon Sep 17 00:00:00 2001 From: BaeRoNuI Date: Tue, 29 Nov 2022 16:10:53 +0900 Subject: [PATCH 02/17] =?UTF-8?q?feat:=20Diary=20=EC=A0=84=EC=86=A1?= =?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=9C=20Endpoint=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Network/Endpoints/DiaryPostEndpoint.swift | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 Segno/Segno/Data/Network/Endpoints/DiaryPostEndpoint.swift diff --git a/Segno/Segno/Data/Network/Endpoints/DiaryPostEndpoint.swift b/Segno/Segno/Data/Network/Endpoints/DiaryPostEndpoint.swift new file mode 100644 index 0000000..ed4bd91 --- /dev/null +++ b/Segno/Segno/Data/Network/Endpoints/DiaryPostEndpoint.swift @@ -0,0 +1,31 @@ +// +// DiaryPostEndpoint.swift +// Segno +// +// Created by TaehoYoo on 2022/11/27. +// + +import Foundation + +enum DiaryPostEndpoint: Endpoint { + case item(DiaryDetail) + + var baseURL: URL? { + return URL(string: BaseURL.urlString) + } + + var httpMethod: HTTPMethod { + return .GET + } + + var path: String { + return "diary" + } + + var parameters: HTTPRequestParameter? { + switch self { + case .item(let diary): + return HTTPRequestParameter.body(diary) + } + } +} From fbf4dec06c9a2112709eb8050e6ba534792fbaec Mon Sep 17 00:00:00 2001 From: BaeRoNuI Date: Tue, 29 Nov 2022 16:11:45 +0900 Subject: [PATCH 03/17] =?UTF-8?q?feat:=20Image=20=EC=A0=84=EC=86=A1?= =?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=9C=20Endpoint=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Network/Endpoints/ImageEndpoint.swift | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 Segno/Segno/Data/Network/Endpoints/ImageEndpoint.swift diff --git a/Segno/Segno/Data/Network/Endpoints/ImageEndpoint.swift b/Segno/Segno/Data/Network/Endpoints/ImageEndpoint.swift new file mode 100644 index 0000000..25ecd06 --- /dev/null +++ b/Segno/Segno/Data/Network/Endpoints/ImageEndpoint.swift @@ -0,0 +1,31 @@ +// +// ImageEndpoint.swift +// Segno +// +// Created by TaehoYoo on 2022/11/27. +// + +import Foundation + +enum ImageEndpoint: Endpoint { + case item(Data) + + var baseURL: URL? { + return URL(string: BaseURL.urlString) + } + + var httpMethod: HTTPMethod { + return .POST + } + + var path: String { + return "image" + } + + var parameters: HTTPRequestParameter? { + switch self { + case .item(let image): + return HTTPRequestParameter.data(image) + } + } +} From ffbc91ab3b595fce5ba0248974c6f1b6346378d6 Mon Sep 17 00:00:00 2001 From: BaeRoNuI Date: Tue, 29 Nov 2022 16:13:04 +0900 Subject: [PATCH 04/17] =?UTF-8?q?fix:=20form-data=20=EC=A0=84=EC=86=A1?= =?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=9C=20NetworkManager=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Segno/Segno/Data/Network/NetworkManager.swift | 43 ++++++++++++++++--- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/Segno/Segno/Data/Network/NetworkManager.swift b/Segno/Segno/Data/Network/NetworkManager.swift index 7b758fe..d5ff632 100644 --- a/Segno/Segno/Data/Network/NetworkManager.swift +++ b/Segno/Segno/Data/Network/NetworkManager.swift @@ -23,13 +23,17 @@ struct NetworkManager { return Disposables.create() } } - - return call(request) + switch endpoint.parameters { + case .data(let data): + return call(request, type: .uploadTask, data: buildDataBody(data)) + default: + return call(request) + } } - private func call(_ request: URLRequest) -> Single { - return Single.create { observer -> Disposable in - let task = URLSession.shared.dataTask(with: request) { data, response, error in + private func call(_ request: URLRequest, type: SessionType = .dataTask, data: Data? = nil) -> Single { + Single.create { observer -> Disposable in + let completeHandler: (Data?, URLResponse?, Error?) -> Void = { data, response, error in if error != nil { observer(.failure(NetworkError.unknownNetworkError)) return @@ -53,8 +57,37 @@ struct NetworkManager { } } + let task = { + switch type { + case .dataTask: + return URLSession.shared.dataTask(with: request, completionHandler: completeHandler) + case .uploadTask: + return URLSession.shared.uploadTask(with: request, from: data, completionHandler: completeHandler) + } + }() + task.resume() return Disposables.create() } } + + func buildDataBody(_ data: Data) -> Data? { + let boundary = "SEGNO" + let headerLines = [ + "--\(boundary)", + "Content-Disposition: form-data; name=\"image\"; filename=\"testImage\"", + "Content-Type: image/png", + "\r\n" + ] + var body = headerLines.joined(separator: "\r\n").data(using: .utf8)! + body.append(contentsOf: data) + body.append(contentsOf: "\r\n--\(boundary)--".data(using: .utf8)!) + + return body + } + + enum SessionType { + case dataTask + case uploadTask + } } From ecd75d5a6b36c4274b9573061f936e3c82751dfe Mon Sep 17 00:00:00 2001 From: BaeRoNuI Date: Tue, 29 Nov 2022 16:14:11 +0900 Subject: [PATCH 05/17] =?UTF-8?q?feat:=20image=20=EC=A0=84=EC=86=A1=20resp?= =?UTF-8?q?onse=EB=A5=BC=20=EB=B0=9B=EA=B8=B0=20=EC=9C=84=ED=95=9C=20DTO?= =?UTF-8?q?=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Segno/Segno/Data/Repository/DTO/ImageDTO.swift | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 Segno/Segno/Data/Repository/DTO/ImageDTO.swift diff --git a/Segno/Segno/Data/Repository/DTO/ImageDTO.swift b/Segno/Segno/Data/Repository/DTO/ImageDTO.swift new file mode 100644 index 0000000..5b0f2b5 --- /dev/null +++ b/Segno/Segno/Data/Repository/DTO/ImageDTO.swift @@ -0,0 +1,10 @@ +// +// ImageDTO.swift +// Segno +// +// Created by TaehoYoo on 2022/11/27. +// + +struct ImageDTO: Decodable { + let filename: String? +} From 223ecd4312d29b14b82dc32ddc348dacff4d514e Mon Sep 17 00:00:00 2001 From: BaeRoNuI Date: Tue, 29 Nov 2022 16:17:04 +0900 Subject: [PATCH 06/17] =?UTF-8?q?feat:=20Diary=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EB=A9=94=EC=86=8C=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Data/Repository/DiaryRepository.swift | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/Segno/Segno/Data/Repository/DiaryRepository.swift b/Segno/Segno/Data/Repository/DiaryRepository.swift index e6f6de6..5e5e97f 100644 --- a/Segno/Segno/Data/Repository/DiaryRepository.swift +++ b/Segno/Segno/Data/Repository/DiaryRepository.swift @@ -12,6 +12,7 @@ import RxSwift protocol DiaryRepository { func getDiaryListItem() -> Single func getDiary(id: String) -> Single + func postDiary(_ diary: DiaryDetail, image: Data) -> Single } final class DiaryRepositoryImpl: DiaryRepository { @@ -47,4 +48,35 @@ final class DiaryRepositoryImpl: DiaryRepository { // return Disposables.create() // } } + + func postDiary(_ diary: DiaryDetail, image: Data) -> Single { + // Dummy endpoint + + let imageEndpoint = ImageEndpoint.item(image) + + let single = NetworkManager.shared.call(imageEndpoint) + .compactMap { + // image 전송 후 이름 받아오기 + let imageDTO = try JSONDecoder().decode(ImageDTO.self, from: $0) + return imageDTO.filename + }.map { imagePath in + // diary에 imagePath넣어 전달 + return DiaryDetail(diary, imagePath: imagePath) + }.flatMap { diaryDetail in + // diary를 다시 서버에 전달 + // TODO: - token 넣어야됩니당 + let testDiaryDetail = DiaryDetail(diaryDetail, token: "0KjV78s0YPKbrlVP3QeAwUJcjohs2h2ysdWDLWg") + + let diaryDetailEndpoint = DiaryPostEndpoint.item(testDiaryDetail) + + return NetworkManager.shared.call(diaryDetailEndpoint) + .map { try JSONDecoder().decode(DiaryDetailDTO.self, from: $0) } + .asObservable() + .asMaybe() + } + .asObservable() + .asSingle() + + return single + } } From df89255b76241a7a9e6d04e47786912f3a7a95bc Mon Sep 17 00:00:00 2001 From: BaeRoNuI Date: Tue, 29 Nov 2022 16:18:25 +0900 Subject: [PATCH 07/17] =?UTF-8?q?feat:=20Diary=20=EC=83=9D=EC=84=B1/?= =?UTF-8?q?=EC=88=98=EC=A0=95=EC=9D=84=20=EC=9C=84=ED=95=9C=20DiaryEditUse?= =?UTF-8?q?Case=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Domain/UseCase/DiaryEditUseCase.swift | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 Segno/Segno/Domain/UseCase/DiaryEditUseCase.swift diff --git a/Segno/Segno/Domain/UseCase/DiaryEditUseCase.swift b/Segno/Segno/Domain/UseCase/DiaryEditUseCase.swift new file mode 100644 index 0000000..5fe04ad --- /dev/null +++ b/Segno/Segno/Domain/UseCase/DiaryEditUseCase.swift @@ -0,0 +1,37 @@ +// +// DiaryEditUseCase.swift +// Segno +// +// Created by TaehoYoo on 2022/11/27. +// +import Foundation + +import RxSwift + +protocol DiaryEditUseCase { + func postDiary(_ diary: DiaryDetail, image: Data) -> Single +} + +final class DiaryEditUseCaseImpl: DiaryEditUseCase { + let repository: DiaryRepository + private let disposeBag = DisposeBag() + + init(repository: DiaryRepository = DiaryRepositoryImpl()) { + self.repository = repository + } + + func postDiary(_ diary: DiaryDetail, image: Data) -> Single { + repository.postDiary(diary, image: image).map { dto in + DiaryDetail( + identifier: dto.id, + title: dto.title, + tags: dto.tags, + imagePath: dto.imagePath, + bodyText: dto.bodyText, + // TODO: MusicInfo, location 업데이트 + musicInfo: nil, + location: nil + ) + } + } +} From 83fb2f647c961a93f24b6ad8c6ac2268bd1b81c6 Mon Sep 17 00:00:00 2001 From: BaeRoNuI Date: Tue, 29 Nov 2022 16:19:36 +0900 Subject: [PATCH 08/17] =?UTF-8?q?fix:=20DiaryDetail=EC=9D=84=20Encodable?= =?UTF-8?q?=20=EC=A4=80=EC=88=98=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Segno/Segno/Entity/DiaryDetail.swift | 47 +++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/Segno/Segno/Entity/DiaryDetail.swift b/Segno/Segno/Entity/DiaryDetail.swift index 89ecbc2..0d1afe3 100644 --- a/Segno/Segno/Entity/DiaryDetail.swift +++ b/Segno/Segno/Entity/DiaryDetail.swift @@ -5,15 +5,52 @@ // Created by Gordon Choi on 2022/11/10. // -// TODO: 코어 로케이션에서 좌표만 뽑아와서 저장하기 -import CoreLocation - -struct DiaryDetail { +struct DiaryDetail: Encodable { let identifier: String let title: String let tags: [String] let imagePath: String let bodyText: String? let musicInfo: MusicInfo? - let location: CLLocation? + let location: Location? + + var token: String? + + init(identifier: String, title: String, tags: [String], imagePath: String, bodyText: String?, musicInfo: MusicInfo?, location: Location?, token: String? = nil) { + self.identifier = identifier + self.title = title + self.tags = tags + self.imagePath = imagePath + self.bodyText = bodyText + self.musicInfo = musicInfo + self.location = location + self.token = token + } + + init(_ diary: DiaryDetail, imagePath: String) { + self.init( + identifier: diary.identifier, + title: diary.title, + tags: diary.tags, + imagePath: imagePath, + bodyText: diary.bodyText, + musicInfo: diary.musicInfo, + location: diary.location, + token: diary.token + ) + } + + // DUMMY + init(_ diary: DiaryDetail, token: String) { + self.init( + identifier: diary.identifier, + title: diary.title, + tags: diary.tags, + imagePath: diary.imagePath, + bodyText: diary.bodyText, + musicInfo: diary.musicInfo, + location: diary.location, + token: token + ) + } } From 309d1a661ce15c55c78c8dbb0c369f7fc6427def Mon Sep 17 00:00:00 2001 From: BaeRoNuI Date: Tue, 29 Nov 2022 16:20:00 +0900 Subject: [PATCH 09/17] =?UTF-8?q?fix:=20Location=EC=9D=84=20Encodable=20?= =?UTF-8?q?=EC=A4=80=EC=88=98=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Segno/Segno/Entity/Location.swift | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Segno/Segno/Entity/Location.swift b/Segno/Segno/Entity/Location.swift index 4a748ab..54c695f 100644 --- a/Segno/Segno/Entity/Location.swift +++ b/Segno/Segno/Entity/Location.swift @@ -6,8 +6,14 @@ // import Foundation +import CoreLocation -struct Location { +struct Location: Encodable { let latitude: Double let longitude: Double + + // TODO: 이 방법이 옳은지 논의를 해봐야합니다. + func createCLLocation() -> CLLocation { + CLLocation(latitude: self.latitude, longitude: self.longitude) + } } From 1cd3f1d4d73492c58432dcab5ecc7f3f9c2786f0 Mon Sep 17 00:00:00 2001 From: BaeRoNuI Date: Tue, 29 Nov 2022 16:20:20 +0900 Subject: [PATCH 10/17] =?UTF-8?q?fix:=20MusicInfo=20Encodable=20=EC=A4=80?= =?UTF-8?q?=EC=88=98=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Segno/Segno/Entity/MusicInfo.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Segno/Segno/Entity/MusicInfo.swift b/Segno/Segno/Entity/MusicInfo.swift index cae9297..b1f1d7a 100644 --- a/Segno/Segno/Entity/MusicInfo.swift +++ b/Segno/Segno/Entity/MusicInfo.swift @@ -8,7 +8,7 @@ import Foundation import ShazamKit -struct MusicInfo { +struct MusicInfo: Encodable { let title: String let artist: String let album: String From ff78c6c624b273b4d76461a4b55ce7479034ad03 Mon Sep 17 00:00:00 2001 From: BaeRoNuI Date: Tue, 29 Nov 2022 16:20:57 +0900 Subject: [PATCH 11/17] =?UTF-8?q?fix:=20ViewController=EC=97=90=EC=84=9C?= =?UTF-8?q?=20location=EC=9D=84=20CLLocation=EC=9C=BC=EB=A1=9C=20=ED=98=95?= =?UTF-8?q?=EB=B3=80=ED=99=98=20=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Presentation/ViewController/DiaryDetailViewController.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Segno/Segno/Presentation/ViewController/DiaryDetailViewController.swift b/Segno/Segno/Presentation/ViewController/DiaryDetailViewController.swift index a71d975..bb6a931 100644 --- a/Segno/Segno/Presentation/ViewController/DiaryDetailViewController.swift +++ b/Segno/Segno/Presentation/ViewController/DiaryDetailViewController.swift @@ -218,6 +218,7 @@ final class DiaryDetailViewController: UIViewController { viewModel.locationObservable .compactMap { $0 } + .map { $0.createCLLocation() } .observe(on: MainScheduler.instance) .subscribe(onNext: { [weak self] location in self?.locationContentView.setLocation(location: location) From d60e939a76616d0b30730559b581a3636d50a334 Mon Sep 17 00:00:00 2001 From: BaeRoNuI Date: Tue, 29 Nov 2022 16:21:19 +0900 Subject: [PATCH 12/17] =?UTF-8?q?chore:=20project=20=ED=8C=8C=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Segno/Segno.xcodeproj/project.pbxproj | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Segno/Segno.xcodeproj/project.pbxproj b/Segno/Segno.xcodeproj/project.pbxproj index f92e98f..24c6368 100644 --- a/Segno/Segno.xcodeproj/project.pbxproj +++ b/Segno/Segno.xcodeproj/project.pbxproj @@ -47,6 +47,10 @@ 6692A9EF292F605E00DDA835 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6692A9EE292F605E00DDA835 /* SettingsViewController.swift */; }; 66F0D7EE2925FF8B0074872E /* DiaryCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66F0D7ED2925FF8B0074872E /* DiaryCell.swift */; }; 66F0D7F729260BA20074872E /* GoogleSignIn in Frameworks */ = {isa = PBXBuildFile; productRef = 66F0D7F629260BA20074872E /* GoogleSignIn */; }; + 791529D82932F364005A8DDB /* DiaryEditUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 791529D72932F364005A8DDB /* DiaryEditUseCase.swift */; }; + 791529DC29332CF2005A8DDB /* ImageDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 791529DB29332CF2005A8DDB /* ImageDTO.swift */; }; + 791529DE29333D40005A8DDB /* ImageEndpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 791529DD29333D40005A8DDB /* ImageEndpoint.swift */; }; + 791529E0293344E9005A8DDB /* DiaryPostEndpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 791529DF293344E8005A8DDB /* DiaryPostEndpoint.swift */; }; 791837FA292225C600BC6992 /* Cafe24Shiningstar.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 791837F7292225BF00BC6992 /* Cafe24Shiningstar.ttf */; }; 791837FB292225C800BC6992 /* Cafe24Ssurround.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 791837F9292225BF00BC6992 /* Cafe24Ssurround.ttf */; }; 791837FC292225CB00BC6992 /* Cafe24SsurroundAir.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 791837F8292225BF00BC6992 /* Cafe24SsurroundAir.ttf */; }; @@ -111,6 +115,10 @@ 6692A9EE292F605E00DDA835 /* SettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = ""; }; 66F0D7ED2925FF8B0074872E /* DiaryCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DiaryCell.swift; sourceTree = ""; }; 66F0D7EF292605AE0074872E /* Segno.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Segno.entitlements; sourceTree = ""; }; + 791529D72932F364005A8DDB /* DiaryEditUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiaryEditUseCase.swift; sourceTree = ""; }; + 791529DB29332CF2005A8DDB /* ImageDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageDTO.swift; sourceTree = ""; }; + 791529DD29333D40005A8DDB /* ImageEndpoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageEndpoint.swift; sourceTree = ""; }; + 791529DF293344E8005A8DDB /* DiaryPostEndpoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiaryPostEndpoint.swift; sourceTree = ""; }; 791837F7292225BF00BC6992 /* Cafe24Shiningstar.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = Cafe24Shiningstar.ttf; sourceTree = ""; }; 791837F8292225BF00BC6992 /* Cafe24SsurroundAir.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = Cafe24SsurroundAir.ttf; sourceTree = ""; }; 791837F9292225BF00BC6992 /* Cafe24Ssurround.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = Cafe24Ssurround.ttf; sourceTree = ""; }; @@ -266,6 +274,7 @@ 9841D6162925FACC00318EA9 /* LoginUseCase.swift */, 7940FB32292E065F00276EFC /* DiaryDetailUseCase.swift */, 988414DA2923606B007C9132 /* DiaryListUseCase.swift */, + 791529D72932F364005A8DDB /* DiaryEditUseCase.swift */, ); path = UseCase; sourceTree = ""; @@ -356,6 +365,7 @@ 4F4E0D73292521D0005ABA8F /* UserInfoDTO.swift */, 7940FB2E292E063100276EFC /* DiaryDetailDTO.swift */, 4F4E0D7A29252526005ABA8F /* TokenDTO.swift */, + 791529DB29332CF2005A8DDB /* ImageDTO.swift */, ); path = DTO; sourceTree = ""; @@ -365,7 +375,9 @@ children = ( 4FA3242A2923646F00DB04D5 /* DiaryListItemEndpoint.swift */, 7940FB30292E065100276EFC /* DiaryDetailEndpoint.swift */, + 791529DF293344E8005A8DDB /* DiaryPostEndpoint.swift */, 4F4E0D7529252236005ABA8F /* LoginEndpoint.swift */, + 791529DD29333D40005A8DDB /* ImageEndpoint.swift */, ); path = Endpoints; sourceTree = ""; @@ -485,6 +497,7 @@ buildActionMask = 2147483647; files = ( 98F5AD2A292DDDEB00E53E25 /* LocationContentView.swift in Sources */, + 791529DE29333D40005A8DDB /* ImageEndpoint.swift in Sources */, 4F4E0D3E2924B925005ABA8F /* LoginRepository.swift in Sources */, 4F9A00212922338E007D9057 /* AppDelegate.swift in Sources */, 66F0D7EE2925FF8B0074872E /* DiaryCell.swift in Sources */, @@ -514,6 +527,7 @@ 666E6F8A291CF82700CECD4B /* TabBarPageCase.swift in Sources */, 79183800292225DC00BC6992 /* UIFont+.swift in Sources */, 666E6F83291CF4A600CECD4B /* TabBarCoordinator.swift in Sources */, + 791529E0293344E9005A8DDB /* DiaryPostEndpoint.swift in Sources */, 4F9A001D29222B1B007D9057 /* Endpoint.swift in Sources */, 4F9A001F29222C97007D9057 /* NetworkError.swift in Sources */, 98FDF8A1292F56580083FA05 /* Location.swift in Sources */, @@ -526,11 +540,13 @@ 4FA3242B2923646F00DB04D5 /* DiaryListItemEndpoint.swift in Sources */, 791837FF292225DC00BC6992 /* UIColor+.swift in Sources */, 666E6F7F291CF46800CECD4B /* AppCoordinator.swift in Sources */, + 791529DC29332CF2005A8DDB /* ImageDTO.swift in Sources */, 9841D61B2926131200318EA9 /* LoginViewModel.swift in Sources */, 988414D72923304F007C9132 /* KeychainError.swift in Sources */, 98B5263E292CA46C00446413 /* TagView.swift in Sources */, 7940FB2F292E063100276EFC /* DiaryDetailDTO.swift in Sources */, 4F4E0D7629252236005ABA8F /* LoginEndpoint.swift in Sources */, + 791529D82932F364005A8DDB /* DiaryEditUseCase.swift in Sources */, 4FA324262923600C00DB04D5 /* DiaryListDTO.swift in Sources */, 666E6F87291CF4B400CECD4B /* DiaryCoordinator.swift in Sources */, 4F31777F291BE4710019BDFC /* SceneDelegate.swift in Sources */, From 36f068a4d829793365898602e9cdcd1361126fdb Mon Sep 17 00:00:00 2001 From: LEEYOONJONG Date: Wed, 30 Nov 2022 16:33:29 +0900 Subject: [PATCH 13/17] =?UTF-8?q?#123=20#124=20feat:=20UseCase=EB=A5=BC=20?= =?UTF-8?q?=ED=86=B5=ED=95=B4=20=EC=84=A4=EC=A0=95=20=EB=82=B4=EC=97=AD?= =?UTF-8?q?=EC=9D=84=20=EA=B0=80=EC=A0=B8=EC=98=A4=EA=B3=A0=20=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Segno/Segno.xcodeproj/project.pbxproj | 4 +++ .../SettingsViewController.swift | 1 + .../ViewModel/SettingsViewModel.swift | 30 +++++++------------ 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/Segno/Segno.xcodeproj/project.pbxproj b/Segno/Segno.xcodeproj/project.pbxproj index ab0ca6c..4ae2a37 100644 --- a/Segno/Segno.xcodeproj/project.pbxproj +++ b/Segno/Segno.xcodeproj/project.pbxproj @@ -70,6 +70,7 @@ 988414D72923304F007C9132 /* KeychainError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 988414D62923304F007C9132 /* KeychainError.swift */; }; 988414D929235345007C9132 /* DiaryCollectionViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 988414D829235345007C9132 /* DiaryCollectionViewModel.swift */; }; 988414DB2923606B007C9132 /* DiaryListUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 988414DA2923606B007C9132 /* DiaryListUseCase.swift */; }; + 9894EAF529373385005F2B15 /* SettingsUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9894EAF429373385005F2B15 /* SettingsUseCase.swift */; }; 98B5263E292CA46C00446413 /* TagView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98B5263D292CA46C00446413 /* TagView.swift */; }; 98B52640292CB92900446413 /* MusicContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98B5263F292CB92900446413 /* MusicContentView.swift */; }; 98BEE36E2934907700B20143 /* LoginError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BEE36D2934907700B20143 /* LoginError.swift */; }; @@ -141,6 +142,7 @@ 988414D62923304F007C9132 /* KeychainError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainError.swift; sourceTree = ""; }; 988414D829235345007C9132 /* DiaryCollectionViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiaryCollectionViewModel.swift; sourceTree = ""; }; 988414DA2923606B007C9132 /* DiaryListUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiaryListUseCase.swift; sourceTree = ""; }; + 9894EAF429373385005F2B15 /* SettingsUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsUseCase.swift; sourceTree = ""; }; 98B5263D292CA46C00446413 /* TagView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagView.swift; sourceTree = ""; }; 98B5263F292CB92900446413 /* MusicContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MusicContentView.swift; sourceTree = ""; }; 98BEE36D2934907700B20143 /* LoginError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginError.swift; sourceTree = ""; }; @@ -281,6 +283,7 @@ 9841D6162925FACC00318EA9 /* LoginUseCase.swift */, 7940FB32292E065F00276EFC /* DiaryDetailUseCase.swift */, 988414DA2923606B007C9132 /* DiaryListUseCase.swift */, + 9894EAF429373385005F2B15 /* SettingsUseCase.swift */, ); path = UseCase; sourceTree = ""; @@ -513,6 +516,7 @@ 4F9A00202922337F007D9057 /* LoginViewController.swift in Sources */, 982A2A472924AE74006F6ACD /* UserDefaultsKey.swift in Sources */, 4F9A001B292227D7007D9057 /* NetworkManager.swift in Sources */, + 9894EAF529373385005F2B15 /* SettingsUseCase.swift in Sources */, 9841D6172925FACC00318EA9 /* LoginUseCase.swift in Sources */, 4FEBFAAD291CF62E00E78139 /* DiaryDetail.swift in Sources */, 4FEBFAB1291CFB5500E78139 /* SHMediaItem+.swift in Sources */, diff --git a/Segno/Segno/Presentation/ViewController/SettingsViewController.swift b/Segno/Segno/Presentation/ViewController/SettingsViewController.swift index e90686e..45600a9 100644 --- a/Segno/Segno/Presentation/ViewController/SettingsViewController.swift +++ b/Segno/Segno/Presentation/ViewController/SettingsViewController.swift @@ -104,6 +104,7 @@ final class SettingsViewController: UIViewController { return cell case .settingsActionSheet(let title): guard let cell = tableView.dequeueReusableCell(withIdentifier: "SettingsActionSheetCell") as? SettingsActionSheetCell else { return UITableViewCell() } + cell.configure(left: title) return cell } diff --git a/Segno/Segno/Presentation/ViewModel/SettingsViewModel.swift b/Segno/Segno/Presentation/ViewModel/SettingsViewModel.swift index 037f506..8aba625 100644 --- a/Segno/Segno/Presentation/ViewModel/SettingsViewModel.swift +++ b/Segno/Segno/Presentation/ViewModel/SettingsViewModel.swift @@ -16,43 +16,33 @@ final class SettingsViewModel { .settingsActionSheet(title: "다크 모드") ]) - init() { - + private let useCase: SettingsUseCase + + init(useCase: SettingsUseCase = SettingsUseCaseImpl()) { + self.useCase = useCase } - // TODO: 닉네임 변경 로직 func changeNickname(to nickname: String) -> Observable { -// return useCase.requestChangeNickname(to: nickname) - - // 임시 처리입니다. return Observable.create { emitter in - emitter.onNext(true) + let result = self.useCase.requestChangeNickname(to: nickname) + emitter.onNext(result) return Disposables.create() } } - // TODO: 음악 자동 재생 여부 불러오기 / 클릭 시 반영하기 func getAutoPlayMode() -> Bool { - // return useCase.getAutoPlayMode() - - return true + return useCase.getAutoPlayMode() } func changeAutoPlayMode(to mode: Bool) { -// useCase.changeAutoPlayMode(to: mode) - - debugPrint("changeAutoPlayMode에서 \(mode)로 변경합니다") + useCase.changeAutoPlayMode(to: mode) } - // TODO: 다크모드 설정 불러오기 / 액션 시트 선택 시 반영하기 func getDarkMode() -> Int { - // return useCase.getDarkMode() - - return 0 + return useCase.getDarkMode() } func changeDarkMode(to mode: Int) { - // TODO: 액션 시트를 띄워야 합니다. - debugPrint("changeDarkMode에서 \(mode)로 변경합니다") + useCase.changeDarkMode(to: mode) } } From 6d2002f18df8ad6fe4fe31bc272625e360ce0499 Mon Sep 17 00:00:00 2001 From: LEEYOONJONG Date: Wed, 30 Nov 2022 16:35:24 +0900 Subject: [PATCH 14/17] =?UTF-8?q?#125=20#126=20feat:=20LocalUtilityReposit?= =?UTF-8?q?ory=EB=A1=9C=EB=B6=80=ED=84=B0=20=EC=84=A4=EC=A0=95=EB=82=B4?= =?UTF-8?q?=EC=97=AD=EC=9D=84=20=EA=B0=80=EC=A0=B8=EC=98=A4=EA=B3=A0=20?= =?UTF-8?q?=EB=B0=98=EC=98=81=ED=95=98=EB=8A=94=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Domain/UseCase/SettingsUseCase.swift | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 Segno/Segno/Domain/UseCase/SettingsUseCase.swift diff --git a/Segno/Segno/Domain/UseCase/SettingsUseCase.swift b/Segno/Segno/Domain/UseCase/SettingsUseCase.swift new file mode 100644 index 0000000..76ee1a6 --- /dev/null +++ b/Segno/Segno/Domain/UseCase/SettingsUseCase.swift @@ -0,0 +1,63 @@ +// +// SettingsUseCase.swift +// Segno +// +// Created by YOONJONG on 2022/11/30. +// + +import RxSwift + +protocol SettingsUseCase { + func requestChangeNickname(to nickname: String) -> Bool + func getAutoPlayMode() -> Bool + func changeAutoPlayMode(to mode: Bool) + func getDarkMode() -> Int + func changeDarkMode(to mode: Int) +} + +final class SettingsUseCaseImpl: SettingsUseCase { + let repository: LocalUtilityRepository + private let disposeBag = DisposeBag() + + init(repository: LocalUtilityRepository = LocalUtilityRepositoryImpl()) { + self.repository = repository + } + + func requestChangeNickname(to nickname: String) -> Bool { + // 임시 처리입니다. + debugPrint("SettingsUseCase - requestChangeNickname : \(nickname)으로 변경") + return true + } + + func getAutoPlayMode() -> Bool { + if let isEnabled = repository.getUserDefaultsObject(forKey: .isAutoPlayEnabled) as? Bool { + debugPrint("SettingsUseCase - getAutoPlayMode : 키가 있습니다 - \(isEnabled)") + return isEnabled + } else { + repository.setUserDefaults(true, forKey: .isAutoPlayEnabled) + debugPrint("SettingsUseCase - getAutoPlayMode : 키가 없어 true 로 설정합니다.") + return true + } + } + + func changeAutoPlayMode(to mode: Bool) { + repository.setUserDefaults(mode, forKey: .isAutoPlayEnabled) + debugPrint("SettingsUseCase - changeAutoPlayMode : \(mode)로 설정") + } + + func getDarkMode() -> Int { + if let mode = repository.getUserDefaultsObject(forKey: .darkmode) as? Int { + debugPrint("SettingsUseCase - getDarkMode : 키가 있습니다 - \(mode)") + return mode + } else { + repository.setUserDefaults(0, forKey: .isAutoPlayEnabled) + debugPrint("SettingsUseCase - getDarkMode : 키가 없어 0 로 설정합니다.") + return 0 + } + } + + func changeDarkMode(to mode: Int) { + repository.setUserDefaults(mode, forKey: .isAutoPlayEnabled) + debugPrint("SettingsUseCase - changeDarkMode : \(mode)로 설정") + } +} From 7cbf0699ddf61a12f266e91b2ffaa7bced32d50c Mon Sep 17 00:00:00 2001 From: LEEYOONJONG Date: Wed, 30 Nov 2022 16:38:18 +0900 Subject: [PATCH 15/17] =?UTF-8?q?#123=20feat:=20dataSource=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=EA=B0=92=EC=9D=84=20UseCase=EB=A5=BC=20=ED=86=B5?= =?UTF-8?q?=ED=95=B4=20=EA=B0=80=EC=A0=B8=EC=98=A4=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Segno/Segno/Presentation/ViewModel/SettingsViewModel.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Segno/Segno/Presentation/ViewModel/SettingsViewModel.swift b/Segno/Segno/Presentation/ViewModel/SettingsViewModel.swift index 8aba625..1b07460 100644 --- a/Segno/Segno/Presentation/ViewModel/SettingsViewModel.swift +++ b/Segno/Segno/Presentation/ViewModel/SettingsViewModel.swift @@ -10,9 +10,9 @@ import Foundation import RxSwift final class SettingsViewModel { - let dataSource = Observable<[SettingsCellModel]>.just([ + lazy var dataSource = Observable<[SettingsCellModel]>.just([ .nickname, - .settingsSwitch(title: "음악 자동 재생", isOn: true), // TODO: isOn은 로컬 디비로부터 불러와야 합니다. + .settingsSwitch(title: "음악 자동 재생", isOn: useCase.getAutoPlayMode()), // TODO: isOn은 로컬 디비로부터 불러와야 합니다. .settingsActionSheet(title: "다크 모드") ]) From af236d81c34ebaf7e660c0051dbfa635cfb01e12 Mon Sep 17 00:00:00 2001 From: LEEYOONJONG Date: Wed, 30 Nov 2022 20:34:25 +0900 Subject: [PATCH 16/17] =?UTF-8?q?#112=20#=20124=20#125=20feat:=20DarkMode?= =?UTF-8?q?=20=EC=97=B4=EA=B1=B0=ED=98=95=EC=9D=84=20=EC=9D=B4=EC=9A=A9?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=8B=A4=ED=81=AC=EB=AA=A8?= =?UTF-8?q?=EB=93=9C=20=EA=B4=80=EB=A0=A8=20=EB=A1=9C=EC=A7=81=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Segno/Segno.xcodeproj/project.pbxproj | 12 +++++++++ .../Domain/UseCase/SettingsUseCase.swift | 8 +++--- .../Segno/Presentation/Utility/DarkMode.swift | 25 +++++++++++++++++++ .../Presentation/View/SettingsCellModel.swift | 2 +- .../SettingsViewController.swift | 22 +++++++++------- .../ViewModel/SettingsViewModel.swift | 4 +-- 6 files changed, 57 insertions(+), 16 deletions(-) create mode 100644 Segno/Segno/Presentation/Utility/DarkMode.swift diff --git a/Segno/Segno.xcodeproj/project.pbxproj b/Segno/Segno.xcodeproj/project.pbxproj index 4ae2a37..3d1afe1 100644 --- a/Segno/Segno.xcodeproj/project.pbxproj +++ b/Segno/Segno.xcodeproj/project.pbxproj @@ -71,6 +71,7 @@ 988414D929235345007C9132 /* DiaryCollectionViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 988414D829235345007C9132 /* DiaryCollectionViewModel.swift */; }; 988414DB2923606B007C9132 /* DiaryListUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 988414DA2923606B007C9132 /* DiaryListUseCase.swift */; }; 9894EAF529373385005F2B15 /* SettingsUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9894EAF429373385005F2B15 /* SettingsUseCase.swift */; }; + 9894EAF829375281005F2B15 /* DarkMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9894EAF729375281005F2B15 /* DarkMode.swift */; }; 98B5263E292CA46C00446413 /* TagView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98B5263D292CA46C00446413 /* TagView.swift */; }; 98B52640292CB92900446413 /* MusicContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98B5263F292CB92900446413 /* MusicContentView.swift */; }; 98BEE36E2934907700B20143 /* LoginError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98BEE36D2934907700B20143 /* LoginError.swift */; }; @@ -143,6 +144,7 @@ 988414D829235345007C9132 /* DiaryCollectionViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiaryCollectionViewModel.swift; sourceTree = ""; }; 988414DA2923606B007C9132 /* DiaryListUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiaryListUseCase.swift; sourceTree = ""; }; 9894EAF429373385005F2B15 /* SettingsUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsUseCase.swift; sourceTree = ""; }; + 9894EAF729375281005F2B15 /* DarkMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DarkMode.swift; sourceTree = ""; }; 98B5263D292CA46C00446413 /* TagView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagView.swift; sourceTree = ""; }; 98B5263F292CB92900446413 /* MusicContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MusicContentView.swift; sourceTree = ""; }; 98BEE36D2934907700B20143 /* LoginError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginError.swift; sourceTree = ""; }; @@ -227,6 +229,7 @@ 4F317792291BEB5E0019BDFC /* Presentation */ = { isa = PBXGroup; children = ( + 9894EAF629375272005F2B15 /* Utility */, 4F31779C291BEE900019BDFC /* Coordinator */, 4F31779B291BEE890019BDFC /* View */, 4F31779A291BEE810019BDFC /* ViewController */, @@ -421,6 +424,14 @@ path = Font; sourceTree = ""; }; + 9894EAF629375272005F2B15 /* Utility */ = { + isa = PBXGroup; + children = ( + 9894EAF729375281005F2B15 /* DarkMode.swift */, + ); + path = Utility; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -530,6 +541,7 @@ 666E6F81291CF49E00CECD4B /* LoginCoordinator.swift in Sources */, 7940FB31292E065100276EFC /* DiaryDetailEndpoint.swift in Sources */, 666E6F85291CF4AD00CECD4B /* MyPageCoordinator.swift in Sources */, + 9894EAF829375281005F2B15 /* DarkMode.swift in Sources */, 983AE9D22934F041006547BD /* NicknameCell.swift in Sources */, 983AE9D4293513AD006547BD /* SettingsCellModel.swift in Sources */, 4F4E0D79292522B7005ABA8F /* BaseURL.swift in Sources */, diff --git a/Segno/Segno/Domain/UseCase/SettingsUseCase.swift b/Segno/Segno/Domain/UseCase/SettingsUseCase.swift index 76ee1a6..b1a0160 100644 --- a/Segno/Segno/Domain/UseCase/SettingsUseCase.swift +++ b/Segno/Segno/Domain/UseCase/SettingsUseCase.swift @@ -50,14 +50,14 @@ final class SettingsUseCaseImpl: SettingsUseCase { debugPrint("SettingsUseCase - getDarkMode : 키가 있습니다 - \(mode)") return mode } else { - repository.setUserDefaults(0, forKey: .isAutoPlayEnabled) - debugPrint("SettingsUseCase - getDarkMode : 키가 없어 0 로 설정합니다.") - return 0 + repository.setUserDefaults(DarkMode.system.rawValue, forKey: .darkmode) + debugPrint("SettingsUseCase - getDarkMode : 키가 없어 \(DarkMode.system.rawValue) 로 설정합니다.") + return DarkMode.system.rawValue } } func changeDarkMode(to mode: Int) { - repository.setUserDefaults(mode, forKey: .isAutoPlayEnabled) + repository.setUserDefaults(mode, forKey: .darkmode) debugPrint("SettingsUseCase - changeDarkMode : \(mode)로 설정") } } diff --git a/Segno/Segno/Presentation/Utility/DarkMode.swift b/Segno/Segno/Presentation/Utility/DarkMode.swift new file mode 100644 index 0000000..2ad45c9 --- /dev/null +++ b/Segno/Segno/Presentation/Utility/DarkMode.swift @@ -0,0 +1,25 @@ +// +// DarkMode.swift +// Segno +// +// Created by YOONJONG on 2022/11/30. +// + +import Foundation + +enum DarkMode: Int, CaseIterable { + case system + case light + case dark + + var title: String { + switch self { + case .system: + return "시스템 설정" + case .light: + return "항상 밝게" + case .dark: + return "항상 어둡게" + } + } +} diff --git a/Segno/Segno/Presentation/View/SettingsCellModel.swift b/Segno/Segno/Presentation/View/SettingsCellModel.swift index 7403fbc..1da7940 100644 --- a/Segno/Segno/Presentation/View/SettingsCellModel.swift +++ b/Segno/Segno/Presentation/View/SettingsCellModel.swift @@ -8,5 +8,5 @@ enum SettingsCellModel { case nickname case settingsSwitch(title: String, isOn: Bool) - case settingsActionSheet(title: String) + case settingsActionSheet(title: String, mode: Int) } diff --git a/Segno/Segno/Presentation/ViewController/SettingsViewController.swift b/Segno/Segno/Presentation/ViewController/SettingsViewController.swift index 45600a9..3c251b3 100644 --- a/Segno/Segno/Presentation/ViewController/SettingsViewController.swift +++ b/Segno/Segno/Presentation/ViewController/SettingsViewController.swift @@ -102,10 +102,10 @@ final class SettingsViewController: UIViewController { cell.configure(title: title, isOn: isOn, action: action) return cell - case .settingsActionSheet(let title): + case .settingsActionSheet(let title, let mode): guard let cell = tableView.dequeueReusableCell(withIdentifier: "SettingsActionSheetCell") as? SettingsActionSheetCell else { return UITableViewCell() } - - cell.configure(left: title) + let darkModeTitle = DarkMode.allCases[mode].title + cell.configure(left: title, right: darkModeTitle) return cell } } @@ -117,15 +117,19 @@ final class SettingsViewController: UIViewController { guard let action = SettingsCellActions(rawValue: indexPath.row) else { return } switch action { case .darkmode: // 다크 모드 설정 + guard let cell = self?.tableView.cellForRow(at: indexPath) as? SettingsActionSheetCell else { return } let actionSheet = UIAlertController(title: "다크 모드 설정", message: nil, preferredStyle: .actionSheet) - actionSheet.addAction(UIAlertAction(title: "시스템 설정", style: .default, handler: { _ in - self?.viewModel.changeDarkMode(to: 0) + actionSheet.addAction(UIAlertAction(title: DarkMode.system.title, style: .default, handler: { _ in + self?.viewModel.changeDarkMode(to: DarkMode.system.rawValue) + cell.configure(right: DarkMode.system.title) })) - actionSheet.addAction(UIAlertAction(title: "항상 밝게", style: .default, handler: { _ in - self?.viewModel.changeDarkMode(to: 1) + actionSheet.addAction(UIAlertAction(title: DarkMode.light.title, style: .default, handler: { _ in + self?.viewModel.changeDarkMode(to: DarkMode.light.rawValue) + cell.configure(right: DarkMode.light.title) })) - actionSheet.addAction(UIAlertAction(title: "항상 어둡게", style: .default, handler: { _ in - self?.viewModel.changeDarkMode(to: 2) + actionSheet.addAction(UIAlertAction(title: DarkMode.dark.title, style: .default, handler: { _ in + self?.viewModel.changeDarkMode(to: DarkMode.dark.rawValue) + cell.configure(right: DarkMode.dark.title) })) self?.present(actionSheet, animated: true) default: diff --git a/Segno/Segno/Presentation/ViewModel/SettingsViewModel.swift b/Segno/Segno/Presentation/ViewModel/SettingsViewModel.swift index 1b07460..47353cb 100644 --- a/Segno/Segno/Presentation/ViewModel/SettingsViewModel.swift +++ b/Segno/Segno/Presentation/ViewModel/SettingsViewModel.swift @@ -12,8 +12,8 @@ import RxSwift final class SettingsViewModel { lazy var dataSource = Observable<[SettingsCellModel]>.just([ .nickname, - .settingsSwitch(title: "음악 자동 재생", isOn: useCase.getAutoPlayMode()), // TODO: isOn은 로컬 디비로부터 불러와야 합니다. - .settingsActionSheet(title: "다크 모드") + .settingsSwitch(title: "음악 자동 재생", isOn: useCase.getAutoPlayMode()), + .settingsActionSheet(title: "다크 모드", mode: useCase.getDarkMode()) ]) private let useCase: SettingsUseCase From 9908d4b4bcafca5e52bf702e9981268f3992d3a3 Mon Sep 17 00:00:00 2001 From: LEEYOONJONG Date: Wed, 30 Nov 2022 21:01:44 +0900 Subject: [PATCH 17/17] =?UTF-8?q?#127=20#128=20refactor:=20SettingsUseCase?= =?UTF-8?q?=EC=9D=98=20=EB=8B=89=EB=84=A4=EC=9E=84=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=EC=9D=84=20ChangeUserNameUseCase=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Segno/Segno.xcodeproj/project.pbxproj | 8 ++++++ .../Data/Repository/SettingsRepository.swift | 16 +++++++++++ .../UseCase/ChangeUserNameUseCase.swift | 27 +++++++++++++++++++ .../Domain/UseCase/SettingsUseCase.swift | 7 ----- .../SettingsViewController.swift | 3 +-- .../ViewModel/SettingsViewModel.swift | 24 ++++++++++------- 6 files changed, 66 insertions(+), 19 deletions(-) create mode 100644 Segno/Segno/Data/Repository/SettingsRepository.swift create mode 100644 Segno/Segno/Domain/UseCase/ChangeUserNameUseCase.swift diff --git a/Segno/Segno.xcodeproj/project.pbxproj b/Segno/Segno.xcodeproj/project.pbxproj index 3d1afe1..d91f400 100644 --- a/Segno/Segno.xcodeproj/project.pbxproj +++ b/Segno/Segno.xcodeproj/project.pbxproj @@ -57,6 +57,8 @@ 7940FB2F292E063100276EFC /* DiaryDetailDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7940FB2E292E063100276EFC /* DiaryDetailDTO.swift */; }; 7940FB31292E065100276EFC /* DiaryDetailEndpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7940FB30292E065100276EFC /* DiaryDetailEndpoint.swift */; }; 7940FB33292E065F00276EFC /* DiaryDetailUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7940FB32292E065F00276EFC /* DiaryDetailUseCase.swift */; }; + 9825F41B29377875005F2163 /* ChangeUserNameUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9825F41A29377875005F2163 /* ChangeUserNameUseCase.swift */; }; + 9825F41D29377ACF005F2163 /* SettingsRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9825F41C29377ACF005F2163 /* SettingsRepository.swift */; }; 982A2A472924AE74006F6ACD /* UserDefaultsKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 982A2A462924AE74006F6ACD /* UserDefaultsKey.swift */; }; 982A3699292C905300FDC6CF /* DiaryDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 982A3698292C905300FDC6CF /* DiaryDetailViewController.swift */; }; 982B3B7F292E68FB0077A44B /* DiaryDetailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 982B3B7E292E68FB0077A44B /* DiaryDetailViewModel.swift */; }; @@ -130,6 +132,8 @@ 7940FB2E292E063100276EFC /* DiaryDetailDTO.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DiaryDetailDTO.swift; sourceTree = ""; }; 7940FB30292E065100276EFC /* DiaryDetailEndpoint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DiaryDetailEndpoint.swift; sourceTree = ""; }; 7940FB32292E065F00276EFC /* DiaryDetailUseCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DiaryDetailUseCase.swift; sourceTree = ""; }; + 9825F41A29377875005F2163 /* ChangeUserNameUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangeUserNameUseCase.swift; sourceTree = ""; }; + 9825F41C29377ACF005F2163 /* SettingsRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsRepository.swift; sourceTree = ""; }; 982A2A462924AE74006F6ACD /* UserDefaultsKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsKey.swift; sourceTree = ""; }; 982A3698292C905300FDC6CF /* DiaryDetailViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DiaryDetailViewController.swift; sourceTree = ""; }; 982B3B7E292E68FB0077A44B /* DiaryDetailViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DiaryDetailViewModel.swift; sourceTree = ""; }; @@ -287,6 +291,7 @@ 7940FB32292E065F00276EFC /* DiaryDetailUseCase.swift */, 988414DA2923606B007C9132 /* DiaryListUseCase.swift */, 9894EAF429373385005F2B15 /* SettingsUseCase.swift */, + 9825F41A29377875005F2163 /* ChangeUserNameUseCase.swift */, ); path = UseCase; sourceTree = ""; @@ -364,6 +369,7 @@ 4FA32427292363AA00DB04D5 /* DiaryRepository.swift */, 982A2A462924AE74006F6ACD /* UserDefaultsKey.swift */, 4F4E0D3D2924B925005ABA8F /* LoginRepository.swift */, + 9825F41C29377ACF005F2163 /* SettingsRepository.swift */, ); path = Repository; sourceTree = ""; @@ -523,6 +529,7 @@ 4F4E0D3E2924B925005ABA8F /* LoginRepository.swift in Sources */, 4F9A00212922338E007D9057 /* AppDelegate.swift in Sources */, 983AE9D82935CEE2006547BD /* SettingsViewModel.swift in Sources */, + 9825F41D29377ACF005F2163 /* SettingsRepository.swift in Sources */, 66F0D7EE2925FF8B0074872E /* DiaryCell.swift in Sources */, 4F9A00202922337F007D9057 /* LoginViewController.swift in Sources */, 982A2A472924AE74006F6ACD /* UserDefaultsKey.swift in Sources */, @@ -552,6 +559,7 @@ 4FCAC5C2292B5C9000BF9CDD /* LoginSession.swift in Sources */, 666E6F7D291CF45600CECD4B /* Coordinator.swift in Sources */, 982A3699292C905300FDC6CF /* DiaryDetailViewController.swift in Sources */, + 9825F41B29377875005F2163 /* ChangeUserNameUseCase.swift in Sources */, 666E6F8C291CFAC200CECD4B /* DiaryCollectionViewController.swift in Sources */, 666E6F8A291CF82700CECD4B /* TabBarPageCase.swift in Sources */, 79183800292225DC00BC6992 /* UIFont+.swift in Sources */, diff --git a/Segno/Segno/Data/Repository/SettingsRepository.swift b/Segno/Segno/Data/Repository/SettingsRepository.swift new file mode 100644 index 0000000..d432626 --- /dev/null +++ b/Segno/Segno/Data/Repository/SettingsRepository.swift @@ -0,0 +1,16 @@ +// +// SettingsRepository.swift +// Segno +// +// Created by YOONJONG on 2022/11/30. +// + +import RxSwift + +protocol SettingsRepository { + +} + +final class SettingsRepositoryImpl: SettingsRepository { + +} diff --git a/Segno/Segno/Domain/UseCase/ChangeUserNameUseCase.swift b/Segno/Segno/Domain/UseCase/ChangeUserNameUseCase.swift new file mode 100644 index 0000000..296a51e --- /dev/null +++ b/Segno/Segno/Domain/UseCase/ChangeUserNameUseCase.swift @@ -0,0 +1,27 @@ +// +// ChangeUserNameUseCase.swift +// Segno +// +// Created by YOONJONG on 2022/11/30. +// + +import RxSwift + +protocol ChangeUserNameUseCase { + func requestChangeNickname(to nickname: String) -> Bool +} + +final class ChangeUserNameUseCaseImpl: ChangeUserNameUseCase { + let repository: SettingsRepository + private let disposeBag = DisposeBag() + + init(repository: SettingsRepository = SettingsRepositoryImpl()) { + self.repository = repository + } + + func requestChangeNickname(to nickname: String) -> Bool { + // 임시 처리입니다. + debugPrint("SettingsUseCase - requestChangeNickname : \(nickname)으로 변경") + return true + } +} diff --git a/Segno/Segno/Domain/UseCase/SettingsUseCase.swift b/Segno/Segno/Domain/UseCase/SettingsUseCase.swift index b1a0160..11e3f76 100644 --- a/Segno/Segno/Domain/UseCase/SettingsUseCase.swift +++ b/Segno/Segno/Domain/UseCase/SettingsUseCase.swift @@ -8,7 +8,6 @@ import RxSwift protocol SettingsUseCase { - func requestChangeNickname(to nickname: String) -> Bool func getAutoPlayMode() -> Bool func changeAutoPlayMode(to mode: Bool) func getDarkMode() -> Int @@ -23,12 +22,6 @@ final class SettingsUseCaseImpl: SettingsUseCase { self.repository = repository } - func requestChangeNickname(to nickname: String) -> Bool { - // 임시 처리입니다. - debugPrint("SettingsUseCase - requestChangeNickname : \(nickname)으로 변경") - return true - } - func getAutoPlayMode() -> Bool { if let isEnabled = repository.getUserDefaultsObject(forKey: .isAutoPlayEnabled) as? Bool { debugPrint("SettingsUseCase - getAutoPlayMode : 키가 있습니다 - \(isEnabled)") diff --git a/Segno/Segno/Presentation/ViewController/SettingsViewController.swift b/Segno/Segno/Presentation/ViewController/SettingsViewController.swift index 3c251b3..6eb369d 100644 --- a/Segno/Segno/Presentation/ViewController/SettingsViewController.swift +++ b/Segno/Segno/Presentation/ViewController/SettingsViewController.swift @@ -74,11 +74,10 @@ final class SettingsViewController: UIViewController { guard let newNickname = cell.nicknameTextField.text else { return Observable.empty() } - debugPrint("입력된 아이디 : ", newNickname) return self.viewModel.changeNickname(to: newNickname) } .subscribe(onNext: { result in - debugPrint("viewModel 메서드 실행 결과 : ", result) + debugPrint("여기에서 \(result)에 대한 피드백 Alert 띄웁니다.") }) .disposed(by: self.disposeBag) diff --git a/Segno/Segno/Presentation/ViewModel/SettingsViewModel.swift b/Segno/Segno/Presentation/ViewModel/SettingsViewModel.swift index 47353cb..d180bf7 100644 --- a/Segno/Segno/Presentation/ViewModel/SettingsViewModel.swift +++ b/Segno/Segno/Presentation/ViewModel/SettingsViewModel.swift @@ -12,37 +12,41 @@ import RxSwift final class SettingsViewModel { lazy var dataSource = Observable<[SettingsCellModel]>.just([ .nickname, - .settingsSwitch(title: "음악 자동 재생", isOn: useCase.getAutoPlayMode()), - .settingsActionSheet(title: "다크 모드", mode: useCase.getDarkMode()) + .settingsSwitch(title: "음악 자동 재생", isOn: settingsUseCase.getAutoPlayMode()), + .settingsActionSheet(title: "다크 모드", mode: settingsUseCase.getDarkMode()) ]) - private let useCase: SettingsUseCase + private let settingsUseCase: SettingsUseCase + private let changeUserNameUseCase: ChangeUserNameUseCase - init(useCase: SettingsUseCase = SettingsUseCaseImpl()) { - self.useCase = useCase + init(settingsUseCase: SettingsUseCase = SettingsUseCaseImpl(), + changeUserNameUseCase: ChangeUserNameUseCase = ChangeUserNameUseCaseImpl() + ) { + self.settingsUseCase = settingsUseCase + self.changeUserNameUseCase = changeUserNameUseCase } func changeNickname(to nickname: String) -> Observable { return Observable.create { emitter in - let result = self.useCase.requestChangeNickname(to: nickname) + let result = self.changeUserNameUseCase.requestChangeNickname(to: nickname) emitter.onNext(result) return Disposables.create() } } func getAutoPlayMode() -> Bool { - return useCase.getAutoPlayMode() + return settingsUseCase.getAutoPlayMode() } func changeAutoPlayMode(to mode: Bool) { - useCase.changeAutoPlayMode(to: mode) + settingsUseCase.changeAutoPlayMode(to: mode) } func getDarkMode() -> Int { - return useCase.getDarkMode() + return settingsUseCase.getDarkMode() } func changeDarkMode(to mode: Int) { - useCase.changeDarkMode(to: mode) + settingsUseCase.changeDarkMode(to: mode) } }