promotedai / ios-metrics-sdk

iOS client library for Promoted.ai metrics tracking.
MIT License
7 stars 1 forks source link

Implement anomaly handling #177

Closed yunapotamus closed 2 years ago

yunapotamus commented 2 years ago

Summary

This PR implements anomaly handling as described in the attached issue. It includes both the detection mechanism itself as well as a modal dialog that interrupts the user when an anomaly occurs. The idea behind this is to be more assertive in debug builds when partner changes break Promoted logging, so that logging changes can be caught before they get merged. Main changes:

  1. AnomalyHandler mechanism as an OperationMonitorListener.
  2. AnomalyHandlerViewController for presenting a modal dialog.

AnomalyHandler

This class is part of a new package that is devoted to detecting logging issues that could result in suboptimal data being sent to Promoted. AnomalyHandler intercepts and analyzes logged events and handles errors or anomalies in one of three ways:

  1. Console log. This could be enabled in production.
  2. Shows a modal dialog. This is to notify developers that they may have introduced a breaking change. This should only happen in dev/debug builds.
  3. Break in the debugger. This (obviously) would only happen in dev/debug builds.

This is currently separate from the remainder of error handling, but will soon be unified.

AnomalyHandlerViewController

Presents a view controller with a modal dialog that interrupts the current task. Serves as a very obvious warning that something is amiss. Must be manually dismissed before interaction with the app can continue. This works in all of UIKit, SwiftUI, and React Native-based apps (since all three use UIWindow under the hood). The screenshot below is from React Native.

React Native Screenshot

A supporting change to UIState and UIKitState adds support for detecting the key window. This needs to be done differently in iOS 13 vs previous versions of iOS.

yunapotamus commented 2 years ago

Side - Is it even possible to distribute a dev/debug build of an app? Just checking to see in case someone accidentally does this.

Not externally on the App Store, but it is possible to do so internally. I also believe you can distribute a debug build via TestFlight but I have never done so.

Also, even though it's not part of the checks in our native SDK, but React Native has separate prod/debug flags that bypass the App Store check.

Side - How does the intercept logic work? I didn't see how AnomalyHandler was called.

It's being done through OperationMonitorListener. When AnomalyHandler is initialized, it adds itself as a listener:

deps.operationMonitor.addOperationMonitorListener(self)