Skip to content

Commit 8df2e0d

Browse files
authored
test: sample app feature flag improvements (#5202)
1 parent a7203db commit 8df2e0d

30 files changed

+296
-359
lines changed

Samples/SentrySampleShared/SentrySampleShared.xcconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,5 @@ CODE_SIGN_IDENTITY =
3030
CODE_SIGN_IDENTITY[sdk=macosx*] =
3131
PROVISIONING_PROFILE_SPECIFIER =
3232
DEVELOPMENT_TEAM =
33+
34+
TARGETED_DEVICE_FAMILY = 1,2,3,4,7

Samples/iOS-Swift/iOS-Swift/Tools/DSNDisplayViewController.swift renamed to Samples/SentrySampleShared/SentrySampleShared/DSNDisplayViewController.swift

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
1-
import SentrySampleShared
1+
#if !os(macOS) && !os(tvOS) && !os(watchOS) && !os(visionOS)
2+
3+
import Sentry
24
import UIKit
35

46
let fontSize: CGFloat = 12
57

6-
func addDSNDisplay(_ vc: UIViewController, vcview: UIView) {
7-
let dsnVC = DSNDisplayViewController(nibName: nil, bundle: nil)
8-
vcview.addSubview(dsnVC.view)
9-
dsnVC.view.matchEdgeAnchors(from: vcview)
10-
vc.addChild(dsnVC)
11-
}
12-
138
class DSNDisplayViewController: UIViewController {
149
let dispatchQueue = DispatchQueue(label: "io.sentry.iOS-Swift.queue.dsn-management", attributes: .concurrent)
1510
let label = UILabel(frame: .zero)
@@ -48,7 +43,7 @@ class DSNDisplayViewController: UIViewController {
4843
])
4944

5045
view.addSubview(stack)
51-
stack.matchEdgeAnchors(from: view, leadingPad: 20)
46+
stack.matchEdgeAnchors(from: view)
5247
buttonStack.translatesAutoresizingMaskIntoConstraints = false
5348
buttonStack.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.3).isActive = true
5449
}
@@ -172,3 +167,5 @@ class DSNDisplayViewController: UIViewController {
172167
return attributedString
173168
}
174169
}
170+
171+
#endif // !os(macOS) && !os(tvOS) && !os(watchOS) && !os(visionOS)

Samples/SentrySampleShared/SentrySampleShared/EnvironmentVariableTableViewCell.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class EnvironmentVariableTableViewCell: UITableViewCell, UITextFieldDelegate {
1818
let stack = UIStackView(arrangedSubviews: [valueField, titleLabel])
1919
stack.spacing = 8
2020
contentView.addSubview(stack)
21-
stack.matchEdgeAnchors(from: contentView, topPad: 8, bottomPad: 8)
21+
stack.matchEdgeAnchors(from: contentView)
2222

2323
valueField.borderStyle = .roundedRect
2424
}
@@ -50,6 +50,7 @@ class EnvironmentVariableTableViewCell: UITableViewCell, UITextFieldDelegate {
5050
} else {
5151
override?.stringValue = textField.text
5252
}
53+
SentrySDKWrapper.shared.startSentry()
5354
}
5455
}
5556
#endif // !os(macOS) && !os(tvOS) && !os(watchOS)

Samples/SentrySampleShared/SentrySampleShared/FeaturesViewController.swift

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,29 @@
1-
#if !os(macOS) && !os(tvOS) && !os(watchOS)
1+
#if !os(macOS) && !os(tvOS) && !os(watchOS) && !os(visionOS)
22
import UIKit
33

4-
public class FeaturesViewController: UITableViewController {
5-
public override func viewDidLoad() {
6-
super.viewDidLoad()
4+
public class FeaturesViewController: UIViewController {
5+
let tableView = UITableView(frame: .zero, style: .plain)
6+
7+
public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
8+
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
9+
710
tableView.register(LaunchArgumentTableViewCell.self, forCellReuseIdentifier: "launchArgumentCell")
811
tableView.register(EnvironmentVariableTableViewCell.self, forCellReuseIdentifier: "environmentVariableCell")
9-
tableView.tableHeaderView = tableHeader
12+
tableView.dataSource = self
13+
14+
let stack = UIStackView(arrangedSubviews: [headerView, tableView])
15+
stack.axis = .vertical
16+
view.addSubview(stack)
17+
stack.matchEdgeAnchors(from: view, safeArea: true)
18+
19+
view.backgroundColor = .white
1020
}
1121

12-
var tableHeader: UIView {
22+
required init?(coder: NSCoder) {
23+
fatalError("init(coder:) not supported")
24+
}
25+
26+
var headerView: UIView {
1327
let resetButton = UIButton(type: .custom)
1428
resetButton.setTitle("Reset Defaults", for: .normal)
1529
resetButton.setTitleColor(.blue, for: .normal)
@@ -18,28 +32,29 @@ public class FeaturesViewController: UITableViewController {
1832
let label = UILabel(frame: .zero)
1933
label.text = SentrySDKOverrides.schemaPrecedenceForEnvironmentVariables ? "Schema Precedence" : "Defaults Precedence"
2034

21-
let stack = UIStackView(arrangedSubviews: [label, resetButton])
22-
stack.spacing = 8
35+
let hstack = UIStackView(arrangedSubviews: [label, resetButton])
36+
hstack.spacing = 8
2337

24-
let header = UIView(frame: .zero)
25-
header.addSubview(stack)
38+
let dsnVC = DSNDisplayViewController(nibName: nil, bundle: nil)
39+
addChild(dsnVC)
2640

27-
stack.matchEdgeAnchors(from: header)
28-
header.heightAnchor.constraint(equalToConstant: 50).isActive = true
29-
30-
return header
41+
let vStack = UIStackView(arrangedSubviews: [dsnVC.view, hstack])
42+
vStack.axis = .vertical
43+
return vStack
3144
}
3245

3346
@objc func resetDefaults() {
3447
SentrySDKOverrides.resetDefaults()
3548
tableView.reloadData()
3649
}
50+
}
3751

38-
public override func numberOfSections(in tableView: UITableView) -> Int {
52+
extension FeaturesViewController: UITableViewDataSource {
53+
public func numberOfSections(in tableView: UITableView) -> Int {
3954
6
4055
}
4156

42-
public override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
57+
public func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
4358
if section == 0 {
4459
return "Special"
4560
} else if section == 1 {
@@ -56,7 +71,7 @@ public class FeaturesViewController: UITableViewController {
5671
return nil
5772
}
5873

59-
public override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
74+
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
6075
if section == 0 {
6176
return SentrySDKOverrides.Special.allCases.count
6277
} else if section == 1 {
@@ -73,7 +88,7 @@ public class FeaturesViewController: UITableViewController {
7388
return 0
7489
}
7590

76-
public override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
91+
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
7792
if indexPath.section == 2 {
7893
if SentrySDKOverrides.Tracing.boolValues.contains(SentrySDKOverrides.Tracing.allCases[indexPath.row]) {
7994
let cell = tableView.dequeueReusableCell(withIdentifier: "launchArgumentCell", for: indexPath) as! LaunchArgumentTableViewCell
@@ -117,4 +132,4 @@ public class FeaturesViewController: UITableViewController {
117132
return cell
118133
}
119134
}
120-
#endif // !os(macOS) && !os(tvOS) && !os(watchOS)
135+
#endif // !os(macOS) && !os(tvOS) && !os(watchOS) && !os(visionOS)

Samples/SentrySampleShared/SentrySampleShared/LaunchArgumentTableViewCell.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,15 @@ class LaunchArgumentTableViewCell: UITableViewCell {
1212

1313
@objc func toggleFlag() {
1414
override?.boolValue = flagSwitch.isOn
15+
SentrySDKWrapper.shared.startSentry()
1516
}
1617

1718
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
1819
super.init(style: style, reuseIdentifier: reuseIdentifier)
1920
let stack = UIStackView(arrangedSubviews: [flagSwitch, titleLabel])
2021
stack.spacing = 8
2122
contentView.addSubview(stack)
22-
stack.matchEdgeAnchors(from: contentView, topPad: 8, bottomPad: 8)
23+
stack.matchEdgeAnchors(from: contentView)
2324
}
2425

2526
required init?(coder: NSCoder) {
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#if !os(macOS) && !os(tvOS) && !os(watchOS) && !os(visionOS)
2+
import UIKit
3+
4+
public class SampleAppDebugMenu: NSObject {
5+
public static let shared = SampleAppDebugMenu()
6+
7+
static var displayingForm = false
8+
9+
let window = {
10+
if #available(iOS 13.0, *) {
11+
if let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
12+
return Window(windowScene: scene)
13+
}
14+
}
15+
return Window()
16+
}()
17+
18+
lazy var rootVC = {
19+
let uivc = UIViewController(nibName: nil, bundle: nil)
20+
uivc.view.addSubview(button)
21+
22+
button.translatesAutoresizingMaskIntoConstraints = false
23+
NSLayoutConstraint.activate([
24+
button.leadingAnchor.constraint(equalTo: uivc.view.safeAreaLayoutGuide.leadingAnchor, constant: 25),
25+
button.bottomAnchor.constraint(equalTo: uivc.view.safeAreaLayoutGuide.bottomAnchor, constant: -75)
26+
])
27+
28+
return uivc
29+
}()
30+
31+
lazy var button = {
32+
let button = UIButton(type: .custom)
33+
button.addTarget(self, action: #selector(displayDebugMenu), for: .touchUpInside)
34+
button.setTitle("SDK Debug", for: .normal)
35+
button.setTitleColor(.blue, for: .normal)
36+
return button
37+
}()
38+
39+
@objc public func display() {
40+
window.rootViewController = rootVC
41+
window.isHidden = false
42+
}
43+
44+
@objc func displayDebugMenu() {
45+
SampleAppDebugMenu.displayingForm = true
46+
rootVC.present(FeaturesViewController(nibName: nil, bundle: nil), animated: true)
47+
}
48+
49+
class Window: UIWindow {
50+
51+
@available(iOS 13.0, *)
52+
override init(windowScene: UIWindowScene) {
53+
super.init(windowScene: windowScene)
54+
commonInit()
55+
}
56+
57+
init() {
58+
super.init(frame: UIScreen.main.bounds)
59+
commonInit()
60+
}
61+
62+
func commonInit() {
63+
windowLevel = UIWindow.Level.alert + 1
64+
}
65+
66+
required init?(coder: NSCoder) {
67+
fatalError("init(coder:) has not been implemented")
68+
}
69+
70+
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
71+
guard !SampleAppDebugMenu.displayingForm else {
72+
return super.hitTest(point, with: event)
73+
}
74+
75+
guard let result = super.hitTest(point, with: event) else {
76+
return nil
77+
}
78+
guard result.isKind(of: UIButton.self) else {
79+
return nil
80+
}
81+
return result
82+
}
83+
}
84+
}
85+
86+
extension SampleAppDebugMenu: UIAdaptivePresentationControllerDelegate {
87+
public func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
88+
rootVC.dismiss(animated: true)
89+
SampleAppDebugMenu.displayingForm = false
90+
}
91+
}
92+
#endif // !os(macOS) && !os(tvOS) && !os(watchOS) && !os(visionOS)

Samples/SentrySampleShared/SentrySampleShared/SentrySDKOverrides.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public enum SentrySDKOverrides {
3333
public enum Special: String, SentrySDKOverride {
3434
case wipeDataOnLaunch = "--io.sentry.wipe-data"
3535
case disableEverything = "--io.sentry.disable-everything"
36+
case skipSDKInit = "--skip-sentry-init"
3637

3738
public var boolValue: Bool {
3839
get {

Samples/SentrySampleShared/SentrySampleShared/SentrySDKWrapper.swift

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,14 @@ public struct SentrySDKWrapper {
2121
#endif // !os(macOS) && !os(tvOS) && !os(watchOS)
2222

2323
public func startSentry() {
24-
SentrySDK.start(configureOptions: configureSentryOptions(options:))
24+
if SentrySDK.isEnabled {
25+
print("SentrySDK already enabled, closing it")
26+
SentrySDK.close()
27+
}
28+
29+
if !SentrySDKOverrides.Special.skipSDKInit.boolValue {
30+
SentrySDK.start(configureOptions: configureSentryOptions(options:))
31+
}
2532
}
2633

2734
func configureSentryOptions(options: Options) {
@@ -382,15 +389,11 @@ extension SentrySDKWrapper {
382389
public static let defaultDSN = "https://[email protected]/5428557"
383390

384391
var args: [String] {
385-
let args = ProcessInfo.processInfo.arguments
386-
print("[iOS-Swift] [debug] launch arguments: \(args)")
387-
return args
392+
return ProcessInfo.processInfo.arguments
388393
}
389394

390395
var env: [String: String] {
391-
let env = ProcessInfo.processInfo.environment
392-
print("[iOS-Swift] [debug] environment: \(env)")
393-
return env
396+
return ProcessInfo.processInfo.environment
394397
}
395398

396399
/// For testing purposes, we want to be able to change the DSN and store it to disk. In a real app, you shouldn't need this behavior.

Samples/iOS-Swift/iOS-Swift/Tools/Toasts.swift renamed to Samples/SentrySampleShared/SentrySampleShared/Toasts.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#if !os(macOS) && !os(tvOS) && !os(watchOS) && !os(visionOS)
2+
13
import UIKit
24

35
public enum ToastType {
@@ -40,3 +42,5 @@ public func showToast(in vc: UIViewController, type: ToastType, message: String)
4042
}
4143
}
4244
}
45+
46+
#endif // !os(macOS) && !os(tvOS) && !os(watchOS) && !os(visionOS)

Samples/SentrySampleShared/SentrySampleShared/UIViewExtension.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@ public extension UIView {
1111
return self
1212
}
1313

14-
func matchEdgeAnchors(from other: UIView, leadingPad: CGFloat = 0, trailingPad: CGFloat = 0, topPad: CGFloat = 0, bottomPad: CGFloat = 0) {
14+
func matchEdgeAnchors(from other: UIView, leadingPad: CGFloat = 0, trailingPad: CGFloat = 0, topPad: CGFloat = 0, bottomPad: CGFloat = 0, safeArea: Bool = false) {
1515
self.translatesAutoresizingMaskIntoConstraints = false
1616
other.translatesAutoresizingMaskIntoConstraints = false
17+
let layoutGuide = safeArea ? other.safeAreaLayoutGuide : other.layoutMarginsGuide
1718
NSLayoutConstraint.activate([
18-
leadingAnchor.constraint(equalTo: other.leadingAnchor, constant: leadingPad),
19-
trailingAnchor.constraint(equalTo: other.trailingAnchor, constant: -trailingPad),
20-
topAnchor.constraint(equalTo: other.topAnchor, constant: topPad),
21-
bottomAnchor.constraint(equalTo: other.bottomAnchor, constant: -bottomPad)
19+
leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor, constant: leadingPad),
20+
trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor, constant: -trailingPad),
21+
topAnchor.constraint(equalTo: layoutGuide.topAnchor, constant: topPad),
22+
bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor, constant: -bottomPad)
2223
])
2324
}
2425
}

0 commit comments

Comments
 (0)