SRGSSR / srganalytics-apple

Covers analytics needs for SRG SSR products.
MIT License
0 stars 1 forks source link

SwiftUI page view tracking #46

Closed defagos closed 3 years ago

defagos commented 3 years ago

We should an API for page view tracking of SwiftUI applications.

defagos commented 3 years ago

Unlike view controller lifecycle methods, SwiftUI onAppear method is called both when a view appears for the first time, as well as when it is revealed by dismissing another one. It therefore leads to undesired events when view controllers are revealed.

Fortunately, as SwiftUI internally makes use of UIKit, we can use standard view controller tracking to have the exact same behavior as we currently have for UIKit apps. For this to work the page view events must be forwarded correctly throughout the app implicit view controller hierarchy, which requires #45 to be implemented first.

Afterwards the strategy is quite simple:

This strategy works not only with mixed UIKit / SwiftUI apps, but also with pure SwiftUI apps (available since iOS / tvOS 14), which also have an internal view controller hierarchy (just call _printHierarchy on the root view controller to see it).

defagos commented 3 years ago

Implemented on the feature/swiftui-page-view-tracking branch.

We need a demo but this is really a task in itself (#47). A second target? A second project (with an additional xcconfig file to maintain)? For the moment I propose to go without, the code above can be easily tested with a pure SwiftUI app, e.g. with two tabs:

import SRGAnalytics
import SwiftUI

@main
struct TestSwiftUIApp: App {
    init() {
        let configuration = SRGAnalyticsConfiguration(businessUnitIdentifier: .RTS, container: 1012, siteName: "test", netMetrixIdentifier: "test")
        SRGAnalyticsTracker.shared.start(with: configuration)
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

and

import SRGAnalyticsSwiftUI
import SwiftUI

struct ContentView: View {
    var body: some View {
        TabView {
            Text("Menu displayed here")
                .tabItem {
                    Image(systemName: "list.dash")
                    Text("Menu")
                }
                .tracked(with: "menu")

            Text("Orders displayed here")
                .tabItem {
                    Image(systemName: "square.and.pencil")
                    Text("Order")
                }
                .tracked(with: "order")
        }
    }
}