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.
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") } } }