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

Refactor [#87] 홈 피트 리팩토링 완료 #89

Merged
merged 16 commits into from
Jan 18, 2025
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
28 changes: 28 additions & 0 deletions Wable-iOS.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
0573B8C42CEC63EC00B5A434 /* FlattenReplyModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0573B8C32CEC63EC00B5A434 /* FlattenReplyModel.swift */; };
0586D89B2D09A68200436080 /* Pretendard-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 0586D8992D09A68200436080 /* Pretendard-Regular.otf */; };
0586D89C2D09A68200436080 /* Pretendard-SemiBold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 0586D89A2D09A68200436080 /* Pretendard-SemiBold.otf */; };
0589AECF2D38311A004F531E /* PopupType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0589AECE2D383119004F531E /* PopupType.swift */; };
0593F6D62C96D6C100FFAD82 /* WablePhotoDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0593F6D52C96D6C100FFAD82 /* WablePhotoDetailView.swift */; };
0593F6DB2C96E75600FFAD82 /* FirebaseAnalytics in Frameworks */ = {isa = PBXBuildFile; productRef = 0593F6DA2C96E75600FFAD82 /* FirebaseAnalytics */; };
0593F6DD2C96E75600FFAD82 /* FirebaseMessaging in Frameworks */ = {isa = PBXBuildFile; productRef = 0593F6DC2C96E75600FFAD82 /* FirebaseMessaging */; };
Expand All @@ -103,6 +104,12 @@
05B4F47D2CF8BE360033FF67 /* Array+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05B4F47C2CF8BE360033FF67 /* Array+.swift */; };
05B4F47F2CF8C2450033FF67 /* BanRequestDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05B4F47E2CF8C2450033FF67 /* BanRequestDTO.swift */; };
05F1FF422D11C95F00982033 /* BanTargetInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05F1FF412D11C95F00982033 /* BanTargetInfo.swift */; };
05F1FF442D17EA1D00982033 /* MigratedHomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05F1FF432D17EA1D00982033 /* MigratedHomeViewController.swift */; };
05F1FF462D1AAAE300982033 /* MigratedHomeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05F1FF452D1AAAE300982033 /* MigratedHomeViewModel.swift */; };
05F1FF482D1AB39000982033 /* MigratedHomeFeedCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05F1FF472D1AB39000982033 /* MigratedHomeFeedCell.swift */; };
05F1FF4A2D1AB42A00982033 /* MigratedHomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05F1FF492D1AB42A00982033 /* MigratedHomeView.swift */; };
05F1FF4C2D32685A00982033 /* PopupViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05F1FF4B2D32685A00982033 /* PopupViewModel.swift */; };
05F1FF502D33DF9600982033 /* HomePopupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05F1FF4F2D33DF9600982033 /* HomePopupViewController.swift */; };
05FBEED22C886A0200E4BF17 /* HomeFeedContentDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05FBEED12C886A0200E4BF17 /* HomeFeedContentDTO.swift */; };
3C3531822C6F15D30015A8FA /* KeychainWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C3531812C6F15D30015A8FA /* KeychainWrapper.swift */; };
3C3531842C6F16D00015A8FA /* Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C3531832C6F16D00015A8FA /* Config.swift */; };
Expand Down Expand Up @@ -309,6 +316,7 @@
0573B8C32CEC63EC00B5A434 /* FlattenReplyModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlattenReplyModel.swift; sourceTree = "<group>"; };
0586D8992D09A68200436080 /* Pretendard-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Pretendard-Regular.otf"; sourceTree = "<group>"; };
0586D89A2D09A68200436080 /* Pretendard-SemiBold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Pretendard-SemiBold.otf"; sourceTree = "<group>"; };
0589AECE2D383119004F531E /* PopupType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopupType.swift; sourceTree = "<group>"; };
0593F6D52C96D6C100FFAD82 /* WablePhotoDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WablePhotoDetailView.swift; sourceTree = "<group>"; };
0593F6E32C9AFC1B00FFAD82 /* WablePushAlarmHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WablePushAlarmHelper.swift; sourceTree = "<group>"; };
05AD1EB42CE4C1D900F36D6B /* Dev.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Dev.xcconfig; sourceTree = "<group>"; };
Expand All @@ -317,6 +325,12 @@
05B4F47C2CF8BE360033FF67 /* Array+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+.swift"; sourceTree = "<group>"; };
05B4F47E2CF8C2450033FF67 /* BanRequestDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BanRequestDTO.swift; sourceTree = "<group>"; };
05F1FF412D11C95F00982033 /* BanTargetInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BanTargetInfo.swift; sourceTree = "<group>"; };
05F1FF432D17EA1D00982033 /* MigratedHomeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigratedHomeViewController.swift; sourceTree = "<group>"; };
05F1FF452D1AAAE300982033 /* MigratedHomeViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigratedHomeViewModel.swift; sourceTree = "<group>"; };
05F1FF472D1AB39000982033 /* MigratedHomeFeedCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigratedHomeFeedCell.swift; sourceTree = "<group>"; };
05F1FF492D1AB42A00982033 /* MigratedHomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigratedHomeView.swift; sourceTree = "<group>"; };
05F1FF4B2D32685A00982033 /* PopupViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopupViewModel.swift; sourceTree = "<group>"; };
05F1FF4F2D33DF9600982033 /* HomePopupViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomePopupViewController.swift; sourceTree = "<group>"; };
05FBEED12C886A0200E4BF17 /* HomeFeedContentDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeFeedContentDTO.swift; sourceTree = "<group>"; };
3C3531812C6F15D30015A8FA /* KeychainWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainWrapper.swift; sourceTree = "<group>"; };
3C3531832C6F16D00015A8FA /* Config.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Config.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -489,6 +503,7 @@
050E0CB42C74B85800326EEA /* HomeView.swift */,
050E0CB62C74B87400326EEA /* FeedDetailView.swift */,
3C8B4E522C83FB7C00174943 /* HomeBottomSheetView.swift */,
05F1FF492D1AB42A00982033 /* MigratedHomeView.swift */,
);
path = Views;
sourceTree = "<group>";
Expand All @@ -499,6 +514,8 @@
050E0CC82C74B92A00326EEA /* HomeViewModel.swift */,
3C8B4E472C80E1C900174943 /* FeedDetailViewModel.swift */,
3C8B4E4E2C83F01500174943 /* LikeViewModel.swift */,
05F1FF452D1AAAE300982033 /* MigratedHomeViewModel.swift */,
05F1FF4B2D32685A00982033 /* PopupViewModel.swift */,
);
path = ViewModels;
sourceTree = "<group>";
Expand All @@ -507,6 +524,7 @@
isa = PBXGroup;
children = (
050E0CCC2C74B95B00326EEA /* Team.swift */,
0589AECE2D383119004F531E /* PopupType.swift */,
);
path = Supports;
sourceTree = "<group>";
Expand All @@ -516,6 +534,7 @@
children = (
050E0CC42C74B8F000326EEA /* HomeFeedTableViewCell.swift */,
050E0CC62C74B8FD00326EEA /* FeedDetailTableViewCell.swift */,
05F1FF472D1AB39000982033 /* MigratedHomeFeedCell.swift */,
);
path = Cells;
sourceTree = "<group>";
Expand Down Expand Up @@ -862,6 +881,8 @@
children = (
0547F4F42C64C76A001E3039 /* HomeViewController.swift */,
050E0CCA2C74B94800326EEA /* FeedDetailViewController.swift */,
05F1FF432D17EA1D00982033 /* MigratedHomeViewController.swift */,
05F1FF4F2D33DF9600982033 /* HomePopupViewController.swift */,
);
path = ViewController;
sourceTree = "<group>";
Expand Down Expand Up @@ -1660,6 +1681,7 @@
3C8B4E182C78E21900174943 /* SocialLoginResponseDTO.swift in Sources */,
0547F49A2C60D968001E3039 /* AppDelegate.swift in Sources */,
050E0CC32C74B8B600326EEA /* FeedBottomView.swift in Sources */,
0589AECF2D38311A004F531E /* PopupType.swift in Sources */,
0547F4DF2C62486C001E3039 /* APIConstants.swift in Sources */,
050E0CD92C74BFC200326EEA /* InfoLogoView.swift in Sources */,
DE54C3E42CF4EB6B00753129 /* NoticeCell.swift in Sources */,
Expand Down Expand Up @@ -1691,6 +1713,7 @@
3CF344DE2C74AB3B0038BB53 /* MyPageAccountInfoViewModel.swift in Sources */,
050E0CF12C750F6300326EEA /* NotificationContentView.swift in Sources */,
3C8B4E1B2C78E55200174943 /* TokenManager.swift in Sources */,
05F1FF4C2D32685A00982033 /* PopupViewModel.swift in Sources */,
3CDE2E1D2C723325004A84CB /* NotificationSegmentedControl.swift in Sources */,
050E0CB52C74B85800326EEA /* HomeView.swift in Sources */,
DE9D0E342CF087B30024BB1F /* LCKGameTypeDTO.swift in Sources */,
Expand All @@ -1702,6 +1725,7 @@
050E0D162C8252B200326EEA /* NotificationAPI.swift in Sources */,
050E0CDF2C74C8B400326EEA /* MatchSessionTableViewCell.swift in Sources */,
3C8B4E3B2C79119700174943 /* MyPageMemberContentResponseDTO.swift in Sources */,
05F1FF442D17EA1D00982033 /* MigratedHomeViewController.swift in Sources */,
3C8B4E352C79117C00174943 /* MyPageMemberDeleteDTO.swift in Sources */,
05FBEED22C886A0200E4BF17 /* HomeFeedContentDTO.swift in Sources */,
0547F4C02C62166C001E3039 /* Adjusted+.swift in Sources */,
Expand Down Expand Up @@ -1744,6 +1768,7 @@
0547F4FC2C64C797001E3039 /* MyPageViewController.swift in Sources */,
0547F4FA2C64C78C001E3039 /* NotificationViewController.swift in Sources */,
3CF344E72C750DBD0038BB53 /* MyPageSignOutReasonViewModel.swift in Sources */,
05F1FF502D33DF9600982033 /* HomePopupViewController.swift in Sources */,
3C8B4E1D2C78E55C00174943 /* TokenReissueResponseDTO.swift in Sources */,
3C8B4E372C79118500174943 /* MyPageAccountInfoResponseDTO.swift in Sources */,
050E0CCD2C74B95B00326EEA /* Team.swift in Sources */,
Expand Down Expand Up @@ -1773,10 +1798,12 @@
050E0CEA2C74DC4B00326EEA /* MatchProgress.swift in Sources */,
3C8B4E262C78E61B00174943 /* HttpMethod.swift in Sources */,
DE8001B32CF323B100D9DAD9 /* InfoNewsViewController.swift in Sources */,
05F1FF4A2D1AB42A00982033 /* MigratedHomeView.swift in Sources */,
05B4F47D2CF8BE360033FF67 /* Array+.swift in Sources */,
05B4F47F2CF8C2450033FF67 /* BanRequestDTO.swift in Sources */,
DE8001B62CF3250800D9DAD9 /* NewsCell.swift in Sources */,
DE8001A82CF31ECE00D9DAD9 /* InfoNewsViewModel.swift in Sources */,
05F1FF462D1AAAE300982033 /* MigratedHomeViewModel.swift in Sources */,
050E0CD12C74B9A700326EEA /* WriteViewController.swift in Sources */,
050E0CAA2C74B7A900326EEA /* FeedDetailReplyDTO.swift in Sources */,
3C35319C2C6F22050015A8FA /* ViewModelType.swift in Sources */,
Expand All @@ -1789,6 +1816,7 @@
DEAD9CBD2CF2618F00D5CD11 /* SessionCell.swift in Sources */,
050E0CA42C74B35500326EEA /* UIApplication+.swift in Sources */,
050E0CB72C74B87400326EEA /* FeedDetailView.swift in Sources */,
05F1FF482D1AB39000982033 /* MigratedHomeFeedCell.swift in Sources */,
DEFF2F7E2D13052500DC1A16 /* AnyPublisher+.swift in Sources */,
050E0CF92C7516C900326EEA /* InfoNotificationDTO.swift in Sources */,
3C8B4E442C80886800174943 /* WriteContentRequestDTO.swift in Sources */,
Expand Down
59 changes: 59 additions & 0 deletions Wable-iOS/Global/Extention/UIView+.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// Created by 박윤빈 on 8/6/24.
//

