Praćenje događaja na strani klijenta općenito se dijeli u tri kategorije:

  • Praćenje pomoću koda
  • Vizualno praćenje
  • Automatsko praćenje

Ovaj članak ponajprije predstavlja zamisli i postupak implementacije automatskog praćenja.

1. Praćenje pomoću koda

Praćenje pomoću koda znači pozivanje sučelja na svakoj točki koju želite pratiti i izravno prenošenje podataka o događaju. Većina analitičkih usluga trećih strana pruža api za praćenje pomoću koda, što je praktično.

No to stvara problem: kôd za praćenje raspršen je po cijeloj poslovnoj logici i čvrsto povezan s njom. Kada se zasloni ili poslovni tokovi promijene, nije jasno što učiniti sa starim događajima ni jesu li potrebni novi. Kako broj događaja raste, održavanje raspršenog koda za praćenje postaje prava noćna mora. Makronaredbe i tvorničke klase mogu pojednostavniti kôd, ali time se problem iz temelja ne mijenja.

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    // 埋点
    APE(kEvent4001);
}

2. Vizualno praćenje

Vizualno praćenje postavlja točke prikupljanja pomoću vizualnog alata. Klijent automatski raščlanjuje konfiguraciju i prijavljuje događaje, čime se postiže takozvano „praćenje bez tragova”. Reprezentativno rješenje otvorenog koda jest Mixpanel.

3. Automatsko praćenje

Automatsko praćenje, koje se naziva i praćenjem svih događaja, zapravo ne znači da instrumentiranja nema. Ono prikuplja i prijavljuje sve događaje, a poslužitelju prepušta filtriranje korisnih podataka.

Kao daljnja optimizacija, poslužitelj može poslati konfiguracijsku datoteku kako bi klijent sam filtrirao događaje.

Zbog KPI-jeva ponovno sam izumio kotač na temelju te zamisli i izradio WKTrackingData.

Ovdje bilježim neke probleme i zamisli iz implementacije alata WKTrackingData.

Zamisao implementacije jednostavna je. Kôd je organiziran ovako:

Izvorna arhitektura alata WKTrackingData: upravitelj, putanje događaja i moduli AOP

Ovdje WKTrackingDataManager upravlja svim podacima i konfiguracijom praćenja događaja.

Izvorni primjer upotrebe konfiguracije praćenja događaja

WKTrackingDataViewPathHelper generira vrijednosti event_path.

AOP je modul odgovoran za praćenje svakog događaja.

Za detaljnu upotrebu posjetite GitHub.

Kako jednoznačno identificirati događaj?

Postoje dva pitanja: kako predstavljamo događaj i kako jamčimo njegovu jedinstvenost?

Predstavljanje događaja

Događaji se predstavljaju pomoću vrijednosti event_path. Za responder koji pokreće događaj osnovna je zamisao pratiti njegov lanac odazivatelja i izgraditi path toga lanca.

Dobiveni path odazivatelja izgleda ovako:

"event_path" = "#buttonClick:#UIButton#UIButton[0]#UIView[0]#ViewController#...#UIApplication#AppDelegate
Jednoznačno identificiranje događaja

U nekim poslovnim scenarijima isti button ili druga kontrola predstavlja različite poslovne događaje kada se promijene njezina svojstva.

Primjerice, button na početnom zaslonu može prikazivati Dodirnite za prijavu dok korisnik nije prijavljen, a nakon prijave Potvrdite identitet ako potvrda identiteta još nije dovršena.

Za taj isti button stablo prikaza nije se promijenilo, pa generirani path odazivatelja ostaje isti.

Slični slučajevi obuhvaćaju uključeno ili isključeno stanje kontrole UISwitch, svojstvo indexSelect kontrole UISegmentedControl, UIStepper te interakcije s cell u kontrolama UITableView ili UICollectionView.

Kako bi to riješio, WKTrackingData gradi event_path selektivnim dodavanjem svojstava same kontrole. Dobiveni event_path tada izgleda ovako:

"event_path" = "#buttonClick:#UIButton#UIButton[0]#UIView[0]#ViewController#...#UIApplication#AppDelegate#currentTitle=Button#state=1#enabled=1#selected=0";
Proširenja specifična za poslovanje

Razmotrite drugi scenarij: vrtuljak banner na početnom zaslonu.

Svako mjesto za banner ima sliku i odredišni url koje šalje poslužitelj, a njihovi su položaji podesivi.

Ovdje banner na svakom index nema fiksno odredište. Događaj na položaju 0 nije moguće odrediti samo iz vrijednosti event_path.

Da bismo jednoznačno identificirali događaj, moramo dodati parametre specifične za poslovanje, kao što je url.

WKTrackingData podržava i proširenja poslovnih parametara, pa pozivatelj može dodati prilagođene parametre:

Izvorni primjer koda koji proširuje događaje poslovnim parametrima

Kontrole koje ne treba pratiti mogu se isključiti pomoću wk_ignoreTracking:

self.slider.wk_ignoreTracking = YES;

