Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
0ee0d14
fix/#273: 북마크 아이콘 수정
pinocchio22 Dec 12, 2025
8b0e9c1
fix/#273: 북마크 전체탭 정렬 수정
pinocchio22 Dec 12, 2025
cc8dbc5
fix/#273: 연속탈퇴 문제 수정
pinocchio22 Dec 12, 2025
478bf80
feat/#273: 로그인 화면 뒤로가기 버튼 추가
pinocchio22 Dec 12, 2025
172c77b
fix/#273: 약관 말줄임표시 수정
pinocchio22 Dec 12, 2025
693d7bc
fix/#273: 알림 설정 유도 이미지 노출 조건 수정
pinocchio22 Dec 12, 2025
37937c4
feat/#273: 최근 로그인 플랫폼 판별 / FCM 토큰 업데이트 시점 추가(앱 진입)
pinocchio22 Dec 12, 2025
efa8e6e
fix/#273: 상세 페이지 북마크 구조 변경 / 알람 응답 모델 date 타입 변경
pinocchio22 Dec 14, 2025
5f38012
fix/#273: 알림 읽음 처리
pinocchio22 Dec 14, 2025
ea1cfd9
fix/#273: 연속검색시 초성검색 불가능
pinocchio22 Dec 14, 2025
ba530db
fix/#273: 연속검색 엔터 허용
pinocchio22 Dec 14, 2025
b4d4533
fix/#273: 연속검색시 최근 검색어 추가
pinocchio22 Dec 14, 2025
ef93d2b
fix/#273: 애플 회원가입 코드 수정
pinocchio22 Dec 14, 2025
bf4886e
fix/#273: 북먀크탭 아이콘 수정
pinocchio22 Dec 14, 2025
9f686a8
style/#273: Apply SwiftLint autocorrect
github-actions[bot] Dec 14, 2025
5433f4b
fix/#273: 키보드 액세서리뷰 -> 닉네임 수정 액세서리뷰
pinocchio22 Dec 14, 2025
d13984f
fix/#273: 북마크 구조 수정 필요 + 북마크 / 도감 데이터 동기화 필요
pinocchio22 Dec 14, 2025
2f5afb7
Merge branch 'refactor/#273-Test-Feedback' of github.com:Team-Maple/M…
pinocchio22 Dec 14, 2025
1553e60
style/#273: Apply SwiftLint autocorrect
github-actions[bot] Dec 14, 2025
591c95e
fix/#273: 상세 -> 컬렉션 추가만 임시 비활성화
pinocchio22 Dec 14, 2025
4c03477
Merge branch 'refactor/#273-Test-Feedback' of github.com:Team-Maple/M…
pinocchio22 Dec 14, 2025
d0386c2
fix/#273: 앱 아이콘 수정
pinocchio22 Dec 14, 2025
4919903
fix/#273: 북마크 추가 버튼 -> 도감(전체)탭으로 이동
pinocchio22 Dec 14, 2025
163a95d
fix/#273: 북마크 구조 대대적 개선(스낵바 노출 시점 수정 + 리스트 / 상세 데이터 동기화 / 상세 컬렉션추가 재활성화)
pinocchio22 Dec 17, 2025
c99d7c4
fix/#273: 로그아웃시 refreshToken / FCMToken도 함께 삭제
pinocchio22 Dec 17, 2025
ee3e86d
fix/#273: POST 요청 실패시 예외처리 (Toast 추가)
pinocchio22 Dec 17, 2025
2233db7
fix/#273: 컬렉션 상세 북마크 인터랙션 비활성화
pinocchio22 Dec 18, 2025
9ade952
fix/#273: 공지사항 / 이벤트 / 패치노트 페이징 적용
pinocchio22 Dec 18, 2025
79cfa0b
style/#273: Apply SwiftLint autocorrect
github-actions[bot] Dec 18, 2025
47bc673
fix/#273: 로그인 시 fcm 토큰 업데이트 로직 수정
pinocchio22 Dec 19, 2025
ee80a3f
reafcator/#273: swiftLint에 맞게 코드 수정
pinocchio22 Dec 19, 2025
04b1a47
Merge branch 'refactor/#273-Test-Feedback' of github.com:Team-Maple/M…
pinocchio22 Dec 19, 2025
8201bdb
Merge pull request #278 from Team-Maple/refactor/#273-Test-Feedback
pinocchio22 Dec 19, 2025
43c4a31
fix/#dev: 제미나이 코드 수정
pinocchio22 Dec 19, 2025
47ee133
fix/dev: 초성 판별 로직 수정
pinocchio22 Dec 19, 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
4 changes: 2 additions & 2 deletions MLS/.swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ line_length:
error: 300

function_body_length:
warning: 80
error: 120
warning: 100
error: 150

disabled_rules:
- force_cast
Expand Down
2 changes: 1 addition & 1 deletion MLS/Data/Data/Network/DTO/AlarmDTO/AlarmResponseDTO.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public struct AlarmResponseDTO: Decodable {
public let type: String
public let title: String
public let link: String
public let date: [Int]
public let date: String
}

public struct AllContent: Decodable {
Expand Down
11 changes: 11 additions & 0 deletions MLS/Data/Data/Network/DTO/BookmarkDTO/SetBookmarkDTO.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import DomainInterface

public struct SetBookmarkDTO: Decodable {
public let bookmarkId: Int
public let bookmarkType: String
public let resourceId: Int

public func toDomain() -> Int {
return self.bookmarkId
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import DomainInterface

public struct DictionaryDetailItemResponseDTO: Decodable {
public let itemId: Int?
public let itemId: Int
public let nameKr: String?
public let nameEn: String?
public let descriptionText: String?
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import DomainInterface

public struct DictionaryDetailMapResponseDTO: Decodable {
public let mapId: Int?
public let mapId: Int
public let nameKr: String?
public let nameEn: String?
public let regionName: String?
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import DomainInterface

public struct DictionaryDetailQuestResponseDTO: Decodable {
public let questId: Int?
public let questId: Int
public let titlePrefix: String?
public let nameKr: String?
public let nameEn: String?
Expand Down
5 changes: 5 additions & 0 deletions MLS/Data/Data/Network/DTO/EmptyResponseDTO.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
public struct EmptyResponseDTO: Decodable {
func toBookmarkDomain() -> Int? {
return nil
}
}
3 changes: 1 addition & 2 deletions MLS/Data/Data/Network/Endpoints/AuthEndPoint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,11 @@ public enum AuthEndPoint {
)
}

public static func fcmToken(credential: String, body: Encodable) -> ResponsableEndPoint<MemberDTO> {
public static func fcmToken(body: Encodable) -> ResponsableEndPoint<MemberDTO> {
.init(
baseURL: base,
path: "/api/v1/auth/member/fcm-token",
method: .PUT,
headers: ["Authorization": "Bearer \(credential)"],
body: body
)
}
Expand Down
4 changes: 2 additions & 2 deletions MLS/Data/Data/Network/Endpoints/BookmarkEndPoint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import DomainInterface
public enum BookmarkEndPoint {
static let base = "https://api.mapleland.kro.kr"

public static func setBookmark(body: Encodable) -> ResponsableEndPoint<[BookmarkDTO]> {
public static func setBookmark(body: Encodable) -> ResponsableEndPoint<SetBookmarkDTO> {
.init(
baseURL: base,
path: "/api/v1/bookmarks",
Expand All @@ -12,7 +12,7 @@ public enum BookmarkEndPoint {
)
}

public static func deleteBookmark(bookmarkId: Int) -> ResponsableEndPoint<[BookmarkDTO]> {
public static func deleteBookmark(bookmarkId: Int) -> ResponsableEndPoint<EmptyResponseDTO> {
.init(
baseURL: base,
path: "/api/v1/bookmarks/\(bookmarkId)",
Expand Down
18 changes: 0 additions & 18 deletions MLS/Data/Data/Network/Endpoints/CollectionEndPoint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,6 @@ public enum CollectionEndPoint {
)
}

public static func addBookmarksToCollection(id: Int, body: Encodable) -> EndPoint {
.init(
baseURL: base,
path: "/api/v1/collections/\(id)/bookmarks",
method: .POST,
body: body
)
}

public static func addCollectionsToBookmark(id: Int, body: Encodable) -> EndPoint {
.init(
baseURL: base,
path: "/api/v1/bookmarks/\(id)/collections",
method: .POST,
body: body
)
}

public static func setCollectionName(id: Int, body: Encodable) -> EndPoint {
.init(
baseURL: base,
Expand Down
11 changes: 10 additions & 1 deletion MLS/Data/Data/Providers/Network/NetworkProviderImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,15 @@ public final class NetworkProviderImpl: NetworkProvider {
do {
let decoded = try JSONDecoder().decode(APIDefaultResponseDTO<T.Response>.self, from: data)
print("🎯 requestData: 디코딩 성공 - \(decoded)")
observer.onNext(decoded.data!)
if let decodedData = decoded.data {
observer.onNext(decodedData)
} else {
if T.Response.self == EmptyResponseDTO.self {
observer.onNext(EmptyResponseDTO() as! T.Response)
} else {
observer.onError(NetworkError.invalidResponse)
}
}
observer.onCompleted()
} catch {
print("❌ requestData: 디코딩 실패 - \(error)")
Expand Down Expand Up @@ -115,6 +123,7 @@ private extension NetworkProviderImpl {
completion(.success(data))
case .failure(let error):
completion(.failure(error))
print("API 통신에러 \(error)")
}
}
task.resume()
Expand Down
22 changes: 11 additions & 11 deletions MLS/Data/Data/Repository/AlarmAPIRepositoryImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,32 @@ public class AlarmAPIRepositoryImpl: AlarmAPIRepository {
self.tokenInterceptor = interceptor
}

public func fetchPatchNotes(cursor: [Int]?, pageSize: Int) -> Observable<PagedEntity<AlarmResponse>> {
let endpoint = AlarmEndPoint.fetchPatchNotes(query: AlarmQuery(cursor: cursor, pageSize: 999/*pageSize*/))
public func fetchPatchNotes(cursor: String?, pageSize: Int) -> Observable<PagedEntity<AlarmResponse>> {
let endpoint = AlarmEndPoint.fetchPatchNotes(query: AlarmQuery(cursor: cursor, pageSize: pageSize))
return provider.requestData(endPoint: endpoint, interceptor: tokenInterceptor)
.map { $0.toAlarmDomain() }
}

public func fetchNotices(cursor: [Int]?, pageSize: Int) -> Observable<PagedEntity<AlarmResponse>> {
let endpoint = AlarmEndPoint.fetchNotices(query: AlarmQuery(cursor: cursor, pageSize: 999/*pageSize*/))
public func fetchNotices(cursor: String?, pageSize: Int) -> Observable<PagedEntity<AlarmResponse>> {
let endpoint = AlarmEndPoint.fetchNotices(query: AlarmQuery(cursor: cursor, pageSize: pageSize))
return provider.requestData(endPoint: endpoint, interceptor: tokenInterceptor)
.map { $0.toAlarmDomain() }
}

public func fetchOutdatedEvents(cursor: [Int]?, pageSize: Int) -> Observable<PagedEntity<AlarmResponse>> {
let endpoint = AlarmEndPoint.fetchOutdatedEvents(query: AlarmQuery(cursor: cursor, pageSize: 999/*pageSize*/))
public func fetchOutdatedEvents(cursor: String?, pageSize: Int) -> Observable<PagedEntity<AlarmResponse>> {
let endpoint = AlarmEndPoint.fetchOutdatedEvents(query: AlarmQuery(cursor: cursor, pageSize: pageSize))
return provider.requestData(endPoint: endpoint, interceptor: tokenInterceptor)
.map { $0.toAlarmDomain() }
}

public func fetchOngoingEvents(cursor: [Int]?, pageSize: Int) -> Observable<PagedEntity<AlarmResponse>> {
let endpoint = AlarmEndPoint.fetchOngoingEvents(query: AlarmQuery(cursor: cursor, pageSize: 999/*pageSize*/))
public func fetchOngoingEvents(cursor: String?, pageSize: Int) -> Observable<PagedEntity<AlarmResponse>> {
let endpoint = AlarmEndPoint.fetchOngoingEvents(query: AlarmQuery(cursor: cursor, pageSize: pageSize))
return provider.requestData(endPoint: endpoint, interceptor: tokenInterceptor)
.map { $0.toAlarmDomain() }
}

public func fetchAll(cursor: [Int]?, pageSize: Int) -> Observable<PagedEntity<AllAlarmResponse>> {
let endpoint = AlarmEndPoint.fetchAll(query: AlarmQuery(cursor: cursor, pageSize: 999/*pageSize*/))
public func fetchAll(cursor: String?, pageSize: Int) -> Observable<PagedEntity<AllAlarmResponse>> {
let endpoint = AlarmEndPoint.fetchAll(query: AlarmQuery(cursor: cursor, pageSize: pageSize))
return provider.requestData(endPoint: endpoint, interceptor: tokenInterceptor)
.map { $0.toAllAlarmDomain() }
}
Expand All @@ -52,7 +52,7 @@ public class AlarmAPIRepositoryImpl: AlarmAPIRepository {

private extension AlarmAPIRepositoryImpl {
struct AlarmQuery: Encodable {
let cursor: [Int]?
let cursor: String?
let pageSize: Int
}

Expand Down
8 changes: 4 additions & 4 deletions MLS/Data/Data/Repository/AuthAPIRepositoryImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,12 @@ public class AuthAPIRepositoryImpl: AuthAPIRepository {

public func reissueToken(refreshToken: String) -> Observable<LoginResponse> {
let endPoint = AuthEndPoint.reIssueToken(refreshToken: refreshToken)
return provider.requestData(endPoint: endPoint, interceptor: authInterceptor).map { $0.toLoginDomain() }
return provider.requestData(endPoint: endPoint, interceptor: nil).map { $0.toLoginDomain() }
}

public func fcmToken(credential: String, fcmToken: String?) -> Completable {
let endPoint = AuthEndPoint.fcmToken(credential: credential, body: FCMTokenBody(fcmToken: fcmToken))
return provider.requestData(endPoint: endPoint, interceptor: tokenInterceptor)
public func fcmToken(fcmToken: String?) -> Completable {
let endPoint = AuthEndPoint.fcmToken(body: FCMTokenBody(fcmToken: fcmToken))
return provider.requestData(endPoint: endPoint, interceptor: authInterceptor)
}

public func fetchJobList() -> Observable<JobListResponse> {
Expand Down
6 changes: 4 additions & 2 deletions MLS/Data/Data/Repository/BookmarkRepositoryImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@ public class BookmarkRepositoryImpl: BookmarkRepository {
self.tokenInterceptor = interceptor
}

public func setBookmark(bookmarkId: Int, type: DictionaryItemType) -> Completable {
public func setBookmark(bookmarkId: Int, type: DictionaryItemType) -> Observable<Int> {
let endPoint = BookmarkEndPoint.setBookmark(body: SetBookmarkQuery(bookmarkType: type.rawValue, resourceId: bookmarkId))
return provider.requestData(endPoint: endPoint, interceptor: tokenInterceptor)
.map { $0.toDomain() }
}

public func deleteBookmark(bookmarkId: Int) -> Completable {
public func deleteBookmark(bookmarkId: Int) -> Observable<Int?> {
let endPoint = BookmarkEndPoint.deleteBookmark(bookmarkId: bookmarkId)
return provider.requestData(endPoint: endPoint, interceptor: tokenInterceptor)
.map { $0.toBookmarkDomain() }
}

public func fetchBookmark(sort: String?) -> Observable<[BookmarkResponse]> {
Expand Down
24 changes: 1 addition & 23 deletions MLS/Data/Data/Repository/CollectionAPIRepositoryImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,29 +31,7 @@ public class CollectionAPIRepositoryImpl: CollectionAPIRepository {
.map { $0.toDomain() }
}

// public func addBookmarksToCollection(collectionId: Int, bookmarkIds: [Int]) -> Completable {
// let endPoint = CollectionEndPoint.addBookmarksToCollection(id: collectionId, body: AddBookmarkRequestBody(bookmarkIds: bookmarkIds))
// return provider.requestData(endPoint: endPoint, interceptor: tokenInterceptor)
// .catch { error in
// if let netErr = error as? NetworkError {
// switch netErr {
// case let .statusError(code, body):
// return .error(DomainHTTPError.httpStatus(code: code, message: body))
// default:
// return .error(DomainHTTPError.unknown)
// }
// } else {
// return .error(DomainHTTPError.unknown)
// }
// }
// }
//
// public func addCollectionsToBookmark(bookmarkId: Int, collectionIds: [Int]) -> Completable {
// let endPoint = CollectionEndPoint.addCollectionsToBookmark(id: bookmarkId, body: AddCollectionRequestBody(collectionIds: collectionIds))
// return provider.requestData(endPoint: endPoint, interceptor: tokenInterceptor)
// }

public func setCollectionName(collectionId: Int, name: String) -> Completable {
public func updateCollectionName(collectionId: Int, name: String) -> Completable {
let endPoint = CollectionEndPoint.setCollectionName(id: collectionId, body: SetCollectionRequestBody(name: name))
return provider.requestData(endPoint: endPoint, interceptor: tokenInterceptor)
}
Expand Down
3 changes: 2 additions & 1 deletion MLS/Data/Data/Repository/UserDefaultsRepositoryImpl.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import DomainInterface
import Foundation

import DomainInterface

import RxSwift

public final class UserDefaultsRepositoryImpl: UserDefaultsRepository {
Expand Down
2 changes: 1 addition & 1 deletion MLS/Data/DataMock/Repository/AuthAPIRepositoryMock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class AuthAPIRepositoryMock: AuthAPIRepository {
return Observable.just(.init(accessToken: "testToken", refreshToken: "testToken"))
}

public func fcmToken(credential: String, fcmToken: String?) -> Completable {
public func fcmToken(fcmToken: String?) -> Completable {
return .empty()
}

Expand Down
5 changes: 4 additions & 1 deletion MLS/Domain/Domain/Interceptor/AuthInterceptor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ public final class AuthInterceptor: Interceptor {
public func adapt(_ request: URLRequest) -> URLRequest {
var request = request
if case .success(let token) = tokenRepository.fetchToken(type: .accessToken) {
#if DEBUG
print("accessToken: \(token)")
#endif
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
}
return request
Expand All @@ -33,7 +36,7 @@ public final class AuthInterceptor: Interceptor {
let repo = authRepository()
repo.reissueToken(refreshToken: refreshToken)
.subscribe(onNext: { _ in
print("✅ reissue 완료 (저장은 UseCase 쪽에서 처리)")
print("✅ reissue 완료")
}, onError: { error in
print("❌ reissue 실패: \(error)")
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class FetchAllAlarmUseCaseImpl: FetchAllAlarmUseCase {
self.repository = repository
}

public func execute(cursor: [Int]?, pageSize: Int) -> Observable<PagedEntity<AllAlarmResponse>> {
public func execute(cursor: String?, pageSize: Int) -> Observable<PagedEntity<AllAlarmResponse>> {
return repository.fetchAll(cursor: cursor, pageSize: pageSize)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class FetchNoticesUseCaseImpl: FetchNoticesUseCase {
self.repository = repository
}

public func execute(cursor: [Int]?, pageSize: Int) -> Observable<PagedEntity<AlarmResponse>> {
public func execute(cursor: String?, pageSize: Int) -> Observable<PagedEntity<AlarmResponse>> {
return repository.fetchNotices(cursor: cursor, pageSize: pageSize)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class FetchOngoingEventsUseCaseImpl: FetchOngoingEventsUseCase {
self.repository = repository
}

public func execute(cursor: [Int]?, pageSize: Int) -> Observable<PagedEntity<AlarmResponse>> {
public func execute(cursor: String?, pageSize: Int) -> Observable<PagedEntity<AlarmResponse>> {
return repository.fetchOngoingEvents(cursor: cursor, pageSize: pageSize)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class FetchOutdatedEventsUseCaseImpl: FetchOutdatedEventsUseCase {
self.repository = repository
}

public func execute(cursor: [Int]?, pageSize: Int) -> Observable<PagedEntity<AlarmResponse>> {
public func execute(cursor: String?, pageSize: Int) -> Observable<PagedEntity<AlarmResponse>> {
return repository.fetchOutdatedEvents(cursor: cursor, pageSize: pageSize)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class FetchPatchNotesUseCaseImpl: FetchPatchNotesUseCase {
self.repository = repository
}

public func execute(cursor: [Int]?, pageSize: Int) -> Observable<PagedEntity<AlarmResponse>> {
public func execute(cursor: String?, pageSize: Int) -> Observable<PagedEntity<AlarmResponse>> {
return repository.fetchPatchNotes(cursor: cursor, pageSize: pageSize)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,25 @@ public class LoginWithAppleUseCaseImpl: LoginWithAppleUseCase {
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")
)
guard case (.success, .success) = (saveAccess, saveRefresh) else {
return Observable.error(TokenRepositoryError.dataConversionError(message: "Failed to save tokens"))
}

var fcmToken: String?
if case .success(let token) = self.tokenRepository.fetchToken(type: .fcmToken) {
fcmToken = token
}

let fcmUpdate = if let fcmToken {
self.authRepository.fcmToken(fcmToken: fcmToken)
.catch { error in
print("FCM token update failed: \(error)")
return .empty()
}
} else {
Completable.empty()
}
return fcmUpdate.andThen(savePlatform).andThen(Observable.just(response))
}
.catch { error in
Observable.error(error)
Expand Down
Loading