import Combine
import UIKit

extension UIView {
Expand All @@ -30,3 +31,61 @@ extension UIView {
return superview as? T ?? superview?.superview(of: type)
}
}

// MARK: - UIGestureRecognizer Combine Publisher

extension UIView {
func gesturePublisher<T: UIGestureRecognizer>(_ gestureRecognizer: T) -> AnyPublisher<T, Never> {
GesturePublisher(view: self, gestureRecognizer: gestureRecognizer).eraseToAnyPublisher()
}
}

// MARK: - GesturePublisher 정의

struct GesturePublisher<T: UIGestureRecognizer>: Publisher {
typealias Output = T
typealias Failure = Never

private let view: UIView
private let gestureRecognizer: T

init(view: UIView, gestureRecognizer: T) {
self.view = view
self.gestureRecognizer = gestureRecognizer
}

func receive<S>(subscriber: S) where S : Subscriber, Failure == S.Failure, Output == S.Input {
let subscription = GestureSubscription(subscriber: subscriber, view: view, gestureRecognizer: gestureRecognizer)
subscriber.receive(subscription: subscription)
}
}

// MARK: - GestureSubscription 정의

final class GestureSubscription<S: Subscriber, T: UIGestureRecognizer>: Subscription where S.Input == T {
private var subscriber: S?
private let gestureRecognizer: T
private weak var view: UIView?

init(subscriber: S, view: UIView, gestureRecognizer: T) {
self.subscriber = subscriber
self.gestureRecognizer = gestureRecognizer
self.view = view

self.view?.isUserInteractionEnabled = true
self.view?.addGestureRecognizer(gestureRecognizer)
self.gestureRecognizer.addTarget(self, action: #selector(handleGesture))
}

func request(_ demand: Subscribers.Demand) {
}

func cancel() {
subscriber = nil
view?.removeGestureRecognizer(gestureRecognizer)
}

@objc private func handleGesture() {
_ = subscriber?.receive(gestureRecognizer)
}
}
Comment on lines +34 to +91
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오호,, 상당히 흥미로운 내용이네요..
UIView 내에서 사용되는 내용이라면, UIView 내부로 감쌀 것 같아요.
extension UIView { }로 말이죠.

그리고 이걸 왜 구현했는지, 무엇을 위해선지가 가장 중요할 것 같아요.
혹시 이유를 알 수 있을까요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사진을 탭할 때의 탭 제스처가 필요했는데,, 찾아보니 이렇게 하라는 내용을 봐서요..! 혹시 다른 방법이 있다면 알려주세요!!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CombineCocoa에 Gesture에 따른 퍼블리셔를 사용할 수 있도록 구현되어 있는 것으로 알고 있어요.
그래서 위 구현사항은 필요가 없을수도 있겠다는 생각이 들었는데요.

이미지뷰라면, userInteraction과 관련된 속성을 true로 변경하고, @objc메서드를 선언하여 이미지뷰가 터치되었을 때 어떠한 동작을 할 지 정의할 수 있는 것으로 알고 있습니다.
또한 이미지뷰의 터치를 뷰모델에 전달해야 한다면, @objc 메서드에서 서브젝트의 send를 호출하여 이미지뷰가 터치되었을 때 신호를 전달할 수 있겠네요.

1 change: 1 addition & 0 deletions Wable-iOS/Global/Literals/ImageLiterals.swift
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ enum ImageLiterals {
static var toastSuccess: UIImage { .load(name: "toast_success") }
static var toastWarning: UIImage { .load(name: "toast_warning") }
static var toastGhost: UIImage { .load(name: "toast_ghost") }
static var toastBan: UIImage { .load(name: "toast_ban") }
static var toastReport: UIImage { .load(name: "toast_report") }
static var toastAgreementLoading: UIImage { .load(name: "toast_agreement_loading") }
}
Expand Down
11 changes: 11 additions & 0 deletions Wable-iOS/Global/Literals/StringLiterals.swift
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,17 @@ enum StringLiterals {
return "v3/content/\(contentID)/comment"
}
static let postBan = "v1/report/ban"
static func postFeedLike(contentID: Int) -> String {
return "v1/content/\(contentID)/liked"
}
static func deleteFeedLike(contentID: Int) -> String {
return "v1/content/\(contentID)/unliked"
}
static func deleteFeed(contentID: Int) -> String {
return "v1/content/\(contentID)"
}
static let postOpacityDown = "v1/ghost2"
static let postReport = "v1/report/slack"
}

