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] #61 - 스탬프 삭제, 초기화 Domain, Data 및 Network 구현 #65

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import Foundation
public struct I18N {
public struct Default {
public static let error = "에러"
public static let networkError = "네트워크 오류가 발생했습니다."
public static let networkError = "네트워크가 원활하지 않습니다."
public static let networkErrorDescription = "인터넷 연결을 확인하고 다시 시도해 주세요."
public static let delete = "삭제"
public static let cancel = "취소"
public static let ok = "확인"
Expand Down Expand Up @@ -92,6 +93,10 @@ public struct I18N {
public static let suggestion = "서비스 의견 제안"
public static let mission = "미션"
public static let resetMission = "미션 초기화"
public static let resetMissionTitle = "스탬프를 초기화 하시겠습니까?"
public static let resetMissionDescription = "사진, 메모가 삭제되고\n 전체 미션이 미완료상태로 초기화됩니다."
public static let reset = "초기화"
public static let resetSuccess = "초기화 되었습니다"
public static let logout = "로그아웃"
public static let withdraw = "탈퇴하기"
public static let passwordEditSuccess = "비밀번호가 변경되었습니다."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ public class ListDetailRepository {

public init(service: StampService) {
self.stampService = service
print("listdetailrepository", userId)
}
}

Expand All @@ -44,26 +43,8 @@ extension ListDetailRepository: ListDetailRepositoryInterface {
}

public func deleteStamp(stampId: Int) -> Driver<Bool> {
// TODO: - networkService
return Just(Bool.random())
.setFailureType(to: Error.self)
.asDriver()
}
}

extension ListDetailRepository {
private func makeMockListDetailEntity() -> Driver<ListDetailModel> {
let mockData = ListDetailEntity.init(
createdAt: "2022-01-22",
updatedAt: "2022-02-01",
id: 1,
contents: "안녕하세요",
images: ["https://avatars.githubusercontent.com/u/81167570?v=4"],
userID: 3,
missionID: 2)
let date = mockData.toDomain()
return Just(date)
.setFailureType(to: Error.self)
return stampService.deleteStamp(stampId: stampId)
.map { $0 == 200 }
.asDriver()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,28 @@ import Network

public class SettingRepository {

private let networkService: AuthService
private let userId: Int = UserDefaultKeyList.Auth.userId ?? 0
private let authService: AuthService
private let stampService: StampService
private let cancelBag = CancelBag()

public init(service: AuthService) {
self.networkService = service
public init(authService: AuthService, stampService: StampService) {
self.authService = authService
self.stampService = stampService
}
}

extension SettingRepository: SettingRepositoryInterface {

public func resetStamp() -> Driver<Bool> {
stampService.resetStamp(userId: userId)
.map { $0 == 200 }
.asDriver()
}
}

extension SettingRepository: PasswordChangeRepositoryInterface {
public func changePassword(password: String) -> AnyPublisher<Bool, Error> {
networkService.changePassword(password: password, userId: 12).map { statusCode in statusCode == 200 }
authService.changePassword(password: password, userId: 12).map { statusCode in statusCode == 200 }
.eraseToAnyPublisher()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ extension ListDetailEntity {

return ListDetailModel.init(image: self.images.first ?? "",
content: self.contents,
date: changeDateformat(self.updatedAt ?? self.createdAt))
date: changeDateformat(self.updatedAt ?? self.createdAt),
stampId: self.id)
}

private func changeDateformat(_ date: String) -> String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import Foundation
public struct ListDetailModel {

public let image, content, date: String
public let stampId: Int

public init(image: String, content: String, date: String) {
public init(image: String, content: String, date: String, stampId: Int) {
self.image = image
self.content = content
self.date = date
self.stampId = stampId
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
// Copyright © 2022 SOPT-Stamp-iOS. All rights reserved.
//

import Core

import Combine

public protocol SettingRepositoryInterface {

func resetStamp() -> Driver<Bool>
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,30 @@

import Combine

public protocol SettingUseCase {
import Core

public protocol SettingUseCase {
func resetStamp()
var resetSuccess: PassthroughSubject<Bool, Error> { get set }
}

public class DefaultSettingUseCase {

private let repository: SettingRepositoryInterface
private var cancelBag = Set<AnyCancellable>()
private var cancelBag = CancelBag()

public var resetSuccess = PassthroughSubject<Bool, Error>()

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

extension DefaultSettingUseCase: SettingUseCase {

public func resetStamp() {
repository.resetStamp()
.sink { success in
self.resetSuccess.send(success)
}.store(in: self.cancelBag)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public enum StampAPI {
case fetchStampListDetail(userId: Int, missionId: Int)
case postStamp(userId: Int, missionId: Int, requestModel: ListDetailRequestModel)
case putStamp(userId: Int, missionId: Int, requestModel: ListDetailRequestModel)
case deleteStamp(stampId: Int)
case resetStamp(userId: Int)
}

extension StampAPI: BaseAPI {
Expand All @@ -26,11 +28,14 @@ extension StampAPI: BaseAPI {
// MARK: - Header
public var headers: [String : String]? {
switch self {
case .fetchStampListDetail(let userId, _):
case .fetchStampListDetail(let userId, _),
.resetStamp(let userId):
return HeaderType.userId(userId: userId).value
case .postStamp(let userId, _, _),
.putStamp(let userId, _, _):
return HeaderType.multipart(userId: userId).value
case .deleteStamp:
return HeaderType.json.value
}
}

Expand All @@ -41,6 +46,10 @@ extension StampAPI: BaseAPI {
.postStamp(_ , let missionId, _),
.putStamp(_ , let missionId, _):
return "/\(missionId)"
case .deleteStamp(let stampId):
return "/\(stampId)"
case .resetStamp:
return "/all"
}
}

Expand All @@ -51,6 +60,8 @@ extension StampAPI: BaseAPI {
return .post
case .putStamp:
return .put
case .deleteStamp, .resetStamp:
return .delete
default: return .get
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ public protocol StampService {
func fetchStampListDetail(userId: Int, missionId: Int) -> AnyPublisher<ListDetailEntity, Error>
func postStamp(userId: Int, missionId: Int, requestModel: ListDetailRequestModel) -> AnyPublisher<ListDetailEntity, Error>
func putStamp(userId: Int, missionId: Int, requestModel: ListDetailRequestModel) -> AnyPublisher<StampEntity, Error>
func deleteStamp(stampId: Int) -> AnyPublisher<Int, Error>
func resetStamp(userId: Int) -> AnyPublisher<Int, Error>
}

extension DefaultStampService: StampService {
Expand All @@ -34,4 +36,12 @@ extension DefaultStampService: StampService {
public func putStamp(userId: Int, missionId: Int, requestModel: ListDetailRequestModel) -> AnyPublisher<StampEntity, Error> {
requestObjectInCombine(StampAPI.putStamp(userId: userId, missionId: missionId, requestModel: requestModel))
}

public func deleteStamp(stampId: Int) -> AnyPublisher<Int, Error> {
return requestObjectInCombineNoResult(StampAPI.deleteStamp(stampId: stampId))
}

public func resetStamp(userId: Int) -> AnyPublisher<Int, Error> {
return requestObjectInCombineNoResult(StampAPI.resetStamp(userId: userId))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ import SnapKit
import Core
import DSKit

public enum AlertType {
case title
case titleDescription
case networkErr
}

public class AlertVC: UIViewController {

// MARK: - Properties
Expand All @@ -24,23 +30,37 @@ public class AlertVC: UIViewController {
private lazy var backgroundDimmerView = CustomDimmerView(self)
private let alertView = UIView()
private let titleLabel = UILabel()
private let descriptionLabel = UILabel()
private let cancelButton = UIButton()
private let customButton = UIButton()
private var alertType: AlertType!

// MARK: - Init

public init(alertType: AlertType) {
self.alertType = alertType
super.init(nibName: nil, bundle: nil)
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

// MARK: - View Life Cycles

public override func viewDidLoad() {
super.viewDidLoad()
setUI()
setLayout()
setLayout(alertType)
setAddTarget()
}

// MARK: - Custom Method

@discardableResult
public func setTitle(_ title: String) -> Self {
public func setTitle(_ title: String, _ description: String = "") -> Self {
self.titleLabel.text = title
self.descriptionLabel.text = description
return self
}

Expand Down Expand Up @@ -77,26 +97,35 @@ public class AlertVC: UIViewController {

extension AlertVC {
private func setUI() {
self.view.backgroundColor = .clear//.black.withAlphaComponent(0.6)
self.view.backgroundColor = .clear
self.alertView.backgroundColor = .white
self.cancelButton.backgroundColor = DSKitAsset.Colors.gray300.color
self.cancelButton.backgroundColor = (self.alertType == .networkErr) ? DSKitAsset.Colors.error200.color : DSKitAsset.Colors.gray300.color
self.customButton.backgroundColor = DSKitAsset.Colors.error200.color

self.titleLabel.setTypoStyle(.subtitle1)
self.descriptionLabel.setTypoStyle(.caption3)
self.cancelButton.titleLabel?.setTypoStyle(.subtitle1)
self.customButton.titleLabel?.setTypoStyle(.subtitle1)

self.titleLabel.textColor = DSKitAsset.Colors.gray900.color
self.descriptionLabel.textColor = DSKitAsset.Colors.gray500.color
self.cancelButton.titleLabel?.textColor = DSKitAsset.Colors.gray700.color
self.customButton.titleLabel?.textColor = DSKitAsset.Colors.white.color

self.cancelButton.setTitle(I18N.Default.cancel, for: .normal)
self.descriptionLabel.textAlignment = .center
self.descriptionLabel.numberOfLines = 2

let cancelTitle = (self.alertType == .networkErr) ? I18N.Default.ok : I18N.Default.cancel
self.cancelButton.setTitle(cancelTitle, for: .normal)

self.alertView.layer.cornerRadius = 10
self.alertView.layer.masksToBounds = true
}

private func setLayout() {
private func setLayout(_ type: AlertType) {
let heightRatio = (type == .title) ? 0.49 : 0.55
let titleOffset = (type == .title) ? -22 : -35

self.view.addSubviews(backgroundDimmerView, alertView)

backgroundDimmerView.snp.makeConstraints { make in
Expand All @@ -106,26 +135,53 @@ extension AlertVC {
alertView.snp.makeConstraints { make in
make.center.equalToSuperview()
make.leading.trailing.equalToSuperview().inset(50)
make.height.equalTo(alertView.snp.width).multipliedBy(0.49)
make.height.equalTo(alertView.snp.width).multipliedBy(heightRatio)
}

alertView.addSubviews(titleLabel, cancelButton, customButton)
self.setButtonLayout(type)

alertView.addSubview(titleLabel)

cancelButton.snp.makeConstraints { make in
make.leading.bottom.equalToSuperview()
make.width.equalTo(alertView.snp.width).multipliedBy(0.5)
make.height.equalTo(cancelButton.snp.width).multipliedBy(0.347)
titleLabel.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.centerY.equalToSuperview().offset(titleOffset)
}

customButton.snp.makeConstraints { make in
make.trailing.bottom.equalToSuperview()
make.leading.equalTo(cancelButton.snp.trailing)
make.top.equalTo(cancelButton.snp.top)
if type != .title {
alertView.addSubview(descriptionLabel)

descriptionLabel.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.centerY.equalToSuperview().offset(-6)
make.leading.trailing.equalToSuperview().inset(30)
}
}
}

private func setButtonLayout(_ type: AlertType) {
alertView.addSubviews(cancelButton)

titleLabel.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.centerY.equalToSuperview().offset(-22)
switch type {
case .title, .titleDescription:
alertView.addSubviews(customButton)

cancelButton.snp.makeConstraints { make in
make.leading.bottom.equalToSuperview()
make.width.equalTo(alertView.snp.width).multipliedBy(0.5)
make.height.equalTo(cancelButton.snp.width).multipliedBy(0.347)
}

customButton.snp.makeConstraints { make in
make.trailing.bottom.equalToSuperview()
make.leading.equalTo(cancelButton.snp.trailing)
make.top.equalTo(cancelButton.snp.top)
}
case .networkErr:
cancelButton.snp.makeConstraints { make in
make.leading.trailing.bottom.equalToSuperview()
make.width.equalTo(alertView.snp.width)
make.height.equalTo(cancelButton.snp.width).multipliedBy(0.17)
}
}
}
}
Loading