0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SwiftUI TCA - API

Posted at

fetch - MemoClient

struct MemoClient {
    typealias Memos = [Memo]
    // fetch single Item
    var fetchMemoItem: (_ id: String) -> Effect<Memo, Failure>

    // fetch 
    var fetchMemos: () -> Effect<Memos, Failure>

    struct Failure: Error, Equatable {}
}

extension MemoClient {
    static let live = Self(
        fetchMemoItem: { id in
            Effect.task {
                let (data, _) = try await URLSession.shared.data(from: URL(string: "....\(id)")!)
                return try JSONDecoder().decode(Memo.self, from: data)
            }
            .mapError { _ in Failure() }
            .eraseToEffect()
        }, fetchMemos: {
            Effect.task {
                let (data, _) = try await URLSession.shared.data(from: URL(string: "....")!)
                return try JSONDecoder().decode(Memos.self, from: data) // [Memo].self
            }
            .mapError { _ in Failure() }
            .eraseToEffect()
        }
    ) // MemoClient()
}

実装

struct MemoState: Equatable {
    var memos: [Memo] = []
    var selectedMemo: Memo? = nil
    var isLoading: Bool = false
}

enum MemoAction: Equaltable {
    case fetchItem(_ id: String) // action
    case fetchItemRespose(Result<Memo, MemoClient.Failure>) // single respose
    case fetchAll // action
    case fetchAllRespose(Result<[Memo], MemoClient.FAilure>) // all respose
}

struct MemoEnviroment {
    var memoClient: MemoClient
    var mainQueue: AnySchedulerOf<DispatchQueue>
}

let memoReducer = Reducer<MemoState, MemoAction, MemoEnviroment> { state, action, enviroment in 
    switch action {
    case .fetchItem(let memoId):
        enum FetchItemID {}
        state.isLoading = true
        return enviroment.memoClient
                .fetchMemoItem(memoId)
                .debounce(id: FetchItemId.self, for: 0.3, scheduler: enviroment.mainQueue)
                .catchToEffect(MemoAction.fetchItemResponse)
    case .fetchItemRespose(.success(let memo)):
        state.selectedMemo = memo
        state.isLoading = false
        return Effect.none
    case .fetchItemRespose(.failure):
        state.selectedMemo = nil
        state.isLoading = false
        return Effect.none
    case .fetchAll:
        enum FetchAllId {}
        state.isLoading = true
        return enviroment.memoClient
                .fetchMemos
                .debounce(id: FetchAllId.self, for: 0.3, scheduler: enviroment.mainQueue)
                .catchToEffect(MemoAction.fetchAllResponse)
    case .fetchAllRespose(.success(let memos)):
        state.memos = memos
        state.isLoading = false
        return Effect.none
    case .fetchAllRespose(.failure):
        state.memos = nil
        state.isLoading = false
        return Effect.none
    }

実装 - View

...

 viewStore.send(.fetchItem("xxx")
 viewStore.send(.fetchAll)


 if viewStore.state.isLoading {
    Color.black.opacity(0.3)
        .edgesIgnoringSafeArea(.fill)
        .overlay { 
            ProgressView().tint(.white)
                .scaleEffect(1.7)
        }.zIndex(1)
 }
 ....
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?