From 2400352972abaa4ea5e7f8dbd0f73d4c2171e6d9 Mon Sep 17 00:00:00 2001 From: Dhiogo Ramos Brustolin Date: Tue, 18 Apr 2023 11:57:20 +0200 Subject: [PATCH 01/17] refactor sample --- .../iOS-Swift.xcodeproj/project.pbxproj | 12 + Samples/iOS-Swift/iOS-Swift/AppDelegate.swift | 16 + .../iOS-Swift/Base.lproj/Main.storyboard | 773 ++++++++++-------- .../iOS-Swift/ErrorsViewController.swift | 111 +++ .../iOS-Swift/ExtraViewController.swift | 234 ++++++ .../iOS-Swift/iOS-Swift/ViewController.swift | 326 -------- .../iOS-SwiftUITests/LaunchUITests.swift | 7 +- .../iOS13-Swift/Base.lproj/Main.storyboard | 47 +- 8 files changed, 818 insertions(+), 708 deletions(-) create mode 100644 Samples/iOS-Swift/iOS-Swift/ErrorsViewController.swift create mode 100644 Samples/iOS-Swift/iOS-Swift/ExtraViewController.swift diff --git a/Samples/iOS-Swift/iOS-Swift.xcodeproj/project.pbxproj b/Samples/iOS-Swift/iOS-Swift.xcodeproj/project.pbxproj index 06cb82bfc36..ab9cf31f787 100644 --- a/Samples/iOS-Swift/iOS-Swift.xcodeproj/project.pbxproj +++ b/Samples/iOS-Swift/iOS-Swift.xcodeproj/project.pbxproj @@ -36,6 +36,10 @@ 84FB812A284001B800F3A94A /* SentryBenchmarking.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84FB8129284001B800F3A94A /* SentryBenchmarking.mm */; }; 84FB812B284001B800F3A94A /* SentryBenchmarking.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84FB8129284001B800F3A94A /* SentryBenchmarking.mm */; }; 8E8C57AF25EF16E6001CEEFA /* TraceTestViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E8C57AE25EF16E6001CEEFA /* TraceTestViewController.swift */; }; + D80D021329EE93630084393D /* ErrorsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D80D021229EE93630084393D /* ErrorsViewController.swift */; }; + D80D021A29EE936F0084393D /* ExtraViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D80D021929EE936F0084393D /* ExtraViewController.swift */; }; + D80D021B29EE9E3D0084393D /* ErrorsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D80D021229EE93630084393D /* ErrorsViewController.swift */; }; + D80D021C29EE9E400084393D /* ExtraViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D80D021929EE936F0084393D /* ExtraViewController.swift */; }; D8105B61297E824C00299F03 /* SentrySwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D8105B5C297E792200299F03 /* SentrySwiftUI.framework */; }; D8105B62297E824C00299F03 /* SentrySwiftUI.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D8105B5C297E792200299F03 /* SentrySwiftUI.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; D8269A3C274C095E00BD5BD5 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8269A3B274C095E00BD5BD5 /* AppDelegate.swift */; }; @@ -293,6 +297,8 @@ 84FB8129284001B800F3A94A /* SentryBenchmarking.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SentryBenchmarking.mm; sourceTree = ""; }; 84FB812C2840021B00F3A94A /* iOS-Swift-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "iOS-Swift-Bridging-Header.h"; sourceTree = ""; }; 8E8C57AE25EF16E6001CEEFA /* TraceTestViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TraceTestViewController.swift; sourceTree = ""; }; + D80D021229EE93630084393D /* ErrorsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorsViewController.swift; sourceTree = ""; }; + D80D021929EE936F0084393D /* ExtraViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtraViewController.swift; sourceTree = ""; }; D8269A39274C095E00BD5BD5 /* iOS13-Swift.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "iOS13-Swift.app"; sourceTree = BUILT_PRODUCTS_DIR; }; D8269A3B274C095E00BD5BD5 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; D8269A3D274C095E00BD5BD5 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -442,6 +448,8 @@ 63F93AA9245AC91600A500DB /* iOS-Swift.entitlements */, 637AFDA9243B02760034958B /* AppDelegate.swift */, 637AFDAD243B02760034958B /* ViewController.swift */, + D80D021229EE93630084393D /* ErrorsViewController.swift */, + D80D021929EE936F0084393D /* ExtraViewController.swift */, 637AFDAF243B02760034958B /* Main.storyboard */, 637AFDB2243B02770034958B /* Assets.xcassets */, 7B3427F725876A5200056519 /* Tongariro.jpg */, @@ -876,11 +884,13 @@ 84FB812A284001B800F3A94A /* SentryBenchmarking.mm in Sources */, D8F3D052274E572F00B56F8C /* DSNStorage.swift in Sources */, D8F3D054274E572F00B56F8C /* RandomErrors.swift in Sources */, + D80D021329EE93630084393D /* ErrorsViewController.swift in Sources */, D8D7BB4C2750095800044146 /* UIViewExtension.swift in Sources */, 7B79000429028C7300A7F467 /* MetricKitManager.swift in Sources */, D8D7BB4A2750067900044146 /* UIAssert.swift in Sources */, D8F3D057274E574200B56F8C /* LoremIpsumViewController.swift in Sources */, D8DBDA78274D5FC400007380 /* SplitViewController.swift in Sources */, + D80D021A29EE936F0084393D /* ExtraViewController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -927,11 +937,13 @@ D8F3D055274E572F00B56F8C /* RandomErrors.swift in Sources */, 0AAAB8572887F7C60011845C /* PermissionsViewController.swift in Sources */, D8269A3C274C095E00BD5BD5 /* AppDelegate.swift in Sources */, + D80D021B29EE9E3D0084393D /* ErrorsViewController.swift in Sources */, D8444E53275F792A0042F4DE /* UIAssert.swift in Sources */, D8269A3E274C095E00BD5BD5 /* SceneDelegate.swift in Sources */, D8444E54275F794D0042F4DE /* SpanObserver.swift in Sources */, D8269A55274C0F9A00BD5BD5 /* TraceTestViewController.swift in Sources */, D88E666828732AE000153425 /* PerformanceViewController.swift in Sources */, + D80D021C29EE9E400084393D /* ExtraViewController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Samples/iOS-Swift/iOS-Swift/AppDelegate.swift b/Samples/iOS-Swift/iOS-Swift/AppDelegate.swift index 2890126b793..e7d3261aad7 100644 --- a/Samples/iOS-Swift/iOS-Swift/AppDelegate.swift +++ b/Samples/iOS-Swift/iOS-Swift/AppDelegate.swift @@ -47,6 +47,22 @@ class AppDelegate: UIResponder, UIApplicationDelegate { let httpStatusCodeRange = HttpStatusCodeRange(min: 400, max: 599) options.failedRequestStatusCodes = [ httpStatusCodeRange ] } + + SentrySDK.configureScope { (scope) in + scope.setEnvironment("debug") + scope.setTag(value: "swift", key: "language") + + let user = User(userId: "1") + user.email = "tony@example.com" + scope.setUser(user) + + if let path = Bundle.main.path(forResource: "Tongariro", ofType: "jpg") { + scope.addAttachment(Attachment(path: path, filename: "Tongariro.jpg", contentType: "image/jpeg")) + } + if let data = "hello".data(using: .utf8) { + scope.addAttachment(Attachment(data: data, filename: "log.txt")) + } + } } func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { diff --git a/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard b/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard index de2b4d2a987..e3e6e9a4e52 100644 --- a/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard +++ b/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard @@ -1,9 +1,9 @@ - + - + @@ -17,329 +17,122 @@ - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - + + - - - - - - + + - - + + + + - @@ -347,25 +140,16 @@ - - - - + + + - - - - - - - - - + @@ -376,7 +160,7 @@ - + @@ -397,7 +181,7 @@ - + @@ -413,7 +197,7 @@ - + @@ -443,7 +227,7 @@ - + @@ -452,7 +236,7 @@ - + @@ -465,7 +249,7 @@ - + @@ -480,7 +264,7 @@ - + @@ -497,7 +281,7 @@ - + @@ -516,23 +300,334 @@ - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Samples/iOS-Swift/iOS-Swift/ErrorsViewController.swift b/Samples/iOS-Swift/iOS-Swift/ErrorsViewController.swift new file mode 100644 index 00000000000..6fffc2c1a5c --- /dev/null +++ b/Samples/iOS-Swift/iOS-Swift/ErrorsViewController.swift @@ -0,0 +1,111 @@ +import Foundation +import UIKit +import Sentry + +class ErrorsViewController : UIViewController { + + private let dispatchQueue = DispatchQueue(label: "ErrorsViewController", attributes: .concurrent) + private let diskWriteException = DiskWriteException() + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + SentrySDK.reportFullyDisplayed() + } + + @IBAction func diskWriteException(_ sender: UIButton) { + highlightButton(sender) + diskWriteException.continuouslyWriteToDisk() + + // As we are writing to disk continuously we would keep adding spans to this UIEventTransaction. + SentrySDK.span?.finish() + } + + @IBAction func crash(_ sender: UIButton) { + SentrySDK.crash() + } + + // swiftlint:disable force_unwrapping + @IBAction func unwrapCrash(_ sender: UIButton) { + highlightButton(sender) + let a: String! = nil + let b: String = a! + print(b) + } + // swiftlint:enable force_unwrapping + + @IBAction func asyncCrash(_ sender: UIButton) { + highlightButton(sender) + DispatchQueue.main.async { + self.asyncCrash1() + } + } + + @IBAction func captureError(_ sender: UIButton) { + highlightButton(sender) + do { + try RandomErrorGenerator.generate() + } catch { + SentrySDK.capture(error: error) { (scope) in + // Changes in here will only be captured for this event + // The scope in this callback is a clone of the current scope + // It contains all data but mutations only influence the event being sent + scope.setTag(value: "value", key: "myTag") + } + } + } + + @IBAction func captureNSException(_ sender: UIButton) { + highlightButton(sender) + let exception = NSException(name: NSExceptionName("My Custom exeption"), reason: "User clicked the button", userInfo: nil) + let scope = Scope() + scope.setLevel(.fatal) + // !!!: By explicity just passing the scope, only the data in this scope object will be added to the event; the global scope (calls to configureScope) will be ignored. If you do that, be careful–a lot of useful info is lost. If you just want to mutate what's in the scope use the callback, see: captureError. + SentrySDK.capture(exception: exception, scope: scope) + } + + @IBAction func captureFatalError(_ sender: UIButton) { + highlightButton(sender) + fatalError("This is a fatal error. Oh no 😬.") + } + + func asyncCrash1() { + DispatchQueue.main.async { + self.asyncCrash2() + } + } + + func asyncCrash2() { + DispatchQueue.main.async { + SentrySDK.crash() + } + } + + @IBAction func oomCrash(_ sender: UIButton) { + highlightButton(sender) + DispatchQueue.main.async { + let megaByte = 1_024 * 1_024 + let memoryPageSize = NSPageSize() + let memoryPages = megaByte / memoryPageSize + + while true { + // Allocate one MB and set one element of each memory page to something. + let ptr = UnsafeMutablePointer.allocate(capacity: megaByte) + for i in 0.. Double { + var denominator = 1.0 + var pi = 0.0 + + for i in 0..<10_000_000 { + if i % 2 == 0 { + pi += 4 / denominator + } else { + pi -= 4 / denominator + } + + denominator += 2 + } + + return pi + } + + func highlightButton(_ sender: UIButton) { + let originalLayerColor = sender.layer.backgroundColor + let originalTitleColor = sender.titleColor(for: .normal) + sender.layer.backgroundColor = UIColor.blue.cgColor + sender.setTitleColor(.white, for: .normal) + DispatchQueue.main.asyncAfter(deadline: .now() + 1) { + sender.layer.backgroundColor = originalLayerColor + sender.setTitleColor(originalTitleColor, for: .normal) + sender.titleLabel?.textColor = originalTitleColor + } + } +} diff --git a/Samples/iOS-Swift/iOS-Swift/ViewController.swift b/Samples/iOS-Swift/iOS-Swift/ViewController.swift index 01854a3b04b..6bb5b96c16f 100644 --- a/Samples/iOS-Swift/iOS-Swift/ViewController.swift +++ b/Samples/iOS-Swift/iOS-Swift/ViewController.swift @@ -2,99 +2,8 @@ import Sentry import UIKit class ViewController: UIViewController { - - @IBOutlet weak var dsnTextField: UITextField! - @IBOutlet weak var anrFullyBlockingButton: UIButton! - @IBOutlet weak var anrFillingRunLoopButton: UIButton! - @IBOutlet weak var framesLabel: UILabel! - @IBOutlet weak var breadcrumbLabel: UILabel! - @IBOutlet weak var uiTestNameLabel: UILabel! private let dispatchQueue = DispatchQueue(label: "ViewController", attributes: .concurrent) - private let diskWriteException = DiskWriteException() - - override func viewDidLoad() { - super.viewDidLoad() - - // Do any additional setup after loading the view. - SentrySDK.configureScope { (scope) in - scope.setEnvironment("debug") - scope.setTag(value: "swift", key: "language") - scope.setExtra(value: String(describing: self), key: "currentViewController") - - let user = User(userId: "1") - user.email = "tony@example.com" - scope.setUser(user) - - if let path = Bundle.main.path(forResource: "Tongariro", ofType: "jpg") { - scope.addAttachment(Attachment(path: path, filename: "Tongariro.jpg", contentType: "image/jpeg")) - } - if let data = "hello".data(using: .utf8) { - scope.addAttachment(Attachment(data: data, filename: "log.txt")) - } - } - - // Also works - let user = User(userId: "1") - user.email = "tony1@example.com" - SentrySDK.setUser(user) - - dispatchQueue.async { - let dsn = DSNStorage.shared.getDSN() - - DispatchQueue.main.async { - self.dsnTextField.text = dsn - self.dsnTextField.backgroundColor = UIColor.systemGreen - } - } - - if let uiTestName = ProcessInfo.processInfo.environment["io.sentry.ui-test.test-name"] { - uiTestNameLabel.text = uiTestName - } - } - - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - SentrySDK.reportFullyDisplayed() - } - - override func viewDidAppear(_ animated: Bool) { - super.viewDidAppear(animated) - - Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { _ in - self.framesLabel?.text = "Frames Total:\(PrivateSentrySDKOnly.currentScreenFrames.total) Slow:\(PrivateSentrySDKOnly.currentScreenFrames.slow) Frozen:\(PrivateSentrySDKOnly.currentScreenFrames.frozen)" - } - - SentrySDK.configureScope { (scope) in - let dict = scope.serialize() - - guard - let crumbs = dict["breadcrumbs"] as? [[String: Any]], - let breadcrumb = crumbs.last, - let data = breadcrumb["data"] as? [String: String] - else { - return - } - - self.breadcrumbLabel?.text = "{ category: \(breadcrumb["category"] ?? "nil"), parentViewController: \(data["parentViewController"] ?? "nil"), beingPresented: \(data["beingPresented"] ?? "nil"), window_isKeyWindow: \(data["window_isKeyWindow"] ?? "nil"), is_window_rootViewController: \(data["is_window_rootViewController"] ?? "nil") }" - } - } - - @IBAction func addBreadcrumb(_ sender: UIButton) { - highlightButton(sender) - let crumb = Breadcrumb(level: SentryLevel.info, category: "Debug") - crumb.message = "tapped addBreadcrumb" - crumb.type = "user" - SentrySDK.addBreadcrumb(crumb) - } - - @IBAction func captureMessage(_ sender: UIButton) { - highlightButton(sender) - let eventId = SentrySDK.capture(message: "Yeah captured a message") - // Returns eventId in case of successfull processed event - // otherwise nil - print("\(String(describing: eventId))") - } @IBAction func uiClickTransaction(_ sender: UIButton) { highlightButton(sender) @@ -111,49 +20,6 @@ class ViewController: UIViewController { let dataTask = session.dataTask(with: imgUrl) { (_, _, _) in } dataTask.resume() } - - @IBAction func captureUserFeedback(_ sender: UIButton) { - highlightButton(sender) - let error = NSError(domain: "UserFeedbackErrorDomain", code: 0, userInfo: [NSLocalizedDescriptionKey: "This never happens."]) - - let eventId = SentrySDK.capture(error: error) { scope in - scope.setLevel(.fatal) - } - - let userFeedback = UserFeedback(eventId: eventId) - userFeedback.comments = "It broke on iOS-Swift. I don't know why, but this happens." - userFeedback.email = "john@me.com" - userFeedback.name = "John Me" - SentrySDK.capture(userFeedback: userFeedback) - } - - @IBAction func captureError(_ sender: UIButton) { - highlightButton(sender) - do { - try RandomErrorGenerator.generate() - } catch { - SentrySDK.capture(error: error) { (scope) in - // Changes in here will only be captured for this event - // The scope in this callback is a clone of the current scope - // It contains all data but mutations only influence the event being sent - scope.setTag(value: "value", key: "myTag") - } - } - } - - @IBAction func captureNSException(_ sender: UIButton) { - highlightButton(sender) - let exception = NSException(name: NSExceptionName("My Custom exeption"), reason: "User clicked the button", userInfo: nil) - let scope = Scope() - scope.setLevel(.fatal) - // !!!: By explicity just passing the scope, only the data in this scope object will be added to the event; the global scope (calls to configureScope) will be ignored. If you do that, be careful–a lot of useful info is lost. If you just want to mutate what's in the scope use the callback, see: captureError. - SentrySDK.capture(exception: exception, scope: scope) - } - - @IBAction func captureFatalError(_ sender: UIButton) { - highlightButton(sender) - fatalError("This is a fatal error. Oh no 😬.") - } var span: Span? let profilerNotification = NSNotification.Name("SentryProfileCompleteNotification") @@ -204,177 +70,7 @@ class ViewController: UIViewController { transaction.finish() }) } - - @IBAction func crash(_ sender: UIButton) { - SentrySDK.crash() - } - // swiftlint:disable force_unwrapping - @IBAction func unwrapCrash(_ sender: UIButton) { - highlightButton(sender) - let a: String! = nil - let b: String = a! - print(b) - } - // swiftlint:enable force_unwrapping - - @IBAction func asyncCrash(_ sender: UIButton) { - highlightButton(sender) - DispatchQueue.main.async { - self.asyncCrash1() - } - } - - func asyncCrash1() { - DispatchQueue.main.async { - self.asyncCrash2() - } - } - - func asyncCrash2() { - DispatchQueue.main.async { - SentrySDK.crash() - } - } - - @IBAction func oomCrash(_ sender: UIButton) { - highlightButton(sender) - DispatchQueue.main.async { - let megaByte = 1_024 * 1_024 - let memoryPageSize = NSPageSize() - let memoryPages = megaByte / memoryPageSize - - while true { - // Allocate one MB and set one element of each memory page to something. - let ptr = UnsafeMutablePointer.allocate(capacity: megaByte) - for i in 0.. Double { - var denominator = 1.0 - var pi = 0.0 - - for i in 0..<10_000_000 { - if i % 2 == 0 { - pi += 4 / denominator - } else { - pi -= 4 / denominator - } - - denominator += 2 - } - - return pi - } - - @IBAction func anrFullyBlocking(_ sender: UIButton) { - highlightButton(sender) - let buttonTitle = self.anrFullyBlockingButton.currentTitle - var i = 0 - - for _ in 0...5_000_000 { - i += Int.random(in: 0...10) - i -= 1 - - self.anrFullyBlockingButton.setTitle("\(i)", for: .normal) - } - - self.anrFullyBlockingButton.setTitle(buttonTitle, for: .normal) - } - - @IBAction func anrFillingRunLoop(_ sender: UIButton) { - highlightButton(sender) - let buttonTitle = self.anrFillingRunLoopButton.currentTitle - var i = 0 - - func sleep(timeout: Double) { - let group = DispatchGroup() - group.enter() - let queue = DispatchQueue(label: "delay", qos: .background, attributes: []) - - queue.asyncAfter(deadline: .now() + timeout) { - group.leave() - } - - group.wait() - } - - dispatchQueue.async { - for _ in 0...30 { - i += Int.random(in: 0...10) - i -= 1 - - DispatchQueue.main.async { - sleep(timeout: 0.1) - self.anrFillingRunLoopButton.setTitle("Title \(i)", for: .normal) - } - } - - DispatchQueue.main.sync { - self.anrFillingRunLoopButton.setTitle(buttonTitle, for: .normal) - } - } - } - - @IBAction func dsnChanged(_ sender: UITextField) { - let options = Options() - options.dsn = sender.text - - if let dsn = options.dsn { - sender.backgroundColor = UIColor.systemGreen - - dispatchQueue.async { - DSNStorage.shared.saveDSN(dsn: dsn) - } - } else { - sender.backgroundColor = UIColor.systemRed - - dispatchQueue.async { - DSNStorage.shared.deleteDSN() - } - } - } - - @IBAction func resetDSN(_ sender: UIButton) { - highlightButton(sender) - self.dsnTextField.text = AppDelegate.defaultDSN - self.dsnTextField.backgroundColor = UIColor.systemGreen - - dispatchQueue.async { - DSNStorage.shared.saveDSN(dsn: AppDelegate.defaultDSN) - } - } - @IBAction func showNibController(_ sender: UIButton) { highlightButton(sender) let nib = NibViewController() @@ -403,28 +99,6 @@ class ViewController: UIViewController { navigationController?.pushViewController(controller, animated: false) } - @IBAction func permissions(_ sender: UIButton) { - highlightButton(sender) - let controller = PermissionsViewController() - controller.title = "Permissions" - navigationController?.pushViewController(controller, animated: true) - } - - @IBAction func flush(_ sender: UIButton) { - highlightButton(sender) - SentrySDK.flush(timeout: 5) - } - - @IBAction func close(_ sender: UIButton) { - highlightButton(sender) - SentrySDK.close() - } - - @IBAction func startSDK(_ sender: UIButton) { - highlightButton(sender) - AppDelegate.startSentry() - } - func highlightButton(_ sender: UIButton) { let originalLayerColor = sender.layer.backgroundColor let originalTitleColor = sender.titleColor(for: .normal) diff --git a/Samples/iOS-Swift/iOS-SwiftUITests/LaunchUITests.swift b/Samples/iOS-Swift/iOS-SwiftUITests/LaunchUITests.swift index 25fa4ccee8a..3121ef81f60 100644 --- a/Samples/iOS-Swift/iOS-SwiftUITests/LaunchUITests.swift +++ b/Samples/iOS-Swift/iOS-SwiftUITests/LaunchUITests.swift @@ -11,7 +11,6 @@ class LaunchUITests: XCTestCase { app.launch() waitForExistenceOfMainScreen() - checkSlowAndFrozenFrames() } override func tearDown() { @@ -19,7 +18,7 @@ class LaunchUITests: XCTestCase { super.tearDown() } - func testCrashRecovery() { + func atestCrashRecovery() { //We will be removing this test from iOS 12 because it fails during CI, which looks like a bug that we cannot reproduce. //If we introduce a bug in the crash report process we will catch it with tests for iOS 13 or above. //For some reason is not possible to use @available(iOS 13, *) in the test function. @@ -35,6 +34,8 @@ class LaunchUITests: XCTestCase { } func testBreadcrumbData() { + XCUIApplication().tabBars["Tab Bar"].buttons["Extra"].tap() + let breadcrumbLabel = app.staticTexts["breadcrumbLabel"] breadcrumbLabel.waitForExistence("Breadcrumb label not found.") XCTAssertEqual(breadcrumbLabel.label, "{ category: ui.lifecycle, parentViewController: UINavigationController, beingPresented: false, window_isKeyWindow: true, is_window_rootViewController: false }") @@ -90,7 +91,7 @@ class LaunchUITests: XCTestCase { private extension LaunchUITests { func waitForExistenceOfMainScreen() { - app.buttons["captureMessageButton"].waitForExistence( "Home Screen doesn't exist.") + app.tabBars["Tab Bar"].waitForExistence( "Home Screen doesn't exist.") } func checkSlowAndFrozenFrames() { diff --git a/Samples/iOS-Swift/iOS13-Swift/Base.lproj/Main.storyboard b/Samples/iOS-Swift/iOS13-Swift/Base.lproj/Main.storyboard index 4bfb9c2963a..5635755e5d5 100644 --- a/Samples/iOS-Swift/iOS13-Swift/Base.lproj/Main.storyboard +++ b/Samples/iOS-Swift/iOS13-Swift/Base.lproj/Main.storyboard @@ -1,9 +1,9 @@ - + - + @@ -18,13 +18,13 @@ - + - - - - - - - - - - - - - - - - @@ -152,9 +122,6 @@ - - - @@ -185,7 +152,7 @@ - + @@ -211,16 +178,16 @@ - - + + From 3d13b8cde1247e59f5ec4cacca3f89a1bb6e6e14 Mon Sep 17 00:00:00 2001 From: Dhiogo Ramos Brustolin Date: Tue, 18 Apr 2023 14:27:57 +0200 Subject: [PATCH 02/17] fix tests --- .../iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard | 1 + .../iOS-Swift/iOS-Swift/ExtraViewController.swift | 3 +++ Samples/iOS-Swift/iOS-Swift/ViewController.swift | 8 +++++++- .../iOS-Swift/iOS-SwiftUITests/LaunchUITests.swift | 13 ++++++++++++- .../iOS-SwiftUITests/ProfilingUITests.swift | 4 ++++ 5 files changed, 27 insertions(+), 2 deletions(-) diff --git a/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard b/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard index e3e6e9a4e52..ef25803d5df 100644 --- a/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard +++ b/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard @@ -623,6 +623,7 @@ + diff --git a/Samples/iOS-Swift/iOS-Swift/ExtraViewController.swift b/Samples/iOS-Swift/iOS-Swift/ExtraViewController.swift index 4959df1fd3d..8e45bbb0946 100644 --- a/Samples/iOS-Swift/iOS-Swift/ExtraViewController.swift +++ b/Samples/iOS-Swift/iOS-Swift/ExtraViewController.swift @@ -34,6 +34,8 @@ class ExtraViewController : UIViewController { Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { _ in self.framesLabel?.text = "Frames Total:\(PrivateSentrySDKOnly.currentScreenFrames.total) Slow:\(PrivateSentrySDKOnly.currentScreenFrames.slow) Frozen:\(PrivateSentrySDKOnly.currentScreenFrames.frozen)" } + + SentrySDK.reportFullyDisplayed() } override func viewDidAppear(_ animated: Bool) { @@ -51,6 +53,7 @@ class ExtraViewController : UIViewController { } self.breadcrumbLabel?.text = "{ category: \(breadcrumb["category"] ?? "nil"), parentViewController: \(data["parentViewController"] ?? "nil"), beingPresented: \(data["beingPresented"] ?? "nil"), window_isKeyWindow: \(data["window_isKeyWindow"] ?? "nil"), is_window_rootViewController: \(data["is_window_rootViewController"] ?? "nil") }" + } } diff --git a/Samples/iOS-Swift/iOS-Swift/ViewController.swift b/Samples/iOS-Swift/iOS-Swift/ViewController.swift index 6bb5b96c16f..a027aa46195 100644 --- a/Samples/iOS-Swift/iOS-Swift/ViewController.swift +++ b/Samples/iOS-Swift/iOS-Swift/ViewController.swift @@ -4,7 +4,13 @@ import UIKit class ViewController: UIViewController { private let dispatchQueue = DispatchQueue(label: "ViewController", attributes: .concurrent) - + + + override func viewDidLoad() { + super.viewDidLoad() + SentrySDK.reportFullyDisplayed() + } + @IBAction func uiClickTransaction(_ sender: UIButton) { highlightButton(sender) dispatchQueue.async { diff --git a/Samples/iOS-Swift/iOS-SwiftUITests/LaunchUITests.swift b/Samples/iOS-Swift/iOS-SwiftUITests/LaunchUITests.swift index 3121ef81f60..422ac35d88c 100644 --- a/Samples/iOS-Swift/iOS-SwiftUITests/LaunchUITests.swift +++ b/Samples/iOS-Swift/iOS-SwiftUITests/LaunchUITests.swift @@ -38,27 +38,31 @@ class LaunchUITests: XCTestCase { let breadcrumbLabel = app.staticTexts["breadcrumbLabel"] breadcrumbLabel.waitForExistence("Breadcrumb label not found.") - XCTAssertEqual(breadcrumbLabel.label, "{ category: ui.lifecycle, parentViewController: UINavigationController, beingPresented: false, window_isKeyWindow: true, is_window_rootViewController: false }") + XCTAssertEqual(breadcrumbLabel.label, "{ category: ui.lifecycle, parentViewController: UITabBarController, beingPresented: false, window_isKeyWindow: true, is_window_rootViewController: false }") } func testLoremIpsum() { + XCUIApplication().tabBars["Tab Bar"].buttons["Transactions"].tap() app.buttons["loremIpsumButton"].tap() app.textViews.firstMatch.waitForExistence("Lorem Ipsum not loaded.") } func testNavigationTransaction() { + XCUIApplication().tabBars["Tab Bar"].buttons["Transactions"].tap() app.buttons["testNavigationTransactionButton"].tap() app.images.firstMatch.waitForExistence("Navigation transaction not loaded.") assertApp() } func testShowNib() { + XCUIApplication().tabBars["Tab Bar"].buttons["Transactions"].tap() app.buttons["showNibButton"].tap() app.buttons["lonelyButton"].waitForExistence("Nib ViewController not loaded.") assertApp() } func testUiClickTransaction() { + XCUIApplication().tabBars["Tab Bar"].buttons["Transactions"].tap() app.buttons["uiClickTransactionButton"].tap() } @@ -71,12 +75,14 @@ class LaunchUITests: XCTestCase { } func testShowTableView() { + XCUIApplication().tabBars["Tab Bar"].buttons["Transactions"].tap() app.buttons["showTableViewButton"].tap() app.navigationBars.buttons.element(boundBy: 0).waitForExistence("TableView not loaded.") assertApp() } func testSplitView() { + XCUIApplication().tabBars["Tab Bar"].buttons["Transactions"].tap() app.buttons["showSplitViewButton"].tap() let app = XCUIApplication() @@ -87,6 +93,11 @@ class LaunchUITests: XCTestCase { assertApp() } } + + func testCheckSlowAndFrozenFrames() { + XCUIApplication().tabBars["Tab Bar"].buttons["Extra"].tap() + checkSlowAndFrozenFrames() + } } private extension LaunchUITests { diff --git a/Samples/iOS-Swift/iOS-SwiftUITests/ProfilingUITests.swift b/Samples/iOS-Swift/iOS-SwiftUITests/ProfilingUITests.swift index 8bb550d8e3e..e283722948d 100644 --- a/Samples/iOS-Swift/iOS-SwiftUITests/ProfilingUITests.swift +++ b/Samples/iOS-Swift/iOS-SwiftUITests/ProfilingUITests.swift @@ -20,10 +20,14 @@ final class ProfilingUITests: XCTestCase { throw XCTSkip("Only run on iOS 15 and above.") } + XCUIApplication().tabBars["Tab Bar"].buttons["Transactions"].tap() app.buttons["Start transaction"].afterWaitingForExistence("Couldn't find button to start transaction").tap() + XCUIApplication().tabBars["Tab Bar"].buttons["Extra"].tap() app.buttons["ANR filling run loop"].afterWaitingForExistence("Couldn't find button to ANR").tap() + XCUIApplication().tabBars["Tab Bar"].buttons["Transactions"].tap() app.buttons["Stop transaction"].afterWaitingForExistence("Couldn't find button to end transaction").tap() + XCUIApplication().tabBars["Tab Bar"].buttons["Extra"].tap() let textField = app.textFields["io.sentry.ui-tests.profile-marshaling-text-field"] textField.waitForExistence("Couldn't find profile marshaling text field.") From e0181af815d8c1a40a7aa6f9eda011e827e0eed0 Mon Sep 17 00:00:00 2001 From: Sentry Github Bot Date: Tue, 18 Apr 2023 12:36:11 +0000 Subject: [PATCH 03/17] Format code --- Samples/iOS-Swift/iOS-Swift/ErrorsViewController.swift | 4 ++-- Samples/iOS-Swift/iOS-Swift/ExtraViewController.swift | 4 ++-- Samples/iOS-Swift/iOS-Swift/ViewController.swift | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Samples/iOS-Swift/iOS-Swift/ErrorsViewController.swift b/Samples/iOS-Swift/iOS-Swift/ErrorsViewController.swift index 6fffc2c1a5c..33d04789fcd 100644 --- a/Samples/iOS-Swift/iOS-Swift/ErrorsViewController.swift +++ b/Samples/iOS-Swift/iOS-Swift/ErrorsViewController.swift @@ -1,8 +1,8 @@ import Foundation -import UIKit import Sentry +import UIKit -class ErrorsViewController : UIViewController { +class ErrorsViewController: UIViewController { private let dispatchQueue = DispatchQueue(label: "ErrorsViewController", attributes: .concurrent) private let diskWriteException = DiskWriteException() diff --git a/Samples/iOS-Swift/iOS-Swift/ExtraViewController.swift b/Samples/iOS-Swift/iOS-Swift/ExtraViewController.swift index 8e45bbb0946..727ef81fd79 100644 --- a/Samples/iOS-Swift/iOS-Swift/ExtraViewController.swift +++ b/Samples/iOS-Swift/iOS-Swift/ExtraViewController.swift @@ -1,8 +1,8 @@ import Foundation -import UIKit import Sentry +import UIKit -class ExtraViewController : UIViewController { +class ExtraViewController: UIViewController { @IBOutlet weak var dsnTextField: UITextField! @IBOutlet weak var framesLabel: UILabel! diff --git a/Samples/iOS-Swift/iOS-Swift/ViewController.swift b/Samples/iOS-Swift/iOS-Swift/ViewController.swift index a027aa46195..11290c1767f 100644 --- a/Samples/iOS-Swift/iOS-Swift/ViewController.swift +++ b/Samples/iOS-Swift/iOS-Swift/ViewController.swift @@ -5,7 +5,6 @@ class ViewController: UIViewController { private let dispatchQueue = DispatchQueue(label: "ViewController", attributes: .concurrent) - override func viewDidLoad() { super.viewDidLoad() SentrySDK.reportFullyDisplayed() From c5304d8b868f7d0675cf2070990d510f991dcab3 Mon Sep 17 00:00:00 2001 From: Dhiogo Ramos Brustolin Date: Tue, 18 Apr 2023 14:52:22 +0200 Subject: [PATCH 04/17] Update SentrySDKPerformanceBenchmarkTests.m --- .../PerformanceBenchmarks/SentrySDKPerformanceBenchmarkTests.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Samples/iOS-Swift/PerformanceBenchmarks/SentrySDKPerformanceBenchmarkTests.m b/Samples/iOS-Swift/PerformanceBenchmarks/SentrySDKPerformanceBenchmarkTests.m index ee91ecf7bfc..ad1fc1c0c8b 100644 --- a/Samples/iOS-Swift/PerformanceBenchmarks/SentrySDKPerformanceBenchmarkTests.m +++ b/Samples/iOS-Swift/PerformanceBenchmarks/SentrySDKPerformanceBenchmarkTests.m @@ -18,6 +18,8 @@ - (void)testCPUBenchmark app.launchArguments = [app.launchArguments arrayByAddingObject:@"--io.sentry.test.benchmarking"]; [app launch]; + [app.tabBars[@"Tab Bar"].buttons[@"Transactions"] tap]; + [app.buttons[@"Performance scenarios"] tap]; // after navigating to the test, the test app will do CPU intensive work until hitting the From 696aff4588605bcc88e9c1e5ef10624201455175 Mon Sep 17 00:00:00 2001 From: Dhiogo Ramos Brustolin Date: Tue, 18 Apr 2023 15:56:19 +0200 Subject: [PATCH 05/17] Update ProfilingUITests.swift --- Samples/iOS-Swift/iOS-SwiftUITests/ProfilingUITests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Samples/iOS-Swift/iOS-SwiftUITests/ProfilingUITests.swift b/Samples/iOS-Swift/iOS-SwiftUITests/ProfilingUITests.swift index e283722948d..46f2c6869be 100644 --- a/Samples/iOS-Swift/iOS-SwiftUITests/ProfilingUITests.swift +++ b/Samples/iOS-Swift/iOS-SwiftUITests/ProfilingUITests.swift @@ -20,6 +20,7 @@ final class ProfilingUITests: XCTestCase { throw XCTSkip("Only run on iOS 15 and above.") } + XCUIApplication().tabBars["Tab Bar"].buttons["Extra"].tap() XCUIApplication().tabBars["Tab Bar"].buttons["Transactions"].tap() app.buttons["Start transaction"].afterWaitingForExistence("Couldn't find button to start transaction").tap() XCUIApplication().tabBars["Tab Bar"].buttons["Extra"].tap() @@ -27,7 +28,6 @@ final class ProfilingUITests: XCTestCase { XCUIApplication().tabBars["Tab Bar"].buttons["Transactions"].tap() app.buttons["Stop transaction"].afterWaitingForExistence("Couldn't find button to end transaction").tap() - XCUIApplication().tabBars["Tab Bar"].buttons["Extra"].tap() let textField = app.textFields["io.sentry.ui-tests.profile-marshaling-text-field"] textField.waitForExistence("Couldn't find profile marshaling text field.") From 9edcad5b2bd84e3fa5affa28b43c9c391b33a48d Mon Sep 17 00:00:00 2001 From: Dhiogo Ramos Brustolin Date: Tue, 18 Apr 2023 16:59:03 +0200 Subject: [PATCH 06/17] moving sample to run test with test configuration --- .../xcshareddata/xcschemes/iOS-Swift.xcscheme | 2 +- .../xcshareddata/xcschemes/iOS-SwiftUITests.xcscheme | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Samples/iOS-Swift/iOS-Swift.xcodeproj/xcshareddata/xcschemes/iOS-Swift.xcscheme b/Samples/iOS-Swift/iOS-Swift.xcodeproj/xcshareddata/xcschemes/iOS-Swift.xcscheme index 6cd297ea423..49ea355db19 100644 --- a/Samples/iOS-Swift/iOS-Swift.xcodeproj/xcshareddata/xcschemes/iOS-Swift.xcscheme +++ b/Samples/iOS-Swift/iOS-Swift.xcodeproj/xcshareddata/xcschemes/iOS-Swift.xcscheme @@ -23,7 +23,7 @@ diff --git a/Samples/iOS-Swift/iOS-Swift.xcodeproj/xcshareddata/xcschemes/iOS-SwiftUITests.xcscheme b/Samples/iOS-Swift/iOS-Swift.xcodeproj/xcshareddata/xcschemes/iOS-SwiftUITests.xcscheme index 4a5f27c25c7..55e1974867d 100644 --- a/Samples/iOS-Swift/iOS-Swift.xcodeproj/xcshareddata/xcschemes/iOS-SwiftUITests.xcscheme +++ b/Samples/iOS-Swift/iOS-Swift.xcodeproj/xcshareddata/xcschemes/iOS-SwiftUITests.xcscheme @@ -7,7 +7,7 @@ buildImplicitDependencies = "YES"> From 91e386214d4b8145e0e3a4e0036f94bd570474d9 Mon Sep 17 00:00:00 2001 From: Dhiogo Ramos Brustolin Date: Fri, 21 Apr 2023 13:38:26 +0200 Subject: [PATCH 07/17] Update SentryTests-Bridging-Header.h --- Tests/SentryTests/SentryTests-Bridging-Header.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/SentryTests/SentryTests-Bridging-Header.h b/Tests/SentryTests/SentryTests-Bridging-Header.h index 012cbcaff01..adde7f00e8d 100644 --- a/Tests/SentryTests/SentryTests-Bridging-Header.h +++ b/Tests/SentryTests/SentryTests-Bridging-Header.h @@ -199,4 +199,4 @@ # import "SentryUIEventTracker.h" # import "SentryUIEventTrackingIntegration.h" # import "SentryUIViewControllerPerformanceTracker.h" -#endif +#endif From def7319d40eba14bc75cab074052ddca8a90db35 Mon Sep 17 00:00:00 2001 From: Sentry Github Bot Date: Fri, 21 Apr 2023 11:39:48 +0000 Subject: [PATCH 08/17] Format code --- Tests/SentryTests/SentryTests-Bridging-Header.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/SentryTests/SentryTests-Bridging-Header.h b/Tests/SentryTests/SentryTests-Bridging-Header.h index adde7f00e8d..012cbcaff01 100644 --- a/Tests/SentryTests/SentryTests-Bridging-Header.h +++ b/Tests/SentryTests/SentryTests-Bridging-Header.h @@ -199,4 +199,4 @@ # import "SentryUIEventTracker.h" # import "SentryUIEventTrackingIntegration.h" # import "SentryUIViewControllerPerformanceTracker.h" -#endif +#endif From 5a97176426c66aec6ff4c09729d7eb9a904c0596 Mon Sep 17 00:00:00 2001 From: Dhiogo Brustolin Date: Mon, 24 Apr 2023 10:21:24 +0200 Subject: [PATCH 09/17] Update Samples/iOS-Swift/iOS-SwiftUITests/LaunchUITests.swift --- Samples/iOS-Swift/iOS-SwiftUITests/LaunchUITests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Samples/iOS-Swift/iOS-SwiftUITests/LaunchUITests.swift b/Samples/iOS-Swift/iOS-SwiftUITests/LaunchUITests.swift index 422ac35d88c..1f1846f087e 100644 --- a/Samples/iOS-Swift/iOS-SwiftUITests/LaunchUITests.swift +++ b/Samples/iOS-Swift/iOS-SwiftUITests/LaunchUITests.swift @@ -18,7 +18,7 @@ class LaunchUITests: XCTestCase { super.tearDown() } - func atestCrashRecovery() { + func testCrashRecovery() { //We will be removing this test from iOS 12 because it fails during CI, which looks like a bug that we cannot reproduce. //If we introduce a bug in the crash report process we will catch it with tests for iOS 13 or above. //For some reason is not possible to use @available(iOS 13, *) in the test function. From 0e0bbdd435bb0f48c784970fbaf032d2427319cb Mon Sep 17 00:00:00 2001 From: Dhiogo Ramos Brustolin Date: Tue, 25 Apr 2023 09:59:58 +0200 Subject: [PATCH 10/17] Update Main.storyboard --- .../iOS-Swift/Base.lproj/Main.storyboard | 257 +++++++++--------- 1 file changed, 125 insertions(+), 132 deletions(-) diff --git a/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard b/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard index ef25803d5df..676f1d68f70 100644 --- a/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard +++ b/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard @@ -4,6 +4,7 @@ + @@ -17,134 +18,118 @@ - - + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + - - + + - + @@ -335,7 +320,7 @@ -