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] #473 - 신규 홈뷰 - 홍보 섹션 API 연동 #480

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,10 @@ extension HomeRepository: HomeRepositoryInterface {
.map { $0.map { $0.toDomain() } }
.eraseToAnyPublisher()
}

public func getAnnouncementPosts() -> AnyPublisher<[Domain.HomeAnnouncementModel], any Error> {
homeService.getHomeEmploymentEntity()
.map { $0.map { $0.toDomain() } }
.eraseToAnyPublisher()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// HomeAnnouncementTransform.swift
// Data
//
// Created by Jae Hyun Lee on 1/20/25.
// Copyright © 2025 SOPT-iOS. All rights reserved.
//

import Foundation

import Domain
import Networks

extension HomeEmploymentEntity {
Copy link
Contributor

Choose a reason for hiding this comment

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

ResponseEntity와 RequestEntity 구분해주세요!
제가 재현님 다음에 올린 PR에 ResponseEntity 폴더를 만들어놓았는데, #481 머지 후 수정해도 좋을 것 같네용

Copy link
Contributor Author

Choose a reason for hiding this comment

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

옙옙! 머지 해주시면 수정하겠습니닷

public func toDomain() -> HomeAnnouncementModel {
return HomeAnnouncementModel(id: id, categoryName: categoryName, title: title, profileImage: profileImage, name: name, content: content, images: images)
}
}
27 changes: 27 additions & 0 deletions SOPT-iOS/Projects/Domain/Sources/Model/HomeAnnouncementModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
// HomeAnnouncementModel.swift
// Domain
//
// Created by Jae Hyun Lee on 1/20/25.
// Copyright © 2025 SOPT-iOS. All rights reserved.
//

import Foundation

public struct HomeAnnouncementModel {
public let id: Int
public let profileImage, name: String?
public let categoryName, title: String
public let content: String
public let images: [String]?

public init(id: Int, categoryName: String, title: String, profileImage: String?, name: String?, content: String, images: [String]?) {
self.id = id
self.categoryName = categoryName
self.title = title
self.profileImage = profileImage
self.name = name
self.content = content
self.images = images
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ public protocol HomeRepositoryInterface {
func getInsightPosts() -> AnyPublisher<[HomeInsightPostsModel], Error>
func getGroupPosts() -> AnyPublisher<[HomeGroupPostModel], Error>
func getCoffeeChatPosts() -> AnyPublisher<[HomeCoffeeChatPostModel], Error>
func getAnnouncementPosts() -> AnyPublisher<[HomeAnnouncementModel], Error>
}
14 changes: 14 additions & 0 deletions SOPT-iOS/Projects/Domain/Sources/UseCase/HomeUseCase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ public protocol HomeUseCase {
var insightPosts: PassthroughSubject<[HomeInsightPostsModel], Never> { get set }
var groupPosts: PassthroughSubject<[HomeGroupPostModel], Never> { get set }
var coffeeChatPosts: PassthroughSubject<[HomeCoffeeChatPostModel], Never> { get set }
var announcementPosts: PassthroughSubject<[HomeAnnouncementModel], Never> { get set }

func getHomeDescription()
func getRecentSchedule()
func getAppServices()
func getInsightPosts()
func getGroupPosts()
func getCoffeeChatPosts()
func getAnnouncementPosts()
}

public class DefaultHomeUseCase {
Expand All @@ -37,6 +39,7 @@ public class DefaultHomeUseCase {
public var insightPosts = PassthroughSubject<[HomeInsightPostsModel], Never>()
public var groupPosts = PassthroughSubject<[HomeGroupPostModel], Never>()
public var coffeeChatPosts = PassthroughSubject<[HomeCoffeeChatPostModel], Never>()
public var announcementPosts = PassthroughSubject<[HomeAnnouncementModel], Never>()

public init(repository: HomeRepositoryInterface) {
self.repository = repository
Expand Down Expand Up @@ -109,4 +112,15 @@ extension DefaultHomeUseCase: HomeUseCase {
}
.store(in: cancelBag)
}

public func getAnnouncementPosts() {
repository.getAnnouncementPosts()
.withUnretained(self)
.sink { event in
print("GetAnnouncementPosts State: \(event)")
} receiveValue: { owner, posts in
owner.announcementPosts.send(posts)
}
.store(in: cancelBag)
}
Comment on lines +116 to +125
Copy link
Contributor

Choose a reason for hiding this comment

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

이 부분 어제 논의한대로 Subject를 반환하는 방식으로 변경하는건 어떨까요?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

넹 변경하는 건 동의하는데, 한꺼번에 기존 코드들과 같이 리팩하는 방향으로 가는 건 어떨까요?

Copy link
Contributor

Choose a reason for hiding this comment

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

좋아요!

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

import UIKit

import Domain
import Core
import DSKit

Expand All @@ -33,7 +34,7 @@ final class AnnouncementCardCVC: UICollectionViewCell {
$0.spacing = 10
}

private let writerProfileImageView = CustomProfileImageView()
private let writerProfileImageView = CustomProfileImageView().hideBorder()

private let writerNameLabel = UILabel().then {
$0.textColor = DSKitAsset.Colors.white.color
Expand Down Expand Up @@ -139,17 +140,21 @@ extension AnnouncementCardCVC {
// MARK: - Methods

extension AnnouncementCardCVC {
func configureCell(model: AnnouncementInfo) {
func configureCell(model: HomeAnnouncementModel?) {
guard let model else { return }

self.categoryTagView.setData(with: model.categoryName, isHotTag: false)
self.categoryDetailLabel.text = model.categoryDetailName
self.writerProfileImageView.setImage(with: model.profileImage)
self.categoryDetailLabel.text = "꿀팁"
if let profileImage = model.profileImage {
self.writerProfileImageView.setImage(with: profileImage)
}
self.writerNameLabel.text = model.name
self.titleLabel.text = model.title
self.contentLabel.text = model.content

let hasCoverImage = (model.images != nil)
updateContentLayout(hasCoverImage: hasCoverImage)
if hasCoverImage, let cover = model.images {
if hasCoverImage, let cover = model.images?.first {
self.coverImageView.setImage(with: cover)
} else {
updateContentLabelAttributes()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ final class HomeCategoryTagView: UIView {

private let contentStackView = UIStackView().then {
$0.axis = .horizontal
$0.alignment = .center
$0.distribution = .equalSpacing
}

private let hotIconImageView = UIImageView().then {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,14 +150,6 @@ extension HomeForMemberVC {
self.collectionView.register(SocialLinkCardCVC.self,
forCellWithReuseIdentifier: SocialLinkCardCVC.className)
}

private func bindViewModels() {
let input = HomeForMemberViewModel.Input(
cellTapped: cellTapped.asDriver()
)

let output = self.viewModel.transform(from: input, cancelBag: self.cancelBag)
}
}

// MARK: - UICollectionViewDelegate
Expand All @@ -169,10 +161,6 @@ extension HomeForMemberVC: UICollectionViewDelegate {
// MARK: - UICollectionViewDataSource

extension HomeForMemberVC: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
cellTapped.send(indexPath)
}

func numberOfSections(in collectionView: UICollectionView) -> Int {
return HomeForMemberSectionLayoutKind.allCases.count
}
Expand Down Expand Up @@ -217,7 +205,7 @@ extension HomeForMemberVC: UICollectionViewDataSource {
case .insight: return viewModel.insightPosts != nil ? 1 : 0
case .group: return viewModel.groupPosts?.count ?? 0
case .coffeeChat: return viewModel.coffeeChatPosts?.count ?? 0
case .announcement: return viewModel.announcementInfoList.count
case .announcement: return viewModel.announcementPosts?.count ?? 0
case .socialLinks: return SocialLinkCardType.allCases.count
}
}
Expand Down Expand Up @@ -305,10 +293,11 @@ extension HomeForMemberVC: UICollectionViewDataSource {
case .announcement:
/// 홍보 카드 셀
let announcementIndex = indexPath.item
guard let announcement = viewModel.announcementPosts?[safe: announcementIndex] else { return UICollectionViewCell() }
Copy link
Contributor

Choose a reason for hiding this comment

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

컬렉션뷰 UI 업데이트할 때 문득 ViewModel의 변수를 참조한다는 것이 어색하게 느껴져서 고민한 부분이 있는데 재현님의 생각도 궁금합니다 !! #481 에 생각 적어두었는데 의견 주세요 ! !

Copy link
Contributor Author

Choose a reason for hiding this comment

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

확인했어요! 홈뷰가 많이 복잡한 편이라서 PresentationModel 만들어서 분리해주는 거 좋은 방법인 듯 해요 🙇🏼 요거 이후에 이슈 파서 한 번에 처리하겠습니다!

guard let announcementCardCell = collectionView
.dequeueReusableCell(withReuseIdentifier: AnnouncementCardCVC.className,
for: indexPath) as? AnnouncementCardCVC else { return UICollectionViewCell() }
announcementCardCell.configureCell(model: viewModel.announcementInfoList[announcementIndex])
announcementCardCell.configureCell(model: announcement)

return announcementCardCell

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ public class HomeForMemberViewModel: HomeForMemberViewModelType {
var insightPosts: [HomeInsightPostsModel]?
var groupPosts: [HomeGroupPostModel]?
var coffeeChatPosts: [HomeCoffeeChatPostModel]?
var announcementPosts: [HomeAnnouncementModel]?

// MARK: - Inputs

Expand Down Expand Up @@ -125,6 +126,7 @@ extension HomeForMemberViewModel {
owner.useCase.getInsightPosts()
owner.useCase.getGroupPosts()
owner.useCase.getCoffeeChatPosts()
owner.useCase.getAnnouncementPosts()
}.store(in: cancelBag)

return output
Expand Down Expand Up @@ -173,5 +175,12 @@ extension HomeForMemberViewModel {
owner.coffeeChatPosts = posts
output.needToReload.send()
}.store(in: cancelBag)

useCase.announcementPosts
.withUnretained(self)
.sink { owner, posts in
owner.announcementPosts = posts
output.needToReload.send()
}.store(in: cancelBag)
}
}
7 changes: 5 additions & 2 deletions SOPT-iOS/Projects/Modules/Networks/Sources/API/HomeAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public enum HomeAPI {
case getInsightPosts
case getGroupAll
case getCoffeeChat
case getEmployment
}

extension HomeAPI: BaseAPI {
Expand All @@ -35,19 +36,21 @@ extension HomeAPI: BaseAPI {
return "/meeting/all"
case .getCoffeeChat:
return "/coffeechat"
case .getEmployment:
return "/employments"
}
}

public var method: Moya.Method {
switch self {
case .getDescription, .getAppServiceAccessStatus, .getInsightPosts, .getGroupAll, .getCoffeeChat:
case .getDescription, .getAppServiceAccessStatus, .getInsightPosts, .getGroupAll, .getCoffeeChat, .getEmployment:
return .get
}
}

public var task: Moya.Task {
switch self {
case .getDescription, .getAppServiceAccessStatus, .getInsightPosts, .getCoffeeChat:
case .getDescription, .getAppServiceAccessStatus, .getInsightPosts, .getCoffeeChat, .getEmployment:
return .requestPlain
case .getGroupAll:
return .requestParameters(parameters: ["page": 1, "take": 10, "category": "행사,세미나"], encoding: URLEncoding.queryString)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// HomeEmploymentEntity.swift
// Networks
//
// Created by Jae Hyun Lee on 1/20/25.
// Copyright © 2025 SOPT-iOS. All rights reserved.
//

import Foundation

// MARK: - HomeEmploymentEntity

public struct HomeEmploymentEntity: Codable {
public let id: Int
public let profileImage, name: String?
public let categoryName, title: String
public let content: String
public let images: [String]
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public protocol HomeService {
func getInsightPosts() -> AnyPublisher<[HomeInsightPostsEntity], Error>
func getGroupAll() -> AnyPublisher<[HomeGroupEntity], Error>
func getCoffeeChat() -> AnyPublisher<[HomeCoffeeChatEntity], Error>
func getHomeEmploymentEntity() -> AnyPublisher<[HomeEmploymentEntity], Error>
}

extension DefaultHomeService: HomeService {
Expand All @@ -41,4 +42,8 @@ extension DefaultHomeService: HomeService {
public func getCoffeeChat() -> AnyPublisher<[HomeCoffeeChatEntity], any Error> {
requestObjectInCombine(.getCoffeeChat)
}

public func getHomeEmploymentEntity() -> AnyPublisher<[HomeEmploymentEntity], any Error> {
requestObjectInCombine(.getEmployment)
}
}