Mobile Analytics in SwiftUI

Hi, I am working on a mobile analytics library which identifies and captures the user interactions in iOS-apps automatically. This is achieved by swizzling the UIApplication's 'sendEvent' method. Every time the user touches a button or makes any other interactions, the swizzled 'sendEvent' is called and with our custom code, we record the event and identify the UI-Control by reading the target view's 'accessibilityLabel' property.  This library works well with UIKit, it captures all the events and identifies the UI-controls that are triggering the event.
 
But when I use the same approach in SwiftUI, I get the events captured, but not the UI-element identity. For example, If there are three buttons in an app and one is touched by the user, then I get the generic button touch event in swizzled 'sendEvent'.. But I could not figure out which button is touched. It's because the underlying target view sent in 'sendEvent' method is 'CGDrawingView' - this doesn't hold the 'accessibilityLabel' property value which is set in the Button by using a ViewModifier.
 
Is there a way to read accessibilityLabel property of the Button from its sendEvent in SwiftUI?

OR is there any other unique identifier that I can use for SwiftUI views?

OR Is there any other standard way to implement mobile analytics in SwiftUI?

I have given the sample code here for reference.

Thank you.

Code Block
// MARK: Swizzling Code
extension UIApplication {
  @objc dynamic func newSendEvent(_ event: UIEvent) {
    newSendEvent(event)
     
    if (event.allTouches != nil){
      let touches: Set<UITouch> = event.allTouches!
      let touch: UITouch = touches.first!
       
      OperationQueue.main.addOperation(){
        if let tView = touch.view {
          print("------------------------------------------")
          print(Mirror(reflecting: tView).subjectType)
          print("accessibilityLabel : \(tView.accessibilityLabel ?? "null")")
        }
      }
    }
  }
}
// MARK: - Demo App Code
struct ContentView: View {
  @State private var segmentValue = 0
  @State private var textValue = ""
  @State private var sliderValue: Float = 0
   
  var body: some View {
    Form {
      Section(header: Text("UI CONTROLS").font(.title).padding(.vertical, 0.0)) {
         
        TextField("TextField", text: $textValue)
          .accessibilityLabel("Text1")
         
        VStack(spacing: 5) {
          Text("Segment Control (\(segmentValue))")
          Picker(selection: $segmentValue, label: Text("Segment Control").padding(10.0)) {
            Text("Red").tag(0)
            Text("Green").tag(1)
            Text("Blue").tag(2)
          }
          .pickerStyle(SegmentedPickerStyle())
          .padding(10.0)
          .accessibilityLabel(Text("SegmentControl1"))
        }
         
        Slider(value: $sliderValue, in: 0...100, step: 1)
          .padding(10.0)
          .accessibilityLabel("Slider1")
         
        Button(action: {
          print("Button1 pressed")
        }, label: {
          Text("Button 1")
        })
        .accessibilityLabel("Button1")
      }
    }
    .onAppear(){
      let uiAppClass = UIApplication.self
      let currentSendEvent = class_getInstanceMethod(uiAppClass, #selector(uiAppClass.sendEvent))
      let newSendEvent = class_getInstanceMethod(uiAppClass, #selector(uiAppClass.newSendEvent))
      method_exchangeImplementations(currentSendEvent!, newSendEvent!)
      print("sendEvent Swizzled")
    }
  }
}


  • The same problem, have you found a solution?

Add a Comment

Replies

I have no idea how to solve your problem, but your code was soooo clear to solve mine (detecting the user events for a kiosk mode).

Thanks so much and I hope you can solve your problem, good luck!

  • Glad to hear that you got some help from the code. Thanks!

Add a Comment

Any progress on it?

Add a Comment

Pendo SDK had a great progress in coddlers analytics for swiftui: https://github.com/pendo-io/pendo-mobile-sdk/blob/master/ios/pnddocs/swiftui.md

  • Gave it a try with Pendo SDK. They were able to capture the events but there is n't any identifiers attached to it.. In the case of a button click event, we cant say which button is clicked.

  • They are extracting accessibility labels and identifiers and attach it to to the button click analytics, that's how they diff between the events. you can see what they collecting in the page tagging, anyway they responsive on the GitHub so you can always ask them if something doesnt work

Add a Comment