Skip to content

Commit

Permalink
Analytics 로깅 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
shp7724 committed Mar 1, 2025
1 parent 754e231 commit d12f170
Show file tree
Hide file tree
Showing 31 changed files with 88 additions and 11 deletions.
7 changes: 6 additions & 1 deletion SNUTT-2022/SNUTT/AppState/States/UserState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,17 @@
//

import SwiftUI
import FirebaseAnalytics

class UserState {
@Published var accessToken: String?
@Published var current: User?
@Published var socialProvider: SocialProvider?

/// Primary key of User. Required to logout. This is not `localId`.
var userId: String?
var userId: String? {
didSet {
Analytics.setUserID(userId)
}
}
}
5 changes: 5 additions & 0 deletions SNUTT-2022/SNUTT/Models/Lecture.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ struct Lecture: Identifiable {
quota - freshmanQuota
}

/// DB에 저장된 강의 고유 ID
var referenceId: String {
lectureId ?? id
}

var createdAt: String
var updatedAt: String
var quota: Int
Expand Down
7 changes: 7 additions & 0 deletions SNUTT-2022/SNUTT/Services/AuthService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,36 +64,42 @@ struct AuthService: AuthServiceProtocol, UserAuthHandler {
}

func loginWithLocalId(localId: String, localPassword: String) async throws {
FirebaseAnalyticsLogger().logEvent(.login(.init(provider: .local)))
let dto = try await authRepository.loginWithLocalId(localId: localId, localPassword: localPassword)
saveAccessTokenFromLoginResponse(dto: dto)
try await registerFCMToken()
}

func registerWithLocalId(localId: String, localPassword: String, email: String) async throws {
FirebaseAnalyticsLogger().logEvent(.signUp)
let dto = try await authRepository.registerWithLocalId(localId: localId, localPassword: localPassword, email: email)
saveAccessTokenFromLoginResponse(dto: dto)
try await registerFCMToken()
}

func loginWithApple(appleToken: String) async throws {
FirebaseAnalyticsLogger().logEvent(.login(.init(provider: .apple)))
let dto = try await authRepository.loginWithApple(appleToken: appleToken)
saveAccessTokenFromLoginResponse(dto: dto)
try await registerFCMToken()
}

func loginWithFacebook(facebookToken: String) async throws {
FirebaseAnalyticsLogger().logEvent(.login(.init(provider: .facebook)))
let dto = try await authRepository.loginWithFacebook(facebookToken: facebookToken)
saveAccessTokenFromLoginResponse(dto: dto)
try await registerFCMToken()
}

func loginWithGoogle(googleToken: String) async throws {
FirebaseAnalyticsLogger().logEvent(.login(.init(provider: .google)))
let dto = try await authRepository.loginWithGoogle(googleToken: googleToken)
saveAccessTokenFromLoginResponse(dto: dto)
try await registerFCMToken()
}

