Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS-8282 analytics parameters update #4135

Open
wants to merge 10 commits into
base: releases/5.18
Choose a base branch
from
9 changes: 3 additions & 6 deletions Tangem/App/Services/Analytics/Analytics+Event.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ extension Analytics {
enum Event: String {
case signedIn = "[Basic] Signed in"
case toppedUp = "[Basic] Topped up"
case walletOpened = "[Basic] Wallet Opened"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А все эти удаленные ивенты чем-то будут заменены?
Просто странно что сами то действия остались (рефреш, перелистывание и т.д.), удалена только их аналитика

case balanceLoaded = "[Basic] Balance Loaded"
case tokenBalanceLoaded = "[Basic] Token Balance"
case cardWasScanned = "[Basic] Card Was Scanned"
Expand Down Expand Up @@ -54,12 +53,9 @@ extension Analytics {
case twinSetupFinished = "[Onboarding / Twins] Twin Setup Finished"
case onboardingButtonChat = "[Onboarding] Button - Chat"
case mainScreenOpened = "[Main Screen] Screen opened"
case mainScreenWalletChangedBySwipe = "[Main Screen] Wallet Swipe"
case noticeRateTheAppButtonTapped = "[Main Screen] Notice - Rate The App Button Tapped"
case buttonManageTokens = "[Portfolio] Button - Manage Tokens"
case tokenIsTapped = "[Portfolio] Token is Tapped"
case mainRefreshed = "[Portfolio] Refreshed"
case buttonOrganizeTokens = "[Portfolio] Button - Organize Tokens"

case organizeTokensScreenOpened = "[Portfolio / Organize Tokens] Organize Tokens Screen Opened"
case organizeTokensButtonSortByBalance = "[Portfolio / Organize Tokens] Button - By Balance"
case organizeTokensButtonGroup = "[Portfolio / Organize Tokens] Button - Group"
Expand All @@ -69,7 +65,6 @@ extension Analytics {
case buttonRemoveToken = "[Token] Button - Remove Token"
case buttonExplore = "[Token] Button - Explore"
case buttonReload = "[Token] Button - Reload"
case refreshed = "[Token] Refreshed"
case buttonBuy = "[Token] Button - Buy"
case buttonSell = "[Token] Button - Sell"
case buttonExchange = "[Token] Button - Exchange"
Expand Down Expand Up @@ -288,6 +283,7 @@ extension Analytics {
case stakingConfirmationScreenOpened = "[Staking] Confirmation Screen Opened"
case stakingErrors = "[Staking] Errors"
case stakingErrorTransactionRejected = "[Staking] Error - Transaction Rejected"
case stakingAppErrors = "[Staking] App Errors"
case stakingSelectedCurrency = "[Staking] Selected Currency"
case stakingButtonShare = "[Staking] Button - Share"
case stakingButtonExplore = "[Staking] Button - Explore"
Expand All @@ -311,6 +307,7 @@ extension Analytics {
case marketsChartButtonReceive = "[Markets / Chart] Button - Receive"
case marketsChartButtonSwap = "[Markets / Chart] Button - Swap"
case marketsChartDataError = "[Markets / Chart] Data Error"
case marketsChartExchangesScreenOpened = "[Markets / Chart] Exchanges Screen Opened"

// MARK: - Manage Tokens

Expand Down
2 changes: 2 additions & 0 deletions Tangem/App/Services/Analytics/Analytics+ParameterKey.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ extension Analytics {
case action = "Action"
case errorDescription = "Error Description"
case errorCode = "Error Code"
case errorMessage = "Error Message"
case newSecOption = "new_security_option"
case errorKey = "Tangem SDK error key"
case walletConnectAction = "wallet_connect_action"
Expand All @@ -26,6 +27,7 @@ extension Analytics {
case currency = "Currency Type" // fiat
case success
case token = "Token"
case tokens = "Tokens"
case derivationPath = "Derivation Path"
case derivation = "Derivation"
case network = "Network"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,29 @@ import Foundation
import TangemStaking

struct CommonStakingAnalyticsLogger: StakingAnalyticsLogger {
func logAPIError(errorDescription: String, currencySymbol: String?) {
var params: [Analytics.ParameterKey: String] = [.errorDescription: errorDescription]
if let currencySymbol {
params[.token] = currencySymbol
func logError(_ error: any Error, currencySymbol: String) {
let event: Analytics.Event
var parameters: [Analytics.ParameterKey: String] = [.token: currencySymbol]
switch error {
case let apiError as StakeKitAPIError:
if let code = apiError.code {
parameters[.errorCode] = code
}
if let message = apiError.message {
parameters[.errorMessage] = message
}
Comment on lines +18 to +23
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: if let не обязателен, можно просто parameters[.errorCode] = apiError.code и т.д.

event = .stakingErrors
case let httpError as StakeKitHTTPError:
parameters[.errorDescription] = httpError.errorDescription
event = .stakingErrors
case let error as LocalizedError where error is StakingManagerError || error is StakeKitMapperError:
parameters[.errorDescription] = error.errorDescription
event = .stakingAppErrors
default: return
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Все другие ошибки (например системные или любые добавленные в будущем) будут втихую игнорироваться

Прошлая реализация работала по другому

}
Analytics.log(event: .stakingErrors, params: params)
Analytics.log(
event: event,
params: parameters
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import SwiftUI

enum TokenNotificationEvent: Hashable {
case networkUnreachable(currencySymbol: String)
case someNetworksUnreachable
case someNetworksUnreachable(networks: [WalletModel])
Copy link
Contributor

@m3g0byt3 m3g0byt3 Nov 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Что-то c большой вероятность где-то утечет, если напрямую в енам класть WalletModel
Это тяжелая модель с кучей подписок и логики внутри, реф тип

Например TokenNotificationEvent.someNetworksUnreachable может бесконечно долго лежать как value в currentSubject, не давая этим wallet model умереть

Мне кажется тут лучше держать айдишники, а не сами walletmodel

case rentFee(rentMessage: String)
case noAccount(message: String)
case existentialDepositWarning(message: String)
Expand Down Expand Up @@ -255,8 +255,9 @@ extension TokenNotificationEvent {
return [.token: currencySymbol]
case .notEnoughFeeForTransaction(let configuration):
return [.token: configuration.eventConfiguration.feeAmountTypeCurrencySymbol]
case .someNetworksUnreachable,
.rentFee,
case .someNetworksUnreachable(let networks):
return [.tokens: networks.map(\.tokenItem.currencySymbol).joined(separator: ", ")]
case .rentFee,
.noAccount,
.existentialDepositWarning,
.bnbBeaconChainRetirement,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,13 @@ final class MultiWalletNotificationManager {
}
}
.sink { [weak self] walletModels in
guard walletModels.contains(where: { $0.state.isBlockchainUnreachable }) else {
let unreachableNetworks = walletModels.filter { $0.state.isBlockchainUnreachable }
guard !unreachableNetworks.isEmpty else {
self?.removeSomeNetworksUnreachable()
return
}

self?.setupSomeNetworksUnreachable()
self?.setupSomeNetworksUnreachable(unreachableNetworks)
}
}

Expand All @@ -49,14 +50,16 @@ final class MultiWalletNotificationManager {
guard let event = $0.settings.event as? TokenNotificationEvent else {
return false
}

return event == .someNetworksUnreachable
switch event {
case .someNetworksUnreachable: return true
default: return false
}
}
}

private func setupSomeNetworksUnreachable() {
private func setupSomeNetworksUnreachable(_ unreachableNetworks: [WalletModel]) {
let factory = NotificationsFactory()
notificationInputsSubject.send([factory.buildNotificationInput(for: TokenNotificationEvent.someNetworksUnreachable)])
notificationInputsSubject.send([factory.buildNotificationInput(for: TokenNotificationEvent.someNetworksUnreachable(networks: unreachableNetworks))])
}
}

Expand Down
2 changes: 0 additions & 2 deletions Tangem/Modules/Main/MainCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,6 @@ extension MainCoordinator: MultiWalletMainContentRoutable {
func openTokenDetails(for model: WalletModel, userWalletModel: UserWalletModel) {
mainBottomSheetUIManager.hide()

Analytics.log(.tokenIsTapped)

let dismissAction: Action<Void> = { [weak self] _ in
self?.tokenDetailsCoordinator = nil
}
Expand Down
5 changes: 0 additions & 5 deletions Tangem/Modules/Main/MainViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,6 @@ final class MainViewModel: ObservableObject {
}

func onPullToRefresh(completionHandler: @escaping RefreshCompletionHandler) {
Analytics.log(.mainRefreshed)

isHorizontalScrollDisabled = true
let completion = { [weak self] in
self?.isHorizontalScrollDisabled = false
Expand Down Expand Up @@ -186,8 +184,6 @@ final class MainViewModel: ObservableObject {
func onPageChange(dueTo reason: CardsInfoPageChangeReason) {
guard reason == .byGesture else { return }

Analytics.log(.mainScreenWalletChangedBySwipe)

if !AppSettings.shared.userDidSwipeWalletsOnMainScreen {
AppSettings.shared.userDidSwipeWalletsOnMainScreen = true
}
Expand Down Expand Up @@ -346,7 +342,6 @@ final class MainViewModel: ObservableObject {
guard let userWalletId = viewModel.pages[safe: newIndex]?.id else {
return
}
Analytics.log(.walletOpened)
viewModel.userWalletRepository.setSelectedUserWalletId(
userWalletId,
reason: .userSelected
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ final class MultiWalletMainContentViewModel: ObservableObject {
}

func onOpenOrganizeTokensButtonTap() {
Analytics.log(.buttonOrganizeTokens)
openOrganizeTokens()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ class MarketsTokenDetailsViewModel: MarketsBaseViewModel {
return
}

Analytics.log(event: .marketsChartExchangesScreenOpened, params: [.token: tokenInfo.symbol.uppercased()])

coordinator?.openExchangesList(tokenId: tokenInfo.id, numberOfExchangesListedOn: numberOfExchangesListedOn, presentationStyle: presentationStyle)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,9 @@ private extension StakingTransactionDispatcher {
do {
try await pendingHashesSender.sendHash(hash)
} catch {
Analytics.log(
event: .stakingErrors,
params: [
.token: walletModel.tokenItem.currencySymbol,
.errorDescription: error.localizedDescription,
]
CommonStakingAnalyticsLogger().logError(
error,
currencySymbol: walletModel.tokenItem.currencySymbol
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,6 @@ class SingleTokenBaseViewModel: NotificationTapDelegate {
return
}

Analytics.log(.refreshed)

if let id = walletModel.tokenItem.currencyId, miniChartsProvider.items.isEmpty {
miniChartsProvider.fetch(for: [id], with: miniChartPriceIntervalType)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,10 @@ final class StakingDetailsViewModel: ObservableObject {
let balances = stakingManager.state.balances.flatMap { String($0.count) } ?? String(0)
Analytics.log(
event: .stakingInfoScreenOpened,
params: [.validatorsCount: balances]
params: [
.validatorsCount: balances,
.token: walletModel.tokenItem.currencySymbol,
]
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class ReceiveBottomSheetViewModel: ObservableObject, Identifiable {
}

func onViewAppear() {
Analytics.log(.receiveScreenOpened)
Analytics.log(event: .receiveScreenOpened, params: [.token: tokenItem.currencySymbol])
}

func headerForAddress(with info: ReceiveAddressInfo) -> String {
Expand Down
12 changes: 11 additions & 1 deletion TangemStaking/Services/StakeKitMapper/StakeKitMapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -369,8 +369,18 @@ struct StakeKitMapper {
}
}

enum StakeKitMapperError: Error {
public enum StakeKitMapperError: Error {
case notImplement
case noData(String)
case tronTransactionMappingFailed
}

extension StakeKitMapperError: LocalizedError {
public var errorDescription: String? {
switch self {
case .notImplement: "Not implemented"
case .noData(let string): string
case .tronTransactionMappingFailed: "TronTransactionMappingFailed"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@

import Foundation

enum StakeKitDTO {
// MARK: - Common
public struct StakeKitAPIError: Decodable, LocalizedError {
public let code: String?
public let message: String?
let level: String?

struct APIError: Decodable, LocalizedError {
let message: String?
let level: String?
public var errorDescription: String? { message }
}

var errorDescription: String? { message }
}
enum StakeKitDTO {
// MARK: - Common

struct Token: Codable {
let network: String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,20 +109,20 @@ private extension StakeKitStakingAPIService {

func tryMapError(target: StakeKitTarget, response: Moya.Response) -> Error? {
do {
let error = try JSONDecoder().decode(StakeKitDTO.APIError.self, from: response.data)
let error = try JSONDecoder().decode(StakeKitAPIError.self, from: response.data)
return error
} catch {
return nil
}
}
}

private enum StakeKitHTTPError: Error {
public enum StakeKitHTTPError: Error {
case badStatusCode(response: String?, code: Int)
}

extension StakeKitHTTPError: LocalizedError {
var errorDescription: String? {
public var errorDescription: String? {
switch self {
case .badStatusCode(let response, let code): response ?? "HTTP error \(code)"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
import Foundation

public protocol StakingAnalyticsLogger {
func logAPIError(errorDescription: String, currencySymbol: String?)
func logError(_ error: any Error, currencySymbol: String)
}
Loading
Loading