Skip to content

Commit

Permalink
Merge pull request sopt-makers#53 from L-j-h-c/feature/sopt-makers#28-…
Browse files Browse the repository at this point in the history
…MissionListBusiness

[Feat] sopt-makers#28 - 미션 리스트 뷰 비즈니스 로직 구현
  • Loading branch information
L-j-h-c authored Dec 24, 2022
2 parents c70cbf2 + 4c534a7 commit 93a36a3
Show file tree
Hide file tree
Showing 19 changed files with 395 additions and 136 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// MissionListFetchType.swift
// Core
//
// Created by Junho Lee on 2022/12/21.
// Copyright © 2022 SOPT-Stamp-iOS. All rights reserved.
//

import Foundation

public enum MissionListFetchType: String {
case all
case complete
case incomplete

public var path: String {
return self.rawValue
}
}
8 changes: 4 additions & 4 deletions SOPT-Stamp-iOS/Projects/Core/Sources/Enum/StarViewLevel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

import Foundation

public enum StarViewLevel {
case levelOne
case levelTwo
case levelThree
public enum StarViewLevel: Int {
case levelOne = 1
case levelTwo = 2
case levelThree = 3
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,38 @@

import Combine

import Core
import Domain
import Network

public class MissionListRepository {

private let networkService: MissionService
private let cancelBag = Set<AnyCancellable>()
private let missionService: MissionService
private let cancelBag = CancelBag()

public init(service: MissionService) {
self.networkService = service
self.missionService = service
}
}

extension MissionListRepository: MissionListRepositoryInterface {

public func fetchMissionList(type: MissionListFetchType, userId: Int?) -> AnyPublisher<[MissionListModel], Error> {
let userId: Int = (userId != nil)
? userId!
: 1
switch type {
case .all:
return missionService.fetchAllMissionList(userId: userId)
.map { $0.toDomain() }
.eraseToAnyPublisher()
case .complete:
return missionService.fetchCompleteMissionList(userId: userId)
.map { $0.toDomain() }
.eraseToAnyPublisher()
case .incomplete:
return missionService.fetchIncompleteMissionList(userId: userId)
.map { $0.toDomain() }
.eraseToAnyPublisher()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// MissionListTransform.swift
// Data
//
// Created by Junho Lee on 2022/12/20.
// Copyright © 2022 SOPT-Stamp-iOS. All rights reserved.
//

import Foundation

import Domain
import Network

public extension MissionListEntity {
func toDomain() -> [MissionListModel] {
return self.map { .init(id: $0.id,
title: $0.title,
level: $0.level,
isCompleted: $0.isCompleted) }
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,16 @@

import Foundation

public struct MissionListModel {

public init() {

public struct MissionListModel: Codable, Hashable {
public let id: Int
public let title: String
public let level: Int
public let isCompleted: Bool

public init(id: Int, title: String, level: Int, isCompleted: Bool) {
self.id = id
self.title = title
self.level = level
self.isCompleted = isCompleted
}
}
16 changes: 0 additions & 16 deletions SOPT-Stamp-iOS/Projects/Domain/Sources/Model/SampleModel.swift

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

import Combine

import Core

public protocol MissionListRepositoryInterface {

func fetchMissionList(type: MissionListFetchType, userId: Int?) -> AnyPublisher<[MissionListModel], Error>
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,43 @@

import Combine

public protocol MissionListUseCase {
import Core

public protocol MissionListUseCase {
func fetchMissionList(type: MissionListFetchType)
func fetchOtherUserMissionList(type: MissionListFetchType, userId: Int)
var missionListModelsFetched: PassthroughSubject<[MissionListModel], Error> { get set }
}

public class DefaultMissionListUseCase {

private let repository: MissionListRepositoryInterface
private var cancelBag = Set<AnyCancellable>()
private var cancelBag = CancelBag()
public var missionListModelsFetched = PassthroughSubject<[MissionListModel], Error>()

public init(repository: MissionListRepositoryInterface) {
self.repository = repository
}
}

extension DefaultMissionListUseCase: MissionListUseCase {

public func fetchOtherUserMissionList(type: MissionListFetchType, userId: Int) {
repository.fetchMissionList(type: type, userId: userId)
.sink(receiveCompletion: { event in
print("completion: \(event)")
}, receiveValue: { model in
self.missionListModelsFetched.send(model)
})
.store(in: cancelBag)
}

public func fetchMissionList(type: MissionListFetchType) {
repository.fetchMissionList(type: type, userId: nil)
.sink(receiveCompletion: { event in
print("completion: \(event)")
}, receiveValue: { model in
self.missionListModelsFetched.send(model)
})
.store(in: cancelBag)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,17 @@ extension CustomNavigationBar {
titleLabel.setTypoStyle(font)
return self
}

@discardableResult
public func setTitleButtonMenu(menuItems: [UIAction]) -> Self {
titleButton.menu = UIMenu(title: "",
image: nil,
identifier: nil,
options: [.displayInline],
children: menuItems)
titleButton.showsMenuAsPrimaryAction = true
return self
}
}

// MARK: - @objc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,56 +8,62 @@

import Foundation

import Core

import Alamofire
import Moya

public enum MissionAPI {
case sample(provider: String)
case fetchMissionList(type: MissionListFetchType, userId: Int)
}

extension MissionAPI: BaseAPI {

public static var apiType: APIType = .auth
public static var apiType: APIType = .mission

// MARK: - Header
public var headers: [String: String]? {
switch self {
case .fetchMissionList(_, let userId):
return HeaderType.userId(userId: userId).value
default: return HeaderType.json.value
}
}

// MARK: - Path
public var path: String {
switch self {
case .sample:
return ""
case .fetchMissionList(let type, _):
return "/\(type.path)"
default: return ""
}
}

// MARK: - Method
public var method: Moya.Method {
switch self {
case .sample:
return .post
default: return .get
}
}

// MARK: - Parameters
private var bodyParameters: Parameters? {
var params: Parameters = [:]
switch self {
case .sample(let provider):
params["platform"] = provider
default: break
}
return params
}

private var parameterEncoding: ParameterEncoding {
switch self {
case .sample:
return URLEncoding.init(destination: .queryString, arrayEncoding: .noBrackets, boolEncoding: .literal)
default:
return JSONEncoding.default
}
}

public var task: Task {
switch self {
case .sample:
return .requestParameters(parameters: bodyParameters ?? [:], encoding: parameterEncoding)
default:
return .requestPlain
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@

import Foundation

public struct MissionListEntity {

public struct MissionListEntityElement: Codable {
public let id: Int
public let title: String
public let level: Int
public let profileImage: [String]?
public let isCompleted: Bool
}

public typealias MissionListEntity = [MissionListEntityElement]
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import Moya
import Foundation

public enum APIType {
case notice
case auth
case alert
case mission
case rank
case stamp
case user
}

Expand All @@ -26,23 +27,44 @@ extension BaseAPI {
var base = Config.Network.baseURL

switch Self.apiType {
case .alert:
base += "/alert"
case .notice:
base += "/notice"
case .auth:
base += "/auth"
case .mission:
base += "/mission"
case .rank:
base += "/rank"
case .stamp:
base += "/stamp"
case .user:
base += "/user"
}

guard let url = URL(string: base) else {
fatalError("baseURL could not be configured")
}

return url
}

public var headers: [String: String]? {
return ["Content-Type": "application/json"]
}
}

public enum HeaderType {
case json
case jsonUserId(userId: Int)
case userId(userId: Int)

public var value: [String: String] {
switch self {
case .json:
return ["Content-Type": "application/json"]
case .jsonUserId(let userId):
return ["Content-Type": "application/json",
"userId": String(userId)]
case .userId(let userId):
return ["userId": String(userId)]
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public extension BaseService {
// MARK: - MakeRequests

extension BaseService {
func requestObjectInCombine<T: Decodable>(_ target: API) -> AnyPublisher<T?, Error> {
func requestObjectInCombine<T: Decodable>(_ target: API) -> AnyPublisher<T, Error> {
return Future { promise in
self.provider.request(target) { response in
switch response {
Expand Down
Loading

0 comments on commit 93a36a3

Please sign in to comment.