func loginWithKakao(kakaoToken: String) async throws {
FirebaseAnalyticsLogger().logEvent(.login(.init(provider: .kakao)))
let dto = try await authRepository.loginWithKakao(kakaoToken: kakaoToken)
saveAccessTokenFromLoginResponse(dto: dto)
try await registerFCMToken()
Expand All @@ -120,6 +126,7 @@ struct AuthService: AuthServiceProtocol, UserAuthHandler {
}

func logout() async throws {
FirebaseAnalyticsLogger().logEvent(.logout)
let fcmToken = userDefaultsRepository.get(String.self, key: .fcmToken, defaultValue: "")
guard let userId = appState.user.userId else { throw STError(.NO_USER_TOKEN) }
let _ = try? await authRepository.logout(userId: userId, fcmToken: fcmToken)
Expand Down
3 changes: 2 additions & 1 deletion SNUTT-2022/SNUTT/Services/LectureService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ struct LectureService: LectureServiceProtocol {
}

func bookmarkLecture(lecture: Lecture) async throws {
try await lectureRepository.bookmarkLecture(lectureId: lecture.lectureId ?? lecture.id)
let lectureReferenceId = lecture.lectureId ?? lecture.id
try await lectureRepository.bookmarkLecture(lectureId: lectureReferenceId)
guard let currentTimetable = appState.timetable.current else { return }
let dto = try await lectureRepository.getBookmark(quarter: currentTimetable.quarter)
let bookmark = Bookmark(from: dto)
Expand Down
1 change: 1 addition & 0 deletions SNUTT-2022/SNUTT/Services/SearchService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ struct SearchService: SearchServiceProtocol {
offset: offset,
limit: searchState.perPage)
let models: [Lecture] = dtos.map { Lecture(from: $0) }
FirebaseAnalyticsLogger().logEvent(.searchLecture(.init(query: searchState.searchText, quarter: currentTimetable.quarter.longString(), page: searchState.pageNum)))
searchState.searchResult = offset == 0 ? models : (searchState.searchResult ?? []) + models
}

Expand Down
2 changes: 2 additions & 0 deletions SNUTT-2022/SNUTT/ViewModels/LectureDetailViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ extension LectureDetailScene {
}

func bookmarkLecture(lecture: Lecture) async {
FirebaseAnalyticsLogger().logEvent(.addToBookmark(.init(lectureID: lecture.referenceId, referrer: .lectureDetail)))
do {
try await services.lectureService.bookmarkLecture(lecture: lecture)
} catch {
Expand All @@ -194,6 +195,7 @@ extension LectureDetailScene {
}

func addVacancyLecture(lecture: Lecture) async {
FirebaseAnalyticsLogger().logEvent(.addToVacancy(.init(lectureID: lecture.referenceId, referrer: .lectureDetail)))
do {
try await services.vacancyService.addLecture(lecture: lecture)
} catch let error as STError where error.code == .INVALID_SEMESTER_FOR_VACANCY_NOTIFICATION {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ struct ExpandableLectureCell: View {
isMainWebView: false,
detailId: reviewDetailId
)
.analyticsScreen(.reviewDetail(.init(lectureID: lecture.referenceId, referrer: viewModel.detailReferrer)))
.id(reviewDetailId)
}
.sheet(isPresented: $isDetailPagePresented) {
Expand All @@ -129,6 +130,7 @@ struct ExpandableLectureCell: View {
lecture: lecture,
displayMode: .preview(shouldHideDismissButton: false)
)
.analyticsScreen(.lectureDetail(.init(lectureID: lecture.referenceId, referrer: viewModel.detailReferrer)))
}
}
}
Expand Down Expand Up @@ -173,7 +175,7 @@ extension ExpandableLectureCell {
var errorTitle: String = ""
var errorMessage: String = ""

private var searchState: SearchState {
var searchState: SearchState {
appState.search
}

Expand All @@ -185,11 +187,30 @@ extension ExpandableLectureCell {
get { appState.system.selectedTab }
set { services.globalUIService.setSelectedTab(newValue) }
}

var detailReferrer: LectureDetailParameter.Referrer {
switch searchState.displayMode {
case .search:
.search(query: searchState.searchText)
case .bookmark:
.bookmark
}
}

var lectureActionReferrer: LectureActionReferrer {
switch searchState.displayMode {
case .search:
return .search(query: searchState.searchText)
case .bookmark:
return .bookmark
}
}
}
}

extension ExpandableLectureCell.ViewModel {
func addLecture(_ lecture: Lecture) async {
FirebaseAnalyticsLogger().logEvent(.addToTimetable(.init(lectureID: lecture.referenceId, timetableID: appState.timetable.current?.id, referrer: lectureActionReferrer)))
do {
try await services.lectureService.addLecture(lecture: lecture)
} catch {
Expand Down Expand Up @@ -225,6 +246,7 @@ extension ExpandableLectureCell.ViewModel {
}

func addVacancyLecture(_ lecture: Lecture) async {
FirebaseAnalyticsLogger().logEvent(.addToVacancy(.init(lectureID: lecture.referenceId, referrer: lectureActionReferrer)))
do {
try await services.vacancyService.addLecture(lecture: lecture)
} catch {
Expand All @@ -241,6 +263,7 @@ extension ExpandableLectureCell.ViewModel {
}

func addBookmarkLecture(_ lecture: Lecture) async {
FirebaseAnalyticsLogger().logEvent(.addToBookmark(.init(lectureID: lecture.referenceId, referrer: lectureActionReferrer)))
isFirstBookmarkAlertPresented = appState.timetable.isFirstBookmark ?? false
do {
try await services.lectureService.bookmarkLecture(lecture: lecture)
Expand Down
1 change: 1 addition & 0 deletions SNUTT-2022/SNUTT/Views/Components/LectureList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ struct LectureList: View {
ForEach(lectures) { lecture in
NavigationLink {
LectureDetailScene(viewModel: .init(container: viewModel.container), lecture: lecture, displayMode: .normal)
.analyticsScreen(.lectureDetail(.init(lectureID: lecture.referenceId, referrer: .lectureList)))
} label: {
VStack(spacing: 0) {
Divider()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ struct MenuSheet: View {
}
}
}
.analyticsScreen(.timetableMenu, isVisible: isOpen)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,6 @@ struct MenuThemeSheet: View {
Spacer()
}
}
.analyticsScreen(.themePreview, isVisible: isOpen)
}
}
1 change: 1 addition & 0 deletions SNUTT-2022/SNUTT/Views/Components/NotificationList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ struct NotificationList: View {
if let lecture = routingInfo.lecture {
ZStack {
LectureDetailScene(viewModel: .init(container: viewModel.container), lecture: lecture, displayMode: .preview(shouldHideDismissButton: true))
.analyticsScreen(.lectureDetail(.init(lectureID: lecture.referenceId, referrer: .notification)))
if let timetableId = routingInfo.timetableId {
VStack {
Spacer()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ struct LectureBlocks: View {
visibilityOptions: config.visibilityOptions)
#else
if let container = container {
NavigationLink(destination: LectureDetailScene(viewModel: .init(container: container), lecture: lecture, displayMode: .normal)) {
NavigationLink(destination: LectureDetailScene(viewModel: .init(container: container), lecture: lecture, displayMode: .normal).analyticsScreen(.lectureDetail(.init(lectureID: lecture.referenceId, referrer: .timetable)))) {
TimetableBlock(lecture: lecture,
timePlace: timePlace,
theme: theme,
Expand Down
1 change: 1 addition & 0 deletions SNUTT-2022/SNUTT/Views/Components/UserSupportView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ struct UserSupportView: View {
}
}
}
.analyticsScreen(.settingsSupport)
.alert("개발자 괴롭히기", isPresented: $alertSendFeedback) {
Button("취소", role: .cancel, action: {})
Button("전송", role: .none, action: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ struct DeveloperInfoView: View {
var body: some View {
SingleWebView(url: WebViewType.developerInfo.url)
.navigationTitle("개발자 정보")
.analyticsScreen(.settingsDevelopers)
}
}

Expand Down
1 change: 1 addition & 0 deletions SNUTT-2022/SNUTT/Views/SNUTTView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ struct SNUTTView: View, Sendable {
}
TabScene(tabType: .review) {
ReviewScene(viewModel: .init(container: viewModel.container), isMainWebView: true)
.analyticsScreen(.reviewHome)
}
TabScene(tabType: .friends) {
FriendsScene(viewModel: .init(container: viewModel.container))
Expand Down
1 change: 1 addition & 0 deletions SNUTT-2022/SNUTT/Views/Scenes/BookmarkScene.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ struct BookmarkScene: View {
.animation(.customSpring, value: viewModel.selectedLecture?.id)
}
}
.analyticsScreen(.bookmark)
.navigationTitle("관심강좌")
.navigationBarTitleDisplayMode(.inline)
.animation(.customSpring, value: viewModel.bookmarkedLectures.count)
Expand Down
1 change: 1 addition & 0 deletions SNUTT-2022/SNUTT/Views/Scenes/FilterSheetScene.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ struct FilterSheetScene: View {
FilterSheetContent(viewModel: viewModel)
}
}
.analyticsScreen(.searchFilter, isVisible: viewModel.isFilterOpen)
.ignoresSafeArea(.keyboard)
}
}
Expand Down
1 change: 1 addition & 0 deletions SNUTT-2022/SNUTT/Views/Scenes/FriendsScene.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ struct FriendsScene: View {
.id(colorScheme)
.navigationBarHidden(true)
.background(STColor.systemBackground)
.analyticsScreen(.friends)
} else {
ProgressView()
}
Expand Down
2 changes: 2 additions & 0 deletions SNUTT-2022/SNUTT/Views/Scenes/LectureDetailScene.swift
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,7 @@ struct LectureDetailScene: View {
}
}.sheet(isPresented: $showSyllabusWebView) {
SyllabusWebView(lectureTitle: lecture.title, urlString: $syllabusURL)
.analyticsScreen(.lectureSyllabus(.init(lectureID: lecture.referenceId)))
.ignoresSafeArea(edges: .bottom)
.interactiveDismissDisabled()
}
Expand All @@ -521,6 +522,7 @@ struct LectureDetailScene: View {
}
.sheet(isPresented: $showReviewWebView) {
ReviewScene(viewModel: .init(container: viewModel.container), isMainWebView: false, detailId: lecture.evLecture?.evLectureId)
.analyticsScreen(.reviewDetail(.init(lectureID: lecture.referenceId, referrer: .lectureDetail)))
.id(colorScheme)
}
}
Expand Down
2 changes: 2 additions & 0 deletions SNUTT-2022/SNUTT/Views/Scenes/LectureListScene.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ struct LectureListScene: View {
lectures: viewModel.lectures)
}
}
.analyticsScreen(.lectureList)
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Expand All @@ -35,6 +36,7 @@ struct LectureListScene: View {
ZStack {
NavigationView {
LectureDetailScene(viewModel: .init(container: viewModel.container), lecture: viewModel.placeholderLecture, displayMode: .create)
.analyticsScreen(.lectureCreate)
}
// this view is duplicated on purpose (i.e. there are 2 instances of LectureTimeSheetScene)
LectureTimeSheetScene(viewModel: .init(container: viewModel.container))
Expand Down
1 change: 1 addition & 0 deletions SNUTT-2022/SNUTT/Views/Scenes/LoginScene.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ struct LoginScene: View {
.disabled(isButtonDisabled)
.animation(.customSpring, value: isButtonDisabled)
}
.analyticsScreen(.login)
.padding()
.navigationTitle(changeTitle ? "아이디 입력" : "로그인")
.navigationBarTitleDisplayMode(.inline)
Expand Down
1 change: 1 addition & 0 deletions SNUTT-2022/SNUTT/Views/Scenes/OnboardScene.swift
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ struct OnboardScene: View {
Spacer().frame(height: proxy.size.height * 0.05)
}
.transition(.scale(scale: 1))
.analyticsScreen(.onboard)
}
} else {
VStack {
Expand Down
1 change: 1 addition & 0 deletions SNUTT-2022/SNUTT/Views/Scenes/PopupScene.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ struct PopupScene: View {
PopupView(popup: currentPopup,
dismiss: viewModel.dismiss(popup:dontShowForWhile:))
.padding(.horizontal, reader.size.width * 0.1)
.analyticsScreen(.popup)
}
}
}
Expand Down
19 changes: 12 additions & 7 deletions SNUTT-2022/SNUTT/Views/Scenes/SearchLectureScene.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,17 +89,22 @@ struct SearchLectureScene: View {
.onTapGesture {
isSearchBarFocused = false
}
.analyticsScreen(.searchHome)
} else if viewModel.searchResult?.count == 0 {
EmptySearchResult()
.analyticsScreen(.searchEmpty)
} else if let searchResult = viewModel.searchResult {
ExpandableLectureList(
viewModel: .init(container: viewModel.container),
lectures: searchResult,
selectedLecture: $viewModel.selectedLecture,
fetchMoreLectures: viewModel.fetchMoreSearchResult
)
VStack(spacing: 0) {
ExpandableLectureList(
viewModel: .init(container: viewModel.container),
lectures: searchResult,
selectedLecture: $viewModel.selectedLecture,
fetchMoreLectures: viewModel.fetchMoreSearchResult
)
.id(reloadSearchList) // reload everything when any of the search conditions changes
}
.analyticsScreen(.searchList)
.animation(.customSpring, value: viewModel.selectedLecture?.id)
.id(reloadSearchList) // reload everything when any of the search conditions changes
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ struct AccountSettingScene: View {
}
}
}
.analyticsScreen(.settingsAccount)
.animation(.customSpring, value: viewModel.currentUser?.fbName)
.animation(.customSpring, value: viewModel.currentUser?.localId)
.listStyle(.insetGrouped)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ struct ColorSchemeSettingScene: View {
}
.listStyle(.insetGrouped)
.navigationTitle("화면 모드")
.analyticsScreen(.settingsColorScheme)
}
}
1 change: 1 addition & 0 deletions SNUTT-2022/SNUTT/Views/Scenes/Settings/SettingScene.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ struct SettingScene: View {
}
}
}
.analyticsScreen(.settingsHome)
.environment(\.defaultMinListHeaderHeight, 1)
.environment(\.hasNewBadgeClosure) { name in viewModel.hasNewBadge(settingName: name) }
.listStyle(.insetGrouped)
Expand Down
Loading

0 comments on commit d12f170

Please sign in to comment.