Ostala pitanja

Za praćenje različitih događaja WKTrackingData slijedi aspektno usmjeren pristup i upotrebljava runtime za izravnu zamjenu metoda.

Međutim, za praćenje kontrola UIAlertView, UIActionSheet, UITableView i UICollectionView moramo zamijeniti njihove metode delegate.

  • Ako delegate class već implementira metodu, jednostavno je zamijenite.

  • Ako je delegate class ne implementira, a ipak želimo pratiti događaj, moramo ručno dodati implementaciju odgovarajuće metode delegate method.

- (void)wk_swizzleInstanceSelector:(SEL)origSel_ fromClass:(Class)fromClass replaceSelector:(SEL)replaceSel_ originNotImp:(SEL)notImpSel_ {
    Method originalMethod = class_getInstanceMethod([self class], origSel_);
    if (originalMethod) {
        [self wk_swizzleInstanceSelector:origSel_ fromClass:fromClass replaceSelector:replaceSel_];
    } else {
        Method notImpMethod = class_getInstanceMethod(fromClass, notImpSel_);
        // 如果delegateClass没有实现 origSel_ 方法
        // 则给delegateClass的 origSel_ 添加 orginReplaceMethod 的实现
        BOOL didAddNotImpMethod =
        class_addMethod([self class],
                        origSel_,
                        method_getImplementation(notImpMethod),
                        method_getTypeEncoding(notImpMethod));
        if (didAddNotImpMethod) {
            NSLog(@"%@ did add not imp method %@" , NSStringFromClass([self class]) , NSStringFromSelector(notImpSel_));
        }
    }
}

Implementacija se nalazi ovdje

U praksi se, međutim, pokazalo da kod kontrola UITableView i UICollectionView, kada njihovi objekti delegate nisu implementirali metodu, ni ručno dodavanje metode tableView:didSelectRowAtIndexPath: s vrijednošću implementation nije uzrokovalo njezino pokretanje.

Najprije pogledajmo uobičajeni stog poziva za tableView:didSelectRowAtIndexPath::

Izvorni stog poziva u programu za ispravljanje pogrešaka pri odabiru retka prikaza tablice

Ovdje UITableView redom poziva ove četiri metode da bi odgovorio na dodir ćelije cell:

  • 1. [UITableView _userSelectRowAtPendingSelectionIndexPath:]
  • 2. [UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:]
  • 3. [UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:isCellMultiSelect:]
  • 4. [TableViewController tableView:didSelectRowAtIndexPath:]

Redoslijed poziva pokazuje da UITableView poziva metodu tableView:didSelectRowAtIndexPath: objekta delegate class tek nakon što prvo pozove vlastitu metodu _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:isCellMultiSelect:.

Postavite prijelomnu točku na _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:isCellMultiSelect: i pregledajte asembler:

Izvorni prikaz asemblera koji pokazuje grananje metode delegata

Ako delegate class implementira tableView:didSelectRowAtIndexPath:, sve radi i poziv metode tableView:didSelectRowAtIndexPath: dovršava se.

No ako delegate class ne implementira tableView:didSelectRowAtIndexPath:, čak ni ručno dodavanje metode tableView:didSelectRowAtIndexPath: s vrijednošću implementation ne uzrokuje pokušaj odgovora na tableView:didSelectRowAtIndexPath:.

Praćenje asemblera otkriva izravan jump na drugu naredbu.

WKTrackingData ovdje primjenjuje drukčiji pristup i izravno zamjenjuje [UITableView _userSelectRowAtPendingSelectionIndexPath:] (uz sličan pristup za UICollectionView). Time se kontrolama UITableView i UICollectionView omogućuje praćenje interakcija čak i kada objekt delegate ne implementira odgovarajuću metodu događaja za cell.

4. Završne misli

Više vrijednosti event_path za isti događaj

Razmotrite više objavljenih verzija s malim razlikama u zaslonima. Isti događaj tada može imati više vrijednosti event_path.

U praksi to mapiranje zahtijeva suradnju s kolegama koji rade na poslužitelju. Može se učiniti podesivim u pozadinskom sustavu.

Optimiziranje analitike događaja

U odjeljku Proširenja specifična za poslovanje opisano je dodavanje poslovnih parametara. WKTrackingData to implementira pomoću kategorija.

U praksi je praćenje svih događaja rasipalo mnogo mrežnog prometa. Mnogi od tih događaja bili su nepotrebni [(ŏ_ŏ)].

Daljnja je optimizacija da poslužitelj pošalje konfiguracijsku datoteku s popisom svih događaja o kojima želi primati izvješća. Prenosi se samo event_path koji odgovara konfiguraciji.

U tom se trenutku poslovni parametri mogu dohvatiti i bez alata WKTrackingData: umjesto toga izravno upotrijebite kvc.

Primjerice:

key_path = "viewController.banner.url"

Ako ste pročitali dovde, otvorite WKTrackingData i dajte mu zvjezdicu. Ako imate pitanja, otvorite problem na GitHubu ili ostavite komentar ispod!