Pantrix UI

Olayları analitiğe bağlamak

Pantrix'in bileşenlerinin hangi olayları bildirdiği, bir olayın neyi taşıyıp neyi asla taşımadığı ve bir uygulamanın bu olayları kendi analitik ürününe (Firebase, Amplitude, PostHog…) nasıl bağladığı. Sorun Pantrix'e özgü değildir: analitiği olan her Compose Multiplatform uygulaması, arayüzün olaylarını ürüne giden olaylara çeviren bir sınıf yazar ve asıl kararlar o sınıftadır.

Bileşenler ve örnek hakkında söylenen her şey bu depoda koşan testlerde ya da cihazlarda görülmüştür. Ürünlerin çağrıları kendi belgelerinden okunmuştur ve burada çalıştırılmamıştır. Hangisinin nerede görüldüğü 7. bölümde yazılıdır.

1. Sorun

Bir bileşen kütüphanesi "şu düğmeye basıldı" der. Ürüne ne gideceği ise uygulamanın kararıdır:

Bu kararlar tek bir yerde verilmezse her ekran kendi olayını kendi adıyla gönderir, kişisel anahtarlar ürüne sızar ve bir ağ kesintisi raporlarda boşluk bırakır.

2. Pantrix'in olayları

Olay

Her bileşen kullanıcının yaptığını bir PantrixUiEvent olarak temanın analitiğine verir:

AlanNeÖrnek
componentBileşenin bildirildiği adButton, SegmentButton, Chart
actionNe olduclick, select, toggle, open
testTagBileşenin otomasyon etiketiCheckout.Button_pay
screenTestScope zinciri, yani ekranın adıCheckout
propsKapalı bir kümeden değerlervariant=Solid, segment=express
PantrixTheme(analytics = PantrixAnalytics { event -> /* bağlayıcıya ver */ }) {
    App()
}

Kimlik: etiket ve ekran

Olaya asla girmeyenler

Özelliklerin üç türü

TürAnahtarlarKişisel mi
Pantrix'in sözcükleri ve doğru/yanlış değerleri (20)action, checked, collapsed, copied, destructive, direction, duration, external, folded, format, part, reselected, revealed, selected, shown, state, to, tone, variant, viaHayır: değerleri kütüphanenin kendi sözcükleridir (Solid, back, true)
Sayılar (8)block, cell, count, index, level, rejected, rows, sizeHayır
Uygulamanın anahtarları (14)row, column, option, node, series, slice, stage, task, tile, destination, section, page, command, segmentOlabilir: uygulamanın bir şeye verdiği anahtardır

page iki türdendir. PantrixCarousel'de, PantrixPagination'da ve PantrixPageJump'ta bir sayıdır, PantrixBreadcrumb'ta ise uygulamanın sayfaya verdiği anahtardır. Örnek bu yüzden onu Pantrix'in değerlerine katmaz.

Uygulamanın anahtarlarını gönderen bileşenler:

AnahtarBileşenDeğeri
row, columnPantrixDataTableSatırın ve sütunun anahtarı
optionPantrixSelect, PantrixMultiSelectSeçeneğin anahtarı
nodePantrixTreeView, PantrixSankeyChartDüğümün anahtarı; Sankey'de bir akış kaynak>hedef
seriesEksenli grafikler, PantrixScatterChart, PantrixRadarChart, PantrixPolarChartSerinin anahtarı
slicePantrixPieChartDilimin anahtarı
stagePantrixFunnelChartAşamanın anahtarı
taskPantrixGanttChartGörevin anahtarı
tilePantrixTreemapKaronun anahtarı
destinationPantrixNavigationBar, PantrixNavigationRail, PantrixSidebarHedefin anahtarı
sectionPantrixAccordion, PantrixSidebarBölümün anahtarı
pagePantrixBreadcrumbSayfanın anahtarı
commandPantrixCommandPaletteKomutun anahtarı
segmentPantrixSegmentButtonSeçeneğin tagKey'i, yoksa sırası

Kütüphane bu anahtarları temanın analitiğine her zaman verir; ürüne gidip gitmeyecekleri bağlayıcının kararıdır. Bileşenlerin testlerinde row'un değerleri kişi adlarıydı (ada, grace): kullanıcılarını adıyla anahtarlayan bir tablonun her olayı o adı taşır.

Kullanıcı bir şey yapmadan gelen olaylar

BileşenOlayNe zaman
PantrixCarouselchange, via=autoKendi kendine döndüğünde
PantrixSnackbarHostdismiss, via=timeoutSüresi dolduğunda
PantrixElasticDatePickerautoRefreshKendiliğinden yenilediğinde
PantrixDialog, PantrixSheet, PantrixMenu, PantrixPopover, PantrixCommandPaletteopenProgramla açıldığında da
PantrixPageScaffold, PantrixLazyPageScaffoldshowtagKey'i olan bir sayfa her kompozisyona girdiğinde: bir ekranın görüntülenmesi

Bunları kullanıcının etkileşimi saymak istemeyen bir bağlayıcı via'ya bakar ya da onlara planında ayrı bir ad verir.

Bileşenlerin olayları

