Skip to content

Commit

Permalink
add debugAllScreenNames property to assist developers tune up view na…
Browse files Browse the repository at this point in the history
…mes when autoCaptureScreenNames is set to true
  • Loading branch information
Hongyan Jiang authored and GitHub Enterprise committed Apr 9, 2024
1 parent 72e20d0 commit 1c50ee4
Show file tree
Hide file tree
Showing 14 changed files with 225 additions and 95 deletions.
2 changes: 1 addition & 1 deletion Changelog.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Changelog

## 1.7.0
- introduce `autoCaptureScreenNames` and `autoViewCaptureAllowedClasses` for InstanaSetupOptions to auto capture view names
- introduce `autoCaptureScreenNames` to auto capture view names and `debugAllScreenNames` to debug all screen names

## 1.6.9
- Support CustomMetric field in reportEvent method
Expand Down
4 changes: 2 additions & 2 deletions Dev/InstanaAgentExample/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {

let options = InstanaSetupOptions(enableCrashReporting: userYes)
// options.slowSendInterval = 60.0
options.autoCaptureScreenNames = AutoCaptureScreenNames.interestedUIViewControllers
options.autoViewCaptureAllowedClasses = ["ViewController", "TopRatedViewController", "WebViewController", "DetailViewController"]
options.autoCaptureScreenNames = true
// options.debugAllScreenNames = true
if !Instana.setup(key: InstanaKey, reportingURL: InstanaURL, options: options) {
os_log("Instana setup failed", log: myLog, type: .error)
}
Expand Down
46 changes: 46 additions & 0 deletions Dev/InstanaAgentExample/PrivacyInfo_crash.xcprivacy
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyTracking</key>
<true/>
<key>NSPrivacyTrackingDomains</key>
<array>
<string>placeholder domain of INSTANA_REPORTING_URL </string>
</array>
<key>NSPrivacyCollectedDataTypes</key>
<array>
<dict>
<key>NSPrivacyCollectedDataType</key>
<string>NSPrivacyCollectedDataTypeCrashData</string>
<key>NSPrivacyCollectedDataTypeLinked</key>
<false/>
<key>NSPrivacyCollectedDataTypeTracking</key>
<false/>
<key>NSPrivacyCollectedDataTypePurposes</key>
<array>
<string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
</array>
</dict>
</array>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>DDA9.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
</array>
</dict>
</plist>
31 changes: 31 additions & 0 deletions Dev/InstanaAgentExample/PrivacyInfo_default.xcprivacy
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyTracking</key>
<true/>
<key>NSPrivacyTrackingDomains</key>
<array>
<string>placeholder domain of INSTANA_REPORTING_URL </string>
</array>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>DDA9.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>CA92.1</string>
</array>
</dict>
</array>
</dict>
</plist>
30 changes: 14 additions & 16 deletions Dev/ObjectiveCAppExample/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,22 @@ @implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

InstanaSetupOptions* options = nil;

//note: explicitly get user permission before setting enableCrashReporting to true
// options = [[InstanaSetupOptions alloc] initWithHttpCaptureConfig: 0
// collectionEnabled: true
// enableCrashReporting: true
// suspendReportingOnLowBattery: true
// suspendReportingOnCellular: false
// slowSendInterval: 0.0
// usiRefreshTimeIntervalInHrs: -1
// autoCaptureScreenNames: true
// debugAllScreenNames: false];

(void)[Instana setupWithKey: @"INSTANA_REPORTING_KEY"
reportingURL: [NSURL URLWithString: @"INSTANA_REPORTING_URL"]
options: nil];

// NSArray<NSString *> *viewControllerClasses = @[@"ViewController"];
// //note: explicitly get user permission before setting enableCrashReporting to true
// InstanaSetupOptions* options = [[InstanaSetupOptions alloc] initWithHttpCaptureConfig: 0
// collectionEnabled: true
// enableCrashReporting: true
// suspendReportingOnLowBattery: true
// suspendReportingOnCellular: false
// slowSendInterval: 0.0
// usiRefreshTimeIntervalInHrs: -1
// autoCaptureScreenNames: 2
// autoViewCaptureAllowedClasses: viewControllerClasses];
// (void)[Instana setupWithKey: @"INSTANA_REPORTING_KEY"
// reportingURL: [NSURL URLWithString: @"INSTANA_REPORTING_URL"]
// options: options];
options: options];

NSURL* url = [NSURL URLWithString: @"https://www.ibm.com/jp-ja"];
NSURLRequest* request = [NSURLRequest requestWithURL: url];
Expand Down
2 changes: 1 addition & 1 deletion Dev/ObjectiveCAppExample/ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ - (void)viewDidLoad {
}


