Skip to content

Commit 7299f6a

Browse files
authored
v1.1.0: 내 체험단 및 알림 탭 추가
v1.1.0: 내 체험단 및 알림 탭 추가
2 parents 5217840 + 7c025bd commit 7299f6a

File tree

152 files changed

+2762
-1170
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

152 files changed

+2762
-1170
lines changed

cherrydan.xcodeproj/project.pbxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@
473473
"$(inherited)",
474474
"@executable_path/Frameworks",
475475
);
476-
MARKETING_VERSION = 1.0.2;
476+
MARKETING_VERSION = 1.1.0;
477477
PRODUCT_BUNDLE_IDENTIFIER = com.teamSquid.cherrydan;
478478
PRODUCT_NAME = "$(TARGET_NAME)";
479479
SWIFT_EMIT_LOC_STRINGS = YES;
@@ -506,7 +506,7 @@
506506
"$(inherited)",
507507
"@executable_path/Frameworks",
508508
);
509-
MARKETING_VERSION = 1.0.2;
509+
MARKETING_VERSION = 1.1.0;
510510
PRODUCT_BUNDLE_IDENTIFIER = com.teamSquid.cherrydan;
511511
PRODUCT_NAME = "$(TARGET_NAME)";
512512
SWIFT_EMIT_LOC_STRINGS = YES;

cherrydan/Application/AppDelegate.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import UIKit
77
import Firebase
88
import FirebaseMessaging
99
import UserNotifications
10+
import SwiftUI
1011

1112
final class AppDelegate: NSObject, UIApplicationDelegate {
1213
private let notificationCenter = UNUserNotificationCenter.current()
@@ -87,6 +88,27 @@ private extension AppDelegate {
8788
func handleNotificationData(_ userInfo: [AnyHashable: Any], isAppActive: Bool = true) {
8889
guard let messageType = userInfo["type"] as? String else { return }
8990

91+
// 서버 타입 → 앱 탭 매핑
92+
let targetTab: NotificationType?
93+
switch messageType {
94+
case "keyword_campaign":
95+
targetTab = .custom
96+
case "activity_reminder":
97+
targetTab = .activity
98+
default:
99+
targetTab = nil
100+
}
101+
102+
if let targetTab {
103+
NotificationCenter.default.post(
104+
name: .didTapPushNotification,
105+
object: nil,
106+
userInfo: [PushRouteUserInfoKey.targetTab: targetTab]
107+
)
108+
return
109+
}
110+
111+
// 기존 기타 타입 처리 분기 (필요 시 확장)
90112
switch messageType {
91113
case "chat":
92114
handleChatNotification(userInfo, isAppActive: isAppActive)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import Foundation
2+
3+
class ActivityRepository {
4+
private let networkAPI: NetworkAPI
5+
6+
init(networkAPI: NetworkAPI = NetworkAPI()) {
7+
self.networkAPI = networkAPI
8+
}
9+
10+
// MARK: - Activity Alerts
11+
func getActivityNotifications(page: Int = 0) async throws ->APIResponse<PageableResponse<ActivityNotification>> {
12+
let query: [String:String] = [
13+
"page": String(page),
14+
"size": "20",
15+
"sort": "alertDate,desc"
16+
]
17+
18+
do {
19+
return try await networkAPI.request(ActivityEndpoint.getActivityNotification, queryParameters: query)
20+
} catch {
21+
print("NotificationRepository Error: \(error)")
22+
throw error
23+
}
24+
}
25+
26+
/// 활동 알림 삭제
27+
func deleteActivityAlerts(alertIds: [Int]) async throws {
28+
let params = ["alertIds": alertIds]
29+
let _: EmptyResult = try await networkAPI.request(
30+
ActivityEndpoint.deleteActivityNotifications,
31+
parameters: params
32+
)
33+
}
34+
35+
/// 활동 알림 읽음 처리
36+
func markActivityAlertsAsRead(alertIds: [Int]) async throws {
37+
let params = ["alertIds": alertIds]
38+
let _: EmptyResult = try await networkAPI.request(
39+
ActivityEndpoint.markActivityAlertsAsRead,
40+
parameters: params
41+
)
42+
}
43+
}
44+
45+

cherrydan/Data/Repositories/AuthRepository.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Foundation
2+
import UIKit
23

34
class AuthRepository {
45
private let networkAPI: NetworkAPI
@@ -9,10 +10,14 @@ class AuthRepository {
910

1011
func socialLogin(_ provider: String,_ token: String, userInfo: UserInfo?) async throws -> SocialLoginResponse {
1112
let fcmToken = KeychainManager.shared.getFcmToken()
12-
var params: [String: Any] = [
13+
let deviceModel = UIDevice.current.modelName
14+
var params: [String: String] = [
1315
"accessToken": token,
14-
"fcmToken": fcmToken,
15-
"deviceType": "iOS"
16+
"fcmToken": fcmToken ?? "",
17+
"deviceType": "iOS",
18+
"deviceModel": deviceModel,
19+
"osVersion": "\(ProcessInfo.processInfo.operatingSystemVersionString)",
20+
"appVersion": "\(Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "1.0")"
1621
]
1722

1823
// 사용자 정보가 있는 경우 추가
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import Foundation
2+
3+
class BookmarkRepository {
4+
private let networkAPI: NetworkAPI
5+
6+
init(networkAPI: NetworkAPI = NetworkAPI()) {
7+
self.networkAPI = networkAPI
8+
}
9+
10+
/// 북마크 추가
11+
func addBookmark(campaignId: Int) async throws {
12+
let _: EmptyResult = try await networkAPI.request(
13+
BookmarkEndpoint.addBookmark(campaignId: campaignId)
14+
)
15+
}
16+
17+
/// 북마크 취소 (is_active = false)
18+
func cancelBookmark(campaignId: Int) async throws {
19+
let _: EmptyResult = try await networkAPI.request(
20+
BookmarkEndpoint.cancelBookmark(campaignId: campaignId)
21+
)
22+
}
23+
24+
/// 북마크 완전 삭제
25+
func deleteBookmark(campaignId: Int) async throws {
26+
let _: EmptyResult = try await networkAPI.request(
27+
BookmarkEndpoint.deleteBookmark(campaignId: campaignId)
28+
)
29+
}
30+
31+
/// 내 북마크 목록 조회
32+
func getOpenBookmarks(page: Int = 0) async throws -> PageableResponse<MyCampaignDTO> {
33+
let query = [
34+
"page": "\(page)",
35+
"size": "20"
36+
]
37+
38+
let response: APIResponse<PageableResponse<MyCampaignDTO>> = try await networkAPI.request(
39+
BookmarkEndpoint.getOpenBookmarks,
40+
queryParameters: query
41+
)
42+
return response.result
43+
}
44+
45+
func getClosedBookmarks(page: Int = 0) async throws -> PageableResponse<MyCampaignDTO> {
46+
let query = [
47+
"page": "\(page)",
48+
"size": "20"
49+
]
50+
51+
let response: APIResponse<PageableResponse<MyCampaignDTO>> = try await networkAPI.request(
52+
BookmarkEndpoint.getClosedBookmarks,
53+
queryParameters: query
54+
)
55+
return response.result
56+
}
57+
}

cherrydan/Data/Repositories/CampaignRepository.swift

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,25 @@ class CampaignRepository {
5656
return response.result
5757
}
5858

59+
func getCampaignByReporter(
60+
sort: SortType = .popular,
61+
page: Int = 0
62+
) async throws -> PageableResponse<CampaignDTO> {
63+
do {
64+
let query: [String: String] = [
65+
"sort": sort.rawValue,
66+
"page": "\(page)",
67+
]
68+
69+
let response: APIResponse<PageableResponse<CampaignDTO>> = try await networkAPI.request(CampaignEndpoint.getCampaignByReporter, queryParameters: query)
70+
return response.result
71+
} catch {
72+
print("CampaignRepository Error: \(error)")
73+
throw error
74+
}
75+
}
76+
77+
5978
/// - Note: HomeView 내부 `제품` 탭에서 호출합니다.
6079
func getCampaignByProduct(
6180
_ product: [ProductCategory] = [],
@@ -79,7 +98,7 @@ class CampaignRepository {
7998

8099
/// - Note: HomeView 내부 `SNS 플랫폼` 탭에서 호출합니다.
81100
func getCampaignBySNSPlatform(
82-
_ snsPlatform: [SocialPlatformType] = [],
101+
_ snsPlatform: [SNSPlatformType] = [],
83102
sort: SortType = .popular,
84103
page: Int = 0
85104
) async throws -> PageableResponse<CampaignDTO> {
@@ -100,7 +119,7 @@ class CampaignRepository {
100119

101120
/// - Note: HomeView 내부 `캠페인 플랫폼` 탭에서 호출합니다.
102121
func getCampaignByCampaignPlatform(
103-
_ campaignPlatform: [CampaignPlatformType] = [],
122+
_ campaignPlatform: [CampaignPlatform] = [],
104123
sort: SortType = .popular,
105124
page: Int = 0
106125
) async throws -> PageableResponse<CampaignDTO> {
@@ -110,7 +129,7 @@ class CampaignRepository {
110129
]
111130

112131
if !campaignPlatform.isEmpty {
113-
query["platform"] = campaignPlatform.map { $0.imageName }.joined(separator: ",")
132+
query["platform"] = campaignPlatform.map { $0.siteNameEn }.joined(separator: ",")
114133
} else {
115134
query["platform"] = "all"
116135
}
@@ -132,7 +151,6 @@ class CampaignRepository {
132151
}
133152
}
134153

135-
136154
/// - Note: SearchView 내부 `검색 단계`에서 호출합니다.
137155
func searchCampaign(_ keyword: String) async throws -> [CampaignDTO] {
138156
let query = ["keyword": keyword]
@@ -154,8 +172,8 @@ class CampaignRepository {
154172
subRegions: [SubRegion] = [],
155173
local: [LocalCategory] = [],
156174
product: [ProductCategory] = [],
157-
snsPlatform: [SocialPlatformType] = [],
158-
campaignPlatform: [CampaignPlatformType] = [],
175+
snsPlatform: [SNSPlatformType] = [],
176+
campaignPlatform: [CampaignPlatform] = [],
159177
sort: SortType = .popular,
160178
page: Int = 0,
161179
focusedCategory: CampaignType? = nil,
@@ -204,7 +222,7 @@ class CampaignRepository {
204222
}
205223
case .campaignPlatform:
206224
if !campaignPlatform.isEmpty {
207-
queryParameters["campaignPlatform"] = campaignPlatform.map { $0.imageName }.joined(separator: ",")
225+
queryParameters["campaignPlatform"] = campaignPlatform.map { $0.siteNameEn }.joined(separator: ",")
208226
} else {
209227
queryParameters["campaignPlatform"] = "all"
210228
}
@@ -225,7 +243,7 @@ class CampaignRepository {
225243
queryParameters["snsPlatform"] = "all"
226244
}
227245
if !campaignPlatform.isEmpty {
228-
queryParameters["campaignPlatform"] = campaignPlatform.map { $0.imageName }.joined(separator: ",")
246+
queryParameters["campaignPlatform"] = campaignPlatform.map { $0.siteNameEn }.joined(separator: ",")
229247
} else {
230248
queryParameters["campaignPlatform"] = "all"
231249
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import Foundation
2+
3+
class KeywordRepository {
4+
private let networkAPI: NetworkAPI
5+
6+
init(networkAPI: NetworkAPI = NetworkAPI()) {
7+
self.networkAPI = networkAPI
8+
}
9+
10+
// MARK: - User Keywords
11+
12+
/// 내 키워드 목록 조회
13+
func getUserKeywords(page: Int = 0, size: Int = 20) async throws -> APIResponse<[UserKeywordResponseDTO]> {
14+
let query: [String: String] = [
15+
"page": String(page),
16+
"size": String(size)
17+
]
18+
19+
return try await networkAPI.request(
20+
KeywordEndpoint.getUserKeywords,
21+
queryParameters: query
22+
)
23+
}
24+
25+
/// 내 키워드 등록
26+
func addUserKeyword(keyword: String) async throws {
27+
let query: [String: String] = [
28+
"keyword": keyword
29+
]
30+
31+
let _: EmptyResult = try await networkAPI.request(
32+
KeywordEndpoint.addUserKeyword(keyword: keyword),
33+
parameters: query
34+
)
35+
}
36+
37+
/// 내 키워드 삭제
38+
func deleteUserKeyword(keywordId: Int) async throws {
39+
let _: EmptyResult = try await networkAPI.request(
40+
KeywordEndpoint.deleteUserKeyword(keywordId: keywordId)
41+
)
42+
}
43+
44+
// MARK: - Keyword Alerts
45+
46+
/// 내 키워드 알림 목록 조회
47+
func getKeywordNotifications(page: Int = 0) async throws -> APIResponse<PageableResponse<KeywordNotification>> {
48+
let query: [String: String] = [
49+
"page": String(page),
50+
"size": "20",
51+
"sort": "alertDate,desc"
52+
]
53+
54+
return try await networkAPI.request(
55+
KeywordEndpoint.getKeywordAlerts,
56+
queryParameters: query
57+
)
58+
}
59+
60+
/// 키워드 알림 삭제
61+
func deleteKeywordAlerts(alertIds: [Int]) async throws {
62+
let params = ["alertIds": alertIds]
63+
let _: EmptyResult = try await networkAPI.request(
64+
KeywordEndpoint.deleteKeywordAlerts,
65+
parameters: params
66+
)
67+
}
68+
69+
// 키워드 알림 읽음 처리
70+
func markKeywordAlertsAsRead(alertIds: [Int]) async throws {
71+
let params = ["alertIds": alertIds]
72+
let _: EmptyResult = try await networkAPI.request(
73+
KeywordEndpoint.markKeywordAlertsAsRead,
74+
parameters: params
75+
)
76+
}
77+
78+
// MARK: - Personalized Campaigns
79+
80+
/// 특정 키워드로 맞춤형 캠페인 조회
81+
func getPersonalizedCampaignsByKeyword(
82+
keyword: String,
83+
date: String,
84+
page: Int = 0
85+
) async throws -> APIResponse<PageableResponse<CampaignDTO>> {
86+
let query: [String: String] = [
87+
"page": String(page),
88+
"date": date,
89+
"size": "20",
90+
"keyword": keyword
91+
]
92+
93+
return try await networkAPI.request(
94+
KeywordEndpoint.getPersonalizedCampaignsByKeyword(keyword: keyword),
95+
queryParameters: query
96+
)
97+
}
98+
}

0 commit comments

Comments
 (0)