Skip to content

Commit 5ba245a

Browse files
authored
Merge pull request #46 from EST-iOS-TEAM2/fix/#45
Home, Article View 에러처리 변경 및 로딩 추가
2 parents f77519f + 7caffd8 commit 5ba245a

9 files changed

Lines changed: 162 additions & 172 deletions

File tree

Dietto/Dietto/Domain/Usecases/UserStorageUsecase.swift

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ protocol UserStorageUsecase {
1313

1414
func createUserData(_ user: UserEntity) async throws
1515
func getUserData() async throws -> UserEntity
16-
func updateUserDefaultData(id: UUID, name: String, gender: Gender, height: Int) async throws
17-
func updateGoal(id: UUID, weight: Int, distance: Int) async throws
16+
func updateUserDefaultData(id: UUID, userEntity: UserEntity) async throws
1817
func updateCurrentWeight(id: UUID, currentWeight: Int) async throws
1918
func deleteUserData() async throws
2019
}
@@ -67,28 +66,17 @@ final class UserStorageUsecaseImpl<Repository: AnotherStorageRepository>: UserSt
6766
}
6867
}
6968

70-
func updateUserDefaultData(id: UUID, name: String, gender: Gender, height: Int) async throws {
69+
func updateUserDefaultData(id: UUID, userEntity: UserEntity) async throws {
7170
do {
7271
let predicate = #Predicate<UserDTO> { $0.id == id }
7372
try await storage.updateData(predicate: predicate) { dto in
74-
dto.name = name
75-
dto.gender = gender.rawValue
76-
dto.height = height
77-
}
78-
changeEvent.send()
79-
}
80-
catch {
81-
print(#function, error.localizedDescription)
82-
throw StorageError.updateError
83-
}
84-
}
85-
86-
func updateGoal(id: UUID, weight: Int, distance: Int) async throws {
87-
do {
88-
let predicate = #Predicate<UserDTO> { $0.id == id }
89-
try await storage.updateData(predicate: predicate) { dto in
90-
dto.targetWeight = weight
91-
dto.targetDistance = distance
73+
dto.name = userEntity.name
74+
dto.gender = userEntity.gender.rawValue
75+
dto.height = userEntity.height
76+
// dto.startWeight = userEntity.startWeight
77+
dto.currentWeight = userEntity.currentWeight
78+
dto.targetWeight = userEntity.targetWeight
79+
dto.targetDistance = userEntity.targetDistance
9280
}
9381
changeEvent.send()
9482
}

Dietto/Dietto/Presentation/Article/View/ArticleView.swift

Lines changed: 40 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -8,56 +8,51 @@
88
import SwiftUI
99

1010
struct ArticleView: View {
11-
let articles = [
12-
"https://www.youtube.com/watch?v=3p8EBPVZ2Iw",
13-
"https://www.news1.kr/articles/?5301234",
14-
"https://www.youtube.com/watch?v=FdYIvEc7e-0",
15-
"https://www.youtube.com/watch?v=2tM1LFFxeKg"
16-
]
11+
1712
@StateObject var viewModel: ArticleViewModel
1813
var body: some View {
19-
ZStack{
20-
Color.backGround.ignoresSafeArea()
21-
22-
NavigationView {
23-
VStack(alignment: .leading){
24-
HStack {
25-
//MARK: - 로고
26-
Text("Dietto")
27-
.font(.NerkoOne40)
28-
.foregroundStyle(.text)
29-
Spacer()
30-
31-
NavigationLink(destination: InterestsView(viewModel: viewModel)) {
32-
Text("관심사 수정")
33-
.font(.pretendardMedium16)
34-
.foregroundColor(.white)
35-
.padding(.vertical, 4)
36-
.padding(.horizontal, 12)
37-
.background(Color.appMain)
38-
.clipShape(Capsule())
39-
}
40-
41-
}
42-
.padding([.leading, .trailing], 16)
43-
Text("내 관심사")
44-
.font(.pretendardBold20)
45-
.padding(.leading, 16)
46-
Interests(
47-
topic: "",
48-
titles: viewModel.selectedInterests.map{$0.title},
49-
onClicked: {_ in },
50-
isSelected: {_ in true}
51-
).padding(.leading, 16)
14+
NavigationView {
15+
VStack(alignment: .leading){
16+
HStack {
17+
//MARK: - 로고
18+
Text("Dietto")
19+
.font(.NerkoOne40)
20+
.foregroundStyle(.text)
21+
Spacer()
5222

53-
List(articles, id: \.self) { item in
54-
LinkRow(previewURL: URL(string: item)!)
55-
.background(Color.backGround).ignoresSafeArea(.all)
23+
NavigationLink(destination: InterestsView(viewModel: viewModel)) {
24+
Text("관심사 수정")
25+
.font(.pretendardMedium16)
26+
.foregroundColor(.white)
27+
.padding(.vertical, 4)
28+
.padding(.horizontal, 12)
29+
.background(Color.appMain)
30+
.clipShape(Capsule())
5631
}
57-
.listStyle(.plain)
32+
33+
}
34+
.padding([.leading, .trailing], 16)
35+
Text("내 관심사")
36+
.font(.pretendardBold20)
37+
.padding(.leading, 16)
38+
Interests(
39+
topic: "",
40+
titles: viewModel.selectedInterests.map{$0.title},
41+
onClicked: {_ in },
42+
isSelected: {_ in true}
43+
).padding(.leading, 16)
44+
45+
List(viewModel.articles, id: \.self) { item in
46+
LinkRow(previewURL: URL(string: item)!)
47+
.background(Color.backGround).ignoresSafeArea(.all)
5848
}
49+
.listStyle(.plain)
50+
.refreshable { viewModel.loadArticles() }
51+
Spacer()
5952
}
60-
.toolbarVisibility(.hidden, for: .navigationBar)
53+
.background(Color.backGround)
54+
.progressOverlay(isPresented: $viewModel.isLoading, message: "아티클 불러오는중..")
55+
.toastView(toast: $viewModel.toastMessage)
6156
}
6257
}
6358
}
@@ -66,53 +61,5 @@ struct ArticleView: View {
6661
// NavigationView {
6762
// ArticleView(viewModel: ArticleViewModel())
6863
// }
69-
//
70-
//}
71-
72-
73-
74-
//
7564
//
76-
//
77-
/*
78-
[
79-
{
80-
"title": "계룡시, 등굣길 금연 캠페인 성황리에 마무리",
81-
"link": "https://www.news1.kr/articles/?5301234"
82-
},
83-
{
84-
"title": "영도구보건소, 금연구역 인증 걷기 챌린지 운영",
85-
"link": "https://www.news2.kr/articles/?5301235"
86-
},
87-
{
88-
"title": "광주시의회, 세계 금연의 날 맞아 금연 결의 대회 개최",
89-
"link": "https://www.news3.kr/articles/?5301236"
90-
},
91-
{
92-
"title": "팔굽혀펴기로 치매 예방하기?...근육량 증가하면 당뇨·치매 위험 낮아져 [Health Recipe]",
93-
"link": "https://www.healthnews.kr/articles/?5301237"
94-
},
95-
{
96-
"title": "노년층 복병 ‘골근감소증’ “장내 미생물 먹었더니”…뼈밀도·근육량 증가↑",
97-
"link": "https://www.healthnews.kr/articles/?5301238"
98-
},
99-
{
100-
"title": "체중 재증가하는 여성은 근육량보다 지방량 증가가 원인",
101-
"link": "https://www.healthnews.kr/articles/?5301239"
102-
},
103-
{
104-
"title": "금연 무기력함 극복하는 꿀팁 3가지를 소개합니다! : 네이버 블로그",
105-
"link": "https://blog.naver.com/PostView.nhn?blogId=example1&logNo=222123456789"
106-
},
107-
{
108-
"title": "근육량 증가, 근성장을 극대화해줄 꿀팁! - 네이버 블로그",
109-
"link": "https://blog.naver.com/PostView.nhn?blogId=example2&logNo=222123456790"
110-
},
111-
{
112-
"title": "지속 가능한 근육량 증가 운동 프로그램 : 네이버 블로그",
113-
"link": "https://blog.naver.com/PostView.nhn?blogId=example3&logNo=222123456791"
114-
}
115-
]
116-
117-
118-
*/
65+
//}

Dietto/Dietto/Presentation/Article/View/LinkRow.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ struct LinkRow : UIViewRepresentable {
1616
func makeUIView(context: Context) -> LPLinkView {
1717
let view = LPLinkView(url: previewURL)
1818

19-
let provider = LPMetadataProvider()
19+
let provider = LPMetadataProvider() // Provider Fetch작업을 VM에서 미리하는 방식이 더 좋을거 같음 경고가 엄청뜬다 (nil경고, 주소유효성 경고 등등)
2020
provider.startFetchingMetadata(for: previewURL) { (metadata, error) in
2121
if let md = metadata {
2222
DispatchQueue.main.async {
@@ -39,4 +39,4 @@ struct LinkRow : UIViewRepresentable {
3939
func updateUIView(_ view: LPLinkView, context: Context) {
4040
// New instance for each update
4141
}
42-
}
42+
}

Dietto/Dietto/Presentation/Article/ViewModel/ArticleViewModel.swift

Lines changed: 62 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
import SwiftUI
99

1010
final class ArticleViewModel: ObservableObject {
11+
@Published var toastMessage: ToastEntity?
1112
@Published var selectedInterests: [InterestEntity] = []
12-
@Published var articles: [ArticleEntity] = []
13-
@Published var isLoading : Bool = false
13+
@Published var articles: [String] = []
14+
@Published var isLoading : Bool = true
1415

1516
private let alanUsecase: AlanUsecase
1617
private let storageUsecase: InterestsUsecase
@@ -22,32 +23,43 @@ final class ArticleViewModel: ObservableObject {
2223
]
2324

2425
init(
25-
alanUsecase: AlanUsecase = AlanUsecaseImpl(repository: NetworkRepositoryImpl()),
26-
storageUsecase: InterestsUsecase /* = InterestsUsecaseImpl(repository: AnotherStorageRepositoryImpl<InterestsDTO>() */
26+
alanUsecase: AlanUsecase,
27+
storageUsecase: InterestsUsecase
2728
) {
2829
self.alanUsecase = alanUsecase
2930
self.storageUsecase = storageUsecase
3031

3132
Task {
3233
do {
3334
let result = try await storageUsecase.fetchInterests()
34-
await MainActor.run { self.selectedInterests = result }
35+
await MainActor.run {
36+
self.selectedInterests = result
37+
loadArticles()
38+
}
3539
}
3640
catch {
37-
#warning("여기에 에러핸들링 토스트 팝업 등 넣기")
41+
await callToastMessage(type: .error, title: "관심사 로드 실패", message: error.localizedDescription)
3842
}
3943
}
4044
}
4145

4246
// MARK: - 아티클 로드
4347
func loadArticles() {
48+
isLoading = true
4449
Task {
4550
do {
46-
let result = try await alanUsecase.fetchArticle(topics: selectedInterests)
47-
await MainActor.run{ articles = result }
51+
// let result = try await alanUsecase.fetchArticle(topics: selectedInterests)
52+
// await MainActor.run{ articles = result }
53+
// MARK: 임시 로직
54+
try await Task.sleep(for: .seconds(5))
55+
await MainActor.run { [weak self] in
56+
self?.articles = Array((self?.dummyData.shuffled().prefix(5))!)
57+
self?.isLoading = false
58+
self?.toastMessage = ToastEntity(type: .success, title: "아티클 업데이트 완료", message: "")
59+
}
4860
}
4961
catch {
50-
#warning("여기에 에러핸들링 토스트 팝업 등 넣기")
62+
await callToastMessage(type: .error, title: "아티클 로드 실패", message: error.localizedDescription)
5163
}
5264
}
5365

@@ -70,18 +82,53 @@ final class ArticleViewModel: ObservableObject {
7082
if selectedInterests.contains(where: { $0.title == title }) {
7183
removeInterest(title)
7284
Task {
73-
do { try await storageUsecase.deleteInterests(InterestEntity(title: title))}
74-
catch { }
75-
#warning("여기에 에러핸들링 토스트 팝업 등 넣기")
85+
do {
86+
try await storageUsecase.deleteInterests(InterestEntity(title: title))
87+
}
88+
catch {
89+
await callToastMessage(type: .error, title: "관심사 삭제 실패", message: error.localizedDescription)
90+
}
7691
}
7792
} else {
7893
addInterest(title)
7994
Task {
80-
do { try await storageUsecase.insertInterests(InterestEntity(title: title)) }
81-
catch { }
82-
#warning("여기에 에러핸들링 토스트 팝업 등 넣기")
95+
do {
96+
try await storageUsecase.insertInterests(InterestEntity(title: title))
97+
}
98+
catch {
99+
await callToastMessage(type: .error, title: "관심사 추가 실패", message: error.localizedDescription)
100+
}
83101
}
84102

85103
}
86104
}
105+
106+
private func callToastMessage(type: ToastStyle, title: String, message: String) async {
107+
await MainActor.run { [weak self] in
108+
self?.toastMessage = ToastEntity(type: type, title: title, message: message)
109+
}
110+
}
111+
112+
let dummyData = [
113+
"https://www.youtube.com/watch?v=jSuxMiRxnZg",
114+
"https://www.youtube.com/watch?v=2lDheJzSYeo",
115+
"https://www.youtube.com/watch?v=TEHS9dzSTZY",
116+
"https://www.youtube.com/watch?v=MjMkBaqimFo",
117+
"https://www.youtube.com/watch?v=Obu25eMlr4A",
118+
"https://www.youtube.com/watch?v=KFbeFLLJbWo",
119+
"https://www.youtube.com/watch?v=BHY0FxzoKZE",
120+
"https://www.youtube.com/watch?v=8so1WZ4j1oQ",
121+
"https://www.youtube.com/watch?v=zlaZGuXvL04",
122+
"https://www.youtube.com/watch?v=1D9ASR6gSc0",
123+
"https://www.youtube.com/watch?v=Cg_GW7yhq20",
124+
"https://www.youtube.com/watch?v=QWF9mGtjju4",
125+
"https://www.youtube.com/watch?v=YMnIhyWjrb4",
126+
"https://www.youtube.com/watch?v=FoRku07ShZM",
127+
"https://www.youtube.com/watch?v=YNsuneGBsMY",
128+
"https://www.youtube.com/watch?v=3DZqX_2YLiw",
129+
"https://www.youtube.com/watch?v=CSjRBBqfhko",
130+
"https://www.youtube.com/watch?v=wWGulLAa0O0",
131+
"https://www.youtube.com/watch?v=4WV7kAUGrgI",
132+
"https://www.youtube.com/watch?v=8so1WZ4j1oQ"
133+
]
87134
}

Dietto/Dietto/Presentation/Common/LogoProgress.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ struct LogoProgressModifier: ViewModifier {
7575
if isPresented {
7676
Rectangle()
7777
.fill(Color.black.opacity(0.3))
78-
.ignoresSafeArea()
78+
// .ignoresSafeArea()
7979

8080
LogoProgress(isAnimated: $isAnimated, message: message)
8181
.onAppear {

0 commit comments

Comments
 (0)