- (void)viewWillAppear:(BOOL)animated {
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// [Instana setViewWithName:@"Objetive-C app View 1"];
}
Expand Down
11 changes: 9 additions & 2 deletions Sources/InstanaAgent/Beacons/Beacons Types/ViewChange.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ class ViewChange: Beacon {

init(timestamp: Instana.Types.Milliseconds = Date().millisecondsSince1970,
viewName: String? = nil, accessibilityLabel: String? = nil,
navigationItemTitle: String? = nil, className: String? = nil) {
navigationItemTitle: String? = nil,
className: String? = nil, isSwiftUI: Bool = false) {
var canonicalName: String? = viewName
var prefix = ""
if accessibilityLabel != nil, !accessibilityLabel!.isEmpty {
Expand All @@ -23,7 +24,13 @@ class ViewChange: Beacon {
}
self.className = className
if self.className != nil {
canonicalName = prefix + "@" + self.className!
let debugAll = Instana.current?.session.debugAllScreenNames ?? false
if !isSwiftUI || debugAll {
canonicalName = prefix + "@" + self.className!
} else {
// SwiftUI class name is overwhelming, hide it if there is a prefix.
canonicalName = prefix.isEmpty ? "@\(self.className!)" : prefix
}
}
super.init(timestamp: timestamp, viewName: canonicalName)
}
Expand Down
6 changes: 3 additions & 3 deletions Sources/InstanaAgent/Beacons/CoreBeacon/CoreBeacon.swift
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,9 @@ struct CoreBeacon: Codable {
* Internal meta data key/value entries
*
* Will be converted at transmission to separated string prefixed by `im_`
* For example: `im_view.accessibilityLabel someLabel`
* For example: `im_view.navigationItemTitle someTitle`
* For example: `im_view.className JSONViewController`
* For example: `im_view.accLabel someLabel`
* For example: `im_view.navItemTitle someNavTitle`
* For example: `im_view.clsName JSONViewController`
*
* optional
* max size 128, max key length 64, max value length 1024
Expand Down
26 changes: 24 additions & 2 deletions Sources/InstanaAgent/Configuration/InstanaSession.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//

import Foundation
import UIKit

class InstanaSession {
/// The current Instana configuration
Expand Down Expand Up @@ -34,19 +35,40 @@ class InstanaSession {
let logger = InstanaLogger()

/// Collecting and reporting can be disabled or enabled at any time
@Atomic var collectionEnabled: Bool
@Atomic var collectionEnabled: Bool {
didSet {
Self.processAutoCaptureScreenNames(collectionEnabled: collectionEnabled, acsn: autoCaptureScreenNames)
}
}

init(configuration: InstanaConfiguration, propertyHandler: InstanaPropertyHandler, sessionID: UUID = UUID(), collectionEnabled: Bool) {
@Atomic var autoCaptureScreenNames: Bool
@Atomic var debugAllScreenNames: Bool

init(configuration: InstanaConfiguration, propertyHandler: InstanaPropertyHandler, sessionID: UUID = UUID(),
collectionEnabled: Bool, autoCaptureScreenNames: Bool = false, debugAllScreenNames: Bool = false) {
self.configuration = configuration
self.propertyHandler = propertyHandler
self.collectionEnabled = collectionEnabled

self.autoCaptureScreenNames = autoCaptureScreenNames
self.debugAllScreenNames = debugAllScreenNames
Self.processAutoCaptureScreenNames(collectionEnabled: collectionEnabled, acsn: autoCaptureScreenNames)

previousSession = PreviousSession.readInPreviousSessionData()
id = sessionID
(userSessionID, usiStartTime) = InstanaSession.usiRetrieve(configuration)
PreviousSession.persistSessionID(sid: sessionID)
}

private static func processAutoCaptureScreenNames(collectionEnabled: Bool, acsn: Bool) {
if collectionEnabled && acsn {
// Automatically setView for Instana with current View Controller's
// class name (or accessibilityLabel / navigation title if they are set)
// when viewDidAppear method is called.
UIViewController.instanaSetViewAutomatically()
}
}

private func isSessionValid() -> Bool {
// Do now allow user_session_id tracking
if configuration.usiRefreshTimeIntervalInHrs == usiTrackingNotAllowed {
Expand Down
31 changes: 11 additions & 20 deletions Sources/InstanaAgent/Instana.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
//

import Foundation
import UIKit

// swiftlint:disable line_length

/// Root object for the Instana agent.
///
Expand Down Expand Up @@ -100,7 +97,9 @@ import UIKit
var suspendReporting = InstanaConfiguration.SuspendReporting.defaults
var slowSendInterval = 0.0
var usiRefreshTimeIntervalInHrs = defaultUsiRefreshTimeIntervalInHrs
var autoCaptureScreenNames: AutoCaptureScreenNames = .none
var autoCaptureScreenNames: Bool = false
var debugAllScreenNames: Bool = false

if let options = options {
httpCaptureConfig = options.httpCaptureConfig
collectionEnabled = options.collectionEnabled
Expand All @@ -126,6 +125,7 @@ import UIKit

usiRefreshTimeIntervalInHrs = options.usiRefreshTimeIntervalInHrs
autoCaptureScreenNames = options.autoCaptureScreenNames
debugAllScreenNames = options.debugAllScreenNames
}

var hybridAgentId: String?
Expand All @@ -144,21 +144,10 @@ import UIKit
hybridAgentId: hybridAgentId,
hybridAgentVersion: hybridAgentVersion)
let session = InstanaSession(configuration: config, propertyHandler: InstanaPropertyHandler(),
collectionEnabled: collectionEnabled)
collectionEnabled: collectionEnabled,
autoCaptureScreenNames: autoCaptureScreenNames,
debugAllScreenNames: debugAllScreenNames)
Instana.current = Instana(session: session)

if autoCaptureScreenNames != AutoCaptureScreenNames.none {
typeAutoCaptureScreenNames = autoCaptureScreenNames
if autoCaptureScreenNames != AutoCaptureScreenNames.allUIViewControllers {
autoViewCaptureAllowedClasses = options!.autoViewCaptureAllowedClasses
}
// Automatically setView for Instana with current View Controller's
// class name (or accessibilityLabel / navigation title if they are set)
// when viewDidAppear method is called.
// Remove Instana.setView calls from all View Controllers that inherit from UIViewController
// otherwise the old approach interferes with this new approach.
UIViewController.instanaSetViewAutomatically()
}
return true
}

Expand Down Expand Up @@ -426,7 +415,8 @@ import UIKit
public func setViewInternal(name: String?,
accessibilityLabel: String? = nil,
navigationItemTitle: String? = nil,
className: String? = nil) {
className: String? = nil,
isSwiftUI: Bool = false) {
guard let propertyHandler = Instana.current?.session.propertyHandler else { return }
let isIdentical = propertyHandler.properties.view?.isSame(name: name,
accessibilityLabel: accessibilityLabel,
Expand All @@ -436,7 +426,8 @@ import UIKit
let view = ViewChange(viewName: name,
accessibilityLabel: accessibilityLabel,
navigationItemTitle: navigationItemTitle,
className: className)
className: className,
isSwiftUI: isSwiftUI)
propertyHandler.properties.view = view

guard view.viewName != nil else { return }
Expand Down
25 changes: 10 additions & 15 deletions Sources/InstanaAgent/InstanaSetupOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,6 @@

import Foundation

@objc public enum AutoCaptureScreenNames: Int {
/// Don't automatically capture any screen names
case none
/// Any class that derives from UIViewController with accessibilityLabel or navigationItem.title set is automatically captured.
/// If a UIViewController class name is passed through autoViewCaptureAllowedClasses array, it's also captured.
case interestedUIViewControllers
/// Any class that derives from UIViewController is automatically captured
case allUIViewControllers
}

@objc public class InstanaSetupOptions: NSObject {
public var httpCaptureConfig: HTTPCaptureConfig
public var collectionEnabled: Bool
Expand All @@ -22,8 +12,13 @@ import Foundation
public var suspendReportingOnCellular: Bool
public var slowSendInterval: Instana.Types.Seconds
public var usiRefreshTimeIntervalInHrs: Double
public var autoCaptureScreenNames: AutoCaptureScreenNames
public var autoViewCaptureAllowedClasses: [String] = []

// If autoCaptureScreenNames is set to true, we could leverage
// certain classes' properties and set active view name automatically.
// The class needs to derive from UIViewController directly or indirectly.
// Instana.setView is triggered on the instance's viewDidAppear call.
public var autoCaptureScreenNames: Bool
public var debugAllScreenNames: Bool

/// Instana custom configuration for setup.
///
Expand All @@ -40,8 +35,8 @@ import Foundation
suspendReportingOnCellular: Bool = false,
slowSendInterval: Instana.Types.Seconds = 0.0,
usiRefreshTimeIntervalInHrs: Double = defaultUsiRefreshTimeIntervalInHrs,
autoCaptureScreenNames: AutoCaptureScreenNames = .none,
autoViewCaptureAllowedClasses: [String] = []) {
autoCaptureScreenNames: Bool = false,
debugAllScreenNames: Bool = false) {
self.httpCaptureConfig = httpCaptureConfig
self.collectionEnabled = collectionEnabled
self.enableCrashReporting = enableCrashReporting
Expand All @@ -50,7 +45,7 @@ import Foundation
self.slowSendInterval = slowSendInterval
self.usiRefreshTimeIntervalInHrs = usiRefreshTimeIntervalInHrs
self.autoCaptureScreenNames = autoCaptureScreenNames
self.autoViewCaptureAllowedClasses = autoViewCaptureAllowedClasses
self.debugAllScreenNames = debugAllScreenNames
}
}

Expand Down
Loading

0 comments on commit 1c50ee4

Please sign in to comment.