Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 3 additions & 4 deletions Data/Project.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@ let project = Project.makeFramework(
.NetworkService,
.SPM.Supabase,
.SPM.GoogleSignIn,
.SPM.AppAuth,
// .SPM.FirebaseAnalytics,
// .SPM.FirebaseCrashlytics,
.SPM.FirebaseAnalytics,
.SPM.FirebaseCrashlytics,
],
hasTests: true,
settings: .settings(
base: SettingsDictionary()
// .otherLinkerFlags(["-all_load", "-ObjC"]),
.otherLinkerFlags(["-all_load -Objc"]),
)
)
170 changes: 85 additions & 85 deletions Data/Sources/Analytics/FirebaseAnalyticsManager.swift
Original file line number Diff line number Diff line change
@@ -1,85 +1,85 @@
//import Foundation
//import FirebaseAnalytics
//import Domain
//import LogMacro
//
///// FirebaseAnalytics를 사용한 Analytics Repository 구현체
//public class FirebaseAnalyticsRepository: AnalyticsRepositoryProtocol, @unchecked Sendable {
//
// public init() {
// #logDebug("🔥 [Analytics] ===== FIREBASE ANALYTICS REPOSITORY INITIALIZED =====")
// #logDebug("🔥 [Analytics] Sending app_analytics_initialized event...")
//
// Analytics.logEvent("app_analytics_initialized", parameters: [
// "timestamp": Date().timeIntervalSince1970,
// "version": "1.0"
// ])
// }
//
// public func sendEvent(_ event: AnalyticsEvent) async {
// switch event {
// case .auth(let eventType, let data):
// await sendAuthEvent(eventType, data)
// case .deeplink(let data):
// await sendDeeplinkEvent(data)
// case .travel(let eventType, let data):
// await sendTravelEvent(eventType, data)
// case .expense(let eventType, let data):
// await sendExpenseEvent(eventType, data)
// }
// }
//
// // MARK: - Private Event Handlers
//
// private func sendAuthEvent(_ eventType: AuthEventType, _ data: AuthEventData) async {
// var params: [String: Any] = ["social_type": data.socialType]
// if let isFirst = data.isFirst {
// params["is_first"] = isFirst
// }
//
// #logDebug("🔥 [Analytics] Parameters: \(params)")
// Analytics.logEvent(eventType.rawValue, parameters: params)
// }
//
// private func sendDeeplinkEvent(_ data: DeeplinkEventData) async {
// let parameters: [String: Any] = [
// "deeplink": data.deeplink,
// "deeplink_type": data.type
// ]
//
// #logDebug("🔥 [Analytics] Parameters: \(parameters)")
// Analytics.logEvent("deeplink_open", parameters: parameters)
// #logDebug("🔥 [Analytics] ✅ deeplink_open event sent to Firebase")
// }
//
// private func sendTravelEvent(_ eventType: TravelEventType, _ data: TravelEventData) async {
// var params: [String: Any] = ["travel_id": data.travelId]
//
// // Optional fields based on event type
// if let userId = data.userId { params["user_id"] = userId }
// if let memberId = data.memberId { params["member_id"] = memberId }
// if let role = data.role { params["role"] = role }
// if let newOwnerId = data.newOwnerId { params["new_owner_id"] = newOwnerId }
//
// #logDebug("🔥 [Analytics] Parameters: \(params)")
// Analytics.logEvent(eventType.rawValue, parameters: params)
// }
//
// private func sendExpenseEvent(_ eventType: ExpenseEventType, _ data: ExpenseEventData) async {
// var params: [String: Any] = ["travel_id": data.travelId]
//
// // Add optional fields
// if let expenseId = data.expenseId { params["expense_id"] = expenseId }
// if let amount = data.amount { params["amount"] = amount }
// if let currency = data.currency { params["currency"] = currency }
// if let category = data.category { params["category"] = category }
// if let payerId = data.payerId { params["payer_id"] = payerId }
// if let source = data.source { params["source"] = source }
// if let tab = data.tab { params["tab"] = tab }
// if let expenseDate = data.expenseDate { params["expense_date"] = expenseDate }
// if let errorCode = data.errorCode { params["error_code"] = errorCode }
//
// #logDebug("🔥 [Analytics] Parameters: \(params)")
// Analytics.logEvent(eventType.rawValue, parameters: params)
// }
//}
import Foundation
import FirebaseAnalytics
import Domain
import LogMacro