enum Info {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "toast.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "[email protected]",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "[email protected]",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
65 changes: 65 additions & 0 deletions Wable-iOS/Network/Home/HomeAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,71 @@ extension HomeAPI {
}
}

func migratedGetHomeFeed(cursor: Int) -> AnyPublisher<[HomeFeedDTO]?, WableNetworkError> {
homeProvider.requestPublisher(.getContent(param: cursor))
.tryMap { [weak self] response -> [HomeFeedDTO]? in
return try self?.parseResponse(statusCode: response.statusCode, data: response.data)
}
.mapError { $0 as? WableNetworkError ?? .unknownError($0.localizedDescription) }
.eraseToAnyPublisher()
}

func postFeedLike(contentID: Int) -> AnyPublisher<EmptyDTO?, WableNetworkError> {
homeProvider.requestPublisher(.postFeedLike(contentID: contentID))
.tryMap { [weak self] response -> EmptyDTO? in
return try self?.parseResponse(statusCode: response.statusCode, data: response.data)
}
.mapError { $0 as? WableNetworkError ?? .unknownError($0.localizedDescription) }
.eraseToAnyPublisher()
}

func deleteFeedLike(contentID: Int) -> AnyPublisher<EmptyDTO?, WableNetworkError> {
homeProvider.requestPublisher(.deleteFeedLike(contentID: contentID))
.tryMap { [weak self] response -> EmptyDTO? in
return try self?.parseResponse(statusCode: response.statusCode, data: response.data)
}
.mapError { $0 as? WableNetworkError ?? .unknownError($0.localizedDescription) }
.eraseToAnyPublisher()
}

func deleteFeed(contentID: Int) -> AnyPublisher<EmptyDTO?, WableNetworkError> {
homeProvider.requestPublisher(.deleteFeed(contentID: contentID))
.tryMap { [weak self] response -> EmptyDTO? in
return try self?.parseResponse(statusCode: response.statusCode, data: response.data)
}
.mapError { $0 as? WableNetworkError ?? .unknownError($0.localizedDescription) }
.eraseToAnyPublisher()
}

func postReport(nickname: String, relateText: String) -> AnyPublisher<EmptyDTO?, WableNetworkError> {
homeProvider.requestPublisher(.postReport(param: ReportRequestDTO(
reportTargetNickname: nickname,
relateText: relateText
)))
.tryMap { [weak self] response -> EmptyDTO? in
return try self?.parseResponse(statusCode: response.statusCode, data: response.data)
}
.mapError { $0 as? WableNetworkError ??
.unknownError($0.localizedDescription) }
.eraseToAnyPublisher()
}

func postBeGhost(triggerType: String, memberID: Int, triggerID: Int) -> AnyPublisher<EmptyDTO?, WableNetworkError> {
let param = PostTransparencyRequestDTO(
alarmTriggerType: triggerType,
targetMemberId: memberID,
alarmTriggerId: triggerID,
ghostReason: ""
)
return homeProvider.requestPublisher(.postBeGhost(param: param))
.tryMap { [weak self] response -> EmptyDTO? in
return try self?.parseResponse(statusCode: response.statusCode, data: response.data)
}
.mapError { $0 as? WableNetworkError ??
.unknownError($0.localizedDescription) }
.eraseToAnyPublisher()
}

func postReply(contentID: Int, requestBody: WriteReplyRequestV3DTO) -> AnyPublisher<EmptyDTO?, WableNetworkError> {
homeProvider.requestPublisher(.postReply(param: contentID, requestBody: requestBody))
.tryMap { [weak self] response -> EmptyDTO? in
Expand Down
Loading