Skip to content

Commit

Permalink
feature: 고양이선택, 고양이 이름짓기 stream listener 연결
Browse files Browse the repository at this point in the history
  • Loading branch information
Jihyun247 committed Nov 24, 2024
1 parent 6b9a3fd commit 1b1e4d9
Show file tree
Hide file tree
Showing 10 changed files with 232 additions and 53 deletions.
52 changes: 45 additions & 7 deletions Projects/Feature/CatFeature/Sources/NamingCat/NamingCatCore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import CatServiceInterface
import DesignSystem
import UserServiceInterface
import DatabaseClientInterface
import StreamListenerInterface

import ComposableArchitecture
import RiveRuntime
Expand Down Expand Up @@ -41,6 +42,8 @@ public struct NamingCatCore {
case setTooltip(DownDirectionTooltip?)
case saveChangedCat(SomeCat)
case _setNextAction
case _postNamedCatRequest(ChangeCatNameRequest)
case _postNamedCatResponse(Result<Void, Error>)
case binding(BindingAction<State>)
}

Expand All @@ -54,6 +57,7 @@ public struct NamingCatCore {
@Dependency(CatService.self) var catService
@Dependency(UserService.self) var userService
@Dependency(DatabaseClient.self) var databaseClient
@Dependency(StreamListener.self) var streamListener
let isOnboardedKey = "mohanyang_userdefaults_isOnboarded"

public init() {}
Expand Down Expand Up @@ -81,12 +85,7 @@ public struct NamingCatCore {
let catName = state.text == "" ? selectedCat.baseInfo.name : state.text
let request = ChangeCatNameRequest(name: catName)
return .run { send in
try await catService.changeCatName(
apiClient: apiClient,
request: request
)
try await self.userService.syncUserInfo(apiClient: self.apiClient, databaseClient: self.databaseClient)
await send(._setNextAction)
await send(._postNamedCatRequest(request))
}

case .catSetInput:
Expand All @@ -107,7 +106,7 @@ public struct NamingCatCore {
case ._setNextAction:
return .run { [state] send in
if state.route == .onboarding {
await userDefaultsClient.setBool(true, key: isOnboardedKey)
await self.userDefaultsClient.setBool(true, key: isOnboardedKey)
await send(.moveToHome)
} else {
if let selectedCat = state.selectedCat {
Expand All @@ -116,6 +115,24 @@ public struct NamingCatCore {
}
}

case let ._postNamedCatRequest(request):
return .run { send in
await self.streamListener.sendServerState(state: .requestStarted)
await send(._postNamedCatResponse(Result {
try await self.catService.changeCatName(apiClient: apiClient, request: request)
}))
}

case ._postNamedCatResponse(.success(_)):
return .run { send in
try await self.userService.syncUserInfo(apiClient: self.apiClient, databaseClient: self.databaseClient)
await self.streamListener.sendServerState(state: .requestCompleted)
await send(._setNextAction)
}

case let ._postNamedCatResponse(.failure(error)):
return self.handleError(error: error)

case .binding(\.text):
state.inputFieldError = setError(state.text)
if state.text == "" && state.route == .myPage {
Expand Down Expand Up @@ -148,3 +165,24 @@ public struct NamingCatCore {
return error
}
}

extension NamingCatCore {
private func handleError(error: any Error) -> EffectOf<NamingCatCore> {
if let networkError = error as? URLError,
networkError.code == .networkConnectionLost ||
networkError.code == .notConnectedToInternet {
return .run { send in
await streamListener.sendServerState(state: .networkDisabled)
}
}
guard let error = error as? NetworkError else { return .none }
switch error {
case .apiError(_):
return .run { send in
await streamListener.sendServerState(state: .errorOccured)
}
default:
return .none
}
}
}
68 changes: 45 additions & 23 deletions Projects/Feature/CatFeature/Sources/SelectCat/SelectCatCore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ public struct SelectCatCore {
case _moveToNamingCat
case _fetchCatListRequest
case _fetchCatListResponse(Result<[Cat], Error>)
case _postSelectedCatRequest(SelectCatRequest)
case _postSelectedCatResponse(Result<Void, Error>)
case binding(BindingAction<State>)
case namingCat(PresentationAction<NamingCatCore.Action>)
}
Expand Down Expand Up @@ -97,9 +99,7 @@ public struct SelectCatCore {
guard let selectedCat = state.selectedCat else { return .none }
let request = SelectCatRequest(catNo: selectedCat.baseInfo.no)
return .run { send in
try await userService.selectCat(apiClient: self.apiClient, request: request)
try await userService.syncUserInfo(apiClient: self.apiClient, databaseClient: self.databaseClient)
await send(._setNextAction)
await send(._postSelectedCatRequest(request))
}

case .saveChangedCat:
Expand All @@ -126,13 +126,9 @@ public struct SelectCatCore {
case ._fetchCatListRequest:
return .run { send in
await streamListener.sendServerState(state: .requestStarted)
await send(
._fetchCatListResponse(
Result {
try await catService.getCatList(apiClient)
}
)
)
await send(._fetchCatListResponse(Result {
try await catService.getCatList(apiClient)
}))
}

case let ._fetchCatListResponse(.success(response)):
Expand All @@ -141,23 +137,27 @@ public struct SelectCatCore {
await streamListener.sendServerState(state: .requestCompleted)
}

// TODO: 리팩토링 필요
case let ._fetchCatListResponse(.failure(error)):
if let networkError = error as? URLError, networkError.code == .notConnectedToInternet {
return .run { send in
await streamListener.sendServerState(state: .networkDisabled)
}
return handleError(error: error)

case let ._postSelectedCatRequest(request):
return .run { send in
await streamListener.sendServerState(state: .requestStarted)
await send(._postSelectedCatResponse(Result {
try await userService.selectCat(apiClient: self.apiClient, request: request)
}))
}
guard let error = error as? NetworkError else { return .none }
switch error {
case .apiError(_):
return .run { send in
await streamListener.sendServerState(state: .errorOccured)
}
default:
return .none

case ._postSelectedCatResponse(.success(_)):
return .run { send in
try await userService.syncUserInfo(apiClient: self.apiClient, databaseClient: self.databaseClient)
await streamListener.sendServerState(state: .requestCompleted)
await send(._setNextAction)
}

case let ._postSelectedCatResponse(.failure(error)):
return handleError(error: error)

case .binding:
return .none

Expand All @@ -166,3 +166,25 @@ public struct SelectCatCore {
}
}
}

extension SelectCatCore {
// TODO: 다른 곳에서도 사용될 코드인데 따로 뺄 방법 ..
private func handleError(error: any Error) -> EffectOf<SelectCatCore> {
if let networkError = error as? URLError,
networkError.code == .networkConnectionLost ||
networkError.code == .notConnectedToInternet {
return .run { send in
await streamListener.sendServerState(state: .networkDisabled)
}
}
guard let error = error as? NetworkError else { return .none }
switch error {
case .apiError(_):
return .run { send in
await streamListener.sendServerState(state: .errorOccured)
}
default:
return .none
}
}
}
12 changes: 6 additions & 6 deletions Projects/Feature/ErrorFeature/Example/Sources/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ struct ContentView: View {

Spacer()
}
.fullScreenCover(isPresented: $isNetworkErrorViewPresented) {
NetworkErrorView()
}
.fullScreenCover(isPresented: $isRequestErrorViewPresented) {
RequestErrorView()
}
// .fullScreenCover(isPresented: $isNetworkErrorViewPresented) {
// NetworkErrorView()
// }
// .fullScreenCover(isPresented: $isRequestErrorViewPresented) {
// RequestErrorView()
// }
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// NetworkErrorCore.swift
// ErrorFeature
//
// Created by 김지현 on 11/24/24.
// Copyright © 2024 PomoNyang. All rights reserved.
//

import ComposableArchitecture

@Reducer
public struct NetworkErrorCore {
@ObservableState
public struct State: Equatable {
public init() { }
}

public enum Action {
case tryAgain
}

public init() { }

public var body: some ReducerOf<Self> {
Reduce(self.core)
}

private func core(_ state: inout State, _ action: Action) -> EffectOf<Self> {
switch action {
case .tryAgain:
return .none
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@ import SwiftUI

import DesignSystem

import ComposableArchitecture

public struct NetworkErrorView: View {
@Environment(\.dismiss) var dismiss

public init() {
let store: StoreOf<NetworkErrorCore>

public init(store: StoreOf<NetworkErrorCore>) {
self.store = store
}

public var body: some View {
Expand All @@ -38,6 +42,7 @@ public struct NetworkErrorView: View {
.padding(.bottom, 34)

Button(title: "다시 시도하기") {
store.send(.tryAgain)
dismiss()
}
.buttonStyle(.box(level: .primary, size: .large, width: .medium))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// RequestErrorCore.swift
// ErrorFeature
//
// Created by 김지현 on 11/24/24.
// Copyright © 2024 PomoNyang. All rights reserved.
//

import Foundation

import ComposableArchitecture

@Reducer
public struct RequestErrorCore {
@ObservableState
public struct State: Equatable {
public init() { }
}

public enum Action {
case moveToHome
case moveToCustomerService
}

public init() { }

@Dependency(\.openURL) var openURL

public var body: some ReducerOf<Self> {
Reduce(self.core)
}

private func core(_ state: inout State, _ action: Action) -> EffectOf<Self> {
switch action {
case .moveToHome:
return .none
case .moveToCustomerService:
guard let feedbackURL = URL(string: "https://forms.gle/wEUPH9Tvxgua4hCZ9") else { return .none }
return .run { _ in await self.openURL(feedbackURL) }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@ import SwiftUI

import DesignSystem

import ComposableArchitecture

public struct RequestErrorView: View {
@Environment(\.dismiss) var dismiss

public init() {
let store: StoreOf<RequestErrorCore>

public init(store: StoreOf<RequestErrorCore>) {
self.store = store
}

public var body: some View {
Expand All @@ -39,13 +43,15 @@ public struct RequestErrorView: View {

VStack(spacing: Alias.Spacing.large) {
Button(title: "홈으로 이동") {
store.send(.moveToHome)
dismiss()
}
.buttonStyle(.box(level: .primary, size: .large, width: .medium))

Button(
action: {
print("고객센터 문의")
store.send(.moveToCustomerService)
dismiss()
},
label: {
Text("고객센터 문의")
Expand Down
Loading

0 comments on commit 1b1e4d9

Please sign in to comment.