Tablo, bileşenlerin testlerinde görülen olaylardan ve kaynaklarından yazıldı. "Ad" sütunu olayın component'idir. Tabloda olmayan bileşenler kendileri olay bildirmez, içlerindeki bileşenler kendi olaylarını bildirir: PantrixTopBar'ın geri düğmesi (PantrixBackButton) bir PantrixIconButton'dır, onun olayını bildirir.

BileşenAdactionprops
PantrixAccordionAccordionexpand, collapsesection
PantrixAlertAlertdismisstone, variant
PantrixBreadcrumbBreadcrumbselectpage (anahtar), folded
PantrixButtonButtonclickvariant
PantrixCardCardclickvariant
PantrixCarouselCarouselchange, pause, playpage (sayı), via
PantrixChart, PantrixLineChart, PantrixBarChart, PantrixAreaChart, PantrixRangeChart, PantrixWaterfallChart, PantrixCandlestickChartChartselect, toggle, zoom, exportseries, shown, to, format
PantrixCheckbox, PantrixTriStateCheckboxCheckboxtogglestate
PantrixChipChipclick, toggle, removeselected
PantrixCodeBlockCodeBlockcopycopied
PantrixCommandPaletteCommandPaletteopen, run, dismisscommand, via
PantrixDataTableDataTableselect, selectAll, sort, expand, collapse, openrow, column, selected, rows, direction
PantrixDatePickerDatePickerselect, yearspart
PantrixDateTextField, PantrixDateFilledTextField, PantrixTimeTextField, PantrixTimeFilledTextFieldBileşenin adı (DateTextField…)focus, open, select—
PantrixDialogDialogopen, dismissvia
PantrixElasticDatePickerElasticDatePickeropen, select, refresh, autoRefresh—
PantrixFileDropFileDropbrowse, drop, filescount, rejected, via
PantrixFunnelChartFunnelselect, exportstage, format
PantrixGanttChartGanttselect, zoom, exporttask, to, format
PantrixGauge, PantrixMeterGroup, PantrixProgressCircle, PantrixSparklineBileşenin adı (Gauge…)exportformat
PantrixHeatmapHeatmapselect, exportcell, format
PantrixIconButtonIconButtonclickvariant
PantrixJsonViewJsonViewexpand, collapse, copylevel, copied
PantrixLinkLinkclickexternal
PantrixMenuMenu; öğesi MenuItemopen, dismiss; öğe: clicköğe: destructive
PantrixMultiSelectMultiSelect; arama alanı MultiSelectSearchopen, toggle; arama: focus, clearoption, selected
PantrixNavigationBar, PantrixNavigationRailBileşenin adıselectdestination, reselected
PantrixPageJumpPageJumpfocus, selectpage (sayı)
PantrixPageScaffold, PantrixLazyPageScaffoldPageScaffoldshow—
PantrixPageSizePageSizeopen, selectsize
PantrixPaginationPaginationselectpage (sayı), via
PantrixPieChartPieChartselect, toggle, exportslice, shown, format
PantrixPolarChart, PantrixRadarChartBileşenin adıselect, toggle, exportseries, shown, format
PantrixPopoverPopoveropen, dismiss—
PantrixRadioButtonRadioButtonselect—
PantrixRadioGroupRadioGroupselectindex
PantrixSankeyChartSankeyselect, exportnode, format
PantrixScatterChartScatterChartselect, toggle, zoom, exportseries, shown, to, format
PantrixSecureTextField, PantrixFilledSecureTextFieldBileşenin adıfocus, clear, togglerevealed
PantrixSegmentButtonSegmentButtonselectsegment
PantrixSelectSelect; arama alanı SelectSearchopen, select; arama: focus, clearoption
PantrixSheetSheetopen, dismissvia
PantrixSidebarSidebarselect, expand, collapsedestination, section, collapsed
PantrixSnackbarHostSnackbaropen, action, dismisstone, duration, action, via
PantrixStatusTrackerStatusTrackerselect, exportblock, format
PantrixSwitchButtonSwitchButtontogglechecked
PantrixTabsTabsselectindex, via
PantrixTextField, PantrixFilledTextField, PantrixAutoResizeTextField, PantrixFilledAutoResizeTextFieldBileşenin adıfocus, clear—
PantrixTimePickerTimePickerselectpart
PantrixTreemapTreemapselect, exporttile, format
PantrixTreeViewTreeViewselect, expand, collapse, check, unchecknode

3. Bağlayıcı

Bağlayıcı, temaya verilen PantrixAnalytics'tir: Pantrix'in olaylarını alır ve ürüne giden olayları kendisi kurar. Örneğin bağlayıcısı ProductAnalytics'tir ve bütün kararlar onun kurucusunda toplanır:

