Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat] #32 Home API 연결 및 바인딩 #33

Merged
merged 4 commits into from
Sep 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 7 additions & 11 deletions dnd-11th-4-iOS/dnd-11th-4-iOS/Network/Base/BaseRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,18 @@ import Alamofire
import RxSwift

final class BaseRequest {
static func request<T: Decodable>(_ endPoint: BaseEndpoint) -> Single<T> {
return Single.create { single in
static func request<T: Decodable>(_ endPoint: BaseEndpoint) -> Observable<T> {
return Observable.create { observer in
let request = APIManager.session.request(endPoint)
.responseDecodable { (response: AFDataResponse<T>) in
switch response.result {
case .success(let result):
do {
guard let statusCode = response.response?.statusCode else { return }
try NetworkManager.statusCodeErrorHandling(statusCode)
single(.success(result))
} catch {
guard let error = error as? MDError else { return }
single(.failure(error))
}
observer.onNext(result)
observer.onCompleted()
case .failure(_):
single(.failure(MDError.serverError))
guard let statusCode = response.response?.statusCode else { return }
let error = NetworkManager.statusCodeErrorHandling(statusCode)
observer.onError(error)
}
}
return Disposables.create { request.cancel() }
Expand Down
3 changes: 3 additions & 0 deletions dnd-11th-4-iOS/dnd-11th-4-iOS/Network/Base/MDError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ enum MDError: Error {
case tokenError
case clientError
case serverError
case castingError

var text: String {
switch self {
Expand All @@ -21,6 +22,8 @@ enum MDError: Error {
return "시스템 오류입니다. 다시 요청해 주세요."
case .serverError:
return "네트워크 오류입니다. 다시 요청해 주세요"
case .castingError:
return "타입 캐스팅 실패"
}
}
}
18 changes: 13 additions & 5 deletions dnd-11th-4-iOS/dnd-11th-4-iOS/Network/Base/NetworkManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,24 @@
import Foundation

final class NetworkManager {
static func statusCodeErrorHandling(_ statusCode: Int) throws {
static func statusCodeErrorHandling(_ statusCode: Int) -> MDError {
switch statusCode {
case 204:
throw MDError.tokenError
return MDError.tokenError
case 400..<500:
throw MDError.clientError
return MDError.clientError
case 500...:
throw MDError.serverError
return MDError.serverError
default:
return
return MDError.serverError
}
}

static func handleError(_ error: Error) -> MDError {
if let mdError = error as? MDError {
return mdError
} else {
return MDError.castingError
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Alamofire
import RxSwift

final class HomeService {
static func getHomeAPI() -> Single<HomeResponse> {
static func getHomeAPI() -> Observable<HomeResponse> {
return BaseRequest.request(HomeEndPoint.getHomeAPI)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ enum MapDeviceInset {
}
}

func deviceInset(size: DeviceSize) -> TopAndLeadingInset {
static func deviceInset(size: DeviceSize) -> TopAndLeadingInset {
switch (size.width, size.height) {
case (430, 932):
return MapDeviceInset.width430Height932.inset
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,25 @@ enum OpacityColorType: Codable {
case blue(Int)
case purple(Int)

init(_ colorString: String, _ opacity: Int) {
switch colorString.lowercased() {
case "pink":
self = .pink(opacity)
case "orange":
self = .orange(opacity)
case "yellow":
self = .yellow(opacity)
case "green":
self = .green(opacity)
case "blue":
self = .blue(opacity)
case "purple":
self = .purple(opacity)
default:
self = .pink(0)
}
}

var color: UIColor {
switch self {
case .pink(let opacity):
Expand All @@ -38,7 +57,7 @@ enum OpacityColorType: Codable {
return .mapPink1
case 2:
return .mapPink2
case 3:
case 3...:
return .mapPink3
default:
return .mapGray
Expand All @@ -51,7 +70,7 @@ enum OpacityColorType: Codable {
return .mapOrange1
case 2:
return .mapOrange2
case 3:
case 3...:
return .mapOrange3
default:
return .mapGray
Expand All @@ -64,7 +83,7 @@ enum OpacityColorType: Codable {
return .mapYellow1
case 2:
return .mapYellow2
case 3:
case 3...:
return .mapYellow3
default:
return .mapGray
Expand All @@ -77,7 +96,7 @@ enum OpacityColorType: Codable {
return .mapGreen1
case 2:
return .mapGreen2
case 3:
case 3...:
return .mapGreen3
default:
return .mapGray
Expand All @@ -90,7 +109,7 @@ enum OpacityColorType: Codable {
return .mapBlue1
case 2:
return .mapBlue2
case 3:
case 3...:
return .mapBlue3
default:
return .mapGray
Expand All @@ -103,7 +122,7 @@ enum OpacityColorType: Codable {
return .mapPurple1
case 2:
return .mapPurple2
case 3:
case 3...:
return .mapPurple3
default:
return .mapGray
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,14 @@ final class HomeMapReactor: Reactor {

enum Mutation {
case setTotalMap(TotalMapModel)
case setSelectedMap(TotalMapModel)
case setSelectedMap(SelectedMapModel?)
case setMapInset(TopAndLeadingInset?)
case setError(MDError)
}

struct State {
var totalMapState = TotalMapModel(selectedMap: nil, totalMapArray: [], visitedMapCount: "0/16")
var dummyState = [ColorWithOpacityModel(name: "서울", opacity: 1, colorType: .pink(3)),
ColorWithOpacityModel(name: "경기도", opacity: 1, colorType: .orange(3)),
ColorWithOpacityModel(name: "인천", opacity: 1, colorType: .blue(1)),
ColorWithOpacityModel(name: "강원도", opacity: 1, colorType: .yellow(3)),
ColorWithOpacityModel(name: "충청북도", opacity: 1, colorType: .blue(2)),
ColorWithOpacityModel(name: "충청남도", opacity: 1, colorType: .pink(1)),
ColorWithOpacityModel(name: "대전", opacity: 1, colorType: .blue(3)),
ColorWithOpacityModel(name: "경상북도", opacity: 1, colorType: .purple(1)),
ColorWithOpacityModel(name: "경상남도", opacity: 1, colorType: .blue(0)),
ColorWithOpacityModel(name: "대구", opacity: 1, colorType: .purple(2)),
ColorWithOpacityModel(name: "울산", opacity: 1, colorType: .blue(1)),
ColorWithOpacityModel(name: "부산", opacity: 1, colorType: .yellow(0)),
ColorWithOpacityModel(name: "전라북도", opacity: 1, colorType: .blue(1)),
ColorWithOpacityModel(name: "전라남도", opacity: 1, colorType: .green(2)),
ColorWithOpacityModel(name: "광주", opacity: 1, colorType: .blue(1)),
ColorWithOpacityModel(name: "제주도", opacity: 1, colorType: .yellow(2))]
var type = MapDeviceInset.width375Height812
var totalMapState: TotalMapModel?
var inset: TopAndLeadingInset?
var selectedMap: String?
}

init() {
Expand All @@ -54,7 +37,13 @@ final class HomeMapReactor: Reactor {
func mutate(action: Action) -> Observable<Mutation> {
switch action {
case .viewWillAppear:
return Observable.just(Mutation.setTotalMap(prepareTotalMap()))
return HomeService.getHomeAPI()
.map { response in
return Mutation.setTotalMap(self.prepareTotalMap(response))
}
.catch { error in
return Observable.just(Mutation.setError(NetworkManager.handleError(error)))
}
case .mapAction(let type):
return Observable.just(Mutation.setSelectedMap(prepareSelectedMap(type: type)))
case .mapInset(let layout):
Expand All @@ -68,41 +57,30 @@ final class HomeMapReactor: Reactor {
case .setTotalMap(let model):
newState.totalMapState = model
case .setSelectedMap(let specificModel):
newState.totalMapState = specificModel
newState.totalMapState?.selectedMap = specificModel
case .setMapInset(let inset):
newState.inset = inset
case .setError(let error):
print(error)
}
return newState
}
}

extension HomeMapReactor {
func prepareTotalMap() -> TotalMapModel {
// 추후 여기서 서버 통신, 현재는 dummyResponse로 color 세팅
let mapArray = initialState.dummyState.map({ data in
MapModel(mapName: data.name, mapColor: data.colorType.color)
})
initialState.totalMapState = TotalMapModel(totalMapArray: mapArray, visitedMapCount: "0/16")
return initialState.totalMapState
}

func prepareSelectedMap(type: RegionType) -> TotalMapModel {
var tempState = initialState.totalMapState
if let index = tempState.totalMapArray.firstIndex(where: { $0.mapName == type.rawValue }) {
tempState.totalMapArray[index] = MapModel(mapName: type.rawValue,
mapColor: .mapSelect)
tempState.selectedMap = SelectedMapModel(selectedMapName: type.rawValue, isHidden: false)
initialState.selectedMap = type.rawValue
func prepareTotalMap(_ response: HomeResponse) -> TotalMapModel {
let mapArray = response.regions.map { region -> MapModel in
let colorType = OpacityColorType(response.selectedColor, region.opacity)
return MapModel(mapName: region.name, mapColor: colorType.color)
}
return tempState
return TotalMapModel(totalMapArray: mapArray, visitedMapCount: "\(response.visitCount)/\(response.totalCount)")
}

func prepareClearMap() -> TotalMapModel {
initialState.totalMapState.selectedMap = nil
return initialState.totalMapState
func prepareSelectedMap(type: RegionType) -> SelectedMapModel? {
type.rawValue == "외부" ? nil : SelectedMapModel(selectedMapName: type.rawValue, isHidden: false)
}

func prepareMapLayoutInset(inset: DeviceSize) -> TopAndLeadingInset {
return initialState.type.deviceInset(size: inset)
return MapDeviceInset.deviceInset(size: inset)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ final class HomeMapViewController: UIViewController, View {
}
.disposed(by: disposeBag)

reactor.state.map{ $0.totalMapState }
reactor.state.compactMap { $0.totalMapState }
.withUnretained(self)
.subscribe { _, data in
for model in data.totalMapArray {
Expand Down Expand Up @@ -180,7 +180,7 @@ final class HomeMapViewController: UIViewController, View {
.disposed(by: disposeBag)

recordButton.rx.tap
.compactMap { reactor.initialState.selectedMap }
.compactMap { reactor.initialState.totalMapState?.selectedMap?.selectedMapName }
.asDriver(onErrorJustReturn: "서울")
.drive(with: self) { owner, text in
let recordVC = RecordViewController(reactor: RecordReactor(),
Expand Down