/// FirebaseAnalytics를 사용한 Analytics Repository 구현체
public class FirebaseAnalyticsRepository: AnalyticsRepositoryProtocol, @unchecked Sendable {

public init() {
#logDebug("🔥 [Analytics] ===== FIREBASE ANALYTICS REPOSITORY INITIALIZED =====")
#logDebug("🔥 [Analytics] Sending app_analytics_initialized event...")

Analytics.logEvent("app_analytics_initialized", parameters: [
"timestamp": Date().timeIntervalSince1970,
"version": "1.0"
])
}

public func sendEvent(_ event: AnalyticsEvent) async {
switch event {
case .auth(let eventType, let data):
await sendAuthEvent(eventType, data)
case .deeplink(let data):
await sendDeeplinkEvent(data)
case .travel(let eventType, let data):
await sendTravelEvent(eventType, data)
case .expense(let eventType, let data):
await sendExpenseEvent(eventType, data)
}
}

// MARK: - Private Event Handlers

private func sendAuthEvent(_ eventType: AuthEventType, _ data: AuthEventData) async {
var params: [String: Any] = ["social_type": data.socialType]
if let isFirst = data.isFirst {
params["is_first"] = isFirst
}

#logDebug("🔥 [Analytics] Parameters: \(params)")
Analytics.logEvent(eventType.rawValue, parameters: params)
}

private func sendDeeplinkEvent(_ data: DeeplinkEventData) async {
let parameters: [String: Any] = [
"deeplink": data.deeplink,
"deeplink_type": data.type
]

#logDebug("🔥 [Analytics] Parameters: \(parameters)")
Analytics.logEvent("deeplink_open", parameters: parameters)
#logDebug("🔥 [Analytics] ✅ deeplink_open event sent to Firebase")
}

private func sendTravelEvent(_ eventType: TravelEventType, _ data: TravelEventData) async {
var params: [String: Any] = ["travel_id": data.travelId]

// Optional fields based on event type
if let userId = data.userId { params["user_id"] = userId }
if let memberId = data.memberId { params["member_id"] = memberId }
if let role = data.role { params["role"] = role }
if let newOwnerId = data.newOwnerId { params["new_owner_id"] = newOwnerId }

#logDebug("🔥 [Analytics] Parameters: \(params)")
Analytics.logEvent(eventType.rawValue, parameters: params)
}

private func sendExpenseEvent(_ eventType: ExpenseEventType, _ data: ExpenseEventData) async {
var params: [String: Any] = ["travel_id": data.travelId]

// Add optional fields
if let expenseId = data.expenseId { params["expense_id"] = expenseId }
if let amount = data.amount { params["amount"] = amount }
if let currency = data.currency { params["currency"] = currency }
if let category = data.category { params["category"] = category }
if let payerId = data.payerId { params["payer_id"] = payerId }
if let source = data.source { params["source"] = source }
if let tab = data.tab { params["tab"] = tab }
if let expenseDate = data.expenseDate { params["expense_date"] = expenseDate }
if let errorCode = data.errorCode { params["error_code"] = errorCode }

#logDebug("🔥 [Analytics] Parameters: \(params)")
Analytics.logEvent(eventType.rawValue, parameters: params)
}
}
7 changes: 5 additions & 2 deletions Data/Sources/DataSource/Remote/AuthRemoteDataSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,16 @@ public protocol AuthRemoteDataSourceProtocol: Sendable {
public struct AuthRemoteDataSource: AuthRemoteDataSourceProtocol {
private let authProvider: MoyaProvider<AuthAPITarget>
private let oauthProvider: MoyaProvider<OAuthAPITarget>
private let noAuthProvider: MoyaProvider<AuthAPITarget>

public init(
authProvider: MoyaProvider<AuthAPITarget> = .authorized,
oauthProvider: MoyaProvider<OAuthAPITarget> = .default
oauthProvider: MoyaProvider<OAuthAPITarget> = .default,
noAuthProvider: MoyaProvider<AuthAPITarget> = .default
) {
self.authProvider = authProvider
self.oauthProvider = oauthProvider
self.noAuthProvider = noAuthProvider
}

public func refresh(token: String) async throws -> TokenResult {
Expand All @@ -56,7 +59,7 @@ public struct AuthRemoteDataSource: AuthRemoteDataSourceProtocol {
public func registerDeviceToken(token: String) async throws -> DeviceToken {
let pendingKey = getOrCreatePendingKey()
let body = DeviceTokenRequestDTO(deviceToken: token, pendingKey: pendingKey)
let response: BaseResponse<DeviceTokenResponseDTO> = try await authProvider.request(.registerDeviceToken(body: body))
let response: BaseResponse<DeviceTokenResponseDTO> = try await noAuthProvider.request(.registerDeviceToken(body: body))
guard let data = response.data else { throw NetworkError.noData }
if let returnedKey = data.pendingKey { persistPendingKey(returnedKey) }
return data.toDomain()
Expand Down
3 changes: 2 additions & 1 deletion Data/Sources/Repository/Auth/AuthRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ final public class AuthRepository: AuthRepositoryProtocol {
public init(
remote: any AuthRemoteDataSourceProtocol = AuthRemoteDataSource(
authProvider: MoyaProvider<AuthAPITarget>.authorized,
oauthProvider: MoyaProvider<OAuthAPITarget>.default
oauthProvider: MoyaProvider<OAuthAPITarget>.default,
noAuthProvider: MoyaProvider<AuthAPITarget>.default
)
) {
self.remote = remote
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//import Foundation
//
///// Analytics 이벤트 전송을 위한 Repository 프로토콜
//public protocol AnalyticsRepositoryProtocol: Sendable {
// func sendEvent(_ event: AnalyticsEvent) async
//}
import Foundation

/// Analytics 이벤트 전송을 위한 Repository 프로토콜
public protocol AnalyticsRepositoryProtocol: Sendable {
func sendEvent(_ event: AnalyticsEvent) async
}
Loading