@Composable
fun App() {
    val scope = rememberCoroutineScope()
    val analytics = remember(scope) {
        ProductAnalytics(
            plan = CHECKOUT_PLAN,            // hangi olay hangi adla, hangi değerlerle
            transport = productTransport,    // ürüne veren tek çağrı (4. bölüm)
            clock = Clock.System,            // olayın olduğu an
            scope = scope,                   // zamanlayıcı ve gönderim ekranla birlikte durur
            policy = SendPolicy()            // 20'lik paketler, 30 saniye, 500 olaylık kuyruk
        )
    }
    // Arka plana geçerken bekleyenler gider: başka bir fırsat olmayabilir.
    LifecycleEventEffect(Lifecycle.Event.ON_STOP) { scope.launch { analytics.flush() } }
    PantrixTheme(analytics = analytics, testTagPolicy = TestTagPolicy.Off) {
        CheckoutScreen()
    }
}

İzleme planı

val CHECKOUT_PLAN = TrackingPlan(
    listOf(
        PlannedEvent(pantrixTestTagOf("IconButton", "more", "Checkout"), "click", "quantity_increased"),
        PlannedEvent(
            tag = pantrixTestTagOf("SegmentButton", "shipping", "Checkout"),
            action = "select",
            name = "shipping_chosen",
            notPersonal = setOf("segment")
        ),
        PlannedEvent(
            tag = pantrixTestTagOf("Button", "pay", "Checkout"),
            action = "click",
            name = "checkout_pay_tapped",
            keep = setOf("variant")
        )
    )
)

Genel olay

Planın adlandırmadığı her olay tek bir ui_interaction olarak gider ve şunları taşır: ui_component, ui_action, ui_screen, ui_tag (yalnızca anahtardan kurulmuşsa) ve Pantrix'in sözcükleri ve sayıları. Uygulamanın anahtarları ve çağrı yerinden kurulan etiketler girmez.

Tek bir genel olayın iki nedeni var. Ürünler ayrı olay adlarını sınırlar (Firebase'de 500), bileşen başına bir ad bu sınırı planın adlarıyla paylaşır. Bir de ürünün raporlarında yalnızca planın adları ürünün diliyle görünür, geri kalanı tek bir yerde süzülür.

İzin

Consent üç değerlidir: Unknown, Granted, Denied. Granted olana kadar hiçbir olay kuyruğa girmez ve günlükte "toplanmadı" diye geçer. İzin geri alınınca bekleyenler atılır ve zamanlayıcılar durur. O anda yolda olan bir paket başaramazsa yeniden denenmez, atılır. Ürünün kendi SDK'sının da izni vardır ve ikisi birlikte değişmelidir (4. bölüm).

Gönderim ve zaman

Ağ yokken

4. Ürüne bağlamak

Bağlayıcının ürünle tek temas noktası Transport'tur:

fun interface Transport {
    /** [batch]'i ürüne verir: vardıysa true. */
    suspend fun send(batch: List<ProductEvent>): Boolean
}

Bir ProductEvent'in adı (name), özellikleri (properties, hepsi String) ve zamanı (at) vardır. Gönderici false dönerse ya da bir hata fırlatırsa paket bekler ve yeniden denenir.

Kendi kuyruğu olan sdk'lar

Aşağıdaki üç SDK da olayları kendisi biriktirir ve paket paket gönderir. Bağlayıcının kuyruğu o zaman ikinci bir kuyruktur. Önerilen kurulum: planı ve izni bağlayıcıda tutun, her olayı SDK'ya hemen verin (SendPolicy(batch = 1)), biriktirmeyi, yeniden denemeyi ve arka planda göndermeyi SDK'ya bırakın. Gönderici, SDK olayı aldığında true döner.

Firebase (Android)

val transport = Transport { batch ->
    batch.forEach { event ->
        Firebase.analytics.logEvent(event.name) {
            event.properties.forEach { (key, value) -> param(key, value) }
        }
    }
    true
}

Amplitude (Android, Kotlin SDK)

val amplitude = Amplitude(AMPLITUDE_API_KEY, applicationContext) {
    flushQueueSize = 20          // varsayılanı 30
    flushIntervalMillis = 30000  // varsayılanı 30000
}
val transport = Transport { batch ->
    batch.forEach { event ->
        amplitude.track(event.name, mutableMapOf<String, Any?>().apply { putAll(event.properties) })
    }
    true
}

PostHog (Android)

PostHogAndroid.setup(context, PostHogAndroidConfig(apiKey = POSTHOG_API_KEY, host = POSTHOG_HOST))
val transport = Transport { batch ->
    batch.forEach { event -> PostHog.capture(event = event.name, properties = event.properties) }
    true
}

Öteki platformlar

Ürünlerin iOS ve web SDK'ları Swift'te ve JavaScript'te yazılıdır. Ortak kod onları iki yoldan çağırır:

5. Test etmek

6. Kütüphanesiz

Bağlayıcının Pantrix'e bağlı tek parçası, olayı alan track(event: PantrixUiEvent) ve planın o olaydan okuduğu dört alandır (component, action, testTag, screen) ile props. Başka bir kaynaktan olay alan bir uygulama productEventOf'u kendi olay türüyle yazar. Kuyruk, izin, gönderim ve Transport aynen kalır: örneğin ProductAnalytics.kt, SendPolicy.kt, Transport.kt ve Consent.kt dosyaları Compose'a da bağlı değildir.

7. Doğrulananlar ve doğrulanmayanlar

Doğrulananlar

Okunan, çalıştırılmayan