-
Notifications
You must be signed in to change notification settings - Fork 133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RUMM-1097 Fix DefaultUIKitRUMViewsPredicate
for Objc view controllers
#419
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,3 +5,4 @@ | |
*/ | ||
|
||
#import "NSURLSessionBridge.h" | ||
#import "CustomObjcViewController.h" |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -58,15 +58,20 @@ public struct DefaultUIKitRUMViewsPredicate: UIKitRUMViewsPredicate { | |
public init () {} | ||
|
||
public func rumView(for viewController: UIViewController) -> RUMView? { | ||
let canonicalClassName = viewController.canonicalClassName | ||
let isCustomClass = canonicalClassName.contains(".") // custom class contains module prefix | ||
|
||
if isCustomClass { | ||
var view = RUMView(name: canonicalClassName) | ||
view.path = canonicalClassName | ||
return view | ||
} else { | ||
guard !isUIKit(class: type(of: viewController)) else { | ||
// do not track bare UIKit's view controllers (UINavigationController, UITabBarController, ...) | ||
return nil | ||
} | ||
|
||
let canonicalClassName = viewController.canonicalClassName | ||
var view = RUMView(name: canonicalClassName) | ||
view.path = canonicalClassName | ||
return view | ||
} | ||
|
||
/// If given `class` comes from UIKit framework. | ||
private func isUIKit(`class`: AnyClass) -> Bool { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nitpick: Put this as an internal extension on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you mean sth like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's not important for me but i was thinking of smth like this:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done 👌 , I added: internal extension Bundle {
var isUIKit: Bool
} extension and bunch of fixtures in tests. |
||
let bundle = Bundle(for: `class`) | ||
return bundle.bundleURL.lastPathComponent == "UIKitCore.framework" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,16 +8,31 @@ import XCTest | |
import Datadog | ||
|
||
class UIKitRUMViewsPredicateTests: XCTestCase { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could also add test cases to check that some known UIKit classes are filtered out, to catch any regressions of the internal There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 to @acgh , we rely on private information ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's already there - just not visible in this diff. We had this test before: func testGivenDefaultPredicate_whenAskingUIKitViewController_itReturnsNoView() {
// Given
let predicate = DefaultUIKitRUMViewsPredicate()
// When
let uiKitViewController = UIViewController()
let rumView = predicate.rumView(for: uiKitViewController)
// Then
XCTAssertNil(rumView)
} |
||
func testGivenDefaultPredicate_whenAskingForCustomViewController_itNamesTheViewByItsClassName() { | ||
func testGivenDefaultPredicate_whenAskingForCustomSwiftViewController_itNamesTheViewByItsClassName() { | ||
// Given | ||
let predicate = DefaultUIKitRUMViewsPredicate() | ||
|
||
// When | ||
let customViewController = createMockView(viewControllerClassName: "Module.CustomViewController") | ||
let customViewController = createMockView(viewControllerClassName: "CustomSwiftViewController") | ||
let rumView = predicate.rumView(for: customViewController) | ||
|
||
// Then | ||
XCTAssertEqual(rumView?.path, "Module.CustomViewController") | ||
XCTAssertEqual(rumView?.name, "CustomSwiftViewController") | ||
XCTAssertEqual(rumView?.path, "CustomSwiftViewController") | ||
XCTAssertTrue(rumView!.attributes.isEmpty) | ||
} | ||
|
||
func testGivenDefaultPredicate_whenAskingForCustomObjcViewController_itNamesTheViewByItsClassName() { | ||
// Given | ||
let predicate = DefaultUIKitRUMViewsPredicate() | ||
|
||
// When | ||
let customViewController = CustomObjcViewController() | ||
let rumView = predicate.rumView(for: customViewController) | ||
|
||
// Then | ||
XCTAssertEqual(rumView?.name, "CustomObjcViewController") | ||
XCTAssertEqual(rumView?.path, "CustomObjcViewController") | ||
XCTAssertTrue(rumView!.attributes.isEmpty) | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* | ||
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. | ||
* This product includes software developed at Datadog (https://www.datadoghq.com/). | ||
* Copyright 2019-2020 Datadog, Inc. | ||
*/ | ||
|
||
#import <UIKit/UIKit.h> | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
@interface CustomObjcViewController : UIViewController | ||
|
||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/* | ||
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. | ||
* This product includes software developed at Datadog (https://www.datadoghq.com/). | ||
* Copyright 2019-2020 Datadog, Inc. | ||
*/ | ||
|
||
#import "CustomObjcViewController.h" | ||
|
||
@interface CustomObjcViewController () | ||
|
||
@end | ||
|
||
@implementation CustomObjcViewController | ||
|
||
- (void)viewDidLoad { | ||
[super viewDidLoad]; | ||
} | ||
|
||
@end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the real goal is excluding container view controllers, exclusion of
UIKit
types is just the workaround that we could come up with.this comment here may be misleading if we come back to this issue later on, can we correct it?
here is the same issue in PR's description as well:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's about plain (not subclassed / customized) VCs from
UIKit
.Before this PR, this implementation was considering
MyCustomNavigationViewController
as the RUM View. I think we shouldn't change that default if no one has reported it being wrong. We're doing a bug fix here, I wouldn't change the previous behaviour.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no i'm not talking about the behavior, my concern is that the comments don't tell the whole story.
we first wanted to exclude containers and then noticed invisible view controllers in the hiearchy. if one asks "why do we exclude UIKit types?", the answer is not obvious without this story.
IMO this comment
do not track UIKit controllers
brings questions (why?) rather than answeringThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see 👍. Improved it with discussing the reasoning and optimisation.