Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
5696549
fix/#264: 북마크탭 분기처리 (loginWithData / loginWithoutData / logout)
pinocchio22 Oct 30, 2025
33a051e
fix/#264: - 로그인 상태에 따른 북마크 아이콘 / 액션 핸들링 수정
pinocchio22 Nov 2, 2025
03a357e
fix/#264: 도감 알림 아이콘 로그인 분기 / 상세 도감 버튼 이벤트 연결
pinocchio22 Nov 4, 2025
a88bb8b
fix/#264: 로그인 이후 화면 전환(AppcCoordinator) / 기로그인여부 확인
pinocchio22 Nov 5, 2025
7dd6bd3
fix/#264: 마이페이지 로그인 여부 확인
pinocchio22 Nov 5, 2025
7146358
fix/#264: 컬렉션 -> 상세 페이지 전환
pinocchio22 Nov 6, 2025
dba0532
fix/#264: 도감메인-알림 수정
pinocchio22 Nov 9, 2025
e94955a
fix/#264: editCollection 버튼 화면 전환 수정 - 데이터 연결 필요
pinocchio22 Nov 11, 2025
03dbe7a
fix/#264: 마이페이지 프로필 설정 관련 UI 수정
pinocchio22 Nov 11, 2025
93e3c2c
style/#264: Apply SwiftLint autocorrect
github-actions[bot] Nov 12, 2025
07c091a
fix/#264: 북마크 GuideAlert 로그인 화면 이동
pinocchio22 Nov 12, 2025
e882eee
Merge branch 'fix/#264-Bookmark-Dictionary-UI' of github.com:Team-Map…
pinocchio22 Nov 12, 2025
60ef5aa
style/#264: Apply SwiftLint autocorrect
github-actions[bot] Nov 12, 2025
cecd35d
fix/#264: CommonButton default initializer 생성
pinocchio22 Nov 12, 2025
23ae137
Merge branch 'fix/#264-Bookmark-Dictionary-UI' of github.com:Team-Map…
pinocchio22 Nov 12, 2025
1a5c94f
style/#264: Apply SwiftLint autocorrect
github-actions[bot] Nov 12, 2025
7810d8a
Merge branch 'dev' of github.com:Team-Maple/MLS-iOS into fix/#264-Boo…
pinocchio22 Nov 13, 2025
1e25944
style/#264: Apply SwiftLint autocorrect
github-actions[bot] Nov 13, 2025
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
Binary file removed .DS_Store
Binary file not shown.
Binary file removed MLS/.DS_Store
Binary file not shown.
16 changes: 12 additions & 4 deletions MLS/Data/Data.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
775D78522E0DA93400DDAD2F /* Data.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0879294D2DB90F3A009C301F /* Data.framework */; };
77660F932DD259AA007A4EF3 /* KakaoSDKAuth in Frameworks */ = {isa = PBXBuildFile; productRef = 77660F922DD259AA007A4EF3 /* KakaoSDKAuth */; };
77660F952DD259AA007A4EF3 /* KakaoSDKUser in Frameworks */ = {isa = PBXBuildFile; productRef = 77660F942DD259AA007A4EF3 /* KakaoSDKUser */; };
776FE2BB2E9FEA930039ACE2 /* RxCocoa in Frameworks */ = {isa = PBXBuildFile; productRef = 776FE2BA2E9FEA930039ACE2 /* RxCocoa */; };
77F0E9522EA525CE007368F8 /* RxCocoa in Frameworks */ = {isa = PBXBuildFile; productRef = 77F0E9512EA525CE007368F8 /* RxCocoa */; };
77FEEF222EC5B2300023197A /* AuthFeatureInterface.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 77FEEF202EC5B2300023197A /* AuthFeatureInterface.framework */; };
77FEEF242EC5B2300023197A /* DictionaryFeatureInterface.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 77FEEF212EC5B2300023197A /* DictionaryFeatureInterface.framework */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand All @@ -36,6 +38,8 @@
0879294D2DB90F3A009C301F /* Data.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Data.framework; sourceTree = BUILT_PRODUCTS_DIR; };
08E4253B2DF17B3700D6ACD3 /* DataMock.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DataMock.framework; sourceTree = BUILT_PRODUCTS_DIR; };
08E425512DF17B5C00D6ACD3 /* DomainInterface.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = DomainInterface.framework; sourceTree = BUILT_PRODUCTS_DIR; };
77FEEF202EC5B2300023197A /* AuthFeatureInterface.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = AuthFeatureInterface.framework; sourceTree = BUILT_PRODUCTS_DIR; };
77FEEF212EC5B2300023197A /* DictionaryFeatureInterface.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = DictionaryFeatureInterface.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */

/* Begin PBXFileSystemSynchronizedRootGroup section */
Expand Down Expand Up @@ -70,7 +74,9 @@
files = (
775D78522E0DA93400DDAD2F /* Data.framework in Frameworks */,
08E425562DF17B6300D6ACD3 /* RxSwift in Frameworks */,
776FE2BB2E9FEA930039ACE2 /* RxCocoa in Frameworks */,
77F0E9522EA525CE007368F8 /* RxCocoa in Frameworks */,
77FEEF242EC5B2300023197A /* DictionaryFeatureInterface.framework in Frameworks */,
77FEEF222EC5B2300023197A /* AuthFeatureInterface.framework in Frameworks */,
08E425522DF17B5C00D6ACD3 /* DomainInterface.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand All @@ -81,6 +87,8 @@
084A256D2DB93C1400C395C0 /* Frameworks */ = {
isa = PBXGroup;
children = (
77FEEF202EC5B2300023197A /* AuthFeatureInterface.framework */,
77FEEF212EC5B2300023197A /* DictionaryFeatureInterface.framework */,
08E425512DF17B5C00D6ACD3 /* DomainInterface.framework */,
080175482DCD274B00D0919F /* DomainInterface.framework */,
084A25C72DB93E0500C395C0 /* Core.framework */,
Expand Down Expand Up @@ -175,7 +183,7 @@
name = DataMock;
packageProductDependencies = (
08E425552DF17B6300D6ACD3 /* RxSwift */,
776FE2BA2E9FEA930039ACE2 /* RxCocoa */,
77F0E9512EA525CE007368F8 /* RxCocoa */,
);
productName = DataMock;
productReference = 08E4253B2DF17B3700D6ACD3 /* DataMock.framework */;
Expand Down Expand Up @@ -633,7 +641,7 @@
package = 77660F912DD259AA007A4EF3 /* XCRemoteSwiftPackageReference "kakao-ios-sdk" */;
productName = KakaoSDKUser;
};
776FE2BA2E9FEA930039ACE2 /* RxCocoa */ = {
77F0E9512EA525CE007368F8 /* RxCocoa */ = {
isa = XCSwiftPackageProductDependency;
package = 0858ABFE2DCFDC340060EBCA /* XCRemoteSwiftPackageReference "RxSwift" */;
productName = RxCocoa;
Expand Down
5 changes: 4 additions & 1 deletion MLS/Data/Data/Network/DTO/AuthDTO/MemberDTO.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ public struct MemberDTO: Decodable {
jobName: "",
level: level,
profileUrl: profileImageUrl,
platform: provider == "APPLE" ? .apple : .kakao
platform: provider == "APPLE" ? .apple : .kakao,
noticeAgreement: noticeAgreement,
patchNoteAgreement: patchNoteAgreement,
eventAgreement: eventAgreement
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,20 @@ public struct DictionaryDetailItemResponseDTO: Decodable {
public let bookmarkId: Int?

public func toDomain() -> DictionaryDetailItemResponse {
return DictionaryDetailItemResponse(itemId: itemId, nameKr: nameKr, nameEn: nameEn, descriptionText: descriptionText, imgUrl: imgUrl, npcPrice: npcPrice, itemType: itemType, categoryHierachy: categoryHierachy, availableJobs: availableJobs, requiredStats: requiredStats, equipmentStats: equipmentStats, scrollDetail: scrollDetail, bookmarkId: bookmarkId)
return DictionaryDetailItemResponse(
itemId: itemId,
nameKr: nameKr,
nameEn: nameEn,
descriptionText: descriptionText,
imgUrl: imgUrl,
npcPrice: npcPrice,
itemType: itemType,
categoryHierachy: categoryHierachy,
availableJobs: availableJobs,
requiredStats: requiredStats,
equipmentStats: equipmentStats,
scrollDetail: scrollDetail,
bookmarkId: bookmarkId
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,24 @@ public struct DictionaryDetailMonsterResponseDTO: Decodable {
public let bookmarkId: Int?

public func toDomain() -> DictionaryDetailMonsterResponse {
return DictionaryDetailMonsterResponse(monsterId: monsterId, nameKr: nameKr, nameEn: nameEn, imageUrl: imageUrl, level: level, exp: exp, hp: hp, mp: mp, physicalDefense: physicalDefense, magicDefense: magicDefense, requiredAccuracy: requiredAccuracy, bonusAccuracyPerLevelLower: bonusAccuracyPerLevelLower, evasionRate: evasionRate, mesoDropAmount: mesoDropAmount, mesoDropRate: mesoDropRate, typeEffectiveness: typeEffectiveness, bookmarkId: bookmarkId)
return DictionaryDetailMonsterResponse(
monsterId: monsterId,
nameKr: nameKr,
nameEn: nameEn,
imageUrl: imageUrl,
level: level,
exp: exp,
hp: hp,
mp: mp,
physicalDefense: physicalDefense,
magicDefense: magicDefense,
requiredAccuracy: requiredAccuracy,
bonusAccuracyPerLevelLower: bonusAccuracyPerLevelLower,
evasionRate: evasionRate,
mesoDropAmount: mesoDropAmount,
mesoDropRate: mesoDropRate,
typeEffectiveness: typeEffectiveness,
bookmarkId: bookmarkId
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,25 @@ public struct DictionaryDetailQuestResponseDTO: Decodable {
public let bookmarkId: Int?

public func toDomain() -> DictionaryDetailQuestResponse {
return DictionaryDetailQuestResponse(questId: questId, titlePrefix: titlePrefix, nameKr: nameKr, nameEn: nameEn, iconUrl: iconUrl, questType: questType, minLevel: minLevel, maxLevel: maxLevel, requiredMesoStart: requiredMesoStart, startNpcId: startNpcId, startNpcName: startNpcName, endNpcId: endNpcId, endNpcName: endNpcName, reward: reward, rewardItems: rewardItems, requirements: requirements, allowedJobs: allowedJobs, bookmarkId: bookmarkId)
return DictionaryDetailQuestResponse(
questId: questId,
titlePrefix: titlePrefix,
nameKr: nameKr,
nameEn: nameEn,
iconUrl: iconUrl,
questType: questType,
minLevel: minLevel,
maxLevel: maxLevel,
requiredMesoStart: requiredMesoStart,
startNpcId: startNpcId,
startNpcName: startNpcName,
endNpcId: endNpcId,
endNpcName: endNpcName,
reward: reward,
rewardItems: rewardItems,
requirements: requirements,
allowedJobs: allowedJobs,
bookmarkId: bookmarkId
)
}
}
2 changes: 1 addition & 1 deletion MLS/Data/Data/Network/Endpoints/AlarmEndPoint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public enum AlarmEndPoint {
public static func fetchAll(query: Encodable) -> ResponsableEndPoint<AlarmResponseDTO> {
.init(
baseURL: base,
path: "/api/v1/alrim/list/all",
path: "/api/v1/alrim/all",
method: .GET,
query: query
)
Expand Down
4 changes: 2 additions & 2 deletions MLS/Data/Data/Repository/AlarmAPIRepositoryImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public class AlarmAPIRepositoryImpl: AlarmAPIRepository {
}

public func setRead(alarmLink: String) -> Completable {
let endpoint = AlarmEndPoint.setRead(query: setReadQuery(alrimLink: alarmLink))
let endpoint = AlarmEndPoint.setRead(query: SetReadQuery(alrimLink: alarmLink))
return provider.requestData(endPoint: endpoint, interceptor: tokenInterceptor)
}

Expand All @@ -56,7 +56,7 @@ private extension AlarmAPIRepositoryImpl {
let pageSize: Int
}

struct setReadQuery: Encodable {
struct SetReadQuery: Encodable {
let alrimLink: String
}
}
5 changes: 3 additions & 2 deletions MLS/Data/Data/Repository/AuthAPIRepositoryImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class AuthAPIRepositoryImpl: AuthAPIRepository {
self.tokenInterceptor = interceptor
}

public func fetchProfile() -> Observable<MyPageResponse> {
public func fetchProfile() -> Observable<MyPageResponse?> {
let endpoint = AuthEndPoint.fetchProfile()
return provider.requestData(endPoint: endpoint, interceptor: tokenInterceptor)
.map { $0.toMyPageDomain() }
Expand Down Expand Up @@ -109,9 +109,10 @@ public class AuthAPIRepositoryImpl: AuthAPIRepository {
return provider.requestData(endPoint: endPoint, interceptor: tokenInterceptor)
}

public func updateNickName(nickName: String) -> Completable {
public func updateNickName(nickName: String) -> Observable<MyPageResponse> {
let endPoint = AuthEndPoint.updateNickName(body: NickNameBody(nickname: nickName))
return provider.requestData(endPoint: endPoint, interceptor: tokenInterceptor)
.map { $0.toMyPageDomain() }
}

public func updateProfileImage(url: String) -> Completable {
Expand Down
48 changes: 35 additions & 13 deletions MLS/Data/Data/Repository/UserDefaultsRepositoryImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import Foundation
import RxSwift

public final class UserDefaultsRepositoryImpl: UserDefaultsRepository {
private let key = "recentSearch"
private let recentSearchkey = "recentSearch"
private let platformKey = "platformKey"

public init() { }
public init() {}

public func fetchRecentSearch() -> Observable<[String]> {
return Observable.create { observer in
let current = UserDefaults.standard.stringArray(forKey: self.key) ?? []
let current = UserDefaults.standard.stringArray(forKey: self.recentSearchkey) ?? []
observer.onNext(current)
observer.onCompleted()
return Disposables.create()
Expand All @@ -19,30 +20,51 @@ public final class UserDefaultsRepositoryImpl: UserDefaultsRepository {

public func addRecentSearch(keyword: String) -> Completable {
return Completable.create { completable in
var current = UserDefaults.standard.stringArray(forKey: self.key) ?? []
var current = UserDefaults.standard.stringArray(forKey: self.recentSearchkey) ?? []

// 중복 제거
current.removeAll(where: { $0 == keyword})
current.removeAll(where: { $0 == keyword })
current.insert(keyword, at: 0)

UserDefaults.standard.set(current, forKey: self.key)
UserDefaults.standard.set(current, forKey: self.recentSearchkey)
completable(.completed)
return Disposables.create()
}
}

public func removeRecentSearch(keyword: String) -> Completable {
return Completable.create { completable in
var current = UserDefaults.standard.stringArray(forKey: self.key) ?? []
var current = UserDefaults.standard.stringArray(forKey: self.recentSearchkey) ?? []

// 해당 키워드 제거
current.removeAll { $0 == keyword }
// 해당 키워드 제거
current.removeAll { $0 == keyword }

// 다시 저장
UserDefaults.standard.set(current, forKey: self.key)
// 다시 저장
UserDefaults.standard.set(current, forKey: self.recentSearchkey)

completable(.completed)
return Disposables.create()
completable(.completed)
return Disposables.create()
}
}

public func fetchPlatform() -> Observable<LoginPlatform?> {
return Observable.create { observer in
if let rawValue = UserDefaults.standard.string(forKey: self.platformKey),
let platform = LoginPlatform(rawValue: rawValue) {
observer.onNext(platform)
} else {
observer.onNext(nil)
}
observer.onCompleted()
return Disposables.create()
}
}

public func savePlatform(platform: LoginPlatform) -> Completable {
return Completable.create { completable in
UserDefaults.standard.set(platform.rawValue, forKey: self.platformKey)
completable(.completed)
return Disposables.create()
}
}
}
7 changes: 6 additions & 1 deletion MLS/Data/DataMock/Factory/LoginFactoryMock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@ import DomainInterface
public final class LoginFactoryMock: LoginFactory {
public init() {}

public func make(isReLogin isRelogin: Bool) -> BaseViewController {
public func make(exitRoute: LoginExitRoute) -> BaseViewController {
let viewController = BaseViewController()
viewController.view.backgroundColor = .blue
return viewController
}

public func make(exitRoute: LoginExitRoute, onLoginCompleted: (() -> Void)?) -> BaseViewController {
return BaseViewController()
}

}
6 changes: 5 additions & 1 deletion MLS/Data/DataMock/Repository/AuthAPIRepositoryMock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import DomainInterface
import RxSwift

public class AuthAPIRepositoryMock: AuthAPIRepository {
public func fetchProfile() -> Observable<MyPageResponse?> {
return .empty()
}

public func fetchJob(jobId: String) -> Observable<Job> {
return .empty()
}
Expand Down Expand Up @@ -94,7 +98,7 @@ public class AuthAPIRepositoryMock: AuthAPIRepository {
return .empty()
}

public func updateNickName(nickName: String) -> RxSwift.Completable {
public func updateNickName(nickName: String) -> Observable<MyPageResponse> {
return .empty()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import DomainInterface

import RxSwift

public class FetchAllUseCaseImpl: FetchAllUseCase {
public class FetchAllAlarmUseCaseImpl: FetchAllAlarmUseCase {
private var repository: AlarmAPIRepository

public init(repository: AlarmAPIRepository) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import Foundation

import DomainInterface

import RxSwift

public class FetchPlatformUseCaseImpl: FetchPlatformUseCase {
private var repository: UserDefaultsRepository

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

public func execute() -> Observable<LoginPlatform?> {
return repository.fetchPlatform()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,33 @@ import DomainInterface
import RxSwift

public class LoginWithAppleUseCaseImpl: LoginWithAppleUseCase {
private var repository: AuthAPIRepository
private var authRepository: AuthAPIRepository
private let tokenRepository: TokenRepository
private var userDefaultsRepository: UserDefaultsRepository

public init(repository: AuthAPIRepository) {
self.repository = repository
public init(authRepository: AuthAPIRepository, tokenRepository: TokenRepository, userDefaultsRepository: UserDefaultsRepository) {
self.authRepository = authRepository
self.tokenRepository = tokenRepository
self.userDefaultsRepository = userDefaultsRepository
}

// 로그인할때 토큰 저장 필요
public func execute(credential: Credential) -> Observable<LoginResponse> {
return repository.loginWithApple(credential: credential)
return authRepository.loginWithApple(credential: credential)
.flatMap { response -> Observable<LoginResponse> in
let saveAccess = self.tokenRepository.saveToken(type: .accessToken, value: response.accessToken)
let saveRefresh = self.tokenRepository.saveToken(type: .refreshToken, value: response.refreshToken)
let savePlatform = self.userDefaultsRepository.savePlatform(platform: .apple)

switch (saveAccess, saveRefresh) {
case (.success, .success):
return savePlatform.andThen(Observable.just(response))
default:
return Observable.error(
TokenRepositoryError.dataConversionError(message: "Failed to save tokens")
)
}
}
.catch { error in
Observable.error(error)
}
Expand Down
Loading