Skip to content

Commit e49a20d

Browse files
authored
Merge pull request #212 from YAPP-Github/qa/#211-sprint-first
Qa/#211 sprint first
2 parents a91b6a8 + db9d1c6 commit e49a20d

43 files changed

Lines changed: 1566 additions & 439 deletions

File tree

Some content is hidden

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

โ€ŽProjects/App/Resources/Pokit-info.plistโ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<key>CFBundlePackageType</key>
2222
<string>APPL</string>
2323
<key>CFBundleShortVersionString</key>
24-
<string>2.0.2</string>
24+
<string>2.1.0</string>
2525
<key>CFBundleURLTypes</key>
2626
<array>
2727
<dict>

โ€ŽProjects/App/ShareExtension/Info.plistโ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<key>CFBundleName</key>
1414
<string>Pokit</string>
1515
<key>CFBundleShortVersionString</key>
16-
<string>2.0.1</string>
16+
<string>2.1.0</string>
1717
<key>CFBundleURLTypes</key>
1818
<array>
1919
<dict>

โ€ŽProjects/App/Sources/MainTab/MainTabFeature.swiftโ€Ž

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import ComposableArchitecture
1010
import FeaturePokit
1111
import FeatureRecommend
1212
import FeatureContentDetail
13+
import FeatureCategoryDetail
1314
import Domain
1415
import DSKit
1516
import Util
@@ -79,14 +80,14 @@ public struct MainTabFeature {
7980
public enum InnerAction: Equatable {
8081
case ๋งํฌ์ถ”๊ฐ€๋ฐ์ˆ˜์ •์ด๋™(contentId: Int)
8182
case linkCopySuccess(URL?)
82-
case ๊ณต์œ ํฌํ‚ท_์ด๋™(sharedCategory: CategorySharing.SharedCategory)
83+
case ๊ณต์œ ๋ฐ›์€_์นดํ…Œ๊ณ ๋ฆฌ_์ด๋™(category: BaseCategoryItem, type: CategoryType)
8384
case ๊ฒฝ๊ณ _๋„์›€(BaseError)
8485
case errorSheetPresented(Bool)
8586
case ๋งํฌํŒ์—…_ํ™œ์„ฑํ™”(PokitLinkPopup.PopupType)
8687
case ์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ_์ด๋™(category: BaseCategoryItem)
8788
}
8889
public enum AsyncAction: Equatable {
89-
case ๊ณต์œ ๋ฐ›์€_์นดํ…Œ๊ณ ๋ฆฌ_์กฐํšŒ(categoryId: Int)
90+
case ๊ณต์œ ๋ฐ›์€_์นดํ…Œ๊ณ ๋ฆฌ_์กฐํšŒ(categoryId: Int, shareType: String?)
9091
}
9192
public enum ScopeAction: Equatable { case doNothing }
9293
public enum DelegateAction: Equatable {
@@ -208,15 +209,17 @@ private extension MainTabFeature {
208209
let categoryIdString = queryItems.first(where: { $0.name == "categoryId" })?.value,
209210
let categoryId = Int(categoryIdString)
210211
else { return .none }
211-
212+
213+
let shareType = queryItems.first(where: { $0.name == "shareType" })?.value
214+
212215
switch state.selectedTab {
213216
case .pokit:
214217
amplitudeTrack(.view_home_pokit(entryPoint: "deeplink"))
215218
case .recommend:
216219
amplitudeTrack(.view_home_recommend(entryPoint: "deeplink"))
217220
}
218221

219-
return .send(.async(.๊ณต์œ ๋ฐ›์€_์นดํ…Œ๊ณ ๋ฆฌ_์กฐํšŒ(categoryId: categoryId)))
222+
return .send(.async(.๊ณต์œ ๋ฐ›์€_์นดํ…Œ๊ณ ๋ฆฌ_์กฐํšŒ(categoryId: categoryId, shareType: shareType)))
220223
case .๊ฒฝ๊ณ _ํ™•์ธ๋ฒ„ํŠผ_ํด๋ฆญ:
221224
state.error = nil
222225
return .run { send in await send(.inner(.errorSheetPresented(false))) }
@@ -275,18 +278,39 @@ private extension MainTabFeature {
275278
}
276279
state.path.append(.์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ(.init(category: category)))
277280
return .none
281+
282+
case let .๊ณต์œ ๋ฐ›์€_์นดํ…Œ๊ณ ๋ฆฌ_์ด๋™(category, type):
283+
state.path.append(.์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ(.init(type: type, category: category)))
284+
return .none
285+
278286
default: return .none
279287
}
280288
}
281289
/// - Async Effect
282290
func handleAsyncAction(_ action: Action.AsyncAction, state: inout State) -> Effect<Action> {
283291
switch action {
284-
case let .๊ณต์œ ๋ฐ›์€_์นดํ…Œ๊ณ ๋ฆฌ_์กฐํšŒ(categoryId: categoryId):
292+
case let .๊ณต์œ ๋ฐ›์€_์นดํ…Œ๊ณ ๋ฆฌ_์กฐํšŒ(categoryId: categoryId, shareType: shareType):
285293
return .run { send in
286294
do {
287-
let request = BasePageableRequest(page: 0, size: 10, sort: ["createdAt", "desc"])
288-
let sharedCategory = try await categoryClient.๊ณต์œ ๋ฐ›์€_์นดํ…Œ๊ณ ๋ฆฌ_์กฐํšŒ("\(categoryId)", request).toDomain()
289-
await send(.inner(.๊ณต์œ ํฌํ‚ท_์ด๋™(sharedCategory: sharedCategory)), animation: .smooth)
295+
let request = BasePageableRequest(page: 0, size: 10, sort: ["createdAt,desc"])
296+
let response = try await categoryClient.๊ณต์œ ๋ฐ›์€_์นดํ…Œ๊ณ ๋ฆฌ_์กฐํšŒ("\(categoryId)", request)
297+
let category = BaseCategoryItem(
298+
id: response.category.categoryId,
299+
userId: 0,
300+
categoryName: response.category.categoryName,
301+
categoryImage: BaseCategoryImage(
302+
imageId: response.category.categoryImageId,
303+
imageURL: response.category.categoryImageUrl
304+
),
305+
contentCount: response.category.contentCount,
306+
createdAt: "",
307+
openType: .๊ณต๊ฐœ,
308+
keywordType: .default,
309+
userCount: 0,
310+
isFavorite: false
311+
)
312+
let type: CategoryType = shareType == "invite" ? .์ดˆ๋Œ€ : .๊ณต์œ 
313+
await send(.inner(.๊ณต์œ ๋ฐ›์€_์นดํ…Œ๊ณ ๋ฆฌ_์ด๋™(category: category, type: type)), animation: .smooth)
290314
} catch {
291315
guard let errorResponse = error as? ErrorResponse else { return }
292316
let errorDomain = BaseError(response: errorResponse)

โ€ŽProjects/App/Sources/MainTab/MainTabFeatureView.swiftโ€Ž

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import FeatureContentDetail
1616
import FeatureContentSetting
1717
import FeatureCategoryDetail
1818
import FeatureContentList
19-
import FeatureCategorySharing
2019

2120
@ViewAction(for: MainTabFeature.self)
2221
public struct MainTabView: View {
@@ -67,10 +66,6 @@ public extension MainTabView {
6766
if let store = store.scope(state: \.๋งํฌ๋ชฉ๋ก, action: \.๋งํฌ๋ชฉ๋ก) {
6867
ContentListView(store: store)
6968
}
70-
case .๋งํฌ๊ณต์œ :
71-
if let store = store.scope(state: \.๋งํฌ๊ณต์œ , action: \.๋งํฌ๊ณต์œ ) {
72-
CategorySharingView(store: store)
73-
}
7469
}
7570

7671
if self.store.linkPopup != nil {

โ€ŽProjects/App/Sources/MainTab/MainTabPath.swiftโ€Ž

Lines changed: 22 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import FeatureCategorySetting
1414
import FeatureContentDetail
1515
import FeatureContentSetting
1616
import FeatureContentList
17-
import FeatureCategorySharing
1817
import Domain
1918
import Util
2019

@@ -29,7 +28,6 @@ public struct MainTabPath {
2928
case ๋งํฌ์ถ”๊ฐ€๋ฐ์ˆ˜์ •(ContentSettingFeature.State)
3029
case ์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ(CategoryDetailFeature.State)
3130
case ๋งํฌ๋ชฉ๋ก(ContentListFeature.State)
32-
case ๋งํฌ๊ณต์œ (CategorySharingFeature.State)
3331
}
3432

3533
public enum Action {
@@ -40,7 +38,6 @@ public struct MainTabPath {
4038
case ๋งํฌ์ถ”๊ฐ€๋ฐ์ˆ˜์ •(ContentSettingFeature.Action)
4139
case ์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ(CategoryDetailFeature.Action)
4240
case ๋งํฌ๋ชฉ๋ก(ContentListFeature.Action)
43-
case ๋งํฌ๊ณต์œ (CategorySharingFeature.Action)
4441
}
4542

4643
public var body: some Reducer<State, Action> {
@@ -51,7 +48,6 @@ public struct MainTabPath {
5148
Scope(state: \.๋งํฌ์ถ”๊ฐ€๋ฐ์ˆ˜์ •, action: \.๋งํฌ์ถ”๊ฐ€๋ฐ์ˆ˜์ •) { ContentSettingFeature() }
5249
Scope(state: \.์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ, action: \.์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ) { CategoryDetailFeature() }
5350
Scope(state: \.๋งํฌ๋ชฉ๋ก, action: \.๋งํฌ๋ชฉ๋ก) { ContentListFeature() }
54-
Scope(state: \.๋งํฌ๊ณต์œ , action: \.๋งํฌ๊ณต์œ ) { CategorySharingFeature() }
5551
}
5652
}
5753

@@ -101,18 +97,10 @@ public extension MainTabFeature {
10197
/// - ํฌํ‚ท `์ถ”๊ฐ€` or `์ˆ˜์ •`์ด ์„ฑ๊ณต์ ์œผ๋กœ `์™„๋ฃŒ`๋˜์—ˆ์„ ๋•Œ
10298
case .path(.element(_, action: .ํฌํ‚ท์ถ”๊ฐ€๋ฐ์ˆ˜์ •(.delegate(.settingSuccess)))):
10399
state.path.removeLast()
104-
guard let lastPath = state.path.last else {
105-
switch state.selectedTab {
106-
case .pokit: return .none
107-
case .recommend:
108-
return .send(.recommend(.delegate(.ํฌํ‚ท_์ถ”๊ฐ€ํ•˜๊ธฐ_์™„๋ฃŒ)))
109-
}
110-
}
111-
switch lastPath {
112-
case .๋งํฌ๊ณต์œ :
113-
state.path.removeLast()
114-
return .none
115-
default: return .none
100+
switch state.selectedTab {
101+
case .pokit: return .none
102+
case .recommend:
103+
return .send(.recommend(.delegate(.ํฌํ‚ท_์ถ”๊ฐ€ํ•˜๊ธฐ_์™„๋ฃŒ)))
116104
}
117105

118106
/// - ํฌํ‚ท ์นดํ…Œ๊ณ ๋ฆฌ ์•„์ดํ…œ ๋ˆŒ๋ €์„ ๋•Œ
@@ -218,51 +206,26 @@ public extension MainTabFeature {
218206
return .send(.delegate(.๋กœ๊ทธ์•„์›ƒ))
219207
case .path(.element(_, action: .์„ค์ •(.delegate(.ํšŒ์›ํƒˆํ‡ด)))):
220208
return .send(.delegate(.ํšŒ์›ํƒˆํ‡ด))
221-
case let .inner(.๊ณต์œ ํฌํ‚ท_์ด๋™(sharedCategory: sharedCategory)):
222-
state.path.append(.๋งํฌ๊ณต์œ (CategorySharingFeature.State(sharedCategory: sharedCategory)))
223-
return .none
224-
225-
/// ๋งํฌ ๊ณต์œ ์—์„œ ์ปจํ…์ธ  ์ƒ์„ธ๋ณด๊ธฐ
226-
case let .path(.element(_, action: .๋งํฌ๊ณต์œ (.delegate(.์ปจํ…์ธ _์•„์ดํ…œ_ํด๋ฆญ(categoryId: categoryId, content: content))))):
227-
state.contentDetail = ContentDetailFeature.State(content: BaseContentDetail(
228-
id: content.id,
229-
category: BaseCategoryInfo(
230-
categoryId: categoryId,
231-
categoryName: content.categoryName
232-
),
233-
title: content.title,
234-
data: content.data,
235-
memo: content.memo ?? "",
236-
createdAt: content.createdAt,
237-
favorites: nil,
238-
alertYn: .no
239-
))
240-
return .none
241-
242-
case let .path(.element(_, action: .๋งํฌ๊ณต์œ (.delegate(.๊ณต์œ ๋ฐ›์€_์นดํ…Œ๊ณ ๋ฆฌ_์ถ”๊ฐ€(sharedCategory))))):
243-
let category = BaseCategoryItem(
244-
id: sharedCategory.categoryId,
245-
userId: 0,
246-
categoryName: sharedCategory.categoryName,
247-
categoryImage: BaseCategoryImage(
248-
imageId: sharedCategory.categoryImageId,
249-
imageURL: sharedCategory.categoryImageUrl
250-
),
251-
contentCount: sharedCategory.contentCount,
252-
createdAt: "",
253-
openType: .๊ณต๊ฐœ,
254-
keywordType: .default,
255-
userCount: 0,
256-
isFavorite: false
257-
)
258-
state.path.append(.ํฌํ‚ท์ถ”๊ฐ€๋ฐ์ˆ˜์ •(PokitCategorySettingFeature.State(
259-
type: .๊ณต์œ ์ถ”๊ฐ€,
260-
category: category
261-
)))
262-
return .none
209+
263210
case .path(.element(_, action: .์•Œ๋ฆผํ•จ(.delegate(.alertBoxDismiss)))):
264-
state.path.popLast()
211+
let _ = state.path.popLast()
265212
return .none
213+
214+
/// - ์ดˆ๋Œ€ ์ˆ˜๋ฝ ์™„๋ฃŒ
215+
case .path(.element(_, action: .์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ(.delegate(.์ดˆ๋Œ€_์ˆ˜๋ฝ_์™„๋ฃŒ)))):
216+
state.path.removeLast()
217+
return .send(.inner(.๋งํฌํŒ์—…_ํ™œ์„ฑํ™”(.success(title: "์ดˆ๋Œ€๋ฅผ ์ˆ˜๋ฝํ–ˆ์Šต๋‹ˆ๋‹ค", until: 2))), animation: .pokitSpring)
218+
219+
/// - ๊ณต์œ  ํฌํ‚ท ์ €์žฅ ์™„๋ฃŒ
220+
case .path(.element(_, action: .์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ(.delegate(.์ €์žฅ_์™„๋ฃŒ)))):
221+
state.path.removeLast()
222+
return .send(.inner(.๋งํฌํŒ์—…_ํ™œ์„ฑํ™”(.success(title: "ํฌํ‚ท์„ ์ €์žฅํ–ˆ์Šต๋‹ˆ๋‹ค", until: 2))), animation: .pokitSpring)
223+
224+
/// - ํฌํ‚ท ๋‚˜๊ฐ€๊ธฐ ์™„๋ฃŒ
225+
case .path(.element(_, action: .์นดํ…Œ๊ณ ๋ฆฌ์ƒ์„ธ(.delegate(.ํฌํ‚ท๋‚˜๊ฐ€๊ธฐ)))):
226+
state.path.removeLast()
227+
return .send(.inner(.๋งํฌํŒ์—…_ํ™œ์„ฑํ™”(.success(title: "ํฌํ‚ท์—์„œ ๋‚˜๊ฐ”์Šต๋‹ˆ๋‹ค", until: 2))), animation: .pokitSpring)
228+
266229
default: return .none
267230
}
268231
}

โ€ŽProjects/CoreKit/Sources/Data/Client/KakaoSDK/Model/CategoryKaKaoShareModel.swiftโ€Ž

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,23 @@
88
import Foundation
99

1010
public struct CategoryKaKaoShareModel {
11+
public enum ShareType: String {
12+
case ๊ณต์œ  = "share"
13+
case ์ดˆ๋Œ€ = "invite"
14+
}
15+
16+
let shareType: ShareType
1117
let categoryName: String
1218
let categoryId: Int
1319
let imageURL: String
1420

1521
public init(
22+
shareType: ShareType,
1623
categoryName: String,
1724
categoryId: Int,
1825
imageURL: String
1926
) {
27+
self.shareType = shareType
2028
self.categoryName = categoryName
2129
self.categoryId = categoryId
2230
self.imageURL = imageURL

โ€ŽProjects/CoreKit/Sources/Data/Client/KakaoSDK/Share/KakaoShareClient+LiveKey.swiftโ€Ž

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ extension KakaoShareClient: DependencyKey {
1919
/// ๋”ฅ๋งํฌ
2020
let appLink = Link(
2121
androidExecutionParams: [
22+
"shareType": model.shareType.rawValue,
2223
"categoryId": "\(model.categoryId)"
2324
], iosExecutionParams: [
25+
"shareType": model.shareType.rawValue,
2426
"categoryId": "\(model.categoryId)"
2527
]
2628
)
@@ -32,12 +34,24 @@ extension KakaoShareClient: DependencyKey {
3234
)
3335

3436
/// ์นด์นด์˜คํ†ก ๋ฉ”์„ธ์ง€ ๋‚ด์šฉ
35-
let content = Content(
36-
title: "\(model.categoryName) ํฌํ‚ท์„ ๊ณต์œ ๋ฐ›์•˜์–ด์š”!",
37-
imageUrl: URL(string: model.imageURL),
38-
description: "์†Œ์ค‘ํ•œ ๋งํฌ๋“ค์ด ๋‹ด๊ธด ํฌํ‚ท์„ Pokit ์•ฑ์—์„œ ์ง€๊ธˆ ๋ฐ”๋กœ ํ™•์ธํ•ด๋ณด์„ธ์š”!",
39-
link: appLink
40-
)
37+
let content = {
38+
switch model.shareType {
39+
case .๊ณต์œ :
40+
Content(
41+
title: "\(model.categoryName) ํฌํ‚ท์„ ๊ณต์œ ๋ฐ›์•˜์–ด์š”!",
42+
imageUrl: URL(string: model.imageURL),
43+
description: "์†Œ์ค‘ํ•œ ๋งํฌ๋“ค์ด ๋‹ด๊ธด ํฌํ‚ท์„ Pokit ์•ฑ์—์„œ ์ง€๊ธˆ ๋ฐ”๋กœ ํ™•์ธํ•ด๋ณด์„ธ์š”!",
44+
link: appLink
45+
)
46+
case .์ดˆ๋Œ€:
47+
Content(
48+
title: "\(model.categoryName) ํฌํ‚ท ์ดˆ๋Œ€์žฅ์ด ์™”์–ด์š”!",
49+
imageUrl: URL(string: model.imageURL),
50+
description: "์†Œ์ค‘ํ•œ ๋งํฌ๋“ค์ด ๋‹ด๊ธด ํฌํ‚ท์„ Pokit ์•ฑ์—์„œ ์ง€๊ธˆ ๋ฐ”๋กœ ์นจ์—ฌํ•ด๋ณด์„ธ์š”!",
51+
link: appLink
52+
)
53+
}
54+
}()
4155

4256
/// ํ”ผ๋“œ ํ…œํ”Œ๋ฆฟ
4357
let template = FeedTemplate(
@@ -60,7 +74,9 @@ extension KakaoShareClient: DependencyKey {
6074
return
6175
}
6276

63-
let serverCallbackArgs = ["categoryId": "\(model.categoryId)"]
77+
let serverCallbackArgs = [
78+
"categoryId": "\(model.categoryId)"
79+
]
6480

6581
ShareApi.shared.shareDefault(
6682
templateObject: templateJsonObject,
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//
2+
// InvitedUserResponse.swift
3+
// CoreKit
4+
//
5+
// Created by ๊น€๋„ํ˜• on 12/25/25.
6+
//
7+
8+
import Foundation
9+
10+
public struct InvitedUserResponse: Decodable {
11+
public let userId: Int
12+
public let nickname: String
13+
public let profileImage: BaseProfileImageResponse?
14+
}
15+
16+
extension InvitedUserResponse {
17+
public static var mock: Self = Self(
18+
userId: 1,
19+
nickname: "PokitUser",
20+
profileImage: .mock
21+
)
22+
}

โ€ŽProjects/CoreKit/Sources/Data/Network/Category/CategoryClient+LiveKey.swiftโ€Ž

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,20 @@ extension CategoryClient: DependencyKey {
5252
},
5353
๊ณต์œ ๋ฐ›์€_์นดํ…Œ๊ณ ๋ฆฌ_์ €์žฅ: { model in
5454
try await provider.requestNoBody(.๊ณต์œ ๋ฐ›์€_์นดํ…Œ๊ณ ๋ฆฌ_์ €์žฅ(model: model))
55+
},
56+
ํฌํ‚ท_์ดˆ๋Œ€๋œ_์œ ์ €_๋ชฉ๋ก_์กฐํšŒ: { id in
57+
try await provider.request(.ํฌํ‚ท_์ดˆ๋Œ€๋œ_์œ ์ €_๋ชฉ๋ก_์กฐํšŒ(categoryId: id))
58+
},
59+
ํฌํ‚ท_๋‚ด๋ณด๋‚ด๊ธฐ: { categoryId, resignUserId in
60+
try await provider.requestNoBody(
61+
.ํฌํ‚ท_๋‚ด๋ณด๋‚ด๊ธฐ(categoryId: categoryId, resignUserId: resignUserId)
62+
)
63+
},
64+
ํฌํ‚ท_๋‚˜๊ฐ€๊ธฐ: { categoryId in
65+
try await provider.requestNoBody(.ํฌํ‚ท_๋‚˜๊ฐ€๊ธฐ(categoryId: categoryId))
66+
},
67+
ํฌํ‚ท_์ดˆ๋Œ€_์ˆ˜๋ฝ: { categoryId in
68+
try await provider.requestNoBody(.ํฌํ‚ท_์ดˆ๋Œ€_์ˆ˜๋ฝ(categoryId: categoryId))
5569
}
5670
)
5771
}()

โ€ŽProjects/CoreKit/Sources/Data/Network/Category/CategoryClient+TestKey.swiftโ€Ž

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ extension CategoryClient: TestDependencyKey {
1818
์œ ์ €_์นดํ…Œ๊ณ ๋ฆฌ_๊ฐœ์ˆ˜_์กฐํšŒ: { .mock },
1919
์นดํ…Œ๊ณ ๋ฆฌ_์ƒ์„ธ_์กฐํšŒ: { _ in .mock },
2020
๊ณต์œ ๋ฐ›์€_์นดํ…Œ๊ณ ๋ฆฌ_์กฐํšŒ: { _, _ in .mock },
21-
๊ณต์œ ๋ฐ›์€_์นดํ…Œ๊ณ ๋ฆฌ_์ €์žฅ: { _ in }
21+
๊ณต์œ ๋ฐ›์€_์นดํ…Œ๊ณ ๋ฆฌ_์ €์žฅ: { _ in },
22+
ํฌํ‚ท_์ดˆ๋Œ€๋œ_์œ ์ €_๋ชฉ๋ก_์กฐํšŒ: { _ in [.mock] },
23+
ํฌํ‚ท_๋‚ด๋ณด๋‚ด๊ธฐ: { _, _ in },
24+
ํฌํ‚ท_๋‚˜๊ฐ€๊ธฐ: { _ in },
25+
ํฌํ‚ท_์ดˆ๋Œ€_์ˆ˜๋ฝ: { _ in }
2226
)
2327
}()
2428
}

0 commit comments

Comments
ย (0)