From 2a1852071012f81ad16bbffb25f46bf95b9a7171 Mon Sep 17 00:00:00 2001 From: realhsb Date: Tue, 14 May 2024 17:50:04 +0900 Subject: [PATCH 01/30] =?UTF-8?q?chore:=20=EB=8F=84=EB=A9=94=EC=9D=B8?= =?UTF-8?q?=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RollTheDice.xcodeproj/project.pbxproj | 30 ++++++++++++------- .../Domain/Foundation/BaseTargetType.swift | 2 +- .../ScoopAPI.swift} | 2 +- .../ScoopAPINews.swift} | 2 +- .../Source/Domain/Service/NewsService.swift | 4 +-- 5 files changed, 24 insertions(+), 16 deletions(-) rename iOS/RollTheDice/RollTheDice/Source/Domain/{RollTheDiceAPI/RollTheDiceAPI.swift => ScoopAPI/ScoopAPI.swift} (87%) rename iOS/RollTheDice/RollTheDice/Source/Domain/{RollTheDiceAPI/RollTheDiceAPINews.swift => ScoopAPI/ScoopAPINews.swift} (82%) diff --git a/iOS/RollTheDice/RollTheDice.xcodeproj/project.pbxproj b/iOS/RollTheDice/RollTheDice.xcodeproj/project.pbxproj index 6c29b5d5..45cb54ca 100644 --- a/iOS/RollTheDice/RollTheDice.xcodeproj/project.pbxproj +++ b/iOS/RollTheDice/RollTheDice.xcodeproj/project.pbxproj @@ -78,8 +78,8 @@ 6CF130BB2BAB74FD00A437B6 /* RxMoya in Frameworks */ = {isa = PBXBuildFile; productRef = 6CF130BA2BAB74FD00A437B6 /* RxMoya */; }; 6CF130BF2BAB783300A437B6 /* APIConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CF130BE2BAB783300A437B6 /* APIConstants.swift */; }; 6CF130C22BAB786600A437B6 /* APIHeaderManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CF130C12BAB786600A437B6 /* APIHeaderManager.swift */; }; - 6CF130C52BAB79DE00A437B6 /* RollTheDiceAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CF130C42BAB79DE00A437B6 /* RollTheDiceAPI.swift */; }; - 6CF130C72BAB7B9800A437B6 /* RollTheDiceAPINews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CF130C62BAB7B9800A437B6 /* RollTheDiceAPINews.swift */; }; + 6CF130C52BAB79DE00A437B6 /* ScoopAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CF130C42BAB79DE00A437B6 /* ScoopAPI.swift */; }; + 6CF130C72BAB7B9800A437B6 /* ScoopAPINews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CF130C62BAB7B9800A437B6 /* ScoopAPINews.swift */; }; 6CF130C92BAB7CC200A437B6 /* BaseTargetType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CF130C82BAB7CC200A437B6 /* BaseTargetType.swift */; }; /* End PBXBuildFile section */ @@ -151,8 +151,8 @@ 6CF130B12BAB74BA00A437B6 /* NewsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsService.swift; sourceTree = ""; }; 6CF130BE2BAB783300A437B6 /* APIConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIConstants.swift; sourceTree = ""; }; 6CF130C12BAB786600A437B6 /* APIHeaderManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIHeaderManager.swift; sourceTree = ""; }; - 6CF130C42BAB79DE00A437B6 /* RollTheDiceAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RollTheDiceAPI.swift; sourceTree = ""; }; - 6CF130C62BAB7B9800A437B6 /* RollTheDiceAPINews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RollTheDiceAPINews.swift; sourceTree = ""; }; + 6CF130C42BAB79DE00A437B6 /* ScoopAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScoopAPI.swift; sourceTree = ""; }; + 6CF130C62BAB7B9800A437B6 /* ScoopAPINews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScoopAPINews.swift; sourceTree = ""; }; 6CF130C82BAB7CC200A437B6 /* BaseTargetType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseTargetType.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -231,6 +231,13 @@ path = ChatList; sourceTree = ""; }; + 6C41B8DD2BE116A200274FA4 /* Social */ = { + isa = PBXGroup; + children = ( + ); + path = Social; + sourceTree = ""; + }; 6C454A762B9DA62C006FD9D0 /* SignUp */ = { isa = PBXGroup; children = ( @@ -291,6 +298,7 @@ 6C7704862B722618001B17CB /* Source */ = { isa = PBXGroup; children = ( + 6C41B8DD2BE116A200274FA4 /* Social */, 6C454A852B9DB429006FD9D0 /* General */, 6C7704882B722647001B17CB /* View */, 6C454A7F2B9DAF21006FD9D0 /* Model */, @@ -519,7 +527,7 @@ 6CF130B02BAB0CEB00A437B6 /* Domain */ = { isa = PBXGroup; children = ( - 6CF130C32BAB794100A437B6 /* RollTheDiceAPI */, + 6CF130C32BAB794100A437B6 /* ScoopAPI */, 6CF130C02BAB785B00A437B6 /* API */, 6CF130BD2BAB77D300A437B6 /* Foundation */, 6CF130BC2BAB77BF00A437B6 /* Service */, @@ -552,13 +560,13 @@ path = API; sourceTree = ""; }; - 6CF130C32BAB794100A437B6 /* RollTheDiceAPI */ = { + 6CF130C32BAB794100A437B6 /* ScoopAPI */ = { isa = PBXGroup; children = ( - 6CF130C42BAB79DE00A437B6 /* RollTheDiceAPI.swift */, - 6CF130C62BAB7B9800A437B6 /* RollTheDiceAPINews.swift */, + 6CF130C42BAB79DE00A437B6 /* ScoopAPI.swift */, + 6CF130C62BAB7B9800A437B6 /* ScoopAPINews.swift */, ); - path = RollTheDiceAPI; + path = ScoopAPI; sourceTree = ""; }; /* End PBXGroup section */ @@ -658,7 +666,7 @@ 6C454A882B9DB6C2006FD9D0 /* CustomNavigationBar.swift in Sources */, 6CF130BF2BAB783300A437B6 /* APIConstants.swift in Sources */, 6CE103102BD56A5B00498AA4 /* TypeReportViewModel.swift in Sources */, - 6CF130C52BAB79DE00A437B6 /* RollTheDiceAPI.swift in Sources */, + 6CF130C52BAB79DE00A437B6 /* ScoopAPI.swift in Sources */, 6CE103132BD56B1200498AA4 /* DailyReportView.swift in Sources */, 6C454A7A2B9DA67C006FD9D0 /* SignUpViewModel.swift in Sources */, 6C3237AA2B7C381500B699AB /* NewsView.swift in Sources */, @@ -705,7 +713,7 @@ 6C7704992B722A20001B17CB /* MainTabViewModel.swift in Sources */, 6C454A7C2B9DA71C006FD9D0 /* SignUpView.swift in Sources */, 6C41B8DA2BE104A800274FA4 /* RecentNewsCardView.swift in Sources */, - 6CF130C72BAB7B9800A437B6 /* RollTheDiceAPINews.swift in Sources */, + 6CF130C72BAB7B9800A437B6 /* ScoopAPINews.swift in Sources */, 6CE1031A2BD57A2500498AA4 /* DebateSummaryView.swift in Sources */, 6CE1030C2BD56A4000498AA4 /* TypeReportView.swift in Sources */, 6C77049D2B722CE0001B17CB /* BookmarkListView.swift in Sources */, diff --git a/iOS/RollTheDice/RollTheDice/Source/Domain/Foundation/BaseTargetType.swift b/iOS/RollTheDice/RollTheDice/Source/Domain/Foundation/BaseTargetType.swift index 53f7a2d7..721441af 100644 --- a/iOS/RollTheDice/RollTheDice/Source/Domain/Foundation/BaseTargetType.swift +++ b/iOS/RollTheDice/RollTheDice/Source/Domain/Foundation/BaseTargetType.swift @@ -13,7 +13,7 @@ public protocol BaseTargetType: TargetType {} extension BaseTargetType { public var baseURL: URL { - return URL(string: RollTheDiceAPI.baseURL)! + return URL(string: ScoopAPI.baseURL)! } public var headers: [String : String]? { diff --git a/iOS/RollTheDice/RollTheDice/Source/Domain/RollTheDiceAPI/RollTheDiceAPI.swift b/iOS/RollTheDice/RollTheDice/Source/Domain/ScoopAPI/ScoopAPI.swift similarity index 87% rename from iOS/RollTheDice/RollTheDice/Source/Domain/RollTheDiceAPI/RollTheDiceAPI.swift rename to iOS/RollTheDice/RollTheDice/Source/Domain/ScoopAPI/ScoopAPI.swift index 9866b7d5..07662c16 100644 --- a/iOS/RollTheDice/RollTheDice/Source/Domain/RollTheDiceAPI/RollTheDiceAPI.swift +++ b/iOS/RollTheDice/RollTheDice/Source/Domain/ScoopAPI/ScoopAPI.swift @@ -7,6 +7,6 @@ import Foundation -enum RollTheDiceAPI { +enum ScoopAPI { static let baseURL = "localhost:8080" } diff --git a/iOS/RollTheDice/RollTheDice/Source/Domain/RollTheDiceAPI/RollTheDiceAPINews.swift b/iOS/RollTheDice/RollTheDice/Source/Domain/ScoopAPI/ScoopAPINews.swift similarity index 82% rename from iOS/RollTheDice/RollTheDice/Source/Domain/RollTheDiceAPI/RollTheDiceAPINews.swift rename to iOS/RollTheDice/RollTheDice/Source/Domain/ScoopAPI/ScoopAPINews.swift index 0de0d616..4dcdf781 100644 --- a/iOS/RollTheDice/RollTheDice/Source/Domain/RollTheDiceAPI/RollTheDiceAPINews.swift +++ b/iOS/RollTheDice/RollTheDice/Source/Domain/ScoopAPI/ScoopAPINews.swift @@ -7,6 +7,6 @@ import Foundation -public enum RollTheDiceAPINews { +public enum ScoopAPINews { public static let newsFetch = String("/news") } diff --git a/iOS/RollTheDice/RollTheDice/Source/Domain/Service/NewsService.swift b/iOS/RollTheDice/RollTheDice/Source/Domain/Service/NewsService.swift index cca6da6f..f554d83e 100644 --- a/iOS/RollTheDice/RollTheDice/Source/Domain/Service/NewsService.swift +++ b/iOS/RollTheDice/RollTheDice/Source/Domain/Service/NewsService.swift @@ -14,13 +14,13 @@ enum NewsService { extension NewsService: BaseTargetType { var baseURL: URL { - return URL(string: RollTheDiceAPI.baseURL)! + return URL(string: ScoopAPI.baseURL)! } var path: String { switch self { case .news: - return RollTheDiceAPINews.newsFetch + return ScoopAPINews.newsFetch } } From e733fbe81c1cc06841c8fa083f7ad04c10e35223 Mon Sep 17 00:00:00 2001 From: realhsb Date: Wed, 15 May 2024 00:31:36 +0900 Subject: [PATCH 02/30] =?UTF-8?q?feat:=20Moya=20networking=20extension=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 --- .../RollTheDice.xcodeproj/project.pbxproj | 28 ++++++ .../Domain/Service/Log/Extension+Log.swift | 43 ++++++++ .../Domain/Service/Log/Extension+OSLog.swift | 18 ++++ .../Source/Domain/Service/Log/Log.swift | 99 +++++++++++++++++++ .../Service/Log/MoyaLoggingPlugin.swift | 96 ++++++++++++++++++ 5 files changed, 284 insertions(+) create mode 100644 iOS/RollTheDice/RollTheDice/Source/Domain/Service/Log/Extension+Log.swift create mode 100644 iOS/RollTheDice/RollTheDice/Source/Domain/Service/Log/Extension+OSLog.swift create mode 100644 iOS/RollTheDice/RollTheDice/Source/Domain/Service/Log/Log.swift create mode 100644 iOS/RollTheDice/RollTheDice/Source/Domain/Service/Log/MoyaLoggingPlugin.swift diff --git a/iOS/RollTheDice/RollTheDice.xcodeproj/project.pbxproj b/iOS/RollTheDice/RollTheDice.xcodeproj/project.pbxproj index 45cb54ca..b9c45fb0 100644 --- a/iOS/RollTheDice/RollTheDice.xcodeproj/project.pbxproj +++ b/iOS/RollTheDice/RollTheDice.xcodeproj/project.pbxproj @@ -34,6 +34,11 @@ 6C454A882B9DB6C2006FD9D0 /* CustomNavigationBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C454A872B9DB6C2006FD9D0 /* CustomNavigationBar.swift */; }; 6C4F7BAB2BDE50C600ED01DA /* DailyReportModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C4F7BAA2BDE50C600ED01DA /* DailyReportModel.swift */; }; 6C4F7BAD2BDE510900ED01DA /* DailyReportViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C4F7BAC2BDE510900ED01DA /* DailyReportViewModel.swift */; }; + 6C7651382BF37E7200196536 /* MoyaLoggingPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C7651372BF37E7200196536 /* MoyaLoggingPlugin.swift */; }; + 6C76513C2BF37ED300196536 /* Extension+Log.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C76513B2BF37ED300196536 /* Extension+Log.swift */; }; + 6C76513E2BF37F1E00196536 /* Extension+OSLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C76513D2BF37F1E00196536 /* Extension+OSLog.swift */; }; + 6C7651402BF37F3400196536 /* Log.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C76513F2BF37F3400196536 /* Log.swift */; }; + 6C7651422BF37F5C00196536 /* OSLog.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C7651412BF37F5C00196536 /* OSLog.framework */; }; 6C77048C2B722686001B17CB /* MainTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C77048B2B722686001B17CB /* MainTabView.swift */; }; 6C77048F2B7229B1001B17CB /* NewsListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C77048E2B7229B1001B17CB /* NewsListView.swift */; }; 6C7704992B722A20001B17CB /* MainTabViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C7704982B722A20001B17CB /* MainTabViewModel.swift */; }; @@ -110,6 +115,11 @@ 6C454A872B9DB6C2006FD9D0 /* CustomNavigationBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomNavigationBar.swift; sourceTree = ""; }; 6C4F7BAA2BDE50C600ED01DA /* DailyReportModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DailyReportModel.swift; sourceTree = ""; }; 6C4F7BAC2BDE510900ED01DA /* DailyReportViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DailyReportViewModel.swift; sourceTree = ""; }; + 6C7651372BF37E7200196536 /* MoyaLoggingPlugin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoyaLoggingPlugin.swift; sourceTree = ""; }; + 6C76513B2BF37ED300196536 /* Extension+Log.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Extension+Log.swift"; sourceTree = ""; }; + 6C76513D2BF37F1E00196536 /* Extension+OSLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Extension+OSLog.swift"; sourceTree = ""; }; + 6C76513F2BF37F3400196536 /* Log.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Log.swift; sourceTree = ""; }; + 6C7651412BF37F5C00196536 /* OSLog.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OSLog.framework; path = System/Library/Frameworks/OSLog.framework; sourceTree = SDKROOT; }; 6C77048B2B722686001B17CB /* MainTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabView.swift; sourceTree = ""; }; 6C77048E2B7229B1001B17CB /* NewsListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsListView.swift; sourceTree = ""; }; 6C7704982B722A20001B17CB /* MainTabViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabViewModel.swift; sourceTree = ""; }; @@ -166,6 +176,7 @@ 6CF130B72BAB74FD00A437B6 /* Moya in Frameworks */, 6CF130B92BAB74FD00A437B6 /* ReactiveMoya in Frameworks */, 6CE2AC1B2BD444BB00416A02 /* OpenAI in Frameworks */, + 6C7651422BF37F5C00196536 /* OSLog.framework in Frameworks */, 6CF130B52BAB74FD00A437B6 /* CombineMoya in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -283,6 +294,17 @@ path = CustomNavigationBar; sourceTree = ""; }; + 6C7651432BF381B000196536 /* Log */ = { + isa = PBXGroup; + children = ( + 6C7651372BF37E7200196536 /* MoyaLoggingPlugin.swift */, + 6C76513B2BF37ED300196536 /* Extension+Log.swift */, + 6C76513D2BF37F1E00196536 /* Extension+OSLog.swift */, + 6C76513F2BF37F3400196536 /* Log.swift */, + ); + path = Log; + sourceTree = ""; + }; 6C7704852B72260F001B17CB /* Resources */ = { isa = PBXGroup; children = ( @@ -511,6 +533,7 @@ 6CE2AC152BD443F400416A02 /* Frameworks */ = { isa = PBXGroup; children = ( + 6C7651412BF37F5C00196536 /* OSLog.framework */, ); name = Frameworks; sourceTree = ""; @@ -538,6 +561,7 @@ 6CF130BC2BAB77BF00A437B6 /* Service */ = { isa = PBXGroup; children = ( + 6C7651432BF381B000196536 /* Log */, 6CF130B12BAB74BA00A437B6 /* NewsService.swift */, ); path = Service; @@ -665,6 +689,7 @@ files = ( 6C454A882B9DB6C2006FD9D0 /* CustomNavigationBar.swift in Sources */, 6CF130BF2BAB783300A437B6 /* APIConstants.swift in Sources */, + 6C76513C2BF37ED300196536 /* Extension+Log.swift in Sources */, 6CE103102BD56A5B00498AA4 /* TypeReportViewModel.swift in Sources */, 6CF130C52BAB79DE00A437B6 /* ScoopAPI.swift in Sources */, 6CE103132BD56B1200498AA4 /* DailyReportView.swift in Sources */, @@ -682,6 +707,7 @@ 6C3237A12B7C377600B699AB /* BookmarkViewModel.swift in Sources */, 6C3237AC2B7C382200B699AB /* News.swift in Sources */, 6CE1030E2BD56A5200498AA4 /* TypeReportModel.swift in Sources */, + 6C76513E2BF37F1E00196536 /* Extension+OSLog.swift in Sources */, 357FC6EA2BCE866B00AD8915 /* DetailCardNews.swift in Sources */, 6CC4DDC92B5574670080E7E8 /* ContentView.swift in Sources */, 6C3237A52B7C37D100B699AB /* BookmarkView.swift in Sources */, @@ -714,9 +740,11 @@ 6C454A7C2B9DA71C006FD9D0 /* SignUpView.swift in Sources */, 6C41B8DA2BE104A800274FA4 /* RecentNewsCardView.swift in Sources */, 6CF130C72BAB7B9800A437B6 /* ScoopAPINews.swift in Sources */, + 6C7651402BF37F3400196536 /* Log.swift in Sources */, 6CE1031A2BD57A2500498AA4 /* DebateSummaryView.swift in Sources */, 6CE1030C2BD56A4000498AA4 /* TypeReportView.swift in Sources */, 6C77049D2B722CE0001B17CB /* BookmarkListView.swift in Sources */, + 6C7651382BF37E7200196536 /* MoyaLoggingPlugin.swift in Sources */, 6C77049B2B722A5A001B17CB /* TabType.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/iOS/RollTheDice/RollTheDice/Source/Domain/Service/Log/Extension+Log.swift b/iOS/RollTheDice/RollTheDice/Source/Domain/Service/Log/Extension+Log.swift new file mode 100644 index 00000000..c376a5bf --- /dev/null +++ b/iOS/RollTheDice/RollTheDice/Source/Domain/Service/Log/Extension+Log.swift @@ -0,0 +1,43 @@ +// +// Extension+Log.swift +// RollTheDice +// +// Created by Subeen on 5/14/24. +// + +import Foundation + +public extension Log { + //MARK: - 디버그 + static func debug(_ message: Any, _ arguments: Any...) { + log(message, arguments, level: .debug) + } + + //MARK: - 문제 해결시 활용할 수 있는, 도움이 되지만 필수적이지 않은 정보 로거 + /** + # info + - Authors : suni + - Note : 문제 해결시 활용할 수 있는, 도움이 되지만 필수적이지 않은 정보 + */ + static func info(_ message: Any, _ arguments: Any...) { + log(message, arguments, level: .info) + } + + + //MARK: - 네트워크 로거 + static func network(_ message: Any, _ arguments: Any...) { + log(message, arguments, level: .network) + } + + //MARK: - 에러 로거 + static func error(_ message: Any, _ arguments: Any...) { + log(message, arguments, level: .error) + } + + //MARK: - 커스텀 로거 + static func custom(category: String, _ message: Any, _ arguments: Any...) { + log(message, arguments, level: .custom(category: category)) + } + +} + diff --git a/iOS/RollTheDice/RollTheDice/Source/Domain/Service/Log/Extension+OSLog.swift b/iOS/RollTheDice/RollTheDice/Source/Domain/Service/Log/Extension+OSLog.swift new file mode 100644 index 00000000..e99d709c --- /dev/null +++ b/iOS/RollTheDice/RollTheDice/Source/Domain/Service/Log/Extension+OSLog.swift @@ -0,0 +1,18 @@ +// +// Extension+OSLog.swift +// RollTheDice +// +// Created by Subeen on 5/14/24. +// + +import Foundation +import OSLog + +extension OSLog { + static let subsystem = Bundle.main.bundleIdentifier! + static let network = OSLog(subsystem: subsystem, category: "Network") + static let debug = OSLog(subsystem: subsystem, category: "Debug") + static let info = OSLog(subsystem: subsystem, category: "Info") + static let error = OSLog(subsystem: subsystem, category: "Error") +} + diff --git a/iOS/RollTheDice/RollTheDice/Source/Domain/Service/Log/Log.swift b/iOS/RollTheDice/RollTheDice/Source/Domain/Service/Log/Log.swift new file mode 100644 index 00000000..affa708c --- /dev/null +++ b/iOS/RollTheDice/RollTheDice/Source/Domain/Service/Log/Log.swift @@ -0,0 +1,99 @@ +// +// Log.swift +// RollTheDice +// +// Created by Subeen on 5/14/24. +// + +import Foundation +import OSLog + +public struct Log { + public init(){} + + public enum LogLevel { + /// 디버깅 로그 + case debug + /// 문제 해결 정보 + case info + /// 네트워크 로그 + case network + /// 오류 로그 + case error + case custom(category: String) + + fileprivate var category: String { + switch self { + case .debug: + return "🟡 DEBUG" + case .info: + return "🟠 INFO" + case .network: + return "🔵 NETWORK" + case .error: + return "🔴 ERROR" + case .custom(let category): + return "🟢 \(category)" + } + } + + fileprivate var osLog: OSLog { + switch self { + case .debug: + return OSLog.debug + case .info: + return OSLog.info + case .network: + return OSLog.network + case .error: + return OSLog.error + case .custom: + return OSLog.debug + } + } + + fileprivate var osLogType: OSLogType { + switch self { + case .debug: + return .debug + case .info: + return .info + case .network: + return .default + case .error: + return .error + case .custom: + return .debug + } + } + + + } + + + static func log(_ message: Any, _ arguments: [Any], level: LogLevel) { + #if DEBUG + if #available(iOS 14.0, *) { + let extraMessage: String = arguments.map({ String(describing: $0) }).joined(separator: " ") + let logger = Logger(subsystem: OSLog.subsystem, category: level.category) + let logMessage = "\(message) \(extraMessage)" + switch level { + case .debug, + .custom: + logger.debug("\(logMessage, privacy: .public)") + case .info: + logger.info("\(logMessage, privacy: .public)") + case .network: + logger.log("\(logMessage, privacy: .public)") + case .error: + logger.error("\(logMessage, privacy: .public)") + } + } else { + let extraMessage: String = arguments.map({ String(describing: $0) }).joined(separator: " ") + os_log("%{public}@", log: level.osLog, type: level.osLogType, "\(message) \(extraMessage)") + } + #endif + } +} + + diff --git a/iOS/RollTheDice/RollTheDice/Source/Domain/Service/Log/MoyaLoggingPlugin.swift b/iOS/RollTheDice/RollTheDice/Source/Domain/Service/Log/MoyaLoggingPlugin.swift new file mode 100644 index 00000000..422781a1 --- /dev/null +++ b/iOS/RollTheDice/RollTheDice/Source/Domain/Service/Log/MoyaLoggingPlugin.swift @@ -0,0 +1,96 @@ +// +// MoyaLoggingPlugin.swift +// RollTheDice +// +// Created by Subeen on 5/14/24. +// + +// 네트워킹 로그 확인 + +import UIKit +import Moya +import OSLog + +public class MoyaLoggingPlugin: PluginType { + + public init() {} + + public func prepare(_ request: URLRequest, target: TargetType) -> URLRequest { + return request + } + // Request를 보낼 때 호출 + public func willSend(_ request: RequestType, target: TargetType) { + guard let httpRequest = request.request else { + #if DEBUG + Log.network("--> 유효하지 않은 요청", (Any).self) + #endif + return + } + + let url = httpRequest.description + let method = httpRequest.httpMethod ?? "메소드값이 nil입니다." + var log = """ + ⎡---------------------서버통신을 시작합니다.----------------------⎤ + [\(method)] \(url) + API: \(target) \n + """ + if let headers = httpRequest.allHTTPHeaderFields, !headers.isEmpty { + log.append("header:\n \(headers) \n") + } + if let body = httpRequest.httpBody, let bodyString = String(bytes: body, encoding: String.Encoding.utf8) { + log.append("\(bodyString)\n") + } + + log.append("⎣------------------ Request END -------------------------⎦") + #if DEBUG + Log.network("", log) + #endif + } + // Response가 왔을 때 + public func didReceive(_ result: Result, target: TargetType) { + switch result { + case let .success(response): + onSucceed(response, target: target, isFromError: false) + case let .failure(error): + onFail(error, target: target) + } + } + + public func process(_ result: Result, target: TargetType) -> Result { + return result + } + + public func onSucceed(_ response: Response, target: TargetType, isFromError: Bool) { + let request = response.request + let url = request?.url?.absoluteString ?? "nil" + let statusCode = response.statusCode + var log = "⎡------------------서버에게 Response가 도착했습니다. ------------------⎤\n" + log.append("API: \(target)\n") + log.append("Status Code: [\(statusCode)]\n") + log.append("URL: \(url)\n") + if let responseData = String(bytes: response.data.map{$0}, encoding: String.Encoding.utf8) { + log.append("Data: \n \(responseData)\n") + } + log.append("⎣------------------ END HTTP (\(response.data.count)-byte body) ------------------⎦") + #if DEBUG + + Log.network("", log) + #endif + + } + + public func onFail(_ error: MoyaError, target: TargetType) { + if let response = error.response { + onSucceed(response, target: target, isFromError: true) + return + } + var log = "네트워크 오류" + log.append("<-- \(error.errorCode) \(target)\n") + log.append("\(error.failureReason ?? error.errorDescription ?? "unknown error")\n") + log.append("<-- END HTTP") + #if DEBUG + Log.network("", log) + #endif + + } +} From 1cc31d6b89689d32963503faaa2f1b52e45cda00 Mon Sep 17 00:00:00 2001 From: realhsb Date: Wed, 15 May 2024 00:32:32 +0900 Subject: [PATCH 03/30] =?UTF-8?q?fix:=20info.plist=20=EB=82=B4=EC=9A=A9=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=ED=8F=B4=EB=8D=94=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=ED=9B=84=20=EA=B2=BD=EB=A1=9C=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HTTP 통신을 위한 환경 설정 및 폴더 수정 후 경로 설정 --- .../RollTheDice.xcodeproj/project.pbxproj | 16 ++++++++++++---- .../{ => Resources/Support}/Info.plist | 5 +++++ 2 files changed, 17 insertions(+), 4 deletions(-) rename iOS/RollTheDice/RollTheDice/{ => Resources/Support}/Info.plist (86%) diff --git a/iOS/RollTheDice/RollTheDice.xcodeproj/project.pbxproj b/iOS/RollTheDice/RollTheDice.xcodeproj/project.pbxproj index b9c45fb0..f93c07b5 100644 --- a/iOS/RollTheDice/RollTheDice.xcodeproj/project.pbxproj +++ b/iOS/RollTheDice/RollTheDice.xcodeproj/project.pbxproj @@ -135,7 +135,7 @@ 6CC4DDC82B5574670080E7E8 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 6CC4DDCA2B5574690080E7E8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 6CC4DDCD2B5574690080E7E8 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; - 6CDB29BF2BA9735C0081037B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; + 6CDB29BF2BA9735C0081037B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 6CDB29C02BA97C550081037B /* Pretendard-Black.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Pretendard-Black.otf"; sourceTree = ""; }; 6CDB29C12BA97C550081037B /* Pretendard-ExtraBold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Pretendard-ExtraBold.otf"; sourceTree = ""; }; 6CDB29C22BA97C550081037B /* Pretendard-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Pretendard-Regular.otf"; sourceTree = ""; }; @@ -305,9 +305,18 @@ path = Log; sourceTree = ""; }; + 6C7651442BF3AF2700196536 /* Support */ = { + isa = PBXGroup; + children = ( + 6CDB29BF2BA9735C0081037B /* Info.plist */, + ); + path = Support; + sourceTree = ""; + }; 6C7704852B72260F001B17CB /* Resources */ = { isa = PBXGroup; children = ( + 6C7651442BF3AF2700196536 /* Support */, 6C94799C2BD3BFFA00D5AEEB /* Image */, 6CA901812BA2EBBA00E20259 /* Font */, 6CC4DDCA2B5574690080E7E8 /* Assets.xcassets */, @@ -453,7 +462,6 @@ 6CC4DDC52B5574670080E7E8 /* RollTheDice */ = { isa = PBXGroup; children = ( - 6CDB29BF2BA9735C0081037B /* Info.plist */, 6C7704862B722618001B17CB /* Source */, 6C7704852B72260F001B17CB /* Resources */, 6CC4DDC62B5574670080E7E8 /* RollTheDiceApp.swift */, @@ -882,7 +890,7 @@ DEVELOPMENT_TEAM = 4YH4UGRTMH; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_FILE = RollTheDice/Info.plist; + INFOPLIST_FILE = RollTheDice/Resources/Support/Info.plist; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; @@ -912,7 +920,7 @@ DEVELOPMENT_TEAM = 4YH4UGRTMH; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_FILE = RollTheDice/Info.plist; + INFOPLIST_FILE = RollTheDice/Resources/Support/Info.plist; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; diff --git a/iOS/RollTheDice/RollTheDice/Info.plist b/iOS/RollTheDice/RollTheDice/Resources/Support/Info.plist similarity index 86% rename from iOS/RollTheDice/RollTheDice/Info.plist rename to iOS/RollTheDice/RollTheDice/Resources/Support/Info.plist index cf8c9292..01a3db65 100644 --- a/iOS/RollTheDice/RollTheDice/Info.plist +++ b/iOS/RollTheDice/RollTheDice/Resources/Support/Info.plist @@ -2,6 +2,11 @@ + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + UIAppFonts Pretendard-Black.otf From 3d280a8b92dcb2bef6439d22c50f25c7a571173f Mon Sep 17 00:00:00 2001 From: realhsb Date: Wed, 15 May 2024 00:34:40 +0900 Subject: [PATCH 04/30] =?UTF-8?q?chore:=20News=20=EC=A0=84=EC=B2=B4=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=EC=8B=9C=20=EC=82=AC=EC=9A=A9=EB=90=98?= =?UTF-8?q?=EB=8A=94=20=EC=BF=BC=EB=A6=AC(sort)=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit string만 입력해주면 됨 --- .../RollTheDice/Source/Domain/Service/NewsService.swift | 9 +++++---- .../Source/View/News/NewsCard/NewsListViewModel.swift | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/iOS/RollTheDice/RollTheDice/Source/Domain/Service/NewsService.swift b/iOS/RollTheDice/RollTheDice/Source/Domain/Service/NewsService.swift index f554d83e..a1722b7b 100644 --- a/iOS/RollTheDice/RollTheDice/Source/Domain/Service/NewsService.swift +++ b/iOS/RollTheDice/RollTheDice/Source/Domain/Service/NewsService.swift @@ -9,7 +9,7 @@ import Foundation import Moya enum NewsService { - case news(page: Int, size: Int, token: String) + case news(page: Int, size: Int, sort: String, token: String) } extension NewsService: BaseTargetType { @@ -33,10 +33,11 @@ extension NewsService: BaseTargetType { var task: Moya.Task { switch self { - case .news(let page, let size, _): + case .news(let page, let size, let sort, _): let parameters : [String : Any] = [ "page" : page, - "size" : size + "size" : size, + "sort" : sort ] return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString) } @@ -45,7 +46,7 @@ extension NewsService: BaseTargetType { var headers: [String : String]? { let token: String switch self { - case .news(_, _, let tokenValue): + case .news(_, _, _, let tokenValue): token = tokenValue return [ "Content-Type": "application/json", diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListViewModel.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListViewModel.swift index 6623d00f..331ff3c4 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListViewModel.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListViewModel.swift @@ -39,7 +39,7 @@ import SwiftUI // // newsCancellable = // provider.requestWithProgressPublisher( -// .news( + sort: "string", // page: page, // size: size, // token: accessToken From 3f619a9550670e98ba470807d950d479cedc67f9 Mon Sep 17 00:00:00 2001 From: realhsb Date: Wed, 15 May 2024 00:36:17 +0900 Subject: [PATCH 05/30] =?UTF-8?q?chore:=20NewsListViewModel=20Macro=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 --- iOS/RollTheDice/RollTheDice/RollTheDiceApp.swift | 2 +- .../Source/View/News/NewsCard/NewsListView.swift | 2 +- .../Source/View/News/NewsCard/NewsListViewModel.swift | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/iOS/RollTheDice/RollTheDice/RollTheDiceApp.swift b/iOS/RollTheDice/RollTheDice/RollTheDiceApp.swift index 1997d440..5908c828 100644 --- a/iOS/RollTheDice/RollTheDice/RollTheDiceApp.swift +++ b/iOS/RollTheDice/RollTheDice/RollTheDiceApp.swift @@ -13,7 +13,7 @@ struct RollTheDiceApp: App { @StateObject var appState = AppState() @StateObject private var pathModel = PathModel() - @StateObject var newsListViewModel = NewsListViewModel() + var newsListViewModel = NewsListViewModel() @StateObject var bookmarkListViewModel = BookmarkListViewModel() var body: some Scene { diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListView.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListView.swift index 8fe212dd..f5f1fe1f 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListView.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListView.swift @@ -9,7 +9,7 @@ import SwiftUI struct NewsListView: View { - @StateObject var newsListViewModel: NewsListViewModel + var newsListViewModel: NewsListViewModel @State var selectedIndex: Int = 0 var body: some View { diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListViewModel.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListViewModel.swift index 331ff3c4..e8c84267 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListViewModel.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListViewModel.swift @@ -11,9 +11,9 @@ import Foundation //import Moya import SwiftUI -//class NewsListViewModel: ObservableObject { -// // News = [NewsModel] -// +// Macro -> iOS 17.0 이상부터. @Published 안 해도 됨. +// 사용할 때 var 형식으로 해도 됨. +@Observable class NewsListViewModel { // // @Published var newsResponse: NewsResponse? // var currentPage = 0 From 64f937d2150e756e0bb3711800e0b53c72aa4cdb Mon Sep 17 00:00:00 2001 From: realhsb Date: Wed, 15 May 2024 00:36:36 +0900 Subject: [PATCH 06/30] =?UTF-8?q?chore:=20=EB=AF=B8=EC=82=AC=EC=9A=A9=20VM?= =?UTF-8?q?=20=EC=A3=BC=EC=84=9D=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/News/NewsCard/NewsViewModel.swift | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsViewModel.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsViewModel.swift index e1e4c7fc..fd7433d6 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsViewModel.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsViewModel.swift @@ -1,16 +1,16 @@ +//// +//// NewsCardViewModel.swift +//// RollTheDice +//// +//// Created by Subeen on 2/9/24. +//// // -// NewsCardViewModel.swift -// RollTheDice +//import Foundation // -// Created by Subeen on 2/9/24. -// - -import Foundation - -public class NewsViewModel: ObservableObject { - @Published var news: News - - init(news: News) { - self.news = news - } -} +//public class NewsViewModel: ObservableObject { +// @Published var news: News +// +// init(news: News) { +// self.news = news +// } +//} From f13bf9ba39de0f7bd7301835c7b30c5920a912b3 Mon Sep 17 00:00:00 2001 From: realhsb Date: Thu, 16 May 2024 00:33:54 +0900 Subject: [PATCH 07/30] =?UTF-8?q?chore:=20API=20base=20url=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RollTheDice/Source/Domain/API/APIHeaderManager.swift | 9 ++++++--- .../Source/Domain/Foundation/APIConstants.swift | 7 ++----- .../RollTheDice/Source/Domain/ScoopAPI/ScoopAPI.swift | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/iOS/RollTheDice/RollTheDice/Source/Domain/API/APIHeaderManager.swift b/iOS/RollTheDice/RollTheDice/Source/Domain/API/APIHeaderManager.swift index dc68e29a..81c204d8 100644 --- a/iOS/RollTheDice/RollTheDice/Source/Domain/API/APIHeaderManager.swift +++ b/iOS/RollTheDice/RollTheDice/Source/Domain/API/APIHeaderManager.swift @@ -7,10 +7,13 @@ import Foundation -public class APIHeaderManger { +public class APIHeaderManager { - static let shared = APIHeaderManger() + static let shared = APIHeaderManager() let contentType: String = "application/json" - let rtdHost: String = "localhost:8080" + let scoopHost: String = "ec2-13-124-191-244.ap-northeast-2.compute.amazonaws.com:8080" } + + +// http://ec2-13-124-191-244.ap-northeast-2.compute.amazonaws.com:8080/swagger-ui/index.html diff --git a/iOS/RollTheDice/RollTheDice/Source/Domain/Foundation/APIConstants.swift b/iOS/RollTheDice/RollTheDice/Source/Domain/Foundation/APIConstants.swift index 2d5ebdcc..fbfda685 100644 --- a/iOS/RollTheDice/RollTheDice/Source/Domain/Foundation/APIConstants.swift +++ b/iOS/RollTheDice/RollTheDice/Source/Domain/Foundation/APIConstants.swift @@ -8,19 +8,16 @@ import Foundation struct APIConstants{ -// static var viewModel: BoardViewModel = BoardViewModel() static let contentType = "Content-Type" static let host = "Host" -// static let Cookie = "Cookie" } extension APIConstants { static var baseHeader: Dictionary { [ - contentType : APIHeaderManger.shared.contentType, - host : APIHeaderManger.shared.rtdHost, -// Cookie : "accessToken=\(viewModel.authCodeToken)" + contentType : APIHeaderManager.shared.contentType, + host : APIHeaderManager.shared.scoopHost, ] } } diff --git a/iOS/RollTheDice/RollTheDice/Source/Domain/ScoopAPI/ScoopAPI.swift b/iOS/RollTheDice/RollTheDice/Source/Domain/ScoopAPI/ScoopAPI.swift index 07662c16..0784adf7 100644 --- a/iOS/RollTheDice/RollTheDice/Source/Domain/ScoopAPI/ScoopAPI.swift +++ b/iOS/RollTheDice/RollTheDice/Source/Domain/ScoopAPI/ScoopAPI.swift @@ -8,5 +8,5 @@ import Foundation enum ScoopAPI { - static let baseURL = "localhost:8080" + static let baseURL = "http://ec2-13-124-191-244.ap-northeast-2.compute.amazonaws.com:8080" } From 44be161fbb90a6d52cced7b007f94c2a1a51af68 Mon Sep 17 00:00:00 2001 From: realhsb Date: Thu, 16 May 2024 00:34:45 +0900 Subject: [PATCH 08/30] =?UTF-8?q?chore:=20=EC=9A=94=EC=95=BD=20=EB=89=B4?= =?UTF-8?q?=EC=8A=A4=20=EC=A0=84=EC=B2=B4=20=EC=A1=B0=ED=9A=8C=20=ED=97=A4?= =?UTF-8?q?=EB=8D=94=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Source/Domain/Service/NewsService.swift | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/iOS/RollTheDice/RollTheDice/Source/Domain/Service/NewsService.swift b/iOS/RollTheDice/RollTheDice/Source/Domain/Service/NewsService.swift index a1722b7b..f3dfd367 100644 --- a/iOS/RollTheDice/RollTheDice/Source/Domain/Service/NewsService.swift +++ b/iOS/RollTheDice/RollTheDice/Source/Domain/Service/NewsService.swift @@ -9,7 +9,7 @@ import Foundation import Moya enum NewsService { - case news(page: Int, size: Int, sort: String, token: String) + case news(page: Int, size: Int, accessToken: String) } extension NewsService: BaseTargetType { @@ -33,24 +33,24 @@ extension NewsService: BaseTargetType { var task: Moya.Task { switch self { - case .news(let page, let size, let sort, _): + case .news(let page, let size, _): let parameters : [String : Any] = [ "page" : page, "size" : size, - "sort" : sort ] return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString) } } var headers: [String : String]? { - let token: String + let accessToken: String switch self { - case .news(_, _, _, let tokenValue): - token = tokenValue + case .news(_, _, let accessTokenValue): + accessToken = accessTokenValue return [ - "Content-Type": "application/json", - "Authorization": "Bearer \(token)" +// "Content-Type": "application/json", + "Authorization": "Bearer \(accessToken)", + "X-Content-Type_Options" : "nosniff" ] } } From cc54731db0295ad729e533223c6f05915bf549de Mon Sep 17 00:00:00 2001 From: realhsb Date: Thu, 16 May 2024 00:35:25 +0900 Subject: [PATCH 09/30] =?UTF-8?q?chore:=20News=20=EB=AA=A8=EB=8D=B8=20?= =?UTF-8?q?=EB=B0=8F=20=EB=B7=B0=EB=AA=A8=EB=8D=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Source/View/News/NewsCard/News.swift | 91 ++++++------ .../News/NewsCard/NewsListViewModel.swift | 134 +++++++++--------- 2 files changed, 119 insertions(+), 106 deletions(-) diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/News.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/News.swift index 76d421a9..2b7372cb 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/News.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/News.swift @@ -1,23 +1,32 @@ // API Test -// -// -// -// -//import Foundation -// -//// MARK: - NewsElement -//struct News: Codable, Hashable { -// let id: Int -// let title, content: String -// let thumbnail: JSONNull? -// let postDate: String -// let isBookmarked: Bool + +import Foundation + +// MARK: - NewsElement +// data는 옵셔널처리. JSONNull 사용 X +//struct NewsResponse: Codable { +// let newsResponse: [News]? //} -// + +struct News: Codable, Identifiable { + let id = UUID().uuidString // 이건 앱자체에서 + let newsId: Int? + let title, content: String? + let thumbnail: String? + let postDate: String? + let isBookmarked: Bool? + + enum CodingKeys: String, CodingKey { + case newsId = "id" + case title, content, thumbnail, postDate, isBookmarked + } +} + //typealias NewsResponse = [News] -// -//// MARK: - Encode/decode helpers -// + + +// MARK: - Encode/decode helpers + //class JSONNull: Codable, Hashable { // // public static func == (lhs: JSONNull, rhs: JSONNull) -> Bool { @@ -58,27 +67,27 @@ // Created by Subeen on 2/9/24. // -import Foundation - -struct News: Hashable { - var id: UUID = UUID() - var title: String - var postDate: String - var image: String - var content: String - var isBookmarked: Bool - - init( - title: String = "", - postDate: String = "", - image: String = "", - content: String = "", - isBookmarked: Bool = false - ) { - self.title = title - self.postDate = postDate - self.image = image - self.content = content - self.isBookmarked = isBookmarked - } -} +//import Foundation +// +//struct News: Hashable { +// var id: UUID = UUID() +// var title: String +// var postDate: String +// var image: String +// var content: String +// var isBookmarked: Bool +// +// init( +// title: String = "", +// postDate: String = "", +// image: String = "", +// content: String = "", +// isBookmarked: Bool = false +// ) { +// self.title = title +// self.postDate = postDate +// self.image = image +// self.content = content +// self.isBookmarked = isBookmarked +// } +//} diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListViewModel.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListViewModel.swift index e8c84267..e676eece 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListViewModel.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListViewModel.swift @@ -6,77 +6,81 @@ // import Foundation -//import Combine -//import CombineMoya -//import Moya +import Combine +import CombineMoya +import Moya import SwiftUI // Macro -> iOS 17.0 이상부터. @Published 안 해도 됨. // 사용할 때 var 형식으로 해도 됨. @Observable class NewsListViewModel { -// -// @Published var newsResponse: NewsResponse? -// var currentPage = 0 -// var newsCancellable: AnyCancellable? -// -// func newsToViewModel(_ list: NewsResponse) { -// self.newsResponse = list -// } -//} + var newsList: [News]? + var currentPage = 0 + var newsCancellable: AnyCancellable? + + + + //TODO: Plugin Settings + let provider = MoyaProvider(plugins: [MoyaLoggingPlugin()]) + + func newsToViewModel(_ list: [News]) { + self.newsList = list + } +} -//extension NewsListViewModel { -// public func getAllNewsData(page: Int, size: Int) { -// print("news : 요약 뉴스 전체 조회") -// -// let accessToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJBY2Nlc3NUb2tlbiIsImV4cCI6MTcxMTQ3NjEzNywiZW1haWwiOiJjaGVueWVvbmp5QGRhdW0ubmV0In0.bEstO5tRBZL1-cah-hEfF270DA37UNQ3gm0txLoDxaGuPNYTfNcDA1UbiNaVIWvMwnw7RQoS8g4WlJrv_Holsw" -// -// if let cancellable = newsCancellable { -// cancellable.cancel() -// } -// -// //TODO: Plugin Settings -// let provider = MoyaProvider() -// -// newsCancellable = -// provider.requestWithProgressPublisher( - sort: "string", -// page: page, -// size: size, -// token: accessToken -// ) -// ) -// .compactMap { $0.response?.data } -// .receive(on: DispatchQueue.main) -// .decode(type: NewsResponse.self, decoder: JSONDecoder()) -// .sink(receiveCompletion: { result in -// switch result { -// // success -// case .finished: -// break -// case .failure(let error): +extension NewsListViewModel { + public func getAllNewsData(page: Int, size: Int) { + + let accessToken = "" + + if let cancellable = newsCancellable { + cancellable.cancel() + } + + newsCancellable = + provider.requestWithProgressPublisher( + .news( + page: page, + size: size, + accessToken: accessToken + ) + ) + .compactMap { $0.response?.data } + .receive(on: DispatchQueue.main) + .decode(type: [News].self, decoder: JSONDecoder()) + .sink(receiveCompletion: { result in + switch result { + // success + case .finished: + print("news 조회 성공") + break + case .failure(let error): // print(error.localizedDescription) -// } -// }, receiveValue: { [weak self] response in -// self?.newsToViewModel(response) -// }) -// } -//} - - -public class NewsListViewModel: ObservableObject { - // News = [NewsModel] - @Published var newsList: [News] = [] -// var currentPage = 0 - - init( - newsList: [News] = [ - - .init(title: "네이버, 사우디 'LEAP 2024'서 AI·로봇 등 자사 기술력 뽐낸다", postDate: "2023년3월3일", image: "https://imgnews.pstatic.net/image/008/2024/03/05/0005007355_001_20240305100101016.jpg?type=w647", content: "네이버(NAVER)는 사우디아라비아에서 지난 4일부터 7일까지 열리는 글로벌 IT전시회 LEAP 2024에서 AI(인공지능), 클라우드, 로봇 등 자사 핵심 기술을 선보이고, 글로벌 업체들과 비즈니스 협력을 강화한다고 5일 밝혔다.", isBookmarked: false), - .init(title: "앤스로픽 최신 AI 모델 '클로드3' 출시", postDate: "2023년3월13일", image: "https://imgnews.pstatic.net/image/014/2024/03/05/0005151141_001_20240305101610000.jpg?type=w647", content: "오픈AI의 대항마 앤스로픽이 생성형 인공지능(AI) 최신 모델 '클로드'(Claude)3를 선보이면서 생성형 AI 주도권을 잡기 위한 경쟁이 다시 뜨거워지고 있다. 앤스로픽은 지난 한 해 동안 구글과 세일즈포스, 아마존 등에서 총 73억 달러(약 9조7309억 원)를 투자받고 '클로드3'를 내놨는데 오픈AI의 챗GPT-4를 능가한다고 도발했다.", isBookmarked: true), - .init(title: "SK C&C, 외부 전문가 대거 영입… “신성장 동력 강화”", postDate: "2023년2월13일", image: "https://imgnews.pstatic.net/image/366/2024/03/05/0000975131_001_20240305093504301.jpg?type=w647", content: "SK C&C는 국내외 신성장 동력 강화를 위해 인공지능(AI)·클라우드·디지털 팩토리·ESG(환경·사회·지배구조) 등 4대 성장 사업과 디지털 컨설팅 중심으로 외부 전문가를 대거 영입해 전진 배치했다고 5일 밝혔다.", isBookmarked: false), - .init(title: "NHN, 작년 영업익 555억원...전년비 42% ↑", postDate: "2023년2월13일", image: "https://cdnimage.dailian.co.kr/news/202402/news_1707866329_1327972_m_1.png", content: "2NHN은 연결기준 지난해 영업이익이 555억원으로 전년 대비 42.2% 증가했다고 14일 밝혔다.같은 기간 매출은 7.3% 증가한 2조2696억원으로 연간 최대치를 기록했다. 작년 4분기 매출은 5983억원으로 전년 동기 대비 6.7% 올랐다. 반면 영업손실은 78억원으로 적자전환했다. 커머스 부문의 장기 미회수채권 대손상각비 인식과 기술 부문의 기 인식 매출 차감 등 일회성 요인이 영향을 미쳤다.", isBookmarked: false), - ] - ) { - self.newsList = newsList + Log.network("network error", error.localizedDescription) + } + }, receiveValue: { [weak self] response in + self?.newsToViewModel(response) + print(response) + // 여기서 status 분기 처리 + }) } } + + +//public class NewsListViewModel: ObservableObject { +// // News = [NewsModel] +// @Published var newsList: [News] = [] +//// var currentPage = 0 +// +// init( +// newsList: [News] = [ +// +// .init(title: "네이버, 사우디 'LEAP 2024'서 AI·로봇 등 자사 기술력 뽐낸다", postDate: "2023년3월3일", image: "https://imgnews.pstatic.net/image/008/2024/03/05/0005007355_001_20240305100101016.jpg?type=w647", content: "네이버(NAVER)는 사우디아라비아에서 지난 4일부터 7일까지 열리는 글로벌 IT전시회 LEAP 2024에서 AI(인공지능), 클라우드, 로봇 등 자사 핵심 기술을 선보이고, 글로벌 업체들과 비즈니스 협력을 강화한다고 5일 밝혔다.", isBookmarked: false), +// .init(title: "앤스로픽 최신 AI 모델 '클로드3' 출시", postDate: "2023년3월13일", image: "https://imgnews.pstatic.net/image/014/2024/03/05/0005151141_001_20240305101610000.jpg?type=w647", content: "오픈AI의 대항마 앤스로픽이 생성형 인공지능(AI) 최신 모델 '클로드'(Claude)3를 선보이면서 생성형 AI 주도권을 잡기 위한 경쟁이 다시 뜨거워지고 있다. 앤스로픽은 지난 한 해 동안 구글과 세일즈포스, 아마존 등에서 총 73억 달러(약 9조7309억 원)를 투자받고 '클로드3'를 내놨는데 오픈AI의 챗GPT-4를 능가한다고 도발했다.", isBookmarked: true), +// .init(title: "SK C&C, 외부 전문가 대거 영입… “신성장 동력 강화”", postDate: "2023년2월13일", image: "https://imgnews.pstatic.net/image/366/2024/03/05/0000975131_001_20240305093504301.jpg?type=w647", content: "SK C&C는 국내외 신성장 동력 강화를 위해 인공지능(AI)·클라우드·디지털 팩토리·ESG(환경·사회·지배구조) 등 4대 성장 사업과 디지털 컨설팅 중심으로 외부 전문가를 대거 영입해 전진 배치했다고 5일 밝혔다.", isBookmarked: false), +// .init(title: "NHN, 작년 영업익 555억원...전년비 42% ↑", postDate: "2023년2월13일", image: "https://cdnimage.dailian.co.kr/news/202402/news_1707866329_1327972_m_1.png", content: "2NHN은 연결기준 지난해 영업이익이 555억원으로 전년 대비 42.2% 증가했다고 14일 밝혔다.같은 기간 매출은 7.3% 증가한 2조2696억원으로 연간 최대치를 기록했다. 작년 4분기 매출은 5983억원으로 전년 동기 대비 6.7% 올랐다. 반면 영업손실은 78억원으로 적자전환했다. 커머스 부문의 장기 미회수채권 대손상각비 인식과 기술 부문의 기 인식 매출 차감 등 일회성 요인이 영향을 미쳤다.", isBookmarked: false), +// ] +// ) { +// self.newsList = newsList +// } +//} From 73543434bbe07f1e90bd789eb5b1af77297ffa12 Mon Sep 17 00:00:00 2001 From: realhsb Date: Thu, 16 May 2024 00:35:46 +0900 Subject: [PATCH 10/30] =?UTF-8?q?chore:=20=EC=B9=B4=EB=93=9C=20=EB=89=B4?= =?UTF-8?q?=EC=8A=A4=20=EB=B0=8F=20=EB=89=B4=EC=8A=A4=20=EB=AA=A9=EB=A1=9D?= =?UTF-8?q?=20UI=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/News/NewsCard/NewsListView.swift | 81 ++++++++++++++----- .../Source/View/News/NewsCard/NewsView.swift | 56 ++++++------- 2 files changed, 88 insertions(+), 49 deletions(-) diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListView.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListView.swift index f5f1fe1f..b6285a5a 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListView.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListView.swift @@ -11,23 +11,17 @@ struct NewsListView: View { var newsListViewModel: NewsListViewModel @State var selectedIndex: Int = 0 + var body: some View { ZStack { Color.backgroundDark.ignoresSafeArea(.all) - NewsListContentView(newsList: newsListViewModel.newsList) - .padding(.leading, 20) - } - } - - private struct NewsListContentView: View { - var newsList: [News] - - fileprivate var body: some View { + + GeometryReader { proxy in ScrollView(.horizontal, showsIndicators: false) { LazyHStack { - ForEach(newsList , id: \.self) { news in + ForEach(newsListViewModel.newsList ?? []) { news in NewsView(news: news) .frame(width: proxy.size.width) @@ -35,7 +29,7 @@ struct NewsListView: View { effect .scaleEffect(phase.isIdentity ? 1 : 0.8) .blur(radius: phase.isIdentity ? 0 : 1) - .offset(x: offset(for: phase)) +// .offset(x: offset(for: phase)) } } } @@ -43,19 +37,64 @@ struct NewsListView: View { } .scrollTargetBehavior(.viewAligned) } +// NewsListContentView(newsList: $newsListViewModel.newsList) +// .padding(.leading, 20) } - - func offset (for phase: ScrollTransitionPhase) -> Double { - switch phase { - case .topLeading: - 700 - case .identity: - 0 - case .bottomTrailing: - -700 - } + .task { + newsListViewModel.getAllNewsData(page: 0, size: 10) + } + } + + func offset (for phase: ScrollTransitionPhase) -> Double { + switch phase { + case .topLeading: + 700 + case .identity: + 0 + case .bottomTrailing: + -700 } } + +// private struct NewsListContentView: View { +// @Binding var newsList: [News] +// +// +// +// fileprivate var body: some View { +// GeometryReader { proxy in +// ScrollView(.horizontal, showsIndicators: false) { +// LazyHStack { +// ForEach(newsList , id: \.self) { news in +// +// NewsView(news: news) +// .frame(width: proxy.size.width) +// .scrollTransition(.interactive, axis: .horizontal) { effect, phase in +// effect +// .scaleEffect(phase.isIdentity ? 1 : 0.8) +// .blur(radius: phase.isIdentity ? 0 : 1) +// .offset(x: offset(for: phase)) +// } +// } +// } +// .scrollTargetLayout() +// } +// .scrollTargetBehavior(.viewAligned) +// } + +// } + +// func offset (for phase: ScrollTransitionPhase) -> Double { +// switch phase { +// case .topLeading: +// 700 +// case .identity: +// 0 +// case .bottomTrailing: +// -700 +// } +// } +// } } #Preview { diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsView.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsView.swift index 668504ed..a1af2088 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsView.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsView.swift @@ -9,7 +9,7 @@ import SwiftUI struct NewsView: View { - @State var news: News + var news: News var isVisibleView: Bool = true var cardWidth: Double = 0.0 var cardHeight: Double = 0.0 @@ -17,7 +17,7 @@ struct NewsView: View { var body: some View { VStack(alignment: .center, spacing: 20) { HStack { - Text(news.title) + Text(news.title ?? "") .font(.pretendardBold32) .foregroundStyle(.basicBlack) .multilineTextAlignment(.leading) @@ -25,31 +25,31 @@ struct NewsView: View { } HStack { Spacer() - Text(news.postDate) + Text(news.postDate ?? "") .font(.pretendardBold12) .foregroundStyle(.gray05) } - AsyncImage(url: URL(string: news.image)) { phase in - switch phase { - case .success(let image): - image - .resizable() - .aspectRatio(contentMode: .fill) - .frame(width: 322, height: 160) - .clipShape(RoundedRectangle(cornerRadius: 8)) - .shadow(color: .black.opacity(0.25), radius: 2, x: 0, y: 0) - case .empty: - Image(systemName: "photo.circle.fill") - - case .failure(_): - Image(systemName: "photo.circle.fill") - @unknown default: - Text(""); - } - - } +// AsyncImage(url: URL(string: news.thumbnail ?? "")) { phase in +// switch phase { +// case .success(let image): +// image +// .resizable() +// .aspectRatio(contentMode: .fill) +// .frame(width: 322, height: 160) +// .clipShape(RoundedRectangle(cornerRadius: 8)) +// .shadow(color: .black.opacity(0.25), radius: 2, x: 0, y: 0) +// case .empty: +// Image(systemName: "photo.circle.fill") +// +// case .failure(_): +// Image(systemName: "photo.circle.fill") +// @unknown default: +// Text(""); +// } +// +// } if isVisibleView { @@ -90,9 +90,9 @@ struct NewsView: View { } } -#Preview(traits: .sizeThatFitsLayout) { - NewsView(news: .init(title: "NHN, 작년 영업익 555억원...전년비 42%", postDate: "2023년2월13일", image: "https://cdnimage.dailian.co.kr/news/202402/news_1707866329_1327972_m_1.png", content: "2NHN은 연결기준 지난해 영업이익이 555억원으로 전년 대비 42.2% 증가했다고 14일 밝혔다.같은 기간 매출은 7.3% 증가한 2조2696억원으로 연간 최대치를 기록했다. 작년 4분기 매출은 5983억원으로 전년 동기 대비 6.7% 올랐다. 반면 영업손실은 78억원으로 적자전환했다. 커머스 부문의 장기 미회수채권 대손상각비 인식과 기술 부문의 기 인식 매출 차감 등 일회성 요인이 영향을 미쳤다.", isBookmarked: false)) - .previewInterfaceOrientation(.landscapeLeft) - .previewLayout(.sizeThatFits) - .colorScheme(.dark) -} +//#Preview(traits: .sizeThatFitsLayout) { +// NewsView(news: .init(title: "NHN, 작년 영업익 555억원...전년비 42%", postDate: "2023년2월13일", image: "https://cdnimage.dailian.co.kr/news/202402/news_1707866329_1327972_m_1.png", content: "2NHN은 연결기준 지난해 영업이익이 555억원으로 전년 대비 42.2% 증가했다고 14일 밝혔다.같은 기간 매출은 7.3% 증가한 2조2696억원으로 연간 최대치를 기록했다. 작년 4분기 매출은 5983억원으로 전년 동기 대비 6.7% 올랐다. 반면 영업손실은 78억원으로 적자전환했다. 커머스 부문의 장기 미회수채권 대손상각비 인식과 기술 부문의 기 인식 매출 차감 등 일회성 요인이 영향을 미쳤다.", isBookmarked: false)) +// .previewInterfaceOrientation(.landscapeLeft) +// .previewLayout(.sizeThatFits) +// .colorScheme(.dark) +//} From 95f065a2b8c72478ff2ac611fe40bd35a2260e94 Mon Sep 17 00:00:00 2001 From: realhsb Date: Thu, 16 May 2024 00:36:40 +0900 Subject: [PATCH 11/30] =?UTF-8?q?chore:=20NewsListViewModel=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=ED=8D=BC=ED=8B=B0=20=EB=9E=98=ED=8D=BC=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RollTheDice/Source/View/MainTab/MainTabView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iOS/RollTheDice/RollTheDice/Source/View/MainTab/MainTabView.swift b/iOS/RollTheDice/RollTheDice/Source/View/MainTab/MainTabView.swift index e5b895ef..037c040a 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/MainTab/MainTabView.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/MainTab/MainTabView.swift @@ -10,7 +10,7 @@ import SwiftUI struct MainTabView: View { @EnvironmentObject private var pathModel: PathModel - @StateObject var newsListViewModel: NewsListViewModel + var newsListViewModel: NewsListViewModel @StateObject var mainTabViewModel = MainTabViewModel() From d820da8bac65a483765a485b0d56667837366199 Mon Sep 17 00:00:00 2001 From: realhsb Date: Thu, 16 May 2024 14:35:50 +0900 Subject: [PATCH 12/30] =?UTF-8?q?feat:=20=EC=A0=84=EC=B2=B4=20=EB=89=B4?= =?UTF-8?q?=EC=8A=A4=20=EC=A1=B0=ED=9A=8C=20=EB=AA=A8=EB=8D=B8=EA=B3=BC=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20=EB=89=B4=EC=8A=A4=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EB=AA=A8=EB=8D=B8=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RollTheDice.xcodeproj/project.pbxproj | 12 ++- .../Source/View/News/NewsCard/News.swift | 98 +++---------------- .../Source/View/News/NewsCard/NewsList.swift | 23 +++++ .../News/NewsCard/NewsListViewModel.swift | 8 +- 4 files changed, 47 insertions(+), 94 deletions(-) create mode 100644 iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsList.swift diff --git a/iOS/RollTheDice/RollTheDice.xcodeproj/project.pbxproj b/iOS/RollTheDice/RollTheDice.xcodeproj/project.pbxproj index f93c07b5..fadadd06 100644 --- a/iOS/RollTheDice/RollTheDice.xcodeproj/project.pbxproj +++ b/iOS/RollTheDice/RollTheDice.xcodeproj/project.pbxproj @@ -16,7 +16,7 @@ 6C3237A52B7C37D100B699AB /* BookmarkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C3237A42B7C37D100B699AB /* BookmarkView.swift */; }; 6C3237A72B7C37E500B699AB /* BookmarkListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C3237A62B7C37E500B699AB /* BookmarkListViewModel.swift */; }; 6C3237AA2B7C381500B699AB /* NewsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C3237A92B7C381500B699AB /* NewsView.swift */; }; - 6C3237AC2B7C382200B699AB /* News.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C3237AB2B7C382200B699AB /* News.swift */; }; + 6C3237AC2B7C382200B699AB /* NewsList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C3237AB2B7C382200B699AB /* NewsList.swift */; }; 6C3237AE2B7C382E00B699AB /* NewsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C3237AD2B7C382E00B699AB /* NewsViewModel.swift */; }; 6C3237B22B7C385000B699AB /* NewsListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C3237B12B7C385000B699AB /* NewsListViewModel.swift */; }; 6C3237B52B7C433D00B699AB /* ChatTypeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C3237B42B7C433D00B699AB /* ChatTypeView.swift */; }; @@ -39,6 +39,7 @@ 6C76513E2BF37F1E00196536 /* Extension+OSLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C76513D2BF37F1E00196536 /* Extension+OSLog.swift */; }; 6C7651402BF37F3400196536 /* Log.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C76513F2BF37F3400196536 /* Log.swift */; }; 6C7651422BF37F5C00196536 /* OSLog.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C7651412BF37F5C00196536 /* OSLog.framework */; }; + 6C7651462BF5B45A00196536 /* News.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C7651452BF5B45A00196536 /* News.swift */; }; 6C77048C2B722686001B17CB /* MainTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C77048B2B722686001B17CB /* MainTabView.swift */; }; 6C77048F2B7229B1001B17CB /* NewsListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C77048E2B7229B1001B17CB /* NewsListView.swift */; }; 6C7704992B722A20001B17CB /* MainTabViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C7704982B722A20001B17CB /* MainTabViewModel.swift */; }; @@ -97,7 +98,7 @@ 6C3237A42B7C37D100B699AB /* BookmarkView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkView.swift; sourceTree = ""; }; 6C3237A62B7C37E500B699AB /* BookmarkListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkListViewModel.swift; sourceTree = ""; }; 6C3237A92B7C381500B699AB /* NewsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsView.swift; sourceTree = ""; }; - 6C3237AB2B7C382200B699AB /* News.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = News.swift; sourceTree = ""; }; + 6C3237AB2B7C382200B699AB /* NewsList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsList.swift; sourceTree = ""; }; 6C3237AD2B7C382E00B699AB /* NewsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsViewModel.swift; sourceTree = ""; }; 6C3237B12B7C385000B699AB /* NewsListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsListViewModel.swift; sourceTree = ""; }; 6C3237B42B7C433D00B699AB /* ChatTypeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatTypeView.swift; sourceTree = ""; }; @@ -120,6 +121,7 @@ 6C76513D2BF37F1E00196536 /* Extension+OSLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Extension+OSLog.swift"; sourceTree = ""; }; 6C76513F2BF37F3400196536 /* Log.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Log.swift; sourceTree = ""; }; 6C7651412BF37F5C00196536 /* OSLog.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OSLog.framework; path = System/Library/Frameworks/OSLog.framework; sourceTree = SDKROOT; }; + 6C7651452BF5B45A00196536 /* News.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = News.swift; sourceTree = ""; }; 6C77048B2B722686001B17CB /* MainTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabView.swift; sourceTree = ""; }; 6C77048E2B7229B1001B17CB /* NewsListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsListView.swift; sourceTree = ""; }; 6C7704982B722A20001B17CB /* MainTabViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabViewModel.swift; sourceTree = ""; }; @@ -211,7 +213,8 @@ 6C3237B12B7C385000B699AB /* NewsListViewModel.swift */, 6C3237A92B7C381500B699AB /* NewsView.swift */, 6C3237AD2B7C382E00B699AB /* NewsViewModel.swift */, - 6C3237AB2B7C382200B699AB /* News.swift */, + 6C3237AB2B7C382200B699AB /* NewsList.swift */, + 6C7651452BF5B45A00196536 /* News.swift */, ); path = NewsCard; sourceTree = ""; @@ -713,7 +716,8 @@ 357666102BBD4BF6002C226A /* ReportListView.swift in Sources */, 6C41B8D42BDE6D2500274FA4 /* TypePieChartView.swift in Sources */, 6C3237A12B7C377600B699AB /* BookmarkViewModel.swift in Sources */, - 6C3237AC2B7C382200B699AB /* News.swift in Sources */, + 6C7651462BF5B45A00196536 /* News.swift in Sources */, + 6C3237AC2B7C382200B699AB /* NewsList.swift in Sources */, 6CE1030E2BD56A5200498AA4 /* TypeReportModel.swift in Sources */, 6C76513E2BF37F1E00196536 /* Extension+OSLog.swift in Sources */, 357FC6EA2BCE866B00AD8915 /* DetailCardNews.swift in Sources */, diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/News.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/News.swift index 2b7372cb..aadf9a00 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/News.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/News.swift @@ -1,93 +1,19 @@ -// API Test - -import Foundation - -// MARK: - NewsElement -// data는 옵셔널처리. JSONNull 사용 X -//struct NewsResponse: Codable { -// let newsResponse: [News]? -//} - -struct News: Codable, Identifiable { - let id = UUID().uuidString // 이건 앱자체에서 - let newsId: Int? - let title, content: String? - let thumbnail: String? - let postDate: String? - let isBookmarked: Bool? - - enum CodingKeys: String, CodingKey { - case newsId = "id" - case title, content, thumbnail, postDate, isBookmarked - } -} - -//typealias NewsResponse = [News] - - -// MARK: - Encode/decode helpers - -//class JSONNull: Codable, Hashable { // -// public static func == (lhs: JSONNull, rhs: JSONNull) -> Bool { -// return true -// } -// -// public var hashValue: Int { -// return 0 -// } -// -// public init() {} +// News.swift +// RollTheDice // -// public required init(from decoder: Decoder) throws { -// let container = try decoder.singleValueContainer() -// if !container.decodeNil() { -// throw DecodingError.typeMismatch(JSONNull.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for JSONNull")) -// } -// } +// Created by Subeen on 5/16/24. // -// public func encode(to encoder: Encoder) throws { -// var container = encoder.singleValueContainer() -// try container.encodeNil() -// } -//} - - - - - +import Foundation -// ======== -// -// NewsCard.swift -// RollTheDice -// -// Created by Subeen on 2/9/24. -// +struct News: Codable, Identifiable { + let id: Int? + let url: String? + let title: String? + let content: String? + let thumbnailURL: String? + let postDate: String? -//import Foundation -// -//struct News: Hashable { -// var id: UUID = UUID() -// var title: String -// var postDate: String -// var image: String -// var content: String -// var isBookmarked: Bool -// -// init( -// title: String = "", -// postDate: String = "", -// image: String = "", -// content: String = "", -// isBookmarked: Bool = false -// ) { -// self.title = title -// self.postDate = postDate -// self.image = image -// self.content = content -// self.isBookmarked = isBookmarked -// } -//} +} diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsList.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsList.swift new file mode 100644 index 00000000..991454f8 --- /dev/null +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsList.swift @@ -0,0 +1,23 @@ +// API Test + +import Foundation + +// MARK: - NewsElement +// data는 옵셔널처리. JSONNull 사용 X +//struct NewsResponse: Codable { +// let newsResponse: [News]? +//} + +struct NewsList: Codable, Identifiable { + let id = UUID().uuidString // 이건 앱자체에서 + let newsId: Int + let title, content: String? + let thumbnail: String? + let postDate: String? + let isBookmarked: Bool? + + enum CodingKeys: String, CodingKey { + case newsId = "id" + case title, content, thumbnail, postDate, isBookmarked + } +} diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListViewModel.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListViewModel.swift index e676eece..8e745a87 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListViewModel.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListViewModel.swift @@ -14,16 +14,16 @@ import SwiftUI // Macro -> iOS 17.0 이상부터. @Published 안 해도 됨. // 사용할 때 var 형식으로 해도 됨. @Observable class NewsListViewModel { - var newsList: [News]? + var newsList: [NewsList]? +// var selectedNewsId: Int? var currentPage = 0 var newsCancellable: AnyCancellable? - //TODO: Plugin Settings let provider = MoyaProvider(plugins: [MoyaLoggingPlugin()]) - func newsToViewModel(_ list: [News]) { + func newsToViewModel(_ list: [NewsList]) { self.newsList = list } } @@ -47,7 +47,7 @@ extension NewsListViewModel { ) .compactMap { $0.response?.data } .receive(on: DispatchQueue.main) - .decode(type: [News].self, decoder: JSONDecoder()) + .decode(type: [NewsList].self, decoder: JSONDecoder()) .sink(receiveCompletion: { result in switch result { // success From 6ef84ace616b7c500b65b01309f35b4d7416c9a6 Mon Sep 17 00:00:00 2001 From: realhsb Date: Thu, 16 May 2024 14:36:34 +0900 Subject: [PATCH 13/30] =?UTF-8?q?feat:=20=EC=83=81=EC=84=B8=20=EB=89=B4?= =?UTF-8?q?=EC=8A=A4=20=EC=A1=B0=ED=9A=8C=20service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Source/Domain/Service/NewsService.swift | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/iOS/RollTheDice/RollTheDice/Source/Domain/Service/NewsService.swift b/iOS/RollTheDice/RollTheDice/Source/Domain/Service/NewsService.swift index f3dfd367..926b96ef 100644 --- a/iOS/RollTheDice/RollTheDice/Source/Domain/Service/NewsService.swift +++ b/iOS/RollTheDice/RollTheDice/Source/Domain/Service/NewsService.swift @@ -9,7 +9,8 @@ import Foundation import Moya enum NewsService { - case news(page: Int, size: Int, accessToken: String) + case news(page: Int, size: Int, accessToken: String) /// 요약 뉴스 전체 조회 + case newsDetail(newsId: Int, accessToken: String) /// 요약 뉴스 상세 조회 } extension NewsService: BaseTargetType { @@ -21,6 +22,9 @@ extension NewsService: BaseTargetType { switch self { case .news: return ScoopAPINews.newsFetch + + case .newsDetail(let newsId, _): + return "\(ScoopAPINews.newsFetch)/\(newsId)" } } @@ -28,6 +32,8 @@ extension NewsService: BaseTargetType { switch self { case .news: return .get + case .newsDetail: + return .get } } @@ -39,7 +45,13 @@ extension NewsService: BaseTargetType { "size" : size, ] return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString) + + case .newsDetail(let newsId, _): + let parameters : [String : Any] = [:] + return .requestParameters(parameters: parameters, encoding: URLEncoding.default) } + + } var headers: [String : String]? { @@ -52,6 +64,14 @@ extension NewsService: BaseTargetType { "Authorization": "Bearer \(accessToken)", "X-Content-Type_Options" : "nosniff" ] + + + case .newsDetail(_, let accessTokenValue): + accessToken = accessTokenValue + return [ + "Authorization": "Bearer \(accessToken)", + "X-Content-Type_Options" : "nosniff" + ] } } } From 19d73f21186ef3847f0b13baf01169efea8208dc Mon Sep 17 00:00:00 2001 From: realhsb Date: Thu, 16 May 2024 14:37:38 +0900 Subject: [PATCH 14/30] =?UTF-8?q?feat:=20=EC=83=81=EC=84=B8=20=EB=89=B4?= =?UTF-8?q?=EC=8A=A4=20=EC=A1=B0=ED=9A=8C=20ViewModel=20=EB=B0=8F=20View?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 선택한 뉴스의 Id 연결 작업 --- .../View/News/NewsCard/NewsListView.swift | 1 + .../Source/View/News/NewsCard/NewsView.swift | 47 ++++++++------ .../View/News/NewsCard/NewsViewModel.swift | 65 ++++++++++++++++--- 3 files changed, 83 insertions(+), 30 deletions(-) diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListView.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListView.swift index b6285a5a..0f2cd649 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListView.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListView.swift @@ -10,6 +10,7 @@ import SwiftUI struct NewsListView: View { var newsListViewModel: NewsListViewModel + var newsId: Int? @State var selectedIndex: Int = 0 diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsView.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsView.swift index a1af2088..c7d9149c 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsView.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsView.swift @@ -9,7 +9,10 @@ import SwiftUI struct NewsView: View { - var news: News + @EnvironmentObject var pathModel : PathModel + +// var newsListViewModel: NewsListViewModel + var news: NewsList var isVisibleView: Bool = true var cardWidth: Double = 0.0 var cardHeight: Double = 0.0 @@ -31,30 +34,32 @@ struct NewsView: View { } -// AsyncImage(url: URL(string: news.thumbnail ?? "")) { phase in -// switch phase { -// case .success(let image): -// image -// .resizable() -// .aspectRatio(contentMode: .fill) -// .frame(width: 322, height: 160) -// .clipShape(RoundedRectangle(cornerRadius: 8)) -// .shadow(color: .black.opacity(0.25), radius: 2, x: 0, y: 0) -// case .empty: -// Image(systemName: "photo.circle.fill") -// -// case .failure(_): -// Image(systemName: "photo.circle.fill") -// @unknown default: -// Text(""); -// } -// -// } + AsyncImage(url: URL(string: news.thumbnail ?? "")) { phase in + switch phase { + case .success(let image): + image + .resizable() + .aspectRatio(contentMode: .fill) + .frame(width: 322, height: 160) + .clipShape(RoundedRectangle(cornerRadius: 8)) + .shadow(color: .black.opacity(0.25), radius: 2, x: 0, y: 0) + case .empty: + Image(systemName: "photo.circle.fill") + + case .failure(_): + Image(systemName: "photo.circle.fill") + @unknown default: + Text(""); + } + + } if isVisibleView { Button { - + let newsId:Int = news.newsId + print("!!!!!!!!!!! newsID : \(news.newsId)") + pathModel.paths.append(.detailNewsView(newsId: newsId)) } label: { Text("더보기") .font(.pretendardBold14) diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsViewModel.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsViewModel.swift index fd7433d6..ffc41fa3 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsViewModel.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsViewModel.swift @@ -5,12 +5,59 @@ //// Created by Subeen on 2/9/24. //// // -//import Foundation -// -//public class NewsViewModel: ObservableObject { -// @Published var news: News -// -// init(news: News) { -// self.news = news -// } -//} +import Foundation +import Combine +import CombineMoya +import Moya +import SwiftUI + +@Observable class NewsViewModel: ObservableObject { + + var newsDetail: News? + + var newsCancellable: AnyCancellable? + + let provider = MoyaProvider(plugins: [MoyaLoggingPlugin()]) + + func newsToViewModel(_ model: News) { + self.newsDetail = model + } + + +} + +extension NewsViewModel { + public func getNewsDetail(newsId: Int) { + let accessToken = "" + + if let cancellable = newsCancellable { + cancellable.cancel() + } + + newsCancellable = + provider.requestWithProgressPublisher( + .newsDetail( + newsId: newsId, + accessToken: accessToken + ) + ) + .compactMap { $0.response?.data } + .receive(on: DispatchQueue.main) + .decode(type: News.self, decoder: JSONDecoder()) + .sink(receiveCompletion: { result in + switch result { + // success + case .finished: + print("newsDetail 조회 성공") + break + case .failure(let error): +// print(error.localizedDescription) + Log.network("network error", error.localizedDescription) + } + }, receiveValue: { [weak self] response in + self?.newsToViewModel(response) + print(response) + // 여기서 status 분기 처리 + }) + } +} From a5a3e056145dfd8cb675c018587db3fa9169cfd7 Mon Sep 17 00:00:00 2001 From: realhsb Date: Thu, 16 May 2024 14:37:53 +0900 Subject: [PATCH 15/30] =?UTF-8?q?chore:=20DetailCardNews=20=EB=94=94?= =?UTF-8?q?=EC=9E=90=EC=9D=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DetailNewsCard/DetailCardNews.swift | 168 +++++++++++------- 1 file changed, 101 insertions(+), 67 deletions(-) diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/DetailNewsCard/DetailCardNews.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/DetailNewsCard/DetailCardNews.swift index ccff4196..1061903e 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/DetailNewsCard/DetailCardNews.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/DetailNewsCard/DetailCardNews.swift @@ -9,94 +9,128 @@ import Foundation import SwiftUI struct DetailCardNews: View { + @EnvironmentObject var pathModel: PathModel + + var newsViewModel = NewsViewModel() + var newsId: Int var body: some View { ZStack{ Color.basicBlack.ignoresSafeArea(.all) - - ZStack { - Rectangle() - .foregroundColor(.basicWhite) - .frame(width: 970, height: 495) - .cornerRadius(20) - .padding(EdgeInsets(top: 170, leading: 112, bottom: 170, trailing: 112)) + VStack { + CustomNavigationBar(isDisplayLeadingBtn: true, leadingItems: [(Image(.chevronLeft), {pathModel.paths.popLast()})]) - HStack(spacing: 30) { - Image("CardSample") - .resizable() - .frame(width: 370, height: 495) - .aspectRatio(contentMode: .fill) - .cornerRadius(15) - .clipped() - .padding(.leading,-58) - + ZStack { + Rectangle() + .foregroundColor(.basicWhite) + .cornerRadius(20) - VStack{ - - Rectangle() - .foregroundColor(.clear) - .frame(width: 534, height: 1) - .background(.black) - .padding(.bottom, 24) + HStack(spacing: 0) { - Rectangle() - .foregroundColor(.clear) - .frame(width: 492, height: 52) - .overlay( - Rectangle() - .inset(by: 0.5) - .stroke(.gray06, lineWidth: 1) - ) - - HStack(alignment: .top){ + AsyncImage(url: URL(string: "https://imgnews.pstatic.net/image/018/2024/05/15/0005739785_001_20240515190608817.jpg?type=w647")) { phase in + switch phase { + case .success(let image): + image + .resizable() + .aspectRatio(contentMode: .fill) + .frame(maxWidth: 300) + .cornerRadius(15) + .clipped() + .shadow(color: /*@START_MENU_TOKEN@*/.black/*@END_MENU_TOKEN@*/.opacity(0.4), radius: 4) + case .empty: + Image(systemName: "photo.circle.fill") - Text("기사 제목 보여주기") - .font( - Font.custom("Pretendard", size: 32) - .weight(.bold) - ) - .foregroundColor(.basicBlack) - .frame(width: 318, alignment: .topLeading) - .padding(.leading, -140) - .padding(.top, -53) + case .failure(_): + Image(systemName: "photo.circle.fill") + @unknown default: + Text(""); + } } +// Image("CardSample") +// .resizable() +// .aspectRatio(contentMode: .fill) +// .frame(maxWidth: 300) +// .cornerRadius(15) +// .clipped() +// - Text("(서울=연합뉴스) 오규진 기자 = 삼성전자는 플래그십 스마트폰 갤럭시 S24 시리즈에 500㎖ 플라스틱 물병 약 5천만 개와 맞먹는 수준으로 재활용 플라스틱을 활용하고 있다고 16일 밝혔다.삼성전자 뉴스룸에 따르면 회사는 오는 22일 지구의 날을 맞아 갤럭시 S24 시리즈에 사용될 재활용 플라스틱이 올해에만 약 100t에 이를 것으로 예상했다.이는 500㎖ 페트병 약 1천만 개를 만드는 데 사용되는 플라스틱 무게와 동일하다.삼성전자는 폐어망과 폐페트병 등을 갤럭시 스마트폰에 사용할 수 있는 고성능 플라스틱 소재로 개발해 사용하고 있다.특히 갤럭시 S24 시리즈에는 신발 제조 공정 중 발생한 열가소성 폴리우레탄(TPU) 부산물을 재활용한 플라스틱 소재가 새롭게 적용됐다.재활용 알루미늄 소재도 같은 기간 330㎖ 알루미늄 음료 캔 약 900만 개에 해당하는 약 110t이 활용될 것으로 회사는 전망했다.제품 패키지 박스도 100% 재활용 종이 소재를 활용하고 있는데, 올해 말까지 A4 용지 약 5억5천200만 장의 무게와 동일한 약 2천760t이 활용될 것으로 예측됐다.이 종이를 쌓으면 아랍에미리트(UAE) 두바이에 있는 세계에서 가장 높은 건축물인 '부르즈 할리파'를 71개 만든 것과 동일하다고 삼성전자는 소개했다.갤럭시 S24 시리즈는 갤럭시 제품 중 처음으로 재활용 코발트, 희토류 등 재활용 광물을 주요 부품에 적용하기도 했다.") - .font( - Font.custom("Pretendard", size: 15) - .weight(.regular) - ) - .foregroundColor(.basicBlack) - .frame(width: 500, alignment: .topLeading) - .padding(.top, 30) - - Rectangle() - .foregroundColor(.clear) - .frame(width: 534, height: 1) - .background(.black) - .padding(.top, 24) - .padding(.bottom, 10) - + VStack(alignment: .center) { + + Rectangle() + .foregroundStyle(.black) + .frame(height: 1) + + Text(newsViewModel.newsDetail?.title ?? "네트워킹 오류") + .font(.pretendardBold32) + .foregroundColor(.basicBlack) + .padding(.vertical, 10) + .padding(.horizontal, 16) + .background(Rectangle().stroke(Color.gray06, lineWidth: 1)) + + HStack { + Spacer() + Text("발행일자 : \(newsViewModel.newsDetail?.postDate ?? "")") + .font(.pretendardRegular14) + .foregroundStyle(.gray05) + + } + .padding(.top, 10) + .padding(.horizontal, 20) + + ScrollView { + Text(newsViewModel.newsDetail?.content ?? "네트워킹 오류") + .font( + .pretendardRegular16 + ) + .multilineTextAlignment(.leading) + .foregroundColor(.gray06) + .frame(alignment: .topLeading) + .padding(.top, 10) + .padding(.horizontal, 20) + } + + HStack { + Spacer() + Button { + + } label: { + Text("원문 보러 가기 ➡️") + .font(.pretendardBold12) + .foregroundStyle(.gray01) + .padding(10) + .background(.primary01) + .clipShape(RoundedRectangle(cornerRadius: 14)) + } + .padding(.trailing, 10) + .padding(.bottom, 10) + } + + Rectangle() + .foregroundColor(.clear) + .frame(height: 1) + .background(.black) + + } + .padding(.vertical, 20) + .padding(.horizontal, 20) } - - - - } + .padding(.vertical, 120) + .padding(.horizontal, 110) } - - } - - + .navigationBarBackButtonHidden() + .task { + newsViewModel.getNewsDetail(newsId: self.newsId) + } } } #Preview { - DetailCardNews() + DetailCardNews(newsId: 260) } From b5feb4b8a1b383c19b062201574ccdc9850a4b49 Mon Sep 17 00:00:00 2001 From: realhsb Date: Thu, 16 May 2024 14:38:34 +0900 Subject: [PATCH 16/30] =?UTF-8?q?feat:=20=EC=83=81=EC=84=B8=20=EB=89=B4?= =?UTF-8?q?=EC=8A=A4=20=EC=A1=B0=ED=9A=8C=20=EB=82=B4=EB=B9=84=EA=B2=8C?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- iOS/RollTheDice/RollTheDice/RollTheDiceApp.swift | 4 ++-- iOS/RollTheDice/RollTheDice/Source/Model/Path/PathType.swift | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iOS/RollTheDice/RollTheDice/RollTheDiceApp.swift b/iOS/RollTheDice/RollTheDice/RollTheDiceApp.swift index 5908c828..34caa1ed 100644 --- a/iOS/RollTheDice/RollTheDice/RollTheDiceApp.swift +++ b/iOS/RollTheDice/RollTheDice/RollTheDiceApp.swift @@ -33,8 +33,8 @@ struct RollTheDiceApp: App { case .chatView(isAiMode: false): Text("user") .navigationBarBackButtonHidden() - case .detailNewsView: - DetailCardNews() + case .detailNewsView(let newsId): + DetailCardNews(newsId: newsId) case .typeReportView: TypeReportView() case .dailyReportView: diff --git a/iOS/RollTheDice/RollTheDice/Source/Model/Path/PathType.swift b/iOS/RollTheDice/RollTheDice/Source/Model/Path/PathType.swift index 2ec6fb10..af5d48c7 100644 --- a/iOS/RollTheDice/RollTheDice/Source/Model/Path/PathType.swift +++ b/iOS/RollTheDice/RollTheDice/Source/Model/Path/PathType.swift @@ -9,7 +9,7 @@ import Foundation enum PathType: Hashable { case chatView(isAiMode: Bool) - case detailNewsView // 뉴스 자세히 보기 + case detailNewsView(newsId: Int) // 뉴스 자세히 보기 case typeReportView // 분야별 뉴스 통계 case dailyReportView // 요일별 뉴스 관람 개수 통계 From c36ef892e1f862644345cbf07ee881870f391e73 Mon Sep 17 00:00:00 2001 From: realhsb Date: Thu, 16 May 2024 14:38:56 +0900 Subject: [PATCH 17/30] =?UTF-8?q?chore:=20Pretendard=20Regular=2016=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 --- iOS/RollTheDice/RollTheDice/Resources/Font/Font.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/iOS/RollTheDice/RollTheDice/Resources/Font/Font.swift b/iOS/RollTheDice/RollTheDice/Resources/Font/Font.swift index b1c49130..3a8fd2ec 100644 --- a/iOS/RollTheDice/RollTheDice/Resources/Font/Font.swift +++ b/iOS/RollTheDice/RollTheDice/Resources/Font/Font.swift @@ -19,6 +19,7 @@ extension Font { // Regular static let pretendardRegular20: Font = .custom("Pretendard-Regular", size: 20) + static let pretendardRegular16: Font = .custom("Pretendard-Regular", size: 16) static let pretendardRegular14: Font = .custom("Pretendard-Regular", size: 14) } From 446a778f72e6fbe795c3dfd0c96cd7ca5616aa8d Mon Sep 17 00:00:00 2001 From: realhsb Date: Thu, 16 May 2024 15:17:34 +0900 Subject: [PATCH 18/30] =?UTF-8?q?chore:=20=EC=83=81=EC=84=B8=20=EB=89=B4?= =?UTF-8?q?=EC=8A=A4=20=EB=AA=A8=EB=8D=B8=20=EB=B0=8F=20=EB=B7=B0=EB=AA=A8?= =?UTF-8?q?=EB=8D=B8=20=EC=9D=B4=EB=A6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit News -> DetailNews --- .../RollTheDice.xcodeproj/project.pbxproj | 16 ++++++++-------- .../NewsCard/{News.swift => DetailNews.swift} | 2 +- .../NewsCard/DetailNewsCard/DetailCardNews.swift | 2 +- ...ViewModel.swift => DetailNewsViewModel.swift} | 12 ++++++------ 4 files changed, 16 insertions(+), 16 deletions(-) rename iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/{News.swift => DetailNews.swift} (84%) rename iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/{NewsViewModel.swift => DetailNewsViewModel.swift} (74%) diff --git a/iOS/RollTheDice/RollTheDice.xcodeproj/project.pbxproj b/iOS/RollTheDice/RollTheDice.xcodeproj/project.pbxproj index fadadd06..06696dae 100644 --- a/iOS/RollTheDice/RollTheDice.xcodeproj/project.pbxproj +++ b/iOS/RollTheDice/RollTheDice.xcodeproj/project.pbxproj @@ -17,7 +17,7 @@ 6C3237A72B7C37E500B699AB /* BookmarkListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C3237A62B7C37E500B699AB /* BookmarkListViewModel.swift */; }; 6C3237AA2B7C381500B699AB /* NewsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C3237A92B7C381500B699AB /* NewsView.swift */; }; 6C3237AC2B7C382200B699AB /* NewsList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C3237AB2B7C382200B699AB /* NewsList.swift */; }; - 6C3237AE2B7C382E00B699AB /* NewsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C3237AD2B7C382E00B699AB /* NewsViewModel.swift */; }; + 6C3237AE2B7C382E00B699AB /* DetailNewsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C3237AD2B7C382E00B699AB /* DetailNewsViewModel.swift */; }; 6C3237B22B7C385000B699AB /* NewsListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C3237B12B7C385000B699AB /* NewsListViewModel.swift */; }; 6C3237B52B7C433D00B699AB /* ChatTypeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C3237B42B7C433D00B699AB /* ChatTypeView.swift */; }; 6C3237B72B7C434600B699AB /* ChatType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C3237B62B7C434600B699AB /* ChatType.swift */; }; @@ -39,7 +39,7 @@ 6C76513E2BF37F1E00196536 /* Extension+OSLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C76513D2BF37F1E00196536 /* Extension+OSLog.swift */; }; 6C7651402BF37F3400196536 /* Log.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C76513F2BF37F3400196536 /* Log.swift */; }; 6C7651422BF37F5C00196536 /* OSLog.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C7651412BF37F5C00196536 /* OSLog.framework */; }; - 6C7651462BF5B45A00196536 /* News.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C7651452BF5B45A00196536 /* News.swift */; }; + 6C7651462BF5B45A00196536 /* DetailNews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C7651452BF5B45A00196536 /* DetailNews.swift */; }; 6C77048C2B722686001B17CB /* MainTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C77048B2B722686001B17CB /* MainTabView.swift */; }; 6C77048F2B7229B1001B17CB /* NewsListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C77048E2B7229B1001B17CB /* NewsListView.swift */; }; 6C7704992B722A20001B17CB /* MainTabViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C7704982B722A20001B17CB /* MainTabViewModel.swift */; }; @@ -99,7 +99,7 @@ 6C3237A62B7C37E500B699AB /* BookmarkListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkListViewModel.swift; sourceTree = ""; }; 6C3237A92B7C381500B699AB /* NewsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsView.swift; sourceTree = ""; }; 6C3237AB2B7C382200B699AB /* NewsList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsList.swift; sourceTree = ""; }; - 6C3237AD2B7C382E00B699AB /* NewsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsViewModel.swift; sourceTree = ""; }; + 6C3237AD2B7C382E00B699AB /* DetailNewsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailNewsViewModel.swift; sourceTree = ""; }; 6C3237B12B7C385000B699AB /* NewsListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsListViewModel.swift; sourceTree = ""; }; 6C3237B42B7C433D00B699AB /* ChatTypeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatTypeView.swift; sourceTree = ""; }; 6C3237B62B7C434600B699AB /* ChatType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatType.swift; sourceTree = ""; }; @@ -121,7 +121,7 @@ 6C76513D2BF37F1E00196536 /* Extension+OSLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Extension+OSLog.swift"; sourceTree = ""; }; 6C76513F2BF37F3400196536 /* Log.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Log.swift; sourceTree = ""; }; 6C7651412BF37F5C00196536 /* OSLog.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OSLog.framework; path = System/Library/Frameworks/OSLog.framework; sourceTree = SDKROOT; }; - 6C7651452BF5B45A00196536 /* News.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = News.swift; sourceTree = ""; }; + 6C7651452BF5B45A00196536 /* DetailNews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailNews.swift; sourceTree = ""; }; 6C77048B2B722686001B17CB /* MainTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabView.swift; sourceTree = ""; }; 6C77048E2B7229B1001B17CB /* NewsListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsListView.swift; sourceTree = ""; }; 6C7704982B722A20001B17CB /* MainTabViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabViewModel.swift; sourceTree = ""; }; @@ -212,9 +212,9 @@ 6C77048E2B7229B1001B17CB /* NewsListView.swift */, 6C3237B12B7C385000B699AB /* NewsListViewModel.swift */, 6C3237A92B7C381500B699AB /* NewsView.swift */, - 6C3237AD2B7C382E00B699AB /* NewsViewModel.swift */, + 6C3237AD2B7C382E00B699AB /* DetailNewsViewModel.swift */, 6C3237AB2B7C382200B699AB /* NewsList.swift */, - 6C7651452BF5B45A00196536 /* News.swift */, + 6C7651452BF5B45A00196536 /* DetailNews.swift */, ); path = NewsCard; sourceTree = ""; @@ -716,14 +716,14 @@ 357666102BBD4BF6002C226A /* ReportListView.swift in Sources */, 6C41B8D42BDE6D2500274FA4 /* TypePieChartView.swift in Sources */, 6C3237A12B7C377600B699AB /* BookmarkViewModel.swift in Sources */, - 6C7651462BF5B45A00196536 /* News.swift in Sources */, + 6C7651462BF5B45A00196536 /* DetailNews.swift in Sources */, 6C3237AC2B7C382200B699AB /* NewsList.swift in Sources */, 6CE1030E2BD56A5200498AA4 /* TypeReportModel.swift in Sources */, 6C76513E2BF37F1E00196536 /* Extension+OSLog.swift in Sources */, 357FC6EA2BCE866B00AD8915 /* DetailCardNews.swift in Sources */, 6CC4DDC92B5574670080E7E8 /* ContentView.swift in Sources */, 6C3237A52B7C37D100B699AB /* BookmarkView.swift in Sources */, - 6C3237AE2B7C382E00B699AB /* NewsViewModel.swift in Sources */, + 6C3237AE2B7C382E00B699AB /* DetailNewsViewModel.swift in Sources */, 6C77048F2B7229B1001B17CB /* NewsListView.swift in Sources */, 357666132BBD54AA002C226A /* SplashView.swift in Sources */, 6C4F7BAD2BDE510900ED01DA /* DailyReportViewModel.swift in Sources */, diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/News.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/DetailNews.swift similarity index 84% rename from iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/News.swift rename to iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/DetailNews.swift index aadf9a00..042322a8 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/News.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/DetailNews.swift @@ -8,7 +8,7 @@ import Foundation -struct News: Codable, Identifiable { +struct DetailNews: Codable, Identifiable { let id: Int? let url: String? let title: String? diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/DetailNewsCard/DetailCardNews.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/DetailNewsCard/DetailCardNews.swift index 1061903e..1639b4ad 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/DetailNewsCard/DetailCardNews.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/DetailNewsCard/DetailCardNews.swift @@ -11,7 +11,7 @@ import SwiftUI struct DetailCardNews: View { @EnvironmentObject var pathModel: PathModel - var newsViewModel = NewsViewModel() + var newsViewModel = DetailNewsViewModel() var newsId: Int var body: some View { diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsViewModel.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/DetailNewsViewModel.swift similarity index 74% rename from iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsViewModel.swift rename to iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/DetailNewsViewModel.swift index ffc41fa3..427140cd 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsViewModel.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/DetailNewsViewModel.swift @@ -11,24 +11,24 @@ import CombineMoya import Moya import SwiftUI -@Observable class NewsViewModel: ObservableObject { +@Observable class DetailNewsViewModel: ObservableObject { - var newsDetail: News? + var newsDetail: DetailNews? var newsCancellable: AnyCancellable? let provider = MoyaProvider(plugins: [MoyaLoggingPlugin()]) - func newsToViewModel(_ model: News) { + func newsToViewModel(_ model: DetailNews) { self.newsDetail = model } } -extension NewsViewModel { +extension DetailNewsViewModel { public func getNewsDetail(newsId: Int) { - let accessToken = "" + let accessToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJBY2Nlc3NUb2tlbiIsImV4cCI6MTcxNjMwMzYwMiwiZW1haWwiOiJjaGVueWVvbmp5QGRhdW0ubmV0In0.UmW0VdDtxsI7L2WSBrpUaAof5zikQ8JWdp_DIsXIlFwPaFBRUrfhgJ0aYljVcosOkQrk4b2NwOhme5lR13aEgw" if let cancellable = newsCancellable { cancellable.cancel() @@ -43,7 +43,7 @@ extension NewsViewModel { ) .compactMap { $0.response?.data } .receive(on: DispatchQueue.main) - .decode(type: News.self, decoder: JSONDecoder()) + .decode(type: DetailNews.self, decoder: JSONDecoder()) .sink(receiveCompletion: { result in switch result { // success From 515aacf75174895ac42e3b4aabe5596303ab1c43 Mon Sep 17 00:00:00 2001 From: realhsb Date: Thu, 16 May 2024 15:21:53 +0900 Subject: [PATCH 19/30] =?UTF-8?q?chore:=20=EB=89=B4=EC=8A=A4=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20UI=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/News/NewsCard/NewsListView.swift | 87 ++++++------------ .../Source/View/News/NewsCard/NewsView.swift | 88 +++++++++++++------ 2 files changed, 88 insertions(+), 87 deletions(-) diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListView.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListView.swift index 0f2cd649..be009789 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListView.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListView.swift @@ -18,11 +18,23 @@ struct NewsListView: View { ZStack { Color.backgroundDark.ignoresSafeArea(.all) - + NewsListContentView(newsList: newsListViewModel.newsList ?? []) + } + .task { + newsListViewModel.getAllNewsData(page: 0, size: 10) + } + } + + private struct NewsListContentView: View { + var newsList: [NewsList] + + + + fileprivate var body: some View { GeometryReader { proxy in ScrollView(.horizontal, showsIndicators: false) { LazyHStack { - ForEach(newsListViewModel.newsList ?? []) { news in + ForEach(newsList) { news in NewsView(news: news) .frame(width: proxy.size.width) @@ -30,7 +42,8 @@ struct NewsListView: View { effect .scaleEffect(phase.isIdentity ? 1 : 0.8) .blur(radius: phase.isIdentity ? 0 : 1) -// .offset(x: offset(for: phase)) + .grayscale(phase.isIdentity ? 0 : 0.7) + .offset(x: offset(for: phase, width: proxy.size.width)) } } } @@ -38,64 +51,22 @@ struct NewsListView: View { } .scrollTargetBehavior(.viewAligned) } -// NewsListContentView(newsList: $newsListViewModel.newsList) -// .padding(.leading, 20) - } - .task { - newsListViewModel.getAllNewsData(page: 0, size: 10) + } - } - - func offset (for phase: ScrollTransitionPhase) -> Double { - switch phase { - case .topLeading: - 700 - case .identity: - 0 - case .bottomTrailing: - -700 + + func offset (for phase: ScrollTransitionPhase, width: CGFloat) -> Double { + var calculatedSize: CGFloat + switch phase { + case .topLeading: + calculatedSize = width / 1.5 + case .identity: + calculatedSize = 0 + case .bottomTrailing: + calculatedSize = -(width / 1.5) + } + return calculatedSize } } - -// private struct NewsListContentView: View { -// @Binding var newsList: [News] -// -// -// -// fileprivate var body: some View { -// GeometryReader { proxy in -// ScrollView(.horizontal, showsIndicators: false) { -// LazyHStack { -// ForEach(newsList , id: \.self) { news in -// -// NewsView(news: news) -// .frame(width: proxy.size.width) -// .scrollTransition(.interactive, axis: .horizontal) { effect, phase in -// effect -// .scaleEffect(phase.isIdentity ? 1 : 0.8) -// .blur(radius: phase.isIdentity ? 0 : 1) -// .offset(x: offset(for: phase)) -// } -// } -// } -// .scrollTargetLayout() -// } -// .scrollTargetBehavior(.viewAligned) -// } - -// } - -// func offset (for phase: ScrollTransitionPhase) -> Double { -// switch phase { -// case .topLeading: -// 700 -// case .identity: -// 0 -// case .bottomTrailing: -// -700 -// } -// } -// } } #Preview { diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsView.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsView.swift index c7d9149c..3944c542 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsView.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsView.swift @@ -13,9 +13,9 @@ struct NewsView: View { // var newsListViewModel: NewsListViewModel var news: NewsList - var isVisibleView: Bool = true - var cardWidth: Double = 0.0 - var cardHeight: Double = 0.0 +// var isVisibleView: Bool = true +// var cardWidth: Double = 0.0 +// var cardHeight: Double = 0.0 var body: some View { VStack(alignment: .center, spacing: 20) { @@ -55,46 +55,76 @@ struct NewsView: View { } - if isVisibleView { - Button { - let newsId:Int = news.newsId - print("!!!!!!!!!!! newsID : \(news.newsId)") - pathModel.paths.append(.detailNewsView(newsId: newsId)) - } label: { - Text("더보기") - .font(.pretendardBold14) - .foregroundStyle(.gray01) - .padding(.horizontal, 30) - .padding(.vertical, 13) - .background(.primary01) - .clipShape( - RoundedRectangle(cornerRadius: 16) - ) - .shadow(color: .basicBlack.opacity(0.25), radius: 2, x: 0, y: 0) - - } +// if isVisibleView { +// Button { +// let newsId:Int = news.newsId +// print("!!!!!!!!!!! newsID : \(news.newsId)") +// pathModel.paths.append(.detailNewsView(newsId: newsId)) +// } label: { +// Text("더보기") +// .font(.pretendardBold14) +// .foregroundStyle(.gray01) +// .padding(.horizontal, 30) +// .padding(.vertical, 13) +// .background(.primary01) +// .clipShape( +// RoundedRectangle(cornerRadius: 16) +// ) +// .shadow(color: .basicBlack.opacity(0.25), radius: 2, x: 0, y: 0) +// +// } +// } + Button { + let newsId:Int = news.newsId + print("!!!!!!!!!!! newsID : \(news.newsId)") + pathModel.paths.append(.detailNewsView(newsId: newsId)) + } label: { + Text("더보기") + .font(.pretendardBold14) + .foregroundStyle(.gray01) + .padding(.horizontal, 30) + .padding(.vertical, 13) + .background(.primary01) + .clipShape( + RoundedRectangle(cornerRadius: 16) + ) + .shadow(color: .basicBlack.opacity(0.25), radius: 2, x: 0, y: 0) + } } .padding(.horizontal, 24) .padding(.bottom, 25) .padding(.top, 50) - .frame(width: 370) + .frame(width: 380) .background( - LinearGradient(colors: isVisibleView ? [.basicWhite, .primaryLight01] : [.basicWhite], startPoint: .top, endPoint: .bottom) +// LinearGradient(colors: isVisibleView ? [.basicWhite, .primaryLight01] : [.basicWhite], startPoint: .top, endPoint: .bottom) + LinearGradient(colors: [.basicWhite, .primaryLight01], startPoint: .top, endPoint: .bottom) ) - .clipShape(RoundedRectangle(cornerRadius: 32)) + .clipShape(RoundedRectangle(cornerRadius: 12)) .overlay { - // TODO : 북마크 버튼 위치 수정하기 - Button { - - } label: { - Image(.bookmarkfill) + // TODO : 북마크 버튼 위치 수정하기 + VStack { + HStack { + Spacer() + Button { + + } label: { + Image(.bookmarkfill) + .shadow(color: .gray06, radius: 2) + } + .offset(CGSize(width: -20, height: -10)) + } + Spacer() } } } } +#Preview { + NewsView(news: .init(newsId: 1, title: "1분기 선방한 dddddddd韓게임사들…엔씨만 울었다", content: "내용내용ㄴㅇㅇㅇ", thumbnail: "", postDate: "2222-22-22", isBookmarked: true)) + .environmentObject(PathModel()) +} //#Preview(traits: .sizeThatFitsLayout) { // NewsView(news: .init(title: "NHN, 작년 영업익 555억원...전년비 42%", postDate: "2023년2월13일", image: "https://cdnimage.dailian.co.kr/news/202402/news_1707866329_1327972_m_1.png", content: "2NHN은 연결기준 지난해 영업이익이 555억원으로 전년 대비 42.2% 증가했다고 14일 밝혔다.같은 기간 매출은 7.3% 증가한 2조2696억원으로 연간 최대치를 기록했다. 작년 4분기 매출은 5983억원으로 전년 동기 대비 6.7% 올랐다. 반면 영업손실은 78억원으로 적자전환했다. 커머스 부문의 장기 미회수채권 대손상각비 인식과 기술 부문의 기 인식 매출 차감 등 일회성 요인이 영향을 미쳤다.", isBookmarked: false)) // .previewInterfaceOrientation(.landscapeLeft) From 46549d31ae5d9a7c71f3bdcd8aca27937f7091f3 Mon Sep 17 00:00:00 2001 From: realhsb Date: Thu, 16 May 2024 17:01:50 +0900 Subject: [PATCH 20/30] =?UTF-8?q?feat:=20ui=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RollTheDice/RollTheDiceApp.swift | 62 ++++- .../Authentication/AuthenticatedView.swift | 125 ++++++++- .../AuthenticationViewModel.swift | 11 +- .../DetailNewsCard/DetailCardNews.swift | 2 +- .../News/NewsCard/NewsListViewModel.swift | 2 +- .../Source/View/News/NewsCard/NewsView.swift | 15 +- .../Source/View/SignIn/SignInView.swift | 258 +++++++++--------- .../Source/View/SignUp/SignUpFinishView.swift | 19 +- .../View/SignUp/SignUpQuestionView.swift | 135 ++++----- .../Source/View/SignUp/SignUpViewModel.swift | 18 +- 10 files changed, 426 insertions(+), 221 deletions(-) diff --git a/iOS/RollTheDice/RollTheDice/RollTheDiceApp.swift b/iOS/RollTheDice/RollTheDice/RollTheDiceApp.swift index 34caa1ed..8c848a75 100644 --- a/iOS/RollTheDice/RollTheDice/RollTheDiceApp.swift +++ b/iOS/RollTheDice/RollTheDice/RollTheDiceApp.swift @@ -13,13 +13,24 @@ struct RollTheDiceApp: App { @StateObject var appState = AppState() @StateObject private var pathModel = PathModel() + var authViewModel = AuthenticationViewModel() + var signUpViewModel = SignUpViewModel() + var newsListViewModel = NewsListViewModel() @StateObject var bookmarkListViewModel = BookmarkListViewModel() var body: some Scene { WindowGroup { - if appState.hasLogin { + switch authViewModel.authenticationState { + case .unauthenticated: + AuthenticatedView() + .environmentObject(authViewModel) + case .authenticated: + SignUpQuestionView() + .environmentObject(authViewModel) + .environmentObject(signUpViewModel) + case .completedSignUp: NavigationStack(path: $pathModel.paths) { MainTabView(newsListViewModel: newsListViewModel) .navigationDestination(for: PathType.self, destination: { pathType in @@ -50,18 +61,57 @@ struct RollTheDiceApp: App { } .environmentObject(pathModel) - - - } else { - SignUpView() + .environmentObject(authViewModel) } + + +// if appState.hasLogin { +// NavigationStack(path: $pathModel.paths) { +// MainTabView(newsListViewModel: newsListViewModel) +// .navigationDestination(for: PathType.self, destination: { pathType in +// +// // 각 뷰마다 .navigationBarBackButtonHidden() 설정하기! +// switch pathType { +// case .chatView(isAiMode: true) : +// GPTChatView() +// .navigationBarBackButtonHidden() +// +// case .chatView(isAiMode: false): +// Text("user") +// .navigationBarBackButtonHidden() +// case .detailNewsView(let newsId): +// DetailCardNews(newsId: newsId) +// case .typeReportView: +// TypeReportView() +// case .dailyReportView: +// DailyReportView() +// case .bookmarkView: +// BookmarkListView(bookmarkListViewModel: bookmarkListViewModel) +// case .mypageView: +// Text("mypageView") +// case .debateSummaryView: +// DebateSummaryView() +// } +// }) +// } +// +// .environmentObject(pathModel) +// +// +// } else { +// AuthenticatedView() +// .environmentObject(pathModel) +// } } } } + + /// 로그인 상태 관리 class AppState: ObservableObject { - @AppStorage("hasLogin") var hasLogin = true + @AppStorage("hasLogin") var hasLogin = false + } diff --git a/iOS/RollTheDice/RollTheDice/Source/View/Authentication/AuthenticatedView.swift b/iOS/RollTheDice/RollTheDice/Source/View/Authentication/AuthenticatedView.swift index d91e1523..2acdef2b 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/Authentication/AuthenticatedView.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/Authentication/AuthenticatedView.swift @@ -8,9 +8,132 @@ import SwiftUI struct AuthenticatedView: View { + @EnvironmentObject var authViewModel: AuthenticationViewModel +// @EnvironmentObject var pathModel: PathModel + + var totalDuration = 10.0 + var body: some View { - Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + ZStack { + Color.backgroundDark.ignoresSafeArea(.all) + + RoundedRectangle(cornerRadius: 12) + .foregroundStyle(.gray01) + .overlay { + VStack { + Rectangle() + .frame(height: 1) + .foregroundStyle(.gray07) + + Spacer() + .frame(height: 66) + + ZStack(alignment: .bottom) { + Rectangle() + .stroke(lineWidth: 1) + .foregroundStyle(.gray07) + .frame(height: 87) + + Text("Scoop!") + .frame(height: heightForFontSize(size: 150)) + .font(.pretendardBold150) + .foregroundStyle(.basicBlack) + } + + Spacer() + keyFrameView + + Spacer() + + signInButtonView + + Spacer() + .frame(height: 30) + + Rectangle() + .frame(height: 1) + .foregroundStyle(.gray07) + + + + + } + .padding(.vertical, 50) + .padding(.horizontal, 60) + } + .clipShape(RoundedRectangle(cornerRadius: 12)) + } + .frame(maxWidth: 880, maxHeight: 600) + + + } + + // TODO : 애니메이션 반복시 자연스럽게 연결 하기 + var keyFrameView: some View { +// ScrollView(.horizontal) { + HStack(spacing: 70) { + Image(.scoopGray01) + .scoopImageModifier() + Image(.scoopOrange04) + .scoopImageModifier() + Image(.scoopGray02) + .scoopImageModifier() + Image(.scoopOrange03) + .scoopImageModifier() + Image(.scoopGray03) + .scoopImageModifier() + Image(.scoopOrange02) + .scoopImageModifier() + Image(.scoopGray04) + .scoopImageModifier() + Image(.scoopOrange01) + .scoopImageModifier() + Image(.scoopGray01) + .scoopImageModifier() + Image(.scoopOrange04) + .scoopImageModifier() + Image(.scoopGray02) + .scoopImageModifier() + } + .keyframeAnimator(initialValue: AnimationProperty(), repeating: true) { content, value in + content + .offset(x: value.xTranslation) + } keyframes: { _ in + KeyframeTrack(\.xTranslation) { + LinearKeyframe(-200, duration: totalDuration) + LinearKeyframe(200, duration: totalDuration) + + } + } + } + + var signInButtonView: some View { + HStack { + Button { + authViewModel.authenticationState = .authenticated + } label: { + Image(.appleSignInBtn01) + .resizable() + .aspectRatio(contentMode: .fit) + .frame(height: 50) + } + + Button { + + } label: { + Image(.kakaoSignInBtn01) + .resizable() + .aspectRatio(contentMode: .fit) + .frame(height: 50) + } + } + + } +} + +struct AnimationProperty { + var xTranslation = 0.0 } #Preview { diff --git a/iOS/RollTheDice/RollTheDice/Source/View/Authentication/AuthenticationViewModel.swift b/iOS/RollTheDice/RollTheDice/Source/View/Authentication/AuthenticationViewModel.swift index 4dabc561..af2bb8d7 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/Authentication/AuthenticationViewModel.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/Authentication/AuthenticationViewModel.swift @@ -8,12 +8,13 @@ import Foundation enum AuthenticationState { - case unauthenticated - case authenticated + case unauthenticated // Kakao & Apple 로그인 전 + case authenticated // 로그인 후 회원가입 진행 중 + case completedSignUp // 회원가입까지 성공 } -class AuthenticationViewModel: ObservableObject { +@Observable class AuthenticationViewModel: ObservableObject { // 로그인 상태에 따라 화면 분기처리 - @Published var authenticationState: AuthenticationState = .unauthenticated - @Published var isLoading = false + var authenticationState: AuthenticationState = .unauthenticated + var isLoading = false } diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/DetailNewsCard/DetailCardNews.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/DetailNewsCard/DetailCardNews.swift index 1639b4ad..047ea7f0 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/DetailNewsCard/DetailCardNews.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/DetailNewsCard/DetailCardNews.swift @@ -27,7 +27,7 @@ struct DetailCardNews: View { HStack(spacing: 0) { - AsyncImage(url: URL(string: "https://imgnews.pstatic.net/image/018/2024/05/15/0005739785_001_20240515190608817.jpg?type=w647")) { phase in + AsyncImage(url: URL(string: newsViewModel.newsDetail?.thumbnailURL ?? "https://imgnews.pstatic.net/image/018/2024/05/15/0005739785_001_20240515190608817.jpg?type=w647")) { phase in switch phase { case .success(let image): image diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListViewModel.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListViewModel.swift index 8e745a87..5afaa6b5 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListViewModel.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListViewModel.swift @@ -31,7 +31,7 @@ import SwiftUI extension NewsListViewModel { public func getAllNewsData(page: Int, size: Int) { - let accessToken = "" + let accessToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJBY2Nlc3NUb2tlbiIsImV4cCI6MTcxNjMwMzYwMiwiZW1haWwiOiJjaGVueWVvbmp5QGRhdW0ubmV0In0.UmW0VdDtxsI7L2WSBrpUaAof5zikQ8JWdp_DIsXIlFwPaFBRUrfhgJ0aYljVcosOkQrk4b2NwOhme5lR13aEgw" if let cancellable = newsCancellable { cancellable.cancel() diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsView.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsView.swift index 3944c542..1d3889b0 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsView.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsView.swift @@ -44,10 +44,19 @@ struct NewsView: View { .clipShape(RoundedRectangle(cornerRadius: 8)) .shadow(color: .black.opacity(0.25), radius: 2, x: 0, y: 0) case .empty: - Image(systemName: "photo.circle.fill") - + Image(.exampleNews) + .resizable() + .aspectRatio(contentMode: .fill) + .frame(width: 322, height: 160) + .clipShape(RoundedRectangle(cornerRadius: 8)) + .shadow(color: .black.opacity(0.25), radius: 2, x: 0, y: 0) case .failure(_): - Image(systemName: "photo.circle.fill") + Image(.exampleNews) + .resizable() + .aspectRatio(contentMode: .fill) + .frame(width: 322, height: 160) + .clipShape(RoundedRectangle(cornerRadius: 8)) + .shadow(color: .black.opacity(0.25), radius: 2, x: 0, y: 0) @unknown default: Text(""); } diff --git a/iOS/RollTheDice/RollTheDice/Source/View/SignIn/SignInView.swift b/iOS/RollTheDice/RollTheDice/Source/View/SignIn/SignInView.swift index d83af96e..92e94250 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/SignIn/SignInView.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/SignIn/SignInView.swift @@ -7,132 +7,132 @@ import SwiftUI -struct SignInView: View { - - var totalDuration = 10.0 - - var body: some View { - ZStack { - Color.backgroundDark.ignoresSafeArea(.all) - - RoundedRectangle(cornerRadius: 12) - .overlay { - VStack { - Rectangle() - .frame(height: 1) - .foregroundStyle(.gray07) - - Spacer() - .frame(height: 66) - - ZStack(alignment: .bottom) { - Rectangle() - .stroke(lineWidth: 1) - .foregroundStyle(.gray07) - .frame(height: 87) - - Text("Scoop!") - .frame(height: heightForFontSize(size: 150)) - .font(.pretendardBold150) - .foregroundStyle(.basicBlack) - } - - Spacer() - keyFrameView - - Spacer() - - signInButtonView - - Spacer() - .frame(height: 30) - - Rectangle() - .frame(height: 1) - .foregroundStyle(.gray07) - - - - - } - .padding(.vertical, 50) - .padding(.horizontal, 60) - } - .clipShape(RoundedRectangle(cornerRadius: 12)) - } - .frame(maxWidth: 880, maxHeight: 600) - - - - } - - // TODO : 애니메이션 반복시 자연스럽게 연결 하기 - var keyFrameView: some View { -// ScrollView(.horizontal) { - HStack(spacing: 70) { - Image(.scoopGray01) - .scoopImageModifier() - Image(.scoopOrange04) - .scoopImageModifier() - Image(.scoopGray02) - .scoopImageModifier() - Image(.scoopOrange03) - .scoopImageModifier() - Image(.scoopGray03) - .scoopImageModifier() - Image(.scoopOrange02) - .scoopImageModifier() - Image(.scoopGray04) - .scoopImageModifier() - Image(.scoopOrange01) - .scoopImageModifier() - Image(.scoopGray01) - .scoopImageModifier() - Image(.scoopOrange04) - .scoopImageModifier() - Image(.scoopGray02) - .scoopImageModifier() - } - .keyframeAnimator(initialValue: AnimationProperty(), repeating: true) { content, value in - content - .offset(x: value.xTranslation) - } keyframes: { _ in - KeyframeTrack(\.xTranslation) { - LinearKeyframe(-200, duration: totalDuration) - LinearKeyframe(200, duration: totalDuration) - - } - } - } - - var signInButtonView: some View { - HStack { - Button { - - } label: { - Image(.appleSignInBtn01) - .resizable() - .aspectRatio(contentMode: .fit) - .frame(height: 50) - } - - Button { - - } label: { - Image(.kakaoSignInBtn01) - .resizable() - .aspectRatio(contentMode: .fit) - .frame(height: 50) - } - } - - } -} - -struct AnimationProperty { - var xTranslation = 0.0 -} - -#Preview { - SignInView() -} +//struct SignInView: View { +// +// var totalDuration = 10.0 +// +// var body: some View { +// ZStack { +// Color.backgroundDark.ignoresSafeArea(.all) +// +// RoundedRectangle(cornerRadius: 12) +// .overlay { +// VStack { +// Rectangle() +// .frame(height: 1) +// .foregroundStyle(.gray07) +// +// Spacer() +// .frame(height: 66) +// +// ZStack(alignment: .bottom) { +// Rectangle() +// .stroke(lineWidth: 1) +// .foregroundStyle(.gray07) +// .frame(height: 87) +// +// Text("Scoop!") +// .frame(height: heightForFontSize(size: 150)) +// .font(.pretendardBold150) +// .foregroundStyle(.basicBlack) +// } +// +// Spacer() +// keyFrameView +// +// Spacer() +// +// signInButtonView +// +// Spacer() +// .frame(height: 30) +// +// Rectangle() +// .frame(height: 1) +// .foregroundStyle(.gray07) +// +// +// +// +// } +// .padding(.vertical, 50) +// .padding(.horizontal, 60) +// } +// .clipShape(RoundedRectangle(cornerRadius: 12)) +// } +// .frame(maxWidth: 880, maxHeight: 600) +// +// +// +// } +// +// // TODO : 애니메이션 반복시 자연스럽게 연결 하기 +// var keyFrameView: some View { +//// ScrollView(.horizontal) { +// HStack(spacing: 70) { +// Image(.scoopGray01) +// .scoopImageModifier() +// Image(.scoopOrange04) +// .scoopImageModifier() +// Image(.scoopGray02) +// .scoopImageModifier() +// Image(.scoopOrange03) +// .scoopImageModifier() +// Image(.scoopGray03) +// .scoopImageModifier() +// Image(.scoopOrange02) +// .scoopImageModifier() +// Image(.scoopGray04) +// .scoopImageModifier() +// Image(.scoopOrange01) +// .scoopImageModifier() +// Image(.scoopGray01) +// .scoopImageModifier() +// Image(.scoopOrange04) +// .scoopImageModifier() +// Image(.scoopGray02) +// .scoopImageModifier() +// } +// .keyframeAnimator(initialValue: AnimationProperty(), repeating: true) { content, value in +// content +// .offset(x: value.xTranslation) +// } keyframes: { _ in +// KeyframeTrack(\.xTranslation) { +// LinearKeyframe(-200, duration: totalDuration) +// LinearKeyframe(200, duration: totalDuration) +// +// } +// } +// } +// +// var signInButtonView: some View { +// HStack { +// Button { +// +// } label: { +// Image(.appleSignInBtn01) +// .resizable() +// .aspectRatio(contentMode: .fit) +// .frame(height: 50) +// } +// +// Button { +// +// } label: { +// Image(.kakaoSignInBtn01) +// .resizable() +// .aspectRatio(contentMode: .fit) +// .frame(height: 50) +// } +// } +// +// } +//} +// +//struct AnimationProperty { +// var xTranslation = 0.0 +//} +// +//#Preview { +// SignInView() +//} diff --git a/iOS/RollTheDice/RollTheDice/Source/View/SignUp/SignUpFinishView.swift b/iOS/RollTheDice/RollTheDice/Source/View/SignUp/SignUpFinishView.swift index df1ed229..94e2d18c 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/SignUp/SignUpFinishView.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/SignUp/SignUpFinishView.swift @@ -8,11 +8,28 @@ import SwiftUI struct SignUpFinishView: View { + @EnvironmentObject var authViewModel: AuthenticationViewModel + var body: some View { - Text("test 끝") + + VStack(spacing: 40) { + Text("회원가입 완료!") + .font(.pretendardBold40) + Button { + authViewModel.authenticationState = .completedSignUp + } label: { + Text("스쿱 보러 가기 🥄") + .foregroundStyle(.basicWhite) + .font(.pretendardBold24) + .padding(20) + .background(.primary01) + .clipShape(RoundedRectangle(cornerRadius: 16)) + } + } } } #Preview { SignUpFinishView() + .environmentObject(AuthenticationViewModel()) } diff --git a/iOS/RollTheDice/RollTheDice/Source/View/SignUp/SignUpQuestionView.swift b/iOS/RollTheDice/RollTheDice/Source/View/SignUp/SignUpQuestionView.swift index 493fc761..4fd1dd70 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/SignUp/SignUpQuestionView.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/SignUp/SignUpQuestionView.swift @@ -8,39 +8,37 @@ import SwiftUI struct SignUpQuestionView: View { - -// @StateObject var p - @StateObject var viewModel = SignUpViewModel() - @State var process: Int = 1 + + @EnvironmentObject var authViewModel: AuthenticationViewModel + @EnvironmentObject var viewModel: SignUpViewModel + @State var process: Int = 0 @State var isSelected: Bool = false + @State var nickname: String = "" + + @State var selectedQuestionNumber: Int? var body: some View { if viewModel.hasDoneTest { - SignUpFinishView() } else { VStack { CustomNavigationBar() - ProcessView(process: $process) + processView + Spacer() VStack { Spacer() - QuestionView(viewModel: viewModel, process: $process, isSelected: $isSelected) + .frame(height: /*@START_MENU_TOKEN@*/100/*@END_MENU_TOKEN@*/) + questionView Spacer() - NextButtonView(process: $process, isSelected: $isSelected) + nextButtonView } - .padding(.horizontal, 15) + .padding(.horizontal, 150) } } } - -} - -private struct ProcessView: View { - @Binding var process: Int - - fileprivate var body: some View { + var processView: some View { VStack { ZStack { Rectangle() @@ -55,73 +53,80 @@ private struct ProcessView: View { } } } -} - -private struct QuestionView: View { - @ObservedObject var viewModel: SignUpViewModel - @Binding var process: Int - @State var question: String = "" - @State var options: [String] = [] - @State var selection: Int = -1 /// 선택한 버튼의 index - @Binding var isSelected: Bool - fileprivate var body: some View { + var questionView: some View { VStack { - - Spacer() HStack { - Text(question) - .font(.largeTitle) + Text(viewModel.questions[process].question) + .font(.pretendardBold40) .foregroundStyle(.basicWhite) + Spacer() } - Spacer() - HStack(spacing: 10) { - ForEach(options.indices, id: \.self) { q in - Button { - selection = q - isSelected = true - } label: { - RoundedRectangle(cornerRadius: 15) - .stroke(lineWidth: 1.0) - .foregroundStyle(q == selection ? .primary01 : .basicWhite) - .frame(height: 200) - .overlay { - Text(options[q]) - .font(.title) - .foregroundStyle(.basicWhite) - } + + if process != 0 { + HStack(spacing: 10) { + ForEach(viewModel.questions[process].options.indices, id: \.self) { q in + Button { + selectedQuestionNumber = q + isSelected = true + } label: { + RoundedRectangle(cornerRadius: 15) + .stroke(lineWidth: 1.0) + .foregroundStyle(q == selectedQuestionNumber ? .primary01 : .basicWhite) + .frame(height: 200) + .overlay { + Text(viewModel.questions[process].options[q]) + .foregroundStyle(.basicWhite) + .font(.pretendardBold24) + } + } + } + } + } else { + RoundedRectangle(cornerRadius: 24) + .fill(.clear) + .overlay { + RoundedRectangle(cornerRadius: 24) + .strokeBorder(Color.primary01, lineWidth: 2) } + .frame(height: 100) + .overlay { + TextField( + "현재 닉네임", + text: self.$nickname, + prompt: Text("이름을 입력하세요").foregroundStyle(.white).font(.pretendardBold24) + ) + .padding(30) } } - - Spacer() } - .onAppear(perform: { - question = viewModel.questions[process].question - options = viewModel.questions[process].options - }) + .onChange(of: nickname) { + if nickname != "" { + isSelected = true + } else { + isSelected = false + } + } .onChange(of: process) { - if process < 6 && process > 1 { - question = viewModel.questions[process].question - options = viewModel.questions[process].options - selection = -1 + if process < 6 && process > -1 { + selectedQuestionNumber = -1 isSelected = false } else if process == 6 { viewModel.hasDoneTest = true } } } -} - -private struct NextButtonView: View { - @Binding var process: Int - @Binding var isSelected: Bool - fileprivate var body: some View { + var nextButtonView: some View { Button { - process += 1 + if process < 5 { + process += 1 + } else { + viewModel.hasDoneTest = true + } } label: { + RoundedRectangle(cornerRadius: 15) .frame(height: 80) .foregroundStyle(isSelected ? .primary01 : .gray05) @@ -133,8 +138,12 @@ private struct NextButtonView: View { } .disabled(!isSelected) } + } + #Preview { SignUpQuestionView() + .environmentObject(SignUpViewModel()) + .environmentObject(AuthenticationViewModel()) } diff --git a/iOS/RollTheDice/RollTheDice/Source/View/SignUp/SignUpViewModel.swift b/iOS/RollTheDice/RollTheDice/Source/View/SignUp/SignUpViewModel.swift index 05e5386a..f59a8bc2 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/SignUp/SignUpViewModel.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/SignUp/SignUpViewModel.swift @@ -7,13 +7,14 @@ import Foundation -class SignUpViewModel: ObservableObject { - @Published var hasDoneTest = false - @Published var questions : [Question] = [ - .init(question: "닉네임을 입력해주세요.", page: 0), +@Observable class SignUpViewModel: ObservableObject { + var hasDoneTest = false + var nickname: String? + var questions : [Question] = [ + .init(question: "닉네임을 입력해주세요.", nickname: "", page: 0), .init(question: "연령대를 선택해주세요.", options: ["10대", "20대", "30대", "40대", "50대 이상"], page: 1), .init(question: "성별을 입력해주세요", options: ["여성", "남성", "밝히지 않음"], page: 2), - .init(question: "선호하는 기사 주제를 선택해주세요. (최대 3개)", options: ["정치", "자연과학", "뭐있지", "여러뉴스", "웅냥", "정성찬", "RIIZE", "흠냐링"], page: 3), + .init(question: "선호하는 기사 주제를 선택해주세요.", options: ["정치", "자연과학", "뭐있지", "여러뉴스", "웅냥", "정성찬", "RIIZE", "흠냐링"], page: 3), .init(question: "뉴스 보는 주기를 선택해주세요.", options: ["여성", "남성", "밝히지 않음"], page: 4), .init(question: "앱을 사용하는 목적을 선택해주세요.", options: ["여성", "남성", "밝히지 않음"], page: 6), ] @@ -25,12 +26,7 @@ struct Question: Hashable { var question: String var options: [String] = [] + var nickname: String? var page: Int - -// struct Option { -// var text: String -// var isSelected: Bool = false -// var nickname: String = "" -// } } From 472b41dd7e934463b5dd4087da46e3ea820cc9a5 Mon Sep 17 00:00:00 2001 From: realhsb Date: Thu, 16 May 2024 18:55:10 +0900 Subject: [PATCH 21/30] =?UTF-8?q?feat:=20WebView=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RollTheDice.xcodeproj/project.pbxproj | 12 ++++ .../RollTheDice/RollTheDiceApp.swift | 2 + .../Source/Model/Path/PathType.swift | 2 + .../View/News/NewsCard/WebView/WebView.swift | 58 +++++++++++++++++++ 4 files changed, 74 insertions(+) create mode 100644 iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/WebView/WebView.swift diff --git a/iOS/RollTheDice/RollTheDice.xcodeproj/project.pbxproj b/iOS/RollTheDice/RollTheDice.xcodeproj/project.pbxproj index 06696dae..efb496c1 100644 --- a/iOS/RollTheDice/RollTheDice.xcodeproj/project.pbxproj +++ b/iOS/RollTheDice/RollTheDice.xcodeproj/project.pbxproj @@ -40,6 +40,7 @@ 6C7651402BF37F3400196536 /* Log.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C76513F2BF37F3400196536 /* Log.swift */; }; 6C7651422BF37F5C00196536 /* OSLog.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C7651412BF37F5C00196536 /* OSLog.framework */; }; 6C7651462BF5B45A00196536 /* DetailNews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C7651452BF5B45A00196536 /* DetailNews.swift */; }; + 6C7651492BF5FDB900196536 /* WebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C7651482BF5FDB900196536 /* WebView.swift */; }; 6C77048C2B722686001B17CB /* MainTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C77048B2B722686001B17CB /* MainTabView.swift */; }; 6C77048F2B7229B1001B17CB /* NewsListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C77048E2B7229B1001B17CB /* NewsListView.swift */; }; 6C7704992B722A20001B17CB /* MainTabViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C7704982B722A20001B17CB /* MainTabViewModel.swift */; }; @@ -122,6 +123,7 @@ 6C76513F2BF37F3400196536 /* Log.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Log.swift; sourceTree = ""; }; 6C7651412BF37F5C00196536 /* OSLog.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OSLog.framework; path = System/Library/Frameworks/OSLog.framework; sourceTree = SDKROOT; }; 6C7651452BF5B45A00196536 /* DetailNews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailNews.swift; sourceTree = ""; }; + 6C7651482BF5FDB900196536 /* WebView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebView.swift; sourceTree = ""; }; 6C77048B2B722686001B17CB /* MainTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabView.swift; sourceTree = ""; }; 6C77048E2B7229B1001B17CB /* NewsListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsListView.swift; sourceTree = ""; }; 6C7704982B722A20001B17CB /* MainTabViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabViewModel.swift; sourceTree = ""; }; @@ -208,6 +210,7 @@ 6C3237A82B7C380200B699AB /* NewsCard */ = { isa = PBXGroup; children = ( + 6C7651472BF5FDB100196536 /* WebView */, 6C94799F2BD3CC0400D5AEEB /* DetailNewsCard */, 6C77048E2B7229B1001B17CB /* NewsListView.swift */, 6C3237B12B7C385000B699AB /* NewsListViewModel.swift */, @@ -316,6 +319,14 @@ path = Support; sourceTree = ""; }; + 6C7651472BF5FDB100196536 /* WebView */ = { + isa = PBXGroup; + children = ( + 6C7651482BF5FDB900196536 /* WebView.swift */, + ); + path = WebView; + sourceTree = ""; + }; 6C7704852B72260F001B17CB /* Resources */ = { isa = PBXGroup; children = ( @@ -707,6 +718,7 @@ 6C454A7A2B9DA67C006FD9D0 /* SignUpViewModel.swift in Sources */, 6C3237AA2B7C381500B699AB /* NewsView.swift in Sources */, 6CF130C92BAB7CC200A437B6 /* BaseTargetType.swift in Sources */, + 6C7651492BF5FDB900196536 /* WebView.swift in Sources */, 6CDB29FF2BAA08280081037B /* GPTChatListViewModel.swift in Sources */, 6CF130AD2BAB0C4400A437B6 /* AuthenticationViewModel.swift in Sources */, 6CDB29F92BAA07350081037B /* GPTChat.swift in Sources */, diff --git a/iOS/RollTheDice/RollTheDice/RollTheDiceApp.swift b/iOS/RollTheDice/RollTheDice/RollTheDiceApp.swift index 8c848a75..22480d6d 100644 --- a/iOS/RollTheDice/RollTheDice/RollTheDiceApp.swift +++ b/iOS/RollTheDice/RollTheDice/RollTheDiceApp.swift @@ -56,6 +56,8 @@ struct RollTheDiceApp: App { Text("mypageView") case .debateSummaryView: DebateSummaryView() + case .webView(let url): + WebView(urlToLoad: url) } }) } diff --git a/iOS/RollTheDice/RollTheDice/Source/Model/Path/PathType.swift b/iOS/RollTheDice/RollTheDice/Source/Model/Path/PathType.swift index af5d48c7..30f880a2 100644 --- a/iOS/RollTheDice/RollTheDice/Source/Model/Path/PathType.swift +++ b/iOS/RollTheDice/RollTheDice/Source/Model/Path/PathType.swift @@ -18,4 +18,6 @@ enum PathType: Hashable { case bookmarkView // 북마크뷰 case mypageView // 마이페이지뷰 + + case webView(url: String) } diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/WebView/WebView.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/WebView/WebView.swift new file mode 100644 index 00000000..4ef1698e --- /dev/null +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/WebView/WebView.swift @@ -0,0 +1,58 @@ +// +// WebView.swift +// RollTheDice +// +// Created by Subeen on 5/16/24. +// + +import SwiftUI +import WebKit + +public struct WebView: UIViewRepresentable { + + //MARK: - 링크할 url + var urlToLoad: String + + public init(urlToLoad: String) { + self.urlToLoad = urlToLoad + } + + public func makeUIView(context: Context) -> WKWebView { + guard let url = URL(string: self.urlToLoad) else { + return WKWebView() + } + + //웹뷰 인스턴스 생성 + let configuration = WKWebViewConfiguration() + let websiteDataStore = WKWebsiteDataStore.default() + let webView = WKWebView(frame: .zero, configuration: configuration) + webView.scrollView.showsVerticalScrollIndicator = false + webView.scrollView.minimumZoomScale = 1.0 + webView.scrollView.maximumZoomScale = 1.0 + webView.allowsLinkPreview = true +// webView.scrollView.setZoomScale(0.3, animated: false) + //웹뷰를 로드한다 + DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { + let request = URLRequest(url: url, cachePolicy: .useProtocolCachePolicy) + let configuration = webView.configuration + + // Set power-saving preferences + webView.configuration.upgradeKnownHostsToHTTPS = true + configuration.preferences.minimumFontSize = 16 + DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { + webView.load(request) + } + + } + print("\(webView)") + return webView + } + + //업데이트 ui view + public func updateUIView(_ uiView: WKWebView, context: UIViewRepresentableContext) { + + } +} + + + From 4c46e28460f79ecd393e5e1023206efa24171ae2 Mon Sep 17 00:00:00 2001 From: realhsb Date: Thu, 16 May 2024 18:55:37 +0900 Subject: [PATCH 22/30] =?UTF-8?q?chore:=20UI=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/Debate/ChatList/ChatListView.swift | 136 +++++++++++++++++- .../Debate/ChatList/RecentNewsCardView.swift | 5 +- .../View/News/NewsCard/DetailNews.swift | 2 +- .../DetailNewsCard/DetailCardNews.swift | 10 +- .../Source/View/News/NewsCard/NewsList.swift | 4 +- .../View/News/NewsCard/NewsListView.swift | 2 +- .../Source/View/News/NewsCard/NewsView.swift | 4 +- .../Source/View/SignUp/SignUpFinishView.swift | 1 + .../Source/View/SignUp/SignUpViewModel.swift | 6 +- 9 files changed, 151 insertions(+), 19 deletions(-) diff --git a/iOS/RollTheDice/RollTheDice/Source/View/Debate/ChatList/ChatListView.swift b/iOS/RollTheDice/RollTheDice/Source/View/Debate/ChatList/ChatListView.swift index 31461291..67ed690b 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/Debate/ChatList/ChatListView.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/Debate/ChatList/ChatListView.swift @@ -48,8 +48,10 @@ struct ChatListView: View { .foregroundStyle(.basicWhite) .font(.pretendardBold32) debateChatCellView - debateChatCellView - debateChatCellView + debateChatCellView2 + debateChatCellView3 + debateChatCellView4 + debateChatCellView5 } } @@ -59,7 +61,135 @@ struct ChatListView: View { Text("🏛️") .padding(.leading, 26) .font(.pretendardBold32) - Text("경제 기사 경제 기사저제목목제목 제목") + Text("삼성, 갤럭시Z플립6 두뇌 전량 퀄컴칩 탑재하나") + .foregroundStyle(.gray07) + .font(.pretendardBold24) + .padding(.vertical, 24) + + Spacer() + Button { + pathModel.paths.append(.chatView(isAiMode: true)) + } label: { + Image(.chevronRight) + } + } + .background(.gray01) + .clipShape(RoundedRectangle(cornerRadius: 8)) + .padding(.trailing, 16) + + //TODO: 버튼 영역 수정하기 + Button { + pathModel.paths.append(.debateSummaryView) + } label: { + Image(.chevronLeft) +// .background(.gray01) + + } + .frame(width: 80, height: 80) + .background(.gray01) + .clipShape(RoundedRectangle(cornerRadius: 8)) + } + } + var debateChatCellView2: some View { + HStack { + HStack(alignment: .center, spacing: 16) { + Text("📱") + .padding(.leading, 26) + .font(.pretendardBold32) + Text("모친 내친 한미약품 형제… 2644억 상속세 마련방안은 `아직`") + .foregroundStyle(.gray07) + .font(.pretendardBold24) + .padding(.vertical, 24) + + Spacer() + Image(.chevronRight) + } + .background(.gray01) + .clipShape(RoundedRectangle(cornerRadius: 8)) + .padding(.trailing, 16) + + //TODO: 버튼 영역 수정하기 + Button { + pathModel.paths.append(.debateSummaryView) + } label: { + Image(.chevronLeft) +// .background(.gray01) + + } + .frame(width: 80, height: 80) + .background(.gray01) + .clipShape(RoundedRectangle(cornerRadius: 8)) + } + } + var debateChatCellView3: some View { + HStack { + HStack(alignment: .center, spacing: 16) { + Text("💌") + .padding(.leading, 26) + .font(.pretendardBold32) + Text("[ET단상]한바탕 휩쓴 방산 해킹 사건, 보안의 다른 \'답\'을 찾아야 할 때") + .foregroundStyle(.gray07) + .font(.pretendardBold24) + .padding(.vertical, 24) + + Spacer() + Image(.chevronRight) + } + .background(.gray01) + .clipShape(RoundedRectangle(cornerRadius: 8)) + .padding(.trailing, 16) + + //TODO: 버튼 영역 수정하기 + Button { + pathModel.paths.append(.debateSummaryView) + } label: { + Image(.chevronLeft) +// .background(.gray01) + + } + .frame(width: 80, height: 80) + .background(.gray01) + .clipShape(RoundedRectangle(cornerRadius: 8)) + } + } + var debateChatCellView4: some View { + HStack { + HStack(alignment: .center, spacing: 16) { + Text("📱") + .padding(.leading, 26) + .font(.pretendardBold32) + Text("삼성, 갤럭시Z플립6 두뇌 전량 퀄컴칩 탑재하나") + .foregroundStyle(.gray07) + .font(.pretendardBold24) + .padding(.vertical, 24) + + Spacer() + Image(.chevronRight) + } + .background(.gray01) + .clipShape(RoundedRectangle(cornerRadius: 8)) + .padding(.trailing, 16) + + //TODO: 버튼 영역 수정하기 + Button { + pathModel.paths.append(.debateSummaryView) + } label: { + Image(.chevronLeft) +// .background(.gray01) + + } + .frame(width: 80, height: 80) + .background(.gray01) + .clipShape(RoundedRectangle(cornerRadius: 8)) + } + } + var debateChatCellView5: some View { + HStack { + HStack(alignment: .center, spacing: 16) { + Text("🏛️") + .padding(.leading, 26) + .font(.pretendardBold32) + Text("삼성, 갤럭시Z플립6 두뇌 전량 퀄컴칩 탑재하나") .foregroundStyle(.gray07) .font(.pretendardBold24) .padding(.vertical, 24) diff --git a/iOS/RollTheDice/RollTheDice/Source/View/Debate/ChatList/RecentNewsCardView.swift b/iOS/RollTheDice/RollTheDice/Source/View/Debate/ChatList/RecentNewsCardView.swift index fa3d688c..9fa0b186 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/Debate/ChatList/RecentNewsCardView.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/Debate/ChatList/RecentNewsCardView.swift @@ -19,8 +19,9 @@ struct RecentNewsCardView: View { var titleView: some View { ZStack { VStack(alignment: .center, spacing: 20) { - Image(.chevronLeft) - Text("제목ahrhrhra제목 제목 미젝ㅁㄱㅈ 메좀ㄱㅈ게조깆거ㅣㅓ린러.ㄴ릴") + Text("📌") + .font(.title) + Text("내 안경 못 봤어?\" 핸드폰이 알려준다…구글 \'일상 AI\' 공략 [팩플]") .multilineTextAlignment(.center) .foregroundStyle(.gray07) .font(.pretendardBold24) diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/DetailNews.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/DetailNews.swift index 042322a8..0ae069db 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/DetailNews.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/DetailNews.swift @@ -13,7 +13,7 @@ struct DetailNews: Codable, Identifiable { let url: String? let title: String? let content: String? - let thumbnailURL: String? + let thumbnailUrl: String? let postDate: String? } diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/DetailNewsCard/DetailCardNews.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/DetailNewsCard/DetailCardNews.swift index 047ea7f0..dc769c7b 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/DetailNewsCard/DetailCardNews.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/DetailNewsCard/DetailCardNews.swift @@ -27,7 +27,7 @@ struct DetailCardNews: View { HStack(spacing: 0) { - AsyncImage(url: URL(string: newsViewModel.newsDetail?.thumbnailURL ?? "https://imgnews.pstatic.net/image/018/2024/05/15/0005739785_001_20240515190608817.jpg?type=w647")) { phase in + AsyncImage(url: URL(string: newsViewModel.newsDetail?.thumbnailUrl ?? "https://imgnews.pstatic.net/image/018/2024/05/15/0005739785_001_20240515190608817.jpg?type=w647")) { phase in switch phase { case .success(let image): image @@ -62,7 +62,7 @@ struct DetailCardNews: View { .foregroundStyle(.black) .frame(height: 1) - Text(newsViewModel.newsDetail?.title ?? "네트워킹 오류") + Text(newsViewModel.newsDetail?.title ?? "기사 제목 불러오는 중 ~") .font(.pretendardBold32) .foregroundColor(.basicBlack) .padding(.vertical, 10) @@ -71,7 +71,7 @@ struct DetailCardNews: View { HStack { Spacer() - Text("발행일자 : \(newsViewModel.newsDetail?.postDate ?? "")") + Text("발행일자 : \(newsViewModel.newsDetail?.postDate ?? "2024-01-01")") .font(.pretendardRegular14) .foregroundStyle(.gray05) @@ -80,7 +80,7 @@ struct DetailCardNews: View { .padding(.horizontal, 20) ScrollView { - Text(newsViewModel.newsDetail?.content ?? "네트워킹 오류") + Text(newsViewModel.newsDetail?.content ?? "요약 불러오는 중 ~") .font( .pretendardRegular16 ) @@ -94,7 +94,7 @@ struct DetailCardNews: View { HStack { Spacer() Button { - + pathModel.paths.append(.webView(url: newsViewModel.newsDetail?.url ?? "https://n.news.naver.com/mnews/article/014/0005185580")) } label: { Text("원문 보러 가기 ➡️") .font(.pretendardBold12) diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsList.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsList.swift index 991454f8..6188cb5c 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsList.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsList.swift @@ -12,12 +12,12 @@ struct NewsList: Codable, Identifiable { let id = UUID().uuidString // 이건 앱자체에서 let newsId: Int let title, content: String? - let thumbnail: String? + let thumbnailUrl: String? let postDate: String? let isBookmarked: Bool? enum CodingKeys: String, CodingKey { case newsId = "id" - case title, content, thumbnail, postDate, isBookmarked + case title, content, thumbnailUrl, postDate, isBookmarked } } diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListView.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListView.swift index be009789..edb29969 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListView.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsListView.swift @@ -33,7 +33,7 @@ struct NewsListView: View { fileprivate var body: some View { GeometryReader { proxy in ScrollView(.horizontal, showsIndicators: false) { - LazyHStack { + LazyHStack(spacing: -234567876455aa0) { ForEach(newsList) { news in NewsView(news: news) diff --git a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsView.swift b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsView.swift index 1d3889b0..859b4230 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsView.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/News/NewsCard/NewsView.swift @@ -34,7 +34,7 @@ struct NewsView: View { } - AsyncImage(url: URL(string: news.thumbnail ?? "")) { phase in + AsyncImage(url: URL(string: news.thumbnailUrl ?? "")) { phase in switch phase { case .success(let image): image @@ -131,7 +131,7 @@ struct NewsView: View { } #Preview { - NewsView(news: .init(newsId: 1, title: "1분기 선방한 dddddddd韓게임사들…엔씨만 울었다", content: "내용내용ㄴㅇㅇㅇ", thumbnail: "", postDate: "2222-22-22", isBookmarked: true)) + NewsView(news: .init(newsId: 1, title: "1분기 선방한 dddddddd韓게임사들…엔씨만 울었다", content: "내용내용ㄴㅇㅇㅇ", thumbnailUrl: "", postDate: "2222-22-22", isBookmarked: true)) .environmentObject(PathModel()) } //#Preview(traits: .sizeThatFitsLayout) { diff --git a/iOS/RollTheDice/RollTheDice/Source/View/SignUp/SignUpFinishView.swift b/iOS/RollTheDice/RollTheDice/Source/View/SignUp/SignUpFinishView.swift index 94e2d18c..d6cd508e 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/SignUp/SignUpFinishView.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/SignUp/SignUpFinishView.swift @@ -9,6 +9,7 @@ import SwiftUI struct SignUpFinishView: View { @EnvironmentObject var authViewModel: AuthenticationViewModel + @EnvironmentObject var signUpViewModel: SignUpViewModel var body: some View { diff --git a/iOS/RollTheDice/RollTheDice/Source/View/SignUp/SignUpViewModel.swift b/iOS/RollTheDice/RollTheDice/Source/View/SignUp/SignUpViewModel.swift index f59a8bc2..4356eafb 100644 --- a/iOS/RollTheDice/RollTheDice/Source/View/SignUp/SignUpViewModel.swift +++ b/iOS/RollTheDice/RollTheDice/Source/View/SignUp/SignUpViewModel.swift @@ -14,9 +14,9 @@ import Foundation .init(question: "닉네임을 입력해주세요.", nickname: "", page: 0), .init(question: "연령대를 선택해주세요.", options: ["10대", "20대", "30대", "40대", "50대 이상"], page: 1), .init(question: "성별을 입력해주세요", options: ["여성", "남성", "밝히지 않음"], page: 2), - .init(question: "선호하는 기사 주제를 선택해주세요.", options: ["정치", "자연과학", "뭐있지", "여러뉴스", "웅냥", "정성찬", "RIIZE", "흠냐링"], page: 3), - .init(question: "뉴스 보는 주기를 선택해주세요.", options: ["여성", "남성", "밝히지 않음"], page: 4), - .init(question: "앱을 사용하는 목적을 선택해주세요.", options: ["여성", "남성", "밝히지 않음"], page: 6), + .init(question: "선호하는 기사 주제를 선택해주세요.", options: ["정치", "자연과학", "경제", "IT/과학", "생활/문화", "세계"], page: 3), + .init(question: "뉴스 보는 주기를 선택해주세요.", options: ["매일", "3일에 1번", "1주일에 1번", "거의 안 봄"], page: 4), + .init(question: "앱을 사용하는 목적을 선택해주세요.", options: ["시사 상식 채우기", "심심풀이", "밝히지 않음"], page: 6), ] } From 993c8d5290bca2940135ae788faafbf47e558b98 Mon Sep 17 00:00:00 2001 From: yeonjy Date: Wed, 29 May 2024 20:29:56 +0900 Subject: [PATCH 23/30] =?UTF-8?q?feat:=20=EC=B5=9C=EA=B7=BC=20=EC=9D=BD?= =?UTF-8?q?=EC=9D=80=20=EB=89=B4=EC=8A=A4=20=EC=A1=B0=ED=9A=8C=20api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/domain/news/api/NewsApi.java | 14 ++++++++++++++ .../backend/domain/news/api/NewsController.java | 11 +++++++++++ 2 files changed, 25 insertions(+) diff --git a/backend/core/src/main/java/com/rollthedice/backend/domain/news/api/NewsApi.java b/backend/core/src/main/java/com/rollthedice/backend/domain/news/api/NewsApi.java index edf03f94..b6d19e4f 100644 --- a/backend/core/src/main/java/com/rollthedice/backend/domain/news/api/NewsApi.java +++ b/backend/core/src/main/java/com/rollthedice/backend/domain/news/api/NewsApi.java @@ -2,6 +2,7 @@ import com.rollthedice.backend.domain.news.dto.response.NewsDetailResponse; import com.rollthedice.backend.domain.news.dto.response.NewsResponse; +import com.rollthedice.backend.domain.news.dto.response.ReadNewsResponse; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.enums.ParameterIn; @@ -46,4 +47,17 @@ NewsDetailResponse getDetailNews( Long newsId ); + @Operation( + summary = "최근 읽은 뉴스 조회", + description = "가장 최근에 읽은 3개의 뉴스를 조회합니다.", + security = {@SecurityRequirement(name = "access_token")}, + tags = {"news"} + ) + @ApiResponse( + responseCode = "200", + description = "요청에 성공하였습니다." + ) + List getReadNews(); + + } diff --git a/backend/core/src/main/java/com/rollthedice/backend/domain/news/api/NewsController.java b/backend/core/src/main/java/com/rollthedice/backend/domain/news/api/NewsController.java index e5e12daf..a6e38e45 100644 --- a/backend/core/src/main/java/com/rollthedice/backend/domain/news/api/NewsController.java +++ b/backend/core/src/main/java/com/rollthedice/backend/domain/news/api/NewsController.java @@ -1,8 +1,11 @@ package com.rollthedice.backend.domain.news.api; +import com.rollthedice.backend.domain.crawling.NewsCrawlingService; import com.rollthedice.backend.domain.news.dto.response.NewsDetailResponse; import com.rollthedice.backend.domain.news.dto.response.NewsResponse; +import com.rollthedice.backend.domain.news.dto.response.ReadNewsResponse; import com.rollthedice.backend.domain.news.service.NewsService; +import com.rollthedice.backend.domain.news.service.ReadNewsService; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; @@ -15,6 +18,8 @@ @RequestMapping("news") public class NewsController implements NewsApi { private final NewsService newsService; + private final ReadNewsService readNewsService; + private final NewsCrawlingService crawlingService; @ResponseStatus(HttpStatus.OK) @GetMapping("") @@ -28,4 +33,10 @@ public List getNews(final Pageable pageable) { public NewsDetailResponse getDetailNews(final @PathVariable Long newsId) { return newsService.getDetailNews(newsId); } + + @ResponseStatus(HttpStatus.OK) + @GetMapping("/viewed-history") + public List getReadNews() { + return readNewsService.getReadNews(); + } } From ec0c5bfb830e30e10fbd0e56f3b6d90cc470047c Mon Sep 17 00:00:00 2001 From: yeonjy Date: Wed, 29 May 2024 20:31:22 +0900 Subject: [PATCH 24/30] refactor: DebateMessageRepository directory news -> debate --- .../{news => debate}/repository/DebateMessageRepository.java | 2 +- .../backend/domain/debate/service/DebateMessageService.java | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) rename backend/core/src/main/java/com/rollthedice/backend/domain/{news => debate}/repository/DebateMessageRepository.java (87%) diff --git a/backend/core/src/main/java/com/rollthedice/backend/domain/news/repository/DebateMessageRepository.java b/backend/core/src/main/java/com/rollthedice/backend/domain/debate/repository/DebateMessageRepository.java similarity index 87% rename from backend/core/src/main/java/com/rollthedice/backend/domain/news/repository/DebateMessageRepository.java rename to backend/core/src/main/java/com/rollthedice/backend/domain/debate/repository/DebateMessageRepository.java index f2456e6f..6dd72f5e 100644 --- a/backend/core/src/main/java/com/rollthedice/backend/domain/news/repository/DebateMessageRepository.java +++ b/backend/core/src/main/java/com/rollthedice/backend/domain/debate/repository/DebateMessageRepository.java @@ -1,4 +1,4 @@ -package com.rollthedice.backend.domain.news.repository; +package com.rollthedice.backend.domain.debate.repository; import com.rollthedice.backend.domain.debate.entity.DebateMessage; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/backend/core/src/main/java/com/rollthedice/backend/domain/debate/service/DebateMessageService.java b/backend/core/src/main/java/com/rollthedice/backend/domain/debate/service/DebateMessageService.java index 032ee552..76d9b583 100644 --- a/backend/core/src/main/java/com/rollthedice/backend/domain/debate/service/DebateMessageService.java +++ b/backend/core/src/main/java/com/rollthedice/backend/domain/debate/service/DebateMessageService.java @@ -2,12 +2,11 @@ import com.rollthedice.backend.domain.debate.dto.request.DebateMessageRequest; import com.rollthedice.backend.domain.debate.dto.response.DebateMessageResponse; -import com.rollthedice.backend.domain.debate.dto.response.DebateSummaryResponse; import com.rollthedice.backend.domain.debate.entity.DebateRoom; import com.rollthedice.backend.domain.debate.exception.DebateRoomNotFoundException; import com.rollthedice.backend.domain.debate.mapper.DebateMessageMapper; import com.rollthedice.backend.domain.debate.repository.DebateRoomRepository; -import com.rollthedice.backend.domain.news.repository.DebateMessageRepository; +import com.rollthedice.backend.domain.debate.repository.DebateMessageRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; From e3454a4141f96a7b1cd8f80b7957a615d7631817 Mon Sep 17 00:00:00 2001 From: yeonjy Date: Wed, 29 May 2024 20:32:03 +0900 Subject: [PATCH 25/30] =?UTF-8?q?feat:=20readNews=20=EC=A1=B0=ED=9A=8C=20&?= =?UTF-8?q?=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/news/service/NewsService.java | 25 +++++++++++++----- .../domain/news/service/ReadNewsService.java | 26 +++++++++++++++++++ 2 files changed, 44 insertions(+), 7 deletions(-) create mode 100644 backend/core/src/main/java/com/rollthedice/backend/domain/news/service/ReadNewsService.java diff --git a/backend/core/src/main/java/com/rollthedice/backend/domain/news/service/NewsService.java b/backend/core/src/main/java/com/rollthedice/backend/domain/news/service/NewsService.java index 02fa2878..757d85b3 100644 --- a/backend/core/src/main/java/com/rollthedice/backend/domain/news/service/NewsService.java +++ b/backend/core/src/main/java/com/rollthedice/backend/domain/news/service/NewsService.java @@ -3,7 +3,10 @@ import com.rollthedice.backend.domain.bookmark.service.BookmarkService; import com.rollthedice.backend.domain.member.entity.Member; import com.rollthedice.backend.domain.news.dto.response.NewsDetailResponse; +import com.rollthedice.backend.domain.news.dto.response.ReadNewsResponse; +import com.rollthedice.backend.domain.news.entity.ReadNews; import com.rollthedice.backend.domain.news.exception.NewsNotFoundException; +import com.rollthedice.backend.domain.news.repository.ReadNewsRepository; import com.rollthedice.backend.global.oauth2.service.AuthService; import com.rollthedice.backend.domain.news.contentqueue.ContentProducer; import com.rollthedice.backend.domain.news.dto.ContentMessageDto; @@ -29,6 +32,7 @@ public class NewsService { private final AuthService authService; private final ContentProducer contentProducer; private final NewsRepository newsRepository; + private final ReadNewsRepository readNewsRepository; private final NewsMapper newsMapper; private final BookmarkService bookmarkService; @@ -50,13 +54,13 @@ public void updateSummarizedNews(ContentMessageDto messageDto) { news.updateSummarizedContent(messageDto.getContent()); } - @Transactional(readOnly = true) - public void summarizeNewsContent() { - List messages = new ArrayList<>(); - newsRepository.findAll().forEach(n -> - messages.add(new ContentMessageDto(n.getId(), n.getContent()))); - messages.forEach(contentProducer::sendMessage); - } +// @Transactional(readOnly = true) +// public void summarizeNewsContent() { +// List messages = new ArrayList<>(); +// newsRepository.findAll().forEach(n -> +// messages.add(new ContentMessageDto(n.getId(), n.getContent()))); +// messages.forEach(contentProducer::sendMessage); +// } @Transactional(readOnly = true) public List getNews(final Pageable pageable) { @@ -69,6 +73,13 @@ public List getNews(final Pageable pageable) { public NewsDetailResponse getDetailNews(Long newsId) { final News news = newsRepository.findById(newsId).orElseThrow(NewsNotFoundException::new); + readNewsRepository.save(ReadNews.builder() + .member(authService.getMember()).news(news).build()); return newsMapper.toDetailResponse(news); } + + public List getNewsByReadNews(final List news) { + return news.stream().map(newsMapper::toReadNewsResponse).collect(Collectors.toList()); + } + } diff --git a/backend/core/src/main/java/com/rollthedice/backend/domain/news/service/ReadNewsService.java b/backend/core/src/main/java/com/rollthedice/backend/domain/news/service/ReadNewsService.java new file mode 100644 index 00000000..c2618ff0 --- /dev/null +++ b/backend/core/src/main/java/com/rollthedice/backend/domain/news/service/ReadNewsService.java @@ -0,0 +1,26 @@ +package com.rollthedice.backend.domain.news.service; + +import com.rollthedice.backend.domain.member.entity.Member; +import com.rollthedice.backend.domain.news.dto.response.ReadNewsResponse; +import com.rollthedice.backend.domain.news.entity.ReadNews; +import com.rollthedice.backend.domain.news.repository.ReadNewsRepository; +import com.rollthedice.backend.global.oauth2.service.AuthService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class ReadNewsService { + private final AuthService authService; + private final ReadNewsRepository readNewsReository; + private final NewsService newsService; + + public List getReadNews() { + Member member = authService.getMember(); + List readNews = readNewsReository.getTop3ByMemberOrderByCreatedAtDesc(member); + return newsService.getNewsByReadNews(readNews.stream().map(r -> r.getNews()).collect(Collectors.toList())); + } +} From 7e14537789acec6ec84c0bbaa07d5034872a6aa5 Mon Sep 17 00:00:00 2001 From: yeonjy Date: Wed, 29 May 2024 20:32:31 +0900 Subject: [PATCH 26/30] feat: ReadNewsRepository --- .../domain/news/repository/ReadNewsRepository.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 backend/core/src/main/java/com/rollthedice/backend/domain/news/repository/ReadNewsRepository.java diff --git a/backend/core/src/main/java/com/rollthedice/backend/domain/news/repository/ReadNewsRepository.java b/backend/core/src/main/java/com/rollthedice/backend/domain/news/repository/ReadNewsRepository.java new file mode 100644 index 00000000..d821b1cb --- /dev/null +++ b/backend/core/src/main/java/com/rollthedice/backend/domain/news/repository/ReadNewsRepository.java @@ -0,0 +1,14 @@ +package com.rollthedice.backend.domain.news.repository; + +import com.rollthedice.backend.domain.member.entity.Member; +import com.rollthedice.backend.domain.news.entity.ReadNews; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface ReadNewsRepository extends JpaRepository { + List getTop3ByMemberOrderByCreatedAtDesc(Member member); + +} From 2f600eb3b08524eefb0b1fb2dbc06812ca7844b3 Mon Sep 17 00:00:00 2001 From: yeonjy Date: Wed, 29 May 2024 20:33:01 +0900 Subject: [PATCH 27/30] =?UTF-8?q?style:=20=EC=A4=84=EB=B0=94=EA=BF=88=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/domain/news/repository/NewsRepository.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/backend/core/src/main/java/com/rollthedice/backend/domain/news/repository/NewsRepository.java b/backend/core/src/main/java/com/rollthedice/backend/domain/news/repository/NewsRepository.java index b70a295a..e147d4ae 100644 --- a/backend/core/src/main/java/com/rollthedice/backend/domain/news/repository/NewsRepository.java +++ b/backend/core/src/main/java/com/rollthedice/backend/domain/news/repository/NewsRepository.java @@ -10,6 +10,5 @@ @Repository public interface NewsRepository extends JpaRepository { List findAllByContentIsNull(); - List findAllByOrderByViewsDescCreatedAtDesc( - final Pageable pageable); + List findAllByOrderByViewsDescCreatedAtDesc(final Pageable pageable); } From f6c2507200b50897212ec6a385a290bbdbe29e39 Mon Sep 17 00:00:00 2001 From: yeonjy Date: Wed, 29 May 2024 20:33:40 +0900 Subject: [PATCH 28/30] =?UTF-8?q?feat:=20ReadNews=20Builder=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rollthedice/backend/domain/news/entity/ReadNews.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/backend/core/src/main/java/com/rollthedice/backend/domain/news/entity/ReadNews.java b/backend/core/src/main/java/com/rollthedice/backend/domain/news/entity/ReadNews.java index 9c7929c3..03abeb91 100644 --- a/backend/core/src/main/java/com/rollthedice/backend/domain/news/entity/ReadNews.java +++ b/backend/core/src/main/java/com/rollthedice/backend/domain/news/entity/ReadNews.java @@ -4,6 +4,7 @@ import com.rollthedice.backend.global.config.BaseTimeEntity; import jakarta.persistence.*; import lombok.AccessLevel; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -23,4 +24,10 @@ public class ReadNews extends BaseTimeEntity { @JoinColumn(name = "news_id") private News news; + @Builder + public ReadNews(Member member, News news) { + this.member = member; + this.news = news; + } + } From 6429b086cbb321cec1d1b7536ea9fc85a2f042b5 Mon Sep 17 00:00:00 2001 From: yeonjy Date: Wed, 29 May 2024 20:34:05 +0900 Subject: [PATCH 29/30] =?UTF-8?q?feat:=20ReadNewsResponse=20DTO=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../news/dto/response/ReadNewsResponse.java | 15 +++++++++++++++ .../backend/domain/news/mapper/NewsMapper.java | 3 +++ 2 files changed, 18 insertions(+) create mode 100644 backend/core/src/main/java/com/rollthedice/backend/domain/news/dto/response/ReadNewsResponse.java diff --git a/backend/core/src/main/java/com/rollthedice/backend/domain/news/dto/response/ReadNewsResponse.java b/backend/core/src/main/java/com/rollthedice/backend/domain/news/dto/response/ReadNewsResponse.java new file mode 100644 index 00000000..215ceedc --- /dev/null +++ b/backend/core/src/main/java/com/rollthedice/backend/domain/news/dto/response/ReadNewsResponse.java @@ -0,0 +1,15 @@ +package com.rollthedice.backend.domain.news.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ReadNewsResponse { + private Long id; + private String title; +} diff --git a/backend/core/src/main/java/com/rollthedice/backend/domain/news/mapper/NewsMapper.java b/backend/core/src/main/java/com/rollthedice/backend/domain/news/mapper/NewsMapper.java index f2b10ba6..d50c6ce7 100644 --- a/backend/core/src/main/java/com/rollthedice/backend/domain/news/mapper/NewsMapper.java +++ b/backend/core/src/main/java/com/rollthedice/backend/domain/news/mapper/NewsMapper.java @@ -2,6 +2,7 @@ import com.rollthedice.backend.domain.news.dto.response.NewsDetailResponse; import com.rollthedice.backend.domain.news.dto.response.NewsResponse; +import com.rollthedice.backend.domain.news.dto.response.ReadNewsResponse; import com.rollthedice.backend.domain.news.entity.News; import org.mapstruct.Mapper; import org.mapstruct.MappingConstants.ComponentModel; @@ -11,5 +12,7 @@ public interface NewsMapper { NewsResponse toResponse(final News news, boolean isBookmarked); + ReadNewsResponse toReadNewsResponse(final News news); + NewsDetailResponse toDetailResponse(final News news); } From cee502b83adbf59bd2fea123ed1319db279c8693 Mon Sep 17 00:00:00 2001 From: yeonjy Date: Wed, 29 May 2024 20:41:32 +0900 Subject: [PATCH 30/30] =?UTF-8?q?style:=20summarizeNewsContent=20=20?= =?UTF-8?q?=EC=A3=BC=EC=84=9D=20=ED=95=B4=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/domain/news/service/NewsService.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/backend/core/src/main/java/com/rollthedice/backend/domain/news/service/NewsService.java b/backend/core/src/main/java/com/rollthedice/backend/domain/news/service/NewsService.java index 757d85b3..bb3136c1 100644 --- a/backend/core/src/main/java/com/rollthedice/backend/domain/news/service/NewsService.java +++ b/backend/core/src/main/java/com/rollthedice/backend/domain/news/service/NewsService.java @@ -54,13 +54,13 @@ public void updateSummarizedNews(ContentMessageDto messageDto) { news.updateSummarizedContent(messageDto.getContent()); } -// @Transactional(readOnly = true) -// public void summarizeNewsContent() { -// List messages = new ArrayList<>(); -// newsRepository.findAll().forEach(n -> -// messages.add(new ContentMessageDto(n.getId(), n.getContent()))); -// messages.forEach(contentProducer::sendMessage); -// } + @Transactional(readOnly = true) + public void summarizeNewsContent() { + List messages = new ArrayList<>(); + newsRepository.findAll().forEach(n -> + messages.add(new ContentMessageDto(n.getId(), n.getContent()))); + messages.forEach(contentProducer::sendMessage); + } @Transactional(readOnly = true) public List getNews(final Pageable pageable) {