Skip to content

Commit

Permalink
Merge pull request #340 from lsj8706/feat/#339-콕-찌르기-피쳐-진입-플로우
Browse files Browse the repository at this point in the history
[Feat] #339 콕 찌르기 피쳐 진입 플로우
  • Loading branch information
lsj8706 authored Dec 27, 2023
2 parents db385b4 + 90b4867 commit bec34e8
Show file tree
Hide file tree
Showing 12 changed files with 132 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public struct UserDefaultKeyList {
@UserDefaultWrapper<String>(key: "sentence") public static var sentence
@UserDefaultWrapper<String>(key: "soptampName") public static var soptampName
@UserDefaultWrapper<String>(key: "pushToken") public static var pushToken
@UserDefaultWrapper<Bool>(key: "isFirstVisitToPokeView") public static var isFirstVisitToPokeView
@UserDefaultWrapper<Bool>(key: "isFirstVisitToPokeView") public static var isFirstVisitToPokeOnboardingView
}

public struct AppNotice {
Expand Down
11 changes: 10 additions & 1 deletion SOPT-iOS/Projects/Data/Sources/Repository/MainRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@ public class MainRepository {
private let userService: UserService
private let configService: ConfigService
private let descriptionService: DescriptionService
private let pokeService: PokeService

private let cancelBag = CancelBag()

public init(userService: UserService, configService: ConfigService, descriptionService: DescriptionService) {
public init(userService: UserService, configService: ConfigService, descriptionService: DescriptionService, pokeService: PokeService) {
self.userService = userService
self.configService = configService
self.descriptionService = descriptionService
self.pokeService = pokeService
}
}

Expand Down Expand Up @@ -77,4 +80,10 @@ extension MainRepository: MainRepositoryInterface {
}
.eraseToAnyPublisher()
}

public func checkPokeNewUser() -> AnyPublisher<Bool, Error> {
pokeService.isNewUser()
.map { $0.isNew }
.eraseToAnyPublisher()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ extension AppDelegate {
MainRepository(
userService: DefaultUserService(),
configService: DefaultConfigService(),
descriptionService: DefaultDescriptionService()
descriptionService: DefaultDescriptionService(),
pokeService: DefaultPokeService()
)
}
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ public protocol MainRepositoryInterface {
func getServiceState() -> AnyPublisher<ServiceStateModel, MainError>
func getMainViewDescription() -> AnyPublisher<MainDescriptionModel, MainError>
func registerPushToken(with token: String) -> AnyPublisher<Bool, Error>
func checkPokeNewUser() -> AnyPublisher<Bool, Error>
}
17 changes: 16 additions & 1 deletion SOPT-iOS/Projects/Domain/Sources/UseCase/MainUseCase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ public protocol MainUseCase {
var serviceState: PassthroughSubject<ServiceStateModel, Never> { get set }
var mainDescription: PassthroughSubject<MainDescriptionModel, Never> { get set }
var mainErrorOccurred: PassthroughSubject<MainError, Never> { get set }
var isPokeNewUser: PassthroughSubject<Bool, Never> { get set }

func getUserMainInfo()
func getServiceState()
func getMainViewDescription()
func registerPushToken()
func checkPokeNewUser()
}

public class DefaultMainUseCase {
Expand All @@ -30,6 +33,7 @@ public class DefaultMainUseCase {
public var serviceState = PassthroughSubject<ServiceStateModel, Never>()
public var mainDescription = PassthroughSubject<MainDescriptionModel, Never>()
public var mainErrorOccurred = PassthroughSubject<MainError, Never>()
public var isPokeNewUser = PassthroughSubject<Bool, Never>()

public init(repository: MainRepositoryInterface) {
self.repository = repository
Expand Down Expand Up @@ -75,12 +79,23 @@ extension DefaultMainUseCase: MainUseCase {

repository.registerPushToken(with: pushToken)
.sink { event in
print("DefaultSplashUseCase : \(event)")
print("MainUseCase Register PushToken: \(event)")
} receiveValue: { didSucceed in
print("푸시 토큰 등록 결과: \(didSucceed)")
}.store(in: cancelBag)
}

public func checkPokeNewUser() {
repository.checkPokeNewUser()
.catch { [weak self] error in
print("MainUseCase CheckPokeNewUser Error: \(error)")
self?.mainErrorOccurred.send(.networkError(message: "Poke 온보딩 대상 여부 확인 실패"))
return Empty<Bool, Never>()
}.sink { [weak self] isNewUser in
self?.isPokeNewUser.send(isNewUser)
}.store(in: cancelBag)
}

private func setUserType(with userType: UserType?) {
switch userType {
case .none, .inactive:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,47 @@ extension MainViewModel {
}.store(in: cancelBag)

input.cellTapped
.sink { [weak self] indexPath in
guard let self = self else { return }
self.bindCellAction(indexPath)
.filter { $0.section == 1 }
.map { $0.item }
.compactMap { [weak self] index in
self?.mainServiceList[index]
}.sink { [weak self] service in
self?.handleMainServiceSectionTap(with: service)
}.store(in: cancelBag)

input.cellTapped
.filter { $0.section == 2 }
.map { $0.item }
.compactMap { [weak self] index in
self?.otherServiceList[index]
}.sink { [weak self] service in
self?.handleOtherServiceSectionTap(with: service)
}.store(in: cancelBag)

let appServiceSectionService = input.cellTapped
.filter { [weak self] _ in
guard let self else { return false }
return self.userType != .visitor
}
.filter { $0.section == 3 }
.map { $0.item }
.compactMap { [weak self] index in
return self?.appServiceList[index]
}.eraseToAnyPublisher()

appServiceSectionService.sink { [weak self] service in
self?.trackAmplitude(event: service.toAmplitudeEventType)
}.store(in: cancelBag)

appServiceSectionService.filter { $0 == .soptamp }
.sink { [weak self] _ in
self?.onSoptamp?()
}.store(in: cancelBag)

appServiceSectionService.filter { $0 == .poke }
.sink { [weak self] _ in
output.isLoading.send(true)
self?.useCase.checkPokeNewUser()
}.store(in: cancelBag)

input.requestUserInfo
Expand Down Expand Up @@ -159,42 +197,33 @@ extension MainViewModel {
self.onNeedSignIn?()
}
}.store(in: self.cancelBag)

useCase.isPokeNewUser
.sink { [weak self] isNewUser in
output.isLoading.send(false)
self?.onPoke?(isNewUser)
}.store(in: cancelBag)
}

private func bindCellAction(_ indexPath: IndexPath) {
switch (indexPath.section, indexPath.row) {
case (0, _): break
case (1, _):
guard let service = mainServiceList[safe: indexPath.item] else { return }
self.trackAmplitude(event: service.toAmplitudeEventType)

guard service != .attendance else {
onAttendance?()
return
}

let needOfficialProject = service == .project && userType == .visitor
let serviceDomainURL = needOfficialProject
? ExternalURL.SOPT.project
: service.serviceDomainLink
onSafari?(serviceDomainURL)
case (2, _):
guard let service = otherServiceList[safe: indexPath.item] else { return }
self.trackAmplitude(event: service.toAmplitudeEventType)

onSafari?(service.serviceDomainLink)
case(3, _):
guard userType != .visitor else { return }
guard let service = appServiceList[safe: indexPath.item] else { return }
self.trackAmplitude(event: service.toAmplitudeEventType)
switch service {
case .soptamp: onSoptamp?()
case .poke:
let isFirstVisitToPokeView = UserDefaultKeyList.User.isFirstVisitToPokeView
onPoke?(isFirstVisitToPokeView ?? true)
}
default: break
private func handleMainServiceSectionTap(with service: ServiceType) {
self.trackAmplitude(event: service.toAmplitudeEventType)

guard service != .attendance else {
onAttendance?()
return
}

let needOfficialProject = service == .project && userType == .visitor
let serviceDomainURL = needOfficialProject
? ExternalURL.SOPT.project
: service.serviceDomainLink
onSafari?(serviceDomainURL)
}

private func handleOtherServiceSectionTap(with service: ServiceType) {
self.trackAmplitude(event: service.toAmplitudeEventType)

onSafari?(service.serviceDomainLink)
}

private func requestAuthorizationForNotification() {
Expand Down Expand Up @@ -224,12 +253,15 @@ extension MainViewModel {
case .visitor:
self.mainServiceList = [.officialHomepage, .review, .project]
self.otherServiceList = [.instagram, .youtube, .faq]
self.appServiceList = [.poke, .soptamp]
case .active:
self.mainServiceList = [.attendance, .group, .playgroundCommunity]
self.otherServiceList = [.member, .project, .officialHomepage]
self.appServiceList = [.poke, .soptamp]
case .inactive:
self.mainServiceList = [.playgroundCommunity, .group, .member]
self.otherServiceList = [.project, .officialHomepage, .instagram, .youtube]
self.appServiceList = [.soptamp]
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ public final class PokeMainVC: UIViewController, PokeMainViewControllable {
public override func viewDidLoad() {
super.viewDidLoad()
self.setUI()
self.setDelegate()
self.setStackView()
self.setLayout()
self.bindViewModel()
Expand All @@ -118,6 +119,10 @@ extension PokeMainVC {
view.backgroundColor = DSKitAsset.Colors.semanticBackground.color
}

private func setDelegate() {
self.navigationController?.interactivePopGestureRecognizer?.delegate = self
}

private func setStackView() {
self.contentStackView.addArrangedSubviews(pokedSectionGroupView,
friendSectionGroupView,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public final class PokeOnboardingViewModel: PokeOnboardingViewModelType {
let randomAcquaintance = PassthroughSubject<[PokeUserModel], Never>()
let pokedResult = PassthroughSubject<PokeUserModel, Never>()
}

public var onNaviBackTapped: (() -> Void)?
public var onFirstVisitInOnboarding: (() -> Void)?
public var onAvartarTapped: ((_ playgroundId: String) -> Void)?
Expand Down Expand Up @@ -54,13 +54,11 @@ extension PokeOnboardingViewModel {
}).store(in: cancelBag)

input.viewDidLoaded
.map { _ in UserDefaultKeyList.User.isFirstVisitToPokeView ?? true }
.map { _ in UserDefaultKeyList.User.isFirstVisitToPokeOnboardingView ?? true }
.sink(receiveValue: { [weak self] isFirstVisit in
guard isFirstVisit else { return }

// UserDefaultKeyList.User.isFirstVisitToPokeView = false
// self?.onFirstVisitInOnboarding?()
self?.onFirstVisitInOnboarding?()
UserDefaultKeyList.User.isFirstVisitToPokeOnboardingView = false
self?.onFirstVisitInOnboarding?()
}).store(in: cancelBag)

input.pokeButtonTapped
Expand All @@ -77,7 +75,7 @@ extension PokeOnboardingViewModel {
.sink(receiveValue: { [weak self] userModel in
self?.onAvartarTapped?(String(describing: userModel.playgroundId))
}).store(in: cancelBag)

input.pullToRefreshTriggered
.withUnretained(self)
.sink(receiveValue: { [weak self] _ in
Expand Down
5 changes: 4 additions & 1 deletion SOPT-iOS/Projects/Modules/Networks/Sources/API/PokeAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import Moya
import Core

public enum PokeAPI {
case isNewUser
case getWhoPokedToMe
case getWhoPokedToMeList(pageIndex: String)
case getFriend
Expand All @@ -29,6 +30,8 @@ extension PokeAPI: BaseAPI {

public var path: String {
switch self {
case .isNewUser:
return "/new"
case .getWhoPokedToMe:
return "/to/me"
case .getWhoPokedToMeList:
Expand All @@ -50,7 +53,7 @@ extension PokeAPI: BaseAPI {

public var method: Moya.Method {
switch self {
case .getWhoPokedToMe, .getWhoPokedToMeList, .getFriend, .getFriendListWithRelation, .getFriendRandomUser,
case .isNewUser, .getWhoPokedToMe, .getWhoPokedToMeList, .getFriend, .getFriendListWithRelation, .getFriendRandomUser,
.getFriendList, .getRandomUsers, .getPokeMessages:
return .get
case .poke:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// PokeIsNewUserEntity.swift
// Networks
//
// Created by sejin on 12/27/23.
// Copyright © 2023 SOPT-iOS. All rights reserved.
//

import Foundation

public struct PokeIsNewUserEntity: Decodable {
public let isNew: Bool
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import Moya
public typealias DefaultPokeService = BaseService<PokeAPI>

public protocol PokeService {
func isNewUser() -> AnyPublisher<PokeIsNewUserEntity, Error>
func getWhoPokedToMe() -> AnyPublisher<PokeUserEntity?, Error>
func getWhoPokedToMeList(pageIndex: String) -> AnyPublisher<PokedToMeHistoryListEntity, Error>
func getFriend() -> AnyPublisher<[PokeUserEntity], Error>
Expand All @@ -26,6 +27,10 @@ public protocol PokeService {
}

extension DefaultPokeService: PokeService {
public func isNewUser() -> AnyPublisher<PokeIsNewUserEntity, Error> {
requestObjectInCombine(.isNewUser)
}

public func getWhoPokedToMe() -> AnyPublisher<PokeUserEntity?, Error> {
requestObjectInCombine(.getWhoPokedToMe)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ extension AppDelegate {
MainRepository(
userService: DefaultUserService(),
configService: DefaultConfigService(),
descriptionService: DefaultDescriptionService()
descriptionService: DefaultDescriptionService(),
pokeService: DefaultPokeService()
)
}
)
Expand Down

0 comments on commit bec34e8

Please sign in to comment.