Skip to content

Commit 6928888

Browse files
authored
Merge pull request #696 from sopt-makers/feat/#673-home-amplitude
[Feat] #673 - 홈화면 앰플리튜드 연동
2 parents ef99665 + 983432c commit 6928888

File tree

19 files changed

+294
-23
lines changed

19 files changed

+294
-23
lines changed

SOPT-iOS/Projects/Core/Sources/Amplitude/AmplitudeEventPropertyKey.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,13 @@ public enum AmplitudeEventPropertyKey: String {
1515
// 콕 찌르기 피쳐 관련 Key
1616
case viewProfile = "view_profile" // 멤버 프로필 id
1717
case friendType = "friend_type"
18+
19+
// 홈 피쳐 관련 Key
20+
case postRanking = "post_ranking"
21+
case sectionName = "section_name"
22+
case postID = "post_id"
23+
case category = "category"
24+
case promoName = "promo_name"
25+
case destinationURL = "destination_url"
26+
case destinationType = "destination_type"
1827
}

SOPT-iOS/Projects/Core/Sources/Amplitude/AmplitudeEventType.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ public enum AmplitudeEventType: String {
4343
case clickPokeMenu = "click_poke_menu"
4444
case clickTodaySoptuneMenu = "click_todaysoptmadi_menu"
4545
case clickSoptampMenu = "click_soptamp_menu"
46+
case clickPostMember = "click_post_member"
47+
case clickPost = "click_post"
48+
case clickEmpty = "click_empty"
49+
case clickViewAll = "click_view_all"
50+
case clickPromo = "click_promo"
4651

4752
// 콕 찌르기 클릭 이벤트
4853
case clickPoke = "click_poke"

SOPT-iOS/Projects/Data/Sources/Transform/HomeLatestPostsTransform.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ extension HomeLatestPostsResponseEntity {
2222
content: self.content,
2323
webLink: self.webLink,
2424
id: self.id,
25-
isOutdated: self.isOutdated
25+
isOutdated: self.isOutdated,
26+
userId: self.userId
2627
)
2728
}
2829
}

SOPT-iOS/Projects/Data/Sources/Transform/HomePopularPostsTransform.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ extension HomePopularPostsResponseEntity {
2222
title: self.title,
2323
content: self.content,
2424
webLink: self.webLink,
25-
id: self.id
25+
id: self.id,
26+
userId: self.userId
2627
)
2728
}
2829
}

SOPT-iOS/Projects/Domain/Sources/Model/HomeLatestPostsModel.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public struct HomeLatestPostModel {
1818
public let webLink: String
1919
public let id: Int?
2020
public let isOutdated: Bool
21+
public let userId: Int?
2122

2223
public init(
2324
profileImage: String?,
@@ -28,7 +29,8 @@ public struct HomeLatestPostModel {
2829
content: String,
2930
webLink: String,
3031
id: Int?,
31-
isOutdated: Bool
32+
isOutdated: Bool,
33+
userId: Int?
3234
) {
3335
self.profileImage = profileImage
3436
self.name = name
@@ -39,5 +41,6 @@ public struct HomeLatestPostModel {
3941
self.webLink = webLink
4042
self.id = id
4143
self.isOutdated = isOutdated
44+
self.userId = userId
4245
}
4346
}

SOPT-iOS/Projects/Domain/Sources/Model/HomePopularPostsModel.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public struct HomePopularPostModel {
1818
public let content: String
1919
public let webLink: String
2020
public let id: Int?
21+
public let userId: Int?
2122

2223
public init(
2324
profileImage: String?,
@@ -28,7 +29,8 @@ public struct HomePopularPostModel {
2829
title: String,
2930
content: String,
3031
webLink: String,
31-
id: Int?
32+
id: Int?,
33+
userId: Int?
3234
) {
3335
self.profileImage = profileImage
3436
self.name = name
@@ -39,5 +41,6 @@ public struct HomePopularPostModel {
3941
self.content = content
4042
self.webLink = webLink
4143
self.id = id
44+
self.userId = userId
4245
}
4346
}

SOPT-iOS/Projects/Features/HomeFeature/Interface/Sources/HomeForMemberPresentable.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public protocol HomeForMemberCoordinatable {
2929
var onPopularPostCellTapped: ((String) -> Void)? { get set }
3030
var onLatestPostCellTapped: ((String) -> Void)? { get set }
3131
var onViewAllContentButtonTapped: ((String) -> Void)? { get set }
32+
var onProfileImageViewTapped: ((Int) -> Void)? { get set }
3233
}
3334
public typealias HomeForMemberViewModelType = ViewModelType & HomeForMemberCoordinatable
3435
public typealias LegacyHomeForMemberPresentable = (vc: HomeForMemberViewControllable, vm: any HomeForMemberViewModelType)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//
2+
// HomeAmplitudeEventPropertyValue.swift
3+
// HomeFeature
4+
//
5+
// Created by Jae Hyun Lee on 9/6/25.
6+
// Copyright © 2025 SOPT-iOS. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
import Core
12+
13+
enum HomeAmplitudeEventPropertyValue: String, AmplitudeEventPropertyValueConvertible {
14+
case latestPosts = "latest_posts"
15+
case realTimeFeed = "realtime_feed"
16+
case homeBanner = "home_banner"
17+
case homeFAB = "home_fab"
18+
case app = "app"
19+
case web = "web"
20+
21+
func toString() -> String {
22+
self.rawValue
23+
}
24+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
//
2+
// HomeEventTracker.swift
3+
// HomeFeature
4+
//
5+
// Created by Jae Hyun Lee on 9/6/25.
6+
// Copyright © 2025 SOPT-iOS. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
import Core
12+
import HomeFeatureInterface
13+
14+
struct HomeEventTracker {
15+
func trackAmplitude(event: AmplitudeEventType?) {
16+
if let event {
17+
AmplitudeInstance.shared.trackWithUserType(event: event)
18+
}
19+
}
20+
21+
func trackClickPostMember(
22+
postRanking: Int?,
23+
sectionName: HomeAmplitudeEventPropertyValue,
24+
postID: Int?,
25+
category: String
26+
) {
27+
let properties = AmplitudeEventPropertyBuilder<HomeAmplitudeEventPropertyValue>()
28+
.add(key: .postRanking, value: postRanking)
29+
.add(key: .sectionName, value: sectionName)
30+
.add(key: .postID, value: postID)
31+
.add(key: .category, value: category)
32+
.addViewType()
33+
.build()
34+
35+
AmplitudeInstance.shared.track(eventType: .clickPostMember, eventProperties: properties)
36+
}
37+
38+
func trackClickPost(
39+
postRanking: Int? = 0, // NOTE: 최신 게시물일 경우, 랭킹이 존재하지 않고 0으로 처리합니다.
40+
sectionName: HomeAmplitudeEventPropertyValue,
41+
postID: Int? = 0,
42+
category: String
43+
) {
44+
let properties = AmplitudeEventPropertyBuilder<HomeAmplitudeEventPropertyValue>()
45+
.add(key: .postRanking, value: postRanking)
46+
.add(key: .sectionName, value: sectionName)
47+
.add(key: .postID, value: postID)
48+
.add(key: .category, value: category)
49+
.addViewType()
50+
.build()
51+
52+
AmplitudeInstance.shared.track(eventType: .clickPost, eventProperties: properties)
53+
}
54+
55+
func trackClickEmpty(
56+
sectionName: HomeAmplitudeEventPropertyValue,
57+
category: String
58+
) {
59+
let properties = AmplitudeEventPropertyBuilder<HomeAmplitudeEventPropertyValue>()
60+
.add(key: .sectionName, value: sectionName)
61+
.add(key: .category, value: category)
62+
.build()
63+
64+
AmplitudeInstance.shared.track(eventType: .clickEmpty, eventProperties: properties)
65+
}
66+
67+
func trackClickViewAll(
68+
sectionName: HomeAmplitudeEventPropertyValue
69+
) {
70+
let properties = AmplitudeEventPropertyBuilder<HomeAmplitudeEventPropertyValue>()
71+
.add(key: .sectionName, value: sectionName)
72+
.build()
73+
74+
AmplitudeInstance.shared.track(eventType: .clickViewAll, eventProperties: properties)
75+
}
76+
77+
func trackClickPromo(
78+
sectionName: HomeAmplitudeEventPropertyValue,
79+
promoName: String? = nil,
80+
destinationURL: String? = nil,
81+
destinationType: HomeAmplitudeEventPropertyValue
82+
) {
83+
let properties = AmplitudeEventPropertyBuilder<HomeAmplitudeEventPropertyValue>()
84+
.add(key: .sectionName, value: sectionName)
85+
.add(key: .promoName, value: promoName)
86+
.add(key: .destinationURL, value: destinationURL)
87+
.add(key: .destinationType, value: destinationType)
88+
.build()
89+
90+
AmplitudeInstance.shared.track(eventType: .clickPromo, eventProperties: properties)
91+
}
92+
93+
}

SOPT-iOS/Projects/Features/HomeFeature/Sources/HomeScene/Cells/DefaultPost/DefaultPostCVC.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,15 @@ enum PostCellType {
2929
case empty
3030
}
3131

32+
// 앰플리튜드 이벤트 트래킹을 위한 구조체입니다.
33+
struct PostInfo {
34+
var postRanking: Int? = 0
35+
let sectionName: HomeAmplitudeEventPropertyValue
36+
var postID: Int? = 0
37+
let category: String
38+
let userID: Int?
39+
}
40+
3241
final class DefaultPostCVC: UICollectionViewCell {
3342

3443
// MARK: - Properties
@@ -37,6 +46,13 @@ final class DefaultPostCVC: UICollectionViewCell {
3746
private let shapeLayer = CAShapeLayer()
3847
var onAnimationCompleted: (() -> Void)?
3948
private var isOutlineAnimationCancelled = false
49+
private var model: PostInfo?
50+
51+
lazy var profileImageViewTap = profileImageView.gesture()
52+
.compactMap { [weak self] _ in self?.model }
53+
.asDriver()
54+
55+
var cancelBag = CancelBag()
4056

4157
// MARK: - UI & Layout
4258

@@ -137,6 +153,8 @@ final class DefaultPostCVC: UICollectionViewCell {
137153
emptySubLabel.text = nil
138154
emptyTitleLabel.text = nil
139155
emptyImageView.image = nil
156+
cancelBag = CancelBag()
157+
model = nil
140158
profileImageView.setPlaceholder()
141159
updateVisibility(for: .latest) // visible 상태는 기본적으로 latest와 같음
142160
}
@@ -333,6 +351,17 @@ extension DefaultPostCVC {
333351
self.postContentLabel.text = model.content
334352
self.postContentLabel.setLineSpacing(lineSpacing: 1)
335353
}
354+
355+
// 앰플리튜드 이벤트 트래킹을 위해 세팅합니다.
356+
func setPostInfo(model: some PostDisplayable, section: HomeAmplitudeEventPropertyValue) {
357+
self.model = PostInfo(
358+
postRanking: model.ranking,
359+
sectionName: section,
360+
postID: model.postID,
361+
category: model.category,
362+
userID: model.userID
363+
)
364+
}
336365
}
337366

338367

0 commit comments

Comments
 (0)