diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 237d5e1aa8..c69a56eaa6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -104,6 +104,14 @@ jobs: path: | ${{ github.workspace }}/*.zip + - name: Archive build log if failed + uses: actions/upload-artifact@v3 + if: ${{ failure() || cancelled() }} + with: + name: raw-build-output-build-xcframework + path: | + build-xcframework.log + validate-xcframework: name: Validate XCFramework Xcode ${{ matrix.xcode }} runs-on: macos-12 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e9ba8a42fc..eadba7c2c9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -287,7 +287,7 @@ jobs: uses: actions/upload-artifact@v3 if: ${{ failure() || cancelled() }} with: - name: raw-test-output-${{matrix.platform}}-xcode-${{matrix.xcode}}-os-${{matrix.test-destination-os}} + name: raw-uitest-output-${{matrix.target}} path: | ~/Library/Logs/scan/*.log ./fastlane/test_output/** @@ -353,7 +353,7 @@ jobs: uses: actions/upload-artifact@v3 if: ${{ failure() || cancelled() }} with: - name: raw-test-output-${{matrix.platform}}-xcode-${{matrix.xcode}}-os-${{matrix.test-destination-os}} + name: raw-uitest-output-${{matrix.target}}-ios-12 path: | ~/Library/Logs/scan/*.log ./fastlane/test_output/** @@ -375,7 +375,7 @@ jobs: uses: actions/upload-artifact@v3 if: ${{ failure() || cancelled() }} with: - name: raw-test-output-${{matrix.platform}}-xcode-${{matrix.xcode}}-os-${{matrix.test-destination-os}} + name: raw-uitest-output-asan path: | ~/Library/Logs/scan/*.log ./fastlane/test_output/** diff --git a/.github/workflows/testflight.yml b/.github/workflows/testflight.yml index 84f35af194..9dc39892dc 100644 --- a/.github/workflows/testflight.yml +++ b/.github/workflows/testflight.yml @@ -16,8 +16,7 @@ jobs: runs-on: macos-12 steps: - uses: actions/checkout@v3 - # Xcode 14.1 has a bug with fastlane see https://github.com/fastlane/fastlane/issues/20910 - - run: ./scripts/ci-select-xcode.sh 14.0.1 + - run: ./scripts/ci-select-xcode.sh 14.2 - run: bundle install # We upload a new version to TestFlight on every commit on main diff --git a/CHANGELOG.md b/CHANGELOG.md index fdfa4b5a1d..6f0c4a93b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,15 +1,41 @@ # Changelog +## 8.3.3 + +### Fixes + +- View hierarchy not sent for crashes (#2781) +- Crash in Tracer for idle timeout (#2834) + +## 8.3.2 + +### Features + +- Add CPU core count in device context (#2814) + +### Fixes + + +- Updating AppHang state on main thread (#2793) +- App Hang report crashes with too many threads (#2811) + +### Improvements + +- Remove not needed locks in SentryUser (#2809) + ## 8.3.1 ### Fixes - Stop using UIScreen.main (#2762) - Profile timestamp alignment with transactions (#2771) and app start spans (#2772) -- Fix crash when compiling profiling data during transaction serialization (#2783) +- Fix crash when compiling profiling data during transaction serialization (#2786) ## 8.3.0 +### Important Note +This release can cause crashes when Profiling is enabled (#2779). Please update to `8.3.1`. + ### Fixes - Crash in AppHangs when no threads (#2725) diff --git a/Gemfile.lock b/Gemfile.lock index d9daed1e82..df2e418690 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,7 +3,7 @@ GEM specs: CFPropertyList (3.0.6) rexml - activesupport (7.0.4.2) + activesupport (7.0.4.3) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) diff --git a/Makefile b/Makefile index ea43494c8f..def0d43e4c 100644 --- a/Makefile +++ b/Makefile @@ -57,7 +57,7 @@ analyze: # For more info check out: https://github.com/Carthage/Carthage/releases/tag/0.38.0 build-xcframework: @echo "--> Carthage: creating Sentry xcframework" - carthage build --use-xcframeworks --no-skip-current + carthage build --use-xcframeworks --no-skip-current --verbose > build-xcframework.log # use ditto here to avoid clobbering symlinks which exist in macOS frameworks ditto -c -k -X --rsrc --keepParent Carthage Sentry.xcframework.zip diff --git a/README.md b/README.md index 171a70546b..749713dfcc 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ _Bad software is everywhere, and we're tired of it. Sentry is on a mission to help developers write better software faster, so we can get back to enjoying technology. If you want to join us [**Check out our open positions**](https://sentry.io/careers/)_ -[![Build](https://img.shields.io/github/workflow/status/getsentry/sentry-cocoa/Build%20%26%20Test)](https://github.com/getsentry/sentry-cocoa/actions?query=workflow%3A%22Build+%26+Test%22) +[![Build](https://img.shields.io/github/actions/workflow/status/getsentry/sentry-cocoa/build.yml?branch=main)](https://github.com/getsentry/sentry-cocoa/actions/workflows/build.yml?query=branch%3Amain) [![codebeat badge](https://codebeat.co/badges/07f0bc91-9102-4fd8-99a6-30b25dc98037)](https://codebeat.co/projects/github-com-getsentry-sentry-cocoa-master) [![codecov.io](https://codecov.io/gh/getsentry/sentry-cocoa/branch/master/graph/badge.svg)](https://codecov.io/gh/getsentry/sentry-cocoa) [![CocoaPods compadible](https://img.shields.io/cocoapods/v/Sentry.svg)](https://cocoapods.org/pods/Sentry) diff --git a/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard b/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard index c5caddff8b..4598c342bd 100644 --- a/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard +++ b/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard @@ -136,7 +136,7 @@ - + + @@ -424,14 +432,14 @@ - + - + diff --git a/Samples/iOS-Swift/iOS-Swift/Tools/RandomErrors.swift b/Samples/iOS-Swift/iOS-Swift/Tools/RandomErrors.swift index 7321b615a8..80e9700091 100644 --- a/Samples/iOS-Swift/iOS-Swift/Tools/RandomErrors.swift +++ b/Samples/iOS-Swift/iOS-Swift/Tools/RandomErrors.swift @@ -6,6 +6,23 @@ enum SampleError: Error { case awesomeCentaur } +extension SampleError: CustomNSError { + var errorUserInfo: [String: Any] { + func getDebugDescription() -> String { + switch self { + case SampleError.bestDeveloper: + return "bestDeveloper" + case .happyCustomer: + return "happyCustomer" + case .awesomeCentaur: + return "awesomeCentaur" + } + } + + return [NSDebugDescriptionErrorKey: getDebugDescription()] + } +} + class RandomErrorGenerator { static func generate() throws { diff --git a/Samples/iOS-Swift/iOS-Swift/ViewController.swift b/Samples/iOS-Swift/iOS-Swift/ViewController.swift index a69aed30ab..cd7f6f2031 100644 --- a/Samples/iOS-Swift/iOS-Swift/ViewController.swift +++ b/Samples/iOS-Swift/iOS-Swift/ViewController.swift @@ -216,6 +216,14 @@ class ViewController: UIViewController { } } } + + @IBAction func start100Threads(_ sender: Any) { + for _ in 0..<100 { + Thread.detachNewThread { + Thread.sleep(forTimeInterval: 10) + } + } + } private func calcPi() -> Double { var denominator = 1.0 @@ -251,18 +259,31 @@ class ViewController: UIViewController { @IBAction func anrFillingRunLoop(_ sender: Any) { 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...100_000 { + for _ in 0...30 { i += Int.random(in: 0...10) i -= 1 DispatchQueue.main.async { - self.anrFillingRunLoopButton.setTitle("Work in Progress \(i)", for: .normal) + sleep(timeout: 0.1) + self.anrFillingRunLoopButton.setTitle("Title \(i)", for: .normal) } } - DispatchQueue.main.async { + DispatchQueue.main.sync { self.anrFillingRunLoopButton.setTitle(buttonTitle, for: .normal) } } diff --git a/Samples/iOS-Swift/iOS-SwiftUITests/LaunchUITests.swift b/Samples/iOS-Swift/iOS-SwiftUITests/LaunchUITests.swift index f2f3360e78..5a3a78c4ba 100644 --- a/Samples/iOS-Swift/iOS-SwiftUITests/LaunchUITests.swift +++ b/Samples/iOS-Swift/iOS-SwiftUITests/LaunchUITests.swift @@ -11,7 +11,7 @@ class LaunchUITests: XCTestCase { XCUIDevice.shared.orientation = .portrait app.launch() - waitForExistenseOfMainScreen() + waitForExistenceOfMainScreen() checkSlowAndFrozenFrames() } @@ -31,7 +31,7 @@ class LaunchUITests: XCTestCase { } app.launch() - waitForExistenseOfMainScreen() + waitForExistenceOfMainScreen() } } @@ -88,7 +88,7 @@ class LaunchUITests: XCTestCase { } } - private func waitForExistenseOfMainScreen() { + private func waitForExistenceOfMainScreen() { app.buttons["captureMessageButton"].waitForExistence( "Home Screen doesn't exist.") } diff --git a/Samples/iOS-Swift/iOS13-SwiftTests/LaunchUITest.swift b/Samples/iOS-Swift/iOS13-SwiftTests/LaunchUITest.swift index 02446f6fea..7eb93026a9 100644 --- a/Samples/iOS-Swift/iOS13-SwiftTests/LaunchUITest.swift +++ b/Samples/iOS-Swift/iOS13-SwiftTests/LaunchUITest.swift @@ -12,7 +12,7 @@ class LaunchUITests: XCTestCase { app.launch() XCUIDevice.shared.orientation = .portrait - waitForExistenseOfMainScreen() + waitForExistenceOfMainScreen() } override func tearDownWithError() throws { @@ -25,7 +25,7 @@ class LaunchUITests: XCTestCase { XCTAssertTrue(app.staticTexts["SwiftUI!"].waitForExistence(timeout: timeout), "SwiftUI not loaded.") } - private func waitForExistenseOfMainScreen() { + private func waitForExistenceOfMainScreen() { XCTAssertTrue(app.buttons["captureMessage"].waitForExistence(timeout: timeout), "Home Screen doesn't exist.") } } diff --git a/Sentry.podspec b/Sentry.podspec index 4a9643b0a9..7d6ab2bf13 100644 --- a/Sentry.podspec +++ b/Sentry.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "Sentry" - s.version = "8.3.1" + s.version = "8.3.3" s.summary = "Sentry client for cocoa" s.homepage = "https://github.com/getsentry/sentry-cocoa" s.license = "mit" @@ -27,7 +27,7 @@ Pod::Spec.new do |s| } s.default_subspecs = ['Core'] - s.dependency "SentryPrivate", "8.3.1" + s.dependency "SentryPrivate", "8.3.3" s.subspec 'Core' do |sp| sp.source_files = "Sources/Sentry/**/*.{h,hpp,m,mm,c,cpp}", diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj index fab663ca19..53fe837d69 100644 --- a/Sentry.xcodeproj/project.pbxproj +++ b/Sentry.xcodeproj/project.pbxproj @@ -168,7 +168,6 @@ 63FE70DD20DA4C1000CDBAE8 /* SentryCrashMonitor_Signal.h in Headers */ = {isa = PBXBuildFile; fileRef = 63FE6FF420DA4C1000CDBAE8 /* SentryCrashMonitor_Signal.h */; }; 63FE70DF20DA4C1000CDBAE8 /* SentryCrashMonitorType.c in Sources */ = {isa = PBXBuildFile; fileRef = 63FE6FF520DA4C1000CDBAE8 /* SentryCrashMonitorType.c */; }; 63FE70E120DA4C1000CDBAE8 /* SentryCrashMonitor_CPPException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 63FE6FF620DA4C1000CDBAE8 /* SentryCrashMonitor_CPPException.cpp */; }; - 63FE70E320DA4C1000CDBAE8 /* SentryCrashMonitor_Zombie.c in Sources */ = {isa = PBXBuildFile; fileRef = 63FE6FF720DA4C1000CDBAE8 /* SentryCrashMonitor_Zombie.c */; }; 63FE70E520DA4C1000CDBAE8 /* SentryCrashMonitor_CPPException.h in Headers */ = {isa = PBXBuildFile; fileRef = 63FE6FF820DA4C1000CDBAE8 /* SentryCrashMonitor_CPPException.h */; }; 63FE70E720DA4C1000CDBAE8 /* SentryCrashMonitor.c in Sources */ = {isa = PBXBuildFile; fileRef = 63FE6FF920DA4C1000CDBAE8 /* SentryCrashMonitor.c */; }; 63FE70EB20DA4C1000CDBAE8 /* SentryCrashMonitor_MachException.h in Headers */ = {isa = PBXBuildFile; fileRef = 63FE6FFB20DA4C1000CDBAE8 /* SentryCrashMonitor_MachException.h */; }; @@ -178,7 +177,6 @@ 63FE70F320DA4C1000CDBAE8 /* SentryCrashMonitor_Signal.c in Sources */ = {isa = PBXBuildFile; fileRef = 63FE6FFF20DA4C1000CDBAE8 /* SentryCrashMonitor_Signal.c */; }; 63FE70F520DA4C1000CDBAE8 /* SentryCrashMonitor_System.h in Headers */ = {isa = PBXBuildFile; fileRef = 63FE700020DA4C1000CDBAE8 /* SentryCrashMonitor_System.h */; }; 63FE70F920DA4C1000CDBAE8 /* SentryCrashMonitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 63FE700220DA4C1000CDBAE8 /* SentryCrashMonitor.h */; }; - 63FE70FB20DA4C1000CDBAE8 /* SentryCrashMonitor_Zombie.h in Headers */ = {isa = PBXBuildFile; fileRef = 63FE700320DA4C1000CDBAE8 /* SentryCrashMonitor_Zombie.h */; }; 63FE70FD20DA4C1000CDBAE8 /* SentryCrashCachedData.c in Sources */ = {isa = PBXBuildFile; fileRef = 63FE700420DA4C1000CDBAE8 /* SentryCrashCachedData.c */; }; 63FE710120DA4C1000CDBAE8 /* SentryCrashDate.h in Headers */ = {isa = PBXBuildFile; fileRef = 63FE700720DA4C1000CDBAE8 /* SentryCrashDate.h */; }; 63FE710320DA4C1000CDBAE8 /* SentryCrashMachineContext_Apple.h in Headers */ = {isa = PBXBuildFile; fileRef = 63FE700820DA4C1000CDBAE8 /* SentryCrashMachineContext_Apple.h */; }; @@ -554,7 +552,6 @@ 7BED3576266F7BFF00EAA70D /* TestSentryCrashWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BED3575266F7BFF00EAA70D /* TestSentryCrashWrapper.m */; }; 7BEF4957270C4B9D00F8F30E /* SentryUIViewControllerSwizzlingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BEF4956270C4B9D00F8F30E /* SentryUIViewControllerSwizzlingTests.swift */; }; 7BEFB044270B0F630025F808 /* SentryTracerObjCTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BEFB043270B0F630025F808 /* SentryTracerObjCTests.m */; }; - 7BF1F6AE282A4FE2006BD6AB /* SentryTestObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BF1F6AD282A4FE2006BD6AB /* SentryTestObserver.m */; }; 7BF536D124BDF3E7004FA6A2 /* SentryEnvelopeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF536D024BDF3E7004FA6A2 /* SentryEnvelopeTests.swift */; }; 7BF536D424BEF255004FA6A2 /* SentryAssertions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF536D324BEF255004FA6A2 /* SentryAssertions.swift */; }; 7BF6505F292B77EC00BBA5A8 /* SentryMetricKitIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF6505E292B77EC00BBA5A8 /* SentryMetricKitIntegrationTests.swift */; }; @@ -751,7 +748,7 @@ D885266427739D01001269FC /* SentryFileIOTrackingIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D885266327739D01001269FC /* SentryFileIOTrackingIntegrationTests.swift */; }; D8853C842833EABC00700D64 /* SentryANRTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BCFA71427D0BAB7008C662C /* SentryANRTracker.h */; }; D88817D826D7149100BF2251 /* SentryTraceContext.m in Sources */ = {isa = PBXBuildFile; fileRef = D88817D626D7149100BF2251 /* SentryTraceContext.m */; }; - D88817DA26D72AB800BF2251 /* SentryTraceContext.h in Headers */ = {isa = PBXBuildFile; fileRef = D88817D926D72AB800BF2251 /* SentryTraceContext.h */; }; + D88817DA26D72AB800BF2251 /* SentryTraceContext.h in Headers */ = {isa = PBXBuildFile; fileRef = D88817D926D72AB800BF2251 /* SentryTraceContext.h */; settings = {ATTRIBUTES = (Private, ); }; }; D88817DD26D72BA500BF2251 /* SentryTraceStateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D88817DB26D72B7B00BF2251 /* SentryTraceStateTests.swift */; }; D8918B222849FA6D00701F9A /* SentrySDKIntegrationTestsBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8918B212849FA6D00701F9A /* SentrySDKIntegrationTestsBase.swift */; }; D8AB40DB2806EC1900E5E9F7 /* SentryScreenshotIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = D8AB40DA2806EC1900E5E9F7 /* SentryScreenshotIntegration.h */; }; @@ -841,7 +838,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 0356A56E288B4612008BF593 /* SentryProfilesSampler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryProfilesSampler.h; path = Sources/Sentry/SentryProfilesSampler.h; sourceTree = SOURCE_ROOT; }; + 0356A56E288B4612008BF593 /* SentryProfilesSampler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryProfilesSampler.h; path = Sources/Sentry/include/SentryProfilesSampler.h; sourceTree = SOURCE_ROOT; }; 0356A56F288B4612008BF593 /* SentryProfilesSampler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SentryProfilesSampler.m; path = Sources/Sentry/SentryProfilesSampler.m; sourceTree = SOURCE_ROOT; }; 035E73C727D56757005EEB11 /* SentryBacktraceTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SentryBacktraceTests.mm; sourceTree = ""; }; 035E73C927D57398005EEB11 /* SentryThreadHandleTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SentryThreadHandleTests.mm; sourceTree = ""; }; @@ -1016,7 +1013,6 @@ 63FE6FF420DA4C1000CDBAE8 /* SentryCrashMonitor_Signal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SentryCrashMonitor_Signal.h; sourceTree = ""; }; 63FE6FF520DA4C1000CDBAE8 /* SentryCrashMonitorType.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SentryCrashMonitorType.c; sourceTree = ""; }; 63FE6FF620DA4C1000CDBAE8 /* SentryCrashMonitor_CPPException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SentryCrashMonitor_CPPException.cpp; sourceTree = ""; }; - 63FE6FF720DA4C1000CDBAE8 /* SentryCrashMonitor_Zombie.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SentryCrashMonitor_Zombie.c; sourceTree = ""; }; 63FE6FF820DA4C1000CDBAE8 /* SentryCrashMonitor_CPPException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SentryCrashMonitor_CPPException.h; sourceTree = ""; }; 63FE6FF920DA4C1000CDBAE8 /* SentryCrashMonitor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SentryCrashMonitor.c; sourceTree = ""; }; 63FE6FFB20DA4C1000CDBAE8 /* SentryCrashMonitor_MachException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SentryCrashMonitor_MachException.h; sourceTree = ""; }; @@ -1026,7 +1022,6 @@ 63FE6FFF20DA4C1000CDBAE8 /* SentryCrashMonitor_Signal.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SentryCrashMonitor_Signal.c; sourceTree = ""; }; 63FE700020DA4C1000CDBAE8 /* SentryCrashMonitor_System.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SentryCrashMonitor_System.h; sourceTree = ""; }; 63FE700220DA4C1000CDBAE8 /* SentryCrashMonitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SentryCrashMonitor.h; sourceTree = ""; }; - 63FE700320DA4C1000CDBAE8 /* SentryCrashMonitor_Zombie.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SentryCrashMonitor_Zombie.h; sourceTree = ""; }; 63FE700420DA4C1000CDBAE8 /* SentryCrashCachedData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SentryCrashCachedData.c; sourceTree = ""; }; 63FE700720DA4C1000CDBAE8 /* SentryCrashDate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SentryCrashDate.h; sourceTree = ""; }; 63FE700820DA4C1000CDBAE8 /* SentryCrashMachineContext_Apple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SentryCrashMachineContext_Apple.h; sourceTree = ""; }; @@ -1424,7 +1419,7 @@ 7BE3C78624472E9800A38442 /* TestRequestManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestRequestManager.swift; sourceTree = ""; }; 7BE8E8442593313500C4DA1F /* SentryAttachment+Equality.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SentryAttachment+Equality.h"; sourceTree = ""; }; 7BE8E8452593313500C4DA1F /* SentryAttachment+Equality.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "SentryAttachment+Equality.m"; sourceTree = ""; }; - 7BE912AA272162AF00E49E62 /* SentryNoOpSpan.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SentryNoOpSpan.h; sourceTree = ""; }; + 7BE912AA272162AF00E49E62 /* SentryNoOpSpan.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryNoOpSpan.h; path = include/SentryNoOpSpan.h; sourceTree = ""; }; 7BE912AC272162D900E49E62 /* SentryNoOpSpan.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryNoOpSpan.m; sourceTree = ""; }; 7BE912AE272166DD00E49E62 /* SentryNoOpSpanTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryNoOpSpanTests.swift; sourceTree = ""; }; 7BE912B02721C76000E49E62 /* SentryPerformanceTrackingIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryPerformanceTrackingIntegrationTests.swift; sourceTree = ""; }; @@ -1435,8 +1430,6 @@ 7BED3575266F7BFF00EAA70D /* TestSentryCrashWrapper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestSentryCrashWrapper.m; sourceTree = ""; }; 7BEF4956270C4B9D00F8F30E /* SentryUIViewControllerSwizzlingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryUIViewControllerSwizzlingTests.swift; sourceTree = ""; }; 7BEFB043270B0F630025F808 /* SentryTracerObjCTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryTracerObjCTests.m; sourceTree = ""; }; - 7BF1F6AC282A4FC6006BD6AB /* SentryTestObserver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SentryTestObserver.h; sourceTree = ""; }; - 7BF1F6AD282A4FE2006BD6AB /* SentryTestObserver.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryTestObserver.m; sourceTree = ""; }; 7BF536D024BDF3E7004FA6A2 /* SentryEnvelopeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryEnvelopeTests.swift; sourceTree = ""; }; 7BF536D324BEF255004FA6A2 /* SentryAssertions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryAssertions.swift; sourceTree = ""; }; 7BF6505E292B77EC00BBA5A8 /* SentryMetricKitIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryMetricKitIntegrationTests.swift; sourceTree = ""; }; @@ -1445,10 +1438,10 @@ 7BF69E062987D1FE002EBCA4 /* SentryCrashDoctorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryCrashDoctorTests.swift; sourceTree = ""; }; 7BF9EF712722A84800B5BBEF /* SentryClassRegistrator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SentryClassRegistrator.h; sourceTree = ""; }; 7BF9EF732722A85B00B5BBEF /* SentryClassRegistrator.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryClassRegistrator.m; sourceTree = ""; }; - 7BF9EF752722B34700B5BBEF /* SentrySubClassFinder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SentrySubClassFinder.h; sourceTree = ""; }; + 7BF9EF752722B34700B5BBEF /* SentrySubClassFinder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentrySubClassFinder.h; path = include/SentrySubClassFinder.h; sourceTree = ""; }; 7BF9EF772722B35D00B5BBEF /* SentrySubClassFinder.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentrySubClassFinder.m; sourceTree = ""; }; 7BF9EF792722B58900B5BBEF /* SentrySubClassFinderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentrySubClassFinderTests.swift; sourceTree = ""; }; - 7BF9EF7B2722B90E00B5BBEF /* SentryDefaultObjCRuntimeWrapper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SentryDefaultObjCRuntimeWrapper.h; sourceTree = ""; }; + 7BF9EF7B2722B90E00B5BBEF /* SentryDefaultObjCRuntimeWrapper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryDefaultObjCRuntimeWrapper.h; path = include/SentryDefaultObjCRuntimeWrapper.h; sourceTree = ""; }; 7BF9EF7D2722B91F00B5BBEF /* SentryDefaultObjCRuntimeWrapper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryDefaultObjCRuntimeWrapper.m; sourceTree = ""; }; 7BF9EF832722D07B00B5BBEF /* SentryObjCRuntimeWrapper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryObjCRuntimeWrapper.h; path = include/SentryObjCRuntimeWrapper.h; sourceTree = ""; }; 7BF9EF852722D10600B5BBEF /* SentryTestObjCRuntimeWrapper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SentryTestObjCRuntimeWrapper.h; sourceTree = ""; }; @@ -2327,8 +2320,6 @@ 63FE6FF420DA4C1000CDBAE8 /* SentryCrashMonitor_Signal.h */, 63FE700020DA4C1000CDBAE8 /* SentryCrashMonitor_System.h */, 63FE6FF320DA4C1000CDBAE8 /* SentryCrashMonitor_System.m */, - 63FE6FF720DA4C1000CDBAE8 /* SentryCrashMonitor_Zombie.c */, - 63FE700320DA4C1000CDBAE8 /* SentryCrashMonitor_Zombie.h */, 63FE6FF920DA4C1000CDBAE8 /* SentryCrashMonitor.c */, 63FE700220DA4C1000CDBAE8 /* SentryCrashMonitor.h */, 63FE6FEE20DA4C1000CDBAE8 /* SentryCrashMonitorContext.h */, @@ -2956,8 +2947,6 @@ 7B6D98EC24C703F8005502FA /* Async.swift */, 7BF9EF712722A84800B5BBEF /* SentryClassRegistrator.h */, 7BF9EF732722A85B00B5BBEF /* SentryClassRegistrator.m */, - 7BF1F6AC282A4FC6006BD6AB /* SentryTestObserver.h */, - 7BF1F6AD282A4FE2006BD6AB /* SentryTestObserver.m */, 7B72D23928D074BC0014798A /* TestExtensions.swift */, 7BB7E7C629267A28004BF96B /* EmptyIntegration.swift */, 7B4F22DB294089530067EA17 /* FormatHexAddress.swift */, @@ -3336,7 +3325,6 @@ D8ACE3CF2762187D00F5A213 /* SentryFileIOTrackingIntegration.h in Headers */, 7BECF42226145C5D00D9826E /* SentryMechanismMeta.h in Headers */, 63FE718920DA4C1100CDBAE8 /* SentryCrash.h in Headers */, - 63FE70FB20DA4C1000CDBAE8 /* SentryCrashMonitor_Zombie.h in Headers */, 63AA769A1EB9C1C200D153DE /* SentryLog.h in Headers */, 7B56D73124616CCD00B842DA /* SentryConcurrentRateLimitsDictionary.h in Headers */, 03F84D2A27DD416B008FE43F /* SentryProfilingLogging.hpp in Headers */, @@ -3977,7 +3965,6 @@ 63FE714120DA4C1100CDBAE8 /* SentryCrashDate.c in Sources */, 63FE70DB20DA4C1000CDBAE8 /* SentryCrashMonitor_System.m in Sources */, 7BA61CBB247BC5D800C130A8 /* SentryCrashDefaultBinaryImageProvider.m in Sources */, - 63FE70E320DA4C1000CDBAE8 /* SentryCrashMonitor_Zombie.c in Sources */, 63FE713120DA4C1100CDBAE8 /* SentryCrashDynamicLinker.c in Sources */, 8E25C95325F836D000DC215B /* SentryRandom.m in Sources */, 7BC85231245812EC005A70F0 /* SentryFileContents.m in Sources */, @@ -4071,7 +4058,6 @@ 7BE3C7752445C82300A38442 /* SentryCurrentDateTests.swift in Sources */, 7B3398672459C4AE00BD9C96 /* SentryEnvelopeRateLimitTests.swift in Sources */, 8EA9AF492665AC48002771B4 /* SentryPerformanceTrackerTests.swift in Sources */, - 7BF1F6AE282A4FE2006BD6AB /* SentryTestObserver.m in Sources */, 7B3B473E25D6CEA500D01640 /* SentryNSErrorTests.swift in Sources */, 632331F62404FFA8008D91D6 /* SentryScopeTests.m in Sources */, D808FB88281AB33C009A2A33 /* SentryUIEventTrackerTests.swift in Sources */, diff --git a/SentryPrivate.podspec b/SentryPrivate.podspec index 3a469bca2c..e591b96c7a 100644 --- a/SentryPrivate.podspec +++ b/SentryPrivate.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "SentryPrivate" - s.version = "8.3.1" + s.version = "8.3.3" s.summary = "Sentry Private Library." s.homepage = "https://github.com/getsentry/sentry-cocoa" s.license = "mit" diff --git a/SentrySwiftUI.podspec b/SentrySwiftUI.podspec index 46098e8df1..453e32ce1d 100644 --- a/SentrySwiftUI.podspec +++ b/SentrySwiftUI.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "SentrySwiftUI" - s.version = "8.3.1" + s.version = "8.3.3" s.summary = "Sentry client for SwiftUI" s.homepage = "https://github.com/getsentry/sentry-cocoa" s.license = "mit" @@ -19,5 +19,5 @@ Pod::Spec.new do |s| s.watchos.framework = 'WatchKit' s.source_files = "Sources/SentrySwiftUI/**/*.{swift,h,m}" - s.dependency 'Sentry', "8.3.1" + s.dependency 'Sentry', "8.3.3" end diff --git a/SentryTestUtils/TestSentryDispatchQueueWrapper.swift b/SentryTestUtils/TestSentryDispatchQueueWrapper.swift index 107a120eed..0dafb6b855 100644 --- a/SentryTestUtils/TestSentryDispatchQueueWrapper.swift +++ b/SentryTestUtils/TestSentryDispatchQueueWrapper.swift @@ -9,7 +9,7 @@ public class TestSentryDispatchQueueWrapper: SentryDispatchQueueWrapper { /// - SeeAlso: `delayDispatches`, which controls whether the block should execute immediately or with the requested delay. public var dispatchAfterExecutesBlock = false - var dispatchAsyncInvocations = Invocations<() -> Void>() + public var dispatchAsyncInvocations = Invocations<() -> Void>() public var dispatchAsyncExecutesBlock = true public override func dispatchAsync(_ block: @escaping () -> Void) { dispatchAsyncCalled += 1 @@ -62,4 +62,13 @@ public class TestSentryDispatchQueueWrapper: SentryDispatchQueueWrapper { public override func dispatchOnce(_ predicate: UnsafeMutablePointer, block: @escaping () -> Void) { block() } + + public var createDispatchBlockReturnsNULL = false + public override func createDispatchBlock(_ block: @escaping () -> Void) -> (() -> Void)? { + if createDispatchBlockReturnsNULL { + return nil + } + return super.createDispatchBlock(block) + } + } diff --git a/Sources/Configuration/Sentry.xcconfig b/Sources/Configuration/Sentry.xcconfig index 4630abf7db..4a5df2947c 100644 --- a/Sources/Configuration/Sentry.xcconfig +++ b/Sources/Configuration/Sentry.xcconfig @@ -2,6 +2,6 @@ PRODUCT_NAME = Sentry INFOPLIST_FILE = Sources/Sentry/Info.plist PRODUCT_BUNDLE_IDENTIFIER = io.sentry.Sentry -CURRENT_PROJECT_VERSION = 8.3.1 +CURRENT_PROJECT_VERSION = 8.3.3 MODULEMAP_FILE = $(SRCROOT)/Sources/Sentry/Sentry.modulemap diff --git a/Sources/Configuration/SentryPrivate.xcconfig b/Sources/Configuration/SentryPrivate.xcconfig index 5948037db1..58d56958be 100644 --- a/Sources/Configuration/SentryPrivate.xcconfig +++ b/Sources/Configuration/SentryPrivate.xcconfig @@ -1,3 +1,3 @@ PRODUCT_NAME = SentryPrivate MACH_O_TYPE = staticlib -CURRENT_PROJECT_VERSION = 8.3.1 +CURRENT_PROJECT_VERSION = 8.3.3 diff --git a/Sources/Sentry/Public/SentryAttachment.h b/Sources/Sentry/Public/SentryAttachment.h index b9217094dc..2f3e2253e2 100644 --- a/Sources/Sentry/Public/SentryAttachment.h +++ b/Sources/Sentry/Public/SentryAttachment.h @@ -11,8 +11,7 @@ NS_SWIFT_NAME(Attachment) SENTRY_NO_INIT /** - * Initializes an attachment with data. Sets the content type to "application/octet-stream". - * + * Initializes an attachment with data. Sets the content type to @c "application/octet-stream". * @param data The data for the attachment. * @param filename The name of the attachment to display in Sentry. */ @@ -20,32 +19,27 @@ SENTRY_NO_INIT /** * Initializes an attachment with data. - * * @param data The data for the attachment. * @param filename The name of the attachment to display in Sentry. - * @param contentType The content type of the attachment. Default is "application/octet-stream". + * @param contentType The content type of the attachment. @c Default is "application/octet-stream". */ - (instancetype)initWithData:(NSData *)data filename:(NSString *)filename contentType:(nullable NSString *)contentType; /** - * Initializes an attachment with a path. Uses the last path compontent of the path as a filename - * and sets the content type to "application/octet-stream". - * + * Initializes an attachment with a path. Uses the last path component of the path as a filename + * and sets the content type to @c "application/octet-stream". * @discussion The file located at the pathname is read lazily when the SDK captures an event or * transaction not when the attachment is initialized. - * * @param path The path of the file whose contents you want to upload to Sentry. */ - (instancetype)initWithPath:(NSString *)path; /** - * Initializes an attachment with a path. Sets the content type to "application/octet-stream". - * - * @discussion The file located at the pathname is read lazily when the SDK captures an event or + * Initializes an attachment with a path. Sets the content type to @c "application/octet-stream". + * @discussion The specified file is read lazily when the SDK captures an event or * transaction not when the attachment is initialized. - * * @param path The path of the file whose contents you want to upload to Sentry. * @param filename The name of the attachment to display in Sentry. */ @@ -53,13 +47,11 @@ SENTRY_NO_INIT /** * Initializes an attachment with a path. - * - * @discussion The file located at the pathname is read lazily when the SDK captures an event or + * @discussion The specifid file is read lazily when the SDK captures an event or * transaction not when the attachment is initialized. - * * @param path The path of the file whose contents you want to upload to Sentry. * @param filename The name of the attachment to display in Sentry. - * @param contentType The content type of the attachment. Default is "application/octet-stream". + * @param contentType The content type of the attachment. Default is @c "application/octet-stream". */ - (instancetype)initWithPath:(NSString *)path filename:(NSString *)filename diff --git a/Sources/Sentry/Public/SentryBreadcrumb.h b/Sources/Sentry/Public/SentryBreadcrumb.h index 0fa5034f61..d6a10b8ca7 100644 --- a/Sources/Sentry/Public/SentryBreadcrumb.h +++ b/Sources/Sentry/Public/SentryBreadcrumb.h @@ -19,7 +19,7 @@ NS_SWIFT_NAME(Breadcrumb) @property (nonatomic, copy) NSString *category; /** - * NSDate when the breadcrumb happened + * @c NSDate when the breadcrumb happened */ @property (nonatomic, strong) NSDate *_Nullable timestamp; @@ -40,11 +40,9 @@ NS_SWIFT_NAME(Breadcrumb) @property (nonatomic, strong) NSDictionary *_Nullable data; /** - * Initializer for SentryBreadcrumb - * + * Initializer for @c SentryBreadcrumb * @param level SentryLevel * @param category String - * @return SentryBreadcrumb */ - (instancetype)initWithLevel:(SentryLevel)level category:(NSString *)category; - (instancetype)init; diff --git a/Sources/Sentry/Public/SentryClient.h b/Sources/Sentry/Public/SentryClient.h index a7db0de3db..facf674f3e 100644 --- a/Sources/Sentry/Public/SentryClient.h +++ b/Sources/Sentry/Public/SentryClient.h @@ -1,7 +1,7 @@ #import "SentryDefines.h" -@class SentryOptions, SentrySession, SentryEvent, SentryScope, SentryFileManager, SentryId, - SentryUserFeedback, SentryTransaction; +@class SentryOptions, SentryEvent, SentryScope, SentryFileManager, SentryId, SentryUserFeedback, + SentryTransaction; NS_ASSUME_NONNULL_BEGIN @@ -13,114 +13,93 @@ SENTRY_NO_INIT @property (nonatomic, strong) SentryOptions *options; /** - * Initializes a SentryClient. Pass in an dictionary of options. - * + * Initializes a @c SentryClient. Pass in a dictionary of options. * @param options Options dictionary - * @return SentryClient + * @return An initialized @c SentryClient or @c nil if an error occurred. */ - (_Nullable instancetype)initWithOptions:(SentryOptions *)options; /** * Captures a manually created event and sends it to Sentry. - * * @param event The event to send to Sentry. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureEvent:(SentryEvent *)event NS_SWIFT_NAME(capture(event:)); /** * Captures a manually created event and sends it to Sentry. - * * @param event The event to send to Sentry. * @param scope The scope containing event metadata. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureEvent:(SentryEvent *)event withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(event:scope:)); /** * Captures an error event and sends it to Sentry. - * * @param error The error to send to Sentry. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureError:(NSError *)error NS_SWIFT_NAME(capture(error:)); /** * Captures an error event and sends it to Sentry. - * * @param error The error to send to Sentry. * @param scope The scope containing event metadata. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureError:(NSError *)error withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(error:scope:)); /** * Captures an exception event and sends it to Sentry. - * * @param exception The exception to send to Sentry. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureException:(NSException *)exception NS_SWIFT_NAME(capture(exception:)); /** * Captures an exception event and sends it to Sentry. - * * @param exception The exception to send to Sentry. * @param scope The scope containing event metadata. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureException:(NSException *)exception withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(exception:scope:)); /** * Captures a message event and sends it to Sentry. - * * @param message The message to send to Sentry. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureMessage:(NSString *)message NS_SWIFT_NAME(capture(message:)); /** * Captures a message event and sends it to Sentry. - * * @param message The message to send to Sentry. * @param scope The scope containing event metadata. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureMessage:(NSString *)message withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(message:scope:)); /** * Captures a manually created user feedback and sends it to Sentry. - * * @param userFeedback The user feedback to send to Sentry. */ - (void)captureUserFeedback:(SentryUserFeedback *)userFeedback NS_SWIFT_NAME(capture(userFeedback:)); -- (void)captureSession:(SentrySession *)session NS_SWIFT_NAME(capture(session:)); - /** * Waits synchronously for the SDK to flush out all queued and cached items for up to the specified * timeout in seconds. If there is no internet connection, the function returns immediately. The SDK * doesn't dispose the client or the hub. - * * @param timeout The time to wait for the SDK to complete the flush. */ - (void)flush:(NSTimeInterval)timeout NS_SWIFT_NAME(flush(timeout:)); /** - * Disables the client and calls flush with ``SentryOptions/shutdownTimeInterval``. + * Disables the client and calls flush with @c SentryOptions.shutdownTimeInterval . */ - (void)close; diff --git a/Sources/Sentry/Public/SentryDebugImageProvider.h b/Sources/Sentry/Public/SentryDebugImageProvider.h index 5f2b9aba8b..9a4c27a7fe 100644 --- a/Sources/Sentry/Public/SentryDebugImageProvider.h +++ b/Sources/Sentry/Public/SentryDebugImageProvider.h @@ -14,21 +14,20 @@ NS_ASSUME_NONNULL_BEGIN /** * Returns a list of debug images that are being referenced in the given threads. - * - * @param threads A list of SentryThread that may or may not contains a stacktrace. + * @param threads A list of @c SentryThread that may or may not contain stacktracse. */ - (NSArray *)getDebugImagesForThreads:(NSArray *)threads; /** * Returns a list of debug images that are being referenced by the given frames. - * * @param frames A list of stack frames. */ - (NSArray *)getDebugImagesForFrames:(NSArray *)frames; /** - * Returns the current list of debug images. Be aware that the SentryDebugMeta is actually - * describing a debug image. This class should be renamed to SentryDebugImage in a future version. + * Returns the current list of debug images. Be aware that the @c SentryDebugMeta is actually + * describing a debug image. + * @todo This class should be renamed to @c SentryDebugImage in a future version. */ - (NSArray *)getDebugImages; diff --git a/Sources/Sentry/Public/SentryDebugMeta.h b/Sources/Sentry/Public/SentryDebugMeta.h index b846850cbd..b00133b26a 100644 --- a/Sources/Sentry/Public/SentryDebugMeta.h +++ b/Sources/Sentry/Public/SentryDebugMeta.h @@ -5,27 +5,25 @@ NS_ASSUME_NONNULL_BEGIN /** - * This class is actually a DebugImage: - * https://develop.sentry.dev/sdk/event-payloads/debugmeta/#debug-images and should be renamed to - * SentryDebugImage in a future version. - * * Contains information about a loaded library in the process and the memory address. - * * @discussion Since 8.2.0, the SDK changed the debug image type from "apple" to "macho". For macho, - * the SDK now sends ``debugID`` instead of ``uuid``, and ``codeFile`` instead of ``name``. For more + * the SDK now sends @c debugID instead of @c uuid , and @c codeFile instead of @c name . For more * information check https://develop.sentry.dev/sdk/event-payloads/debugmeta/#mach-o-images. + * @todo This class is actually a DebugImage: + * https://develop.sentry.dev/sdk/event-payloads/debugmeta/#debug-images and should be renamed to + * @c SentryDebugImage in a future version. */ NS_SWIFT_NAME(DebugMeta) @interface SentryDebugMeta : NSObject /** - * The UUID of the image. Use ``debugID`` when using ``type`` "macho". + * The UUID of the image. Use @c debugID when using "macho" as the @c type . */ @property (nonatomic, copy) NSString *_Nullable uuid; /** - * Identifier of the dynamic library or executable. It is the value of the LC_UUID load command in - * the Mach header, formatted as UUID. + * Identifier of the dynamic library or executable. It is the value of the @c LC_UUID load command + * in the Mach header, formatted as UUID. */ @property (nonatomic, copy) NSString *_Nullable debugID; @@ -35,7 +33,7 @@ NS_SWIFT_NAME(DebugMeta) @property (nonatomic, copy) NSString *_Nullable type; /** - * Name of the image. Use ``codeFile`` when using ``type`` "macho". + * Name of the image. Use @c codeFile when using "macho" as the @c type . */ @property (nonatomic, copy) NSString *_Nullable name; diff --git a/Sources/Sentry/Public/SentryDefines.h b/Sources/Sentry/Public/SentryDefines.h index ec8e709c39..2253a719bf 100644 --- a/Sources/Sentry/Public/SentryDefines.h +++ b/Sources/Sentry/Public/SentryDefines.h @@ -37,14 +37,14 @@ typedef void (^SentryRequestFinished)(NSError *_Nullable error); /** - * Block used for request operation finished, shouldDiscardEvent is YES if event + * Block used for request operation finished, @c shouldDiscardEvent is @c YES if event * should be deleted regardless if an error occurred or not */ typedef void (^SentryRequestOperationFinished)( NSHTTPURLResponse *_Nullable response, NSError *_Nullable error); /** * Block can be used to mutate a breadcrumb before it's added to the scope. - * To avoid adding the breadcrumb altogether, return nil instead. + * To avoid adding the breadcrumb altogether, return @c nil instead. */ typedef SentryBreadcrumb *_Nullable (^SentryBeforeBreadcrumbCallback)( SentryBreadcrumb *_Nonnull breadcrumb); @@ -71,24 +71,21 @@ typedef BOOL (^SentryShouldQueueEvent)( /** * Function pointer for a sampler callback. - * * @param samplingContext context of the sampling. - * - * @return A sample rate that is >= 0.0 and <= 1.0 or NIL if no sampling decision has been taken.. - * When returning a value out of range the SDK uses the default of 0. + * @return A sample rate that is >= @c 0.0 and \<= @c 1.0 or @c nil if no sampling decision has + * been taken. When returning a value out of range the SDK uses the default of @c 0. */ typedef NSNumber *_Nullable (^SentryTracesSamplerCallback)( SentrySamplingContext *_Nonnull samplingContext); /** * Function pointer for span manipulation. - * * @param span The span to be used. */ typedef void (^SentrySpanCallback)(id _Nullable span); /** - * Loglevel + * Log level. */ typedef NS_ENUM(NSInteger, SentryLogLevel) { kSentryLogLevelNone = 1, @@ -98,7 +95,7 @@ typedef NS_ENUM(NSInteger, SentryLogLevel) { }; /** - * Sentry level + * Sentry level. */ typedef NS_ENUM(NSUInteger, SentryLevel) { // Defaults to None which doesn't get serialized @@ -112,7 +109,7 @@ typedef NS_ENUM(NSUInteger, SentryLevel) { }; /** - * Static internal helper to convert enum to string + * Static internal helper to convert enum to string. */ static DEPRECATED_MSG_ATTRIBUTE( "Use nameForSentryLevel() instead.") NSString *_Nonnull const SentryLevelNames[] @@ -128,7 +125,7 @@ static DEPRECATED_MSG_ATTRIBUTE( static NSUInteger const defaultMaxBreadcrumbs = 100; /** - * Transaction name source + * Transaction name source. */ typedef NS_ENUM(NSInteger, SentryTransactionNameSource) { kSentryTransactionNameSourceCustom = 0, diff --git a/Sources/Sentry/Public/SentryEvent.h b/Sources/Sentry/Public/SentryEvent.h index 364f9d2629..56d2e00a8d 100644 --- a/Sources/Sentry/Public/SentryEvent.h +++ b/Sources/Sentry/Public/SentryEvent.h @@ -23,55 +23,55 @@ NS_SWIFT_NAME(Event) /** * The error of the event. This property adds convenience to access the error directly in - * beforeSend. This property is not serialized. Instead when preparing the event the SentryClient - * puts the error into exceptions. + * @c beforeSend. This property is not serialized. Instead when preparing the event the + * @c SentryClient puts the error into exceptions. */ @property (nonatomic, copy) NSError *_Nullable error; /** - * NSDate of when the event occurred + * @c NSDate of when the event occurred. */ @property (nonatomic, strong) NSDate *_Nullable timestamp; /** - * NSDate of when the event started, mostly useful if event type transaction + * @c NSDate of when the event started, mostly useful if event type transaction. */ @property (nonatomic, strong) NSDate *_Nullable startTimestamp; /** - * SentryLevel of the event + * @c SentryLevel of the event. */ @property (nonatomic) enum SentryLevel level; /** - * Platform this will be used for symbolicating on the server should be "cocoa" + * This will be used for symbolicating on the server should be "cocoa". */ @property (nonatomic, copy) NSString *platform; /** - * Define the logger name + * Define the logger name. */ @property (nonatomic, copy) NSString *_Nullable logger; /** - * Define the server name + * Define the server name. */ @property (nonatomic, copy) NSString *_Nullable serverName; /** - * This property will be filled before the event is sent. + * @note This property will be filled before the event is sent. * @warning This is maintained automatically, and shouldn't normally need to be modified. */ @property (nonatomic, copy) NSString *_Nullable releaseName; /** - * This property will be filled before the event is sent. + * @note This property will be filled before the event is sent. * @warning This is maintained automatically, and shouldn't normally need to be modified. */ @property (nonatomic, copy) NSString *_Nullable dist; /** - * The environment used for this event + * The environment used for this event. */ @property (nonatomic, copy) NSString *_Nullable environment; @@ -81,17 +81,17 @@ NS_SWIFT_NAME(Event) @property (nonatomic, copy) NSString *_Nullable transaction; /** - * The type of the event, null, default or transaction + * The type of the event, null, default or transaction. */ @property (nonatomic, copy) NSString *_Nullable type; /** - * Arbitrary key:value (string:string ) data that will be shown with the event + * Arbitrary key:value (string:string ) data that will be shown with the event. */ @property (nonatomic, strong) NSDictionary *_Nullable tags; /** - * Arbitrary additional information that will be sent with the event + * Arbitrary additional information that will be sent with the event. */ @property (nonatomic, strong) NSDictionary *_Nullable extra; @@ -111,7 +111,7 @@ NS_SWIFT_NAME(Event) @property (nonatomic, strong) NSDictionary *_Nullable sdk; /** - * Modules of the event + * Modules of the event. */ @property (nonatomic, strong) NSDictionary *_Nullable modules; @@ -121,7 +121,7 @@ NS_SWIFT_NAME(Event) @property (nonatomic, strong) NSArray *_Nullable fingerprint; /** - * Set the SentryUser for the event + * Set the @c SentryUser for the event. */ @property (nonatomic, strong) SentryUser *_Nullable user; @@ -133,56 +133,50 @@ NS_SWIFT_NAME(Event) NSDictionary *> *_Nullable context; /** - * Contains SentryThread if an crash occurred of it's an user reported exception + * Contains @c SentryThread if a crash occurred or for a user reported exception. */ @property (nonatomic, strong) NSArray *_Nullable threads; /** - * General information about the SentryException, usually there is only one - * exception in the array + * General information about the @c SentryException, usually there is only one + * exception in the array. */ @property (nonatomic, strong) NSArray *_Nullable exceptions; /** - * Separate SentryStacktrace that can be sent with the event, besides threads + * Separate @c SentryStacktrace that can be sent with the event, besides threads. */ @property (nonatomic, strong) SentryStacktrace *_Nullable stacktrace; /** - * Containing images loaded during runtime + * Containing images loaded during runtime. */ @property (nonatomic, strong) NSArray *_Nullable debugMeta; /** * This contains all breadcrumbs available at the time when the event - * occurred/will be sent + * occurred/will be sent. */ @property (nonatomic, strong) NSArray *_Nullable breadcrumbs; /** - * Set the Http request information. + * Set the HTTP request information. */ @property (nonatomic, strong, nullable) SentryRequest *request; /** - * Init an SentryEvent will set all needed fields by default - * @return SentryEvent + * Init an @c SentryEvent will set all needed fields by default. */ - (instancetype)init; /** - * Init an SentryEvent will set all needed fields by default - * @param level SentryLevel - * @return SentryEvent + * Init a @c SentryEvent with a @c SentryLevelError and set all needed fields by default. */ - (instancetype)initWithLevel:(enum SentryLevel)level NS_DESIGNATED_INITIALIZER; /** - * Initializes a SentryEvent with an NSError and sets the level to SentryLevelError. - * + * Initializes a @c SentryEvent with an @c NSError and sets the level to @c SentryLevelError. * @param error The error of the event. - * - * @return The initialized SentryEvent. */ - (instancetype)initWithError:(NSError *)error; diff --git a/Sources/Sentry/Public/SentryException.h b/Sources/Sentry/Public/SentryException.h index 37eac9d846..344566a90b 100644 --- a/Sources/Sentry/Public/SentryException.h +++ b/Sources/Sentry/Public/SentryException.h @@ -32,7 +32,7 @@ SENTRY_NO_INIT @property (nonatomic, copy) NSString *_Nullable module; /** - * An optional value which refers to a thread in `SentryEvent.threads`. + * An optional value which refers to a thread in @c SentryEvent.threads */ @property (nonatomic, copy) NSNumber *_Nullable threadId; diff --git a/Sources/Sentry/Public/SentryHttpStatusCodeRange.h b/Sources/Sentry/Public/SentryHttpStatusCodeRange.h index 38e6f53457..ce50f0bb98 100644 --- a/Sources/Sentry/Public/SentryHttpStatusCodeRange.h +++ b/Sources/Sentry/Public/SentryHttpStatusCodeRange.h @@ -3,11 +3,7 @@ NS_ASSUME_NONNULL_BEGIN /** - * The Http status code range. - * The range is inclusive so the min and max is considered part of the range. - * - * Example for a range: 400 to 499, 500 to 599, 400 to 599. - * Example for a single status code 400, 500. + * An HTTP status code range. */ NS_SWIFT_NAME(HttpStatusCodeRange) @interface SentryHttpStatusCodeRange : NSObject @@ -18,17 +14,15 @@ SENTRY_NO_INIT @property (nonatomic, readonly) NSInteger max; /** - * The Http status code min and max. - * The range is inclusive so the min and max is considered part of the range. - * - * Example for a range: 400 to 499, 500 to 599, 400 to 599. + * The HTTP status code min and max. + * @discussion The range is inclusive so the min and max is considered part of the range. + * @example For a range: 400 to 499; 500 to 599; 400 to 599. */ - (instancetype)initWithMin:(NSInteger)min max:(NSInteger)max; /** - * The Http status code. - * - * Example for a single status code 400, 500. + * The HTTP status code. + * @example For a single status code: 400; 500. */ - (instancetype)initWithStatusCode:(NSInteger)statusCode; diff --git a/Sources/Sentry/Public/SentryHub.h b/Sources/Sentry/Public/SentryHub.h index 9a94d6cb84..caf5fc5bbb 100644 --- a/Sources/Sentry/Public/SentryHub.h +++ b/Sources/Sentry/Public/SentryHub.h @@ -2,8 +2,8 @@ #import "SentryIntegrationProtocol.h" #import "SentrySpanProtocol.h" -@class SentryEvent, SentryClient, SentryScope, SentrySession, SentryUser, SentryBreadcrumb, - SentryId, SentryUserFeedback, SentryTransactionContext; +@class SentryEvent, SentryClient, SentryScope, SentryUser, SentryBreadcrumb, SentryId, + SentryUserFeedback, SentryTransactionContext; NS_ASSUME_NONNULL_BEGIN @interface SentryHub : NSObject @@ -12,11 +12,6 @@ SENTRY_NO_INIT - (instancetype)initWithClient:(SentryClient *_Nullable)client andScope:(SentryScope *_Nullable)scope; -/** - * Since there's no scope stack, single hub instance, we keep the session here. - */ -@property (nonatomic, readonly, strong) SentrySession *_Nullable session; - /** * Starts a new SentrySession. If there's a running SentrySession, it ends it before starting the * new one. You can use this method in combination with endSession to manually track SentrySessions. @@ -33,26 +28,21 @@ SENTRY_NO_INIT /** * Ends the current session with the given timestamp. - * * @param timestamp The timestamp to end the session with. */ - (void)endSessionWithTimestamp:(NSDate *)timestamp; /** * Captures a manually created event and sends it to Sentry. - * * @param event The event to send to Sentry. - * * @return The SentryId of the event or SentryId.empty if the event is not sent. */ - (SentryId *)captureEvent:(SentryEvent *)event NS_SWIFT_NAME(capture(event:)); /** * Captures a manually created event and sends it to Sentry. - * * @param event The event to send to Sentry. * @param scope The scope containing event metadata. - * * @return The SentryId of the event or SentryId.empty if the event is not sent. */ - (SentryId *)captureEvent:(SentryEvent *)event @@ -60,10 +50,8 @@ SENTRY_NO_INIT /** * Creates a transaction, binds it to the hub and returns the instance. - * * @param name The transaction name. * @param operation Short code identifying the type of operation the span is measuring. - * * @return The created transaction. */ - (id)startTransactionWithName:(NSString *)name @@ -72,11 +60,9 @@ SENTRY_NO_INIT /** * Creates a transaction, binds it to the hub and returns the instance. - * * @param name The transaction name. * @param operation Short code identifying the type of operation the span is measuring. * @param bindToScope Indicates whether the SDK should bind the new transaction to the scope. - * * @return The created transaction. */ - (id)startTransactionWithName:(NSString *)name @@ -86,9 +72,7 @@ SENTRY_NO_INIT /** * Creates a transaction, binds it to the hub and returns the instance. - * * @param transactionContext The transaction context. - * * @return The created transaction. */ - (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext @@ -96,10 +80,8 @@ SENTRY_NO_INIT /** * Creates a transaction, binds it to the hub and returns the instance. - * * @param transactionContext The transaction context. * @param bindToScope Indicates whether the SDK should bind the new transaction to the scope. - * * @return The created transaction. */ - (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext @@ -108,11 +90,9 @@ SENTRY_NO_INIT /** * Creates a transaction, binds it to the hub and returns the instance. - * * @param transactionContext The transaction context. * @param bindToScope Indicates whether the SDK should bind the new transaction to the scope. * @param customSamplingContext Additional information about the sampling context. - * * @return The created transaction. */ - (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext @@ -122,10 +102,8 @@ SENTRY_NO_INIT /** * Creates a transaction, binds it to the hub and returns the instance. - * * @param transactionContext The transaction context. * @param customSamplingContext Additional information about the sampling context. - * * @return The created transaction. */ - (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext @@ -134,67 +112,54 @@ SENTRY_NO_INIT /** * Captures an error event and sends it to Sentry. - * * @param error The error to send to Sentry. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureError:(NSError *)error NS_SWIFT_NAME(capture(error:)); /** * Captures an error event and sends it to Sentry. - * * @param error The error to send to Sentry. * @param scope The scope containing event metadata. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureError:(NSError *)error withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(error:scope:)); /** * Captures an exception event and sends it to Sentry. - * * @param exception The exception to send to Sentry. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureException:(NSException *)exception NS_SWIFT_NAME(capture(exception:)); /** * Captures an exception event and sends it to Sentry. - * * @param exception The exception to send to Sentry. * @param scope The scope containing event metadata. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureException:(NSException *)exception withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(exception:scope:)); /** * Captures a message event and sends it to Sentry. - * * @param message The message to send to Sentry. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureMessage:(NSString *)message NS_SWIFT_NAME(capture(message:)); /** * Captures a message event and sends it to Sentry. - * * @param message The message to send to Sentry. * @param scope The scope containing event metadata. - * - * @return The SentryId of the event or SentryId.empty if the event is not sent. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. */ - (SentryId *)captureMessage:(NSString *)message withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(message:scope:)); /** * Captures a manually created user feedback and sends it to Sentry. - * * @param userFeedback The user feedback to send to Sentry. */ - (void)captureUserFeedback:(SentryUserFeedback *)userFeedback @@ -203,14 +168,12 @@ SENTRY_NO_INIT /** * Use this method to modify the Scope of the Hub. The SDK uses the Scope to attach * contextual data to events. - * * @param callback The callback for configuring the Scope of the Hub. */ - (void)configureScope:(void (^)(SentryScope *scope))callback; /** * Adds a breadcrumb to the Scope of the Hub. - * * @param crumb The Breadcrumb to add to the Scope of the Hub. */ - (void)addBreadcrumb:(SentryBreadcrumb *)crumb; @@ -221,7 +184,7 @@ SENTRY_NO_INIT - (SentryClient *_Nullable)getClient; /** - * Returns either the current scope and if nil a new one. + * Returns either the current scope or a new one if it was @c nil . */ @property (nonatomic, readonly, strong) SentryScope *scope; @@ -236,15 +199,14 @@ SENTRY_NO_INIT - (BOOL)hasIntegration:(NSString *)integrationName; /** - * Checks if a specific Integration (`integrationClass`) has been installed. - * - * @return BOOL If instance of `integrationClass` exists within `SentryHub.installedIntegrations`. + * Checks if a specific Integration (@c integrationClass) has been installed. + * @return @c YES if instance of @c integrationClass exists within + * @c SentryHub.installedIntegrations */ - (BOOL)isIntegrationInstalled:(Class)integrationClass; /** * Set user to the Scope of the Hub. - * * @param user The user to set to the Scope. */ - (void)setUser:(SentryUser *_Nullable)user; @@ -253,13 +215,12 @@ SENTRY_NO_INIT * Waits synchronously for the SDK to flush out all queued and cached items for up to the specified * timeout in seconds. If there is no internet connection, the function returns immediately. The SDK * doesn't dispose the client or the hub. - * * @param timeout The time to wait for the SDK to complete the flush. */ - (void)flush:(NSTimeInterval)timeout NS_SWIFT_NAME(flush(timeout:)); /** - * Calls flush with ``SentryOptions/shutdownTimeInterval``. + * Calls flush with @c SentryOptions/shutdownTimeInterval . */ - (void)close; diff --git a/Sources/Sentry/Public/SentryId.h b/Sources/Sentry/Public/SentryId.h index dba269d2e5..2024a374ff 100644 --- a/Sources/Sentry/Public/SentryId.h +++ b/Sources/Sentry/Public/SentryId.h @@ -6,13 +6,13 @@ NS_ASSUME_NONNULL_BEGIN * A wrapper around UUID. * UUIDs are declared as either 32 character hexadecimal strings without dashes * "12c2d058d58442709aa2eca08bf20986", or 36 character strings with dashes - * "12c2d058-d584-4270-9aa2-eca08bf20986". It is recommended to omit dashes and use UUID v4 in all - * cases. + * "12c2d058-d584-4270-9aa2-eca08bf20986". + * @note It is recommended to omit dashes and use UUID v4 in cases. */ @interface SentryId : NSObject /** - * Creates a SentryId with a random SentryId. + * Creates a @c SentryId with a random UUID. */ - (instancetype)init; @@ -22,22 +22,21 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithUUID:(NSUUID *)uuid; /** - * Creates a SentryId from a 32 character hexadecimal string without dashes such as + * Creates a @c SentryId from a 32 character hexadecimal string without dashes such as * "12c2d058d58442709aa2eca08bf20986" or a 36 character hexadecimal string such as such as * "12c2d058-d584-4270-9aa2-eca08bf20986". - * * @return SentryId.empty for invalid strings. */ - (instancetype)initWithUUIDString:(NSString *)string; /** - * Returns a 32 lowercase character hexadecimal string description of the SentryId, such as + * Returns a 32 lowercase character hexadecimal string description of the @c SentryId, such as * "12c2d058d58442709aa2eca08bf20986". */ @property (readonly, copy) NSString *sentryIdString; /** - * A SentryId with an empty UUID "00000000000000000000000000000000". + * A @c SentryId with an empty UUID "00000000000000000000000000000000". */ @property (class, nonatomic, readonly, strong) SentryId *empty; diff --git a/Sources/Sentry/Public/SentryMeasurementUnit.h b/Sources/Sentry/Public/SentryMeasurementUnit.h index e7a5b3462a..3e2183bcf6 100644 --- a/Sources/Sentry/Public/SentryMeasurementUnit.h +++ b/Sources/Sentry/Public/SentryMeasurementUnit.h @@ -4,13 +4,12 @@ NS_ASSUME_NONNULL_BEGIN /** * The unit of measurement of a metric value. - * - * Units augment metric values by giving them a magnitude and semantics. There are certain types - * of units that are subdivided in their precision, such as the ``SentryMeasurementUnitDuration`` - * for time measurements. The following unit types are available: ``SentryMeasurementUnitDuration``, - * ``SentryMeasurementUnitInformation``, and``SentryMeasurementUnitFraction``. - * - * When using the units to custom measurements, Sentry will apply formatting to display + * @discussion Units augment metric values by giving them a magnitude and semantics. There are + * certain types of units that are subdivided in their precision, such as the + * @c SentryMeasurementUnitDuration for time measurements. The following unit types are available: + * @c SentryMeasurementUnitDuration , + * @c SentryMeasurementUnitInformation , and @c SentryMeasurementUnitFraction . + * @note When using the units to custom measurements, Sentry will apply formatting to display * measurement values in the UI. */ NS_SWIFT_NAME(MeasurementUnit) @@ -19,17 +18,18 @@ SENTRY_NO_INIT /** * Returns an initialized SentryMeasurementUnit with a custom measurement unit. - * * @param unit Your own custom unit without built-in conversion in Sentry. */ - (instancetype)initWithUnit:(NSString *)unit; /** - * The NSString representation of the measurement unit. + * The @c NSString representation of the measurement unit. */ @property (readonly, copy) NSString *unit; -/** Untyped value without a unit. */ +/** + * Untyped value without a unit. + */ @property (class, readonly, copy) SentryMeasurementUnit *none; @end @@ -41,81 +41,124 @@ NS_SWIFT_NAME(MeasurementUnitDuration) @interface SentryMeasurementUnitDuration : SentryMeasurementUnit SENTRY_NO_INIT -/** Nanosecond, 10^-9 seconds. */ +/** + * Nanosecond, 10^-9 seconds. + */ @property (class, readonly, copy) SentryMeasurementUnitDuration *nanosecond; -/** Microsecond , 10^-6 seconds. */ +/** + * Microsecond , 10^-6 seconds. + */ @property (class, readonly, copy) SentryMeasurementUnitDuration *microsecond; -/** Millisecond, 10^-3 seconds. */ +/** + * Millisecond, 10^-3 seconds. + */ @property (class, readonly, copy) SentryMeasurementUnitDuration *millisecond; -/** Full second. */ +/** + * Full second. + */ @property (class, readonly, copy) SentryMeasurementUnitDuration *second; -/** Minute, 60 seconds. */ +/** + * Minute, 60 seconds. + */ @property (class, readonly, copy) SentryMeasurementUnitDuration *minute; -/** Hour, 3600 seconds. */ +/** + * Hour, 3600 seconds. + */ @property (class, readonly, copy) SentryMeasurementUnitDuration *hour; -/** Day, 86,400 seconds. */ +/** + * Day, 86,400 seconds. + */ @property (class, readonly, copy) SentryMeasurementUnitDuration *day; -/** Week, 604,800 seconds. */ +/** + * Week, 604,800 seconds. + */ @property (class, readonly, copy) SentryMeasurementUnitDuration *week; @end /** * Size of information units derived from bytes. - * - * See also [Units of information](https://en.wikipedia.org/wiki/Units_of_information) + * @see https://en.wikipedia.org/wiki/Units_of_information */ NS_SWIFT_NAME(MeasurementUnitInformation) @interface SentryMeasurementUnitInformation : SentryMeasurementUnit SENTRY_NO_INIT -/** Bit, corresponding to 1/8 of a byte. */ +/** + * Bit, corresponding to 1/8 of a byte + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *bit; -/** Byte. */ +/** + * Byte. + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *byte; -/** Kilobyte, 10^3 bytes. */ +/** + * Kilobyte, 10^3 bytes + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *kilobyte; -/** Kibibyte, 2^10 bytes. */ +/** + * Kibibyte, 2^10 bytes. + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *kibibyte; -/** Megabyte, 10^6 bytes. */ +/** + * Megabyte, 10^6 bytes + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *megabyte; -/** Mebibyte, 2^20 bytes. */ +/** + * Mebibyte, 2^20 bytes. + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *mebibyte; -/** Gigabyte, 10^9 bytes. */ +/** + * Gigabyte, 10^9 bytes + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *gigabyte; -/** Gibibyte, 2^30 bytes. */ +/** + * Gibibyte, 2^30 bytes. + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *gibibyte; -/** Terabyte, 10^12 bytes. */ +/** + * Terabyte, 10^12 bytes + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *terabyte; -/** Tebibyte, 2^40 bytes. */ +/** + * Tebibyte, 2^40 bytes. + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *tebibyte; -/** Petabyte, 10^15 bytes. */ +/** + * Petabyte, 10^15 bytes + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *petabyte; -/** Pebibyte, 2^50 bytes. */ +/** + * Pebibyte, 2^50 bytes. + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *pebibyte; -/** Exabyte, 10^18 bytes. */ +/** + * Exabyte, 10^18 bytes + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *exabyte; -/** Exbibyte, 2^60 bytes. */ +/** + * Exbibyte, 2^60 bytes. + */ @property (class, readonly, copy) SentryMeasurementUnitInformation *exbibyte; @end @@ -123,14 +166,18 @@ SENTRY_NO_INIT /** * Units of fraction. */ -NS_SWIFT_NAME(MeasurementUnitFraction) -@interface SentryMeasurementUnitFraction : SentryMeasurementUnit +NS_SWIFT_NAME(MeasurementUnitFraction) @interface SentryMeasurementUnitFraction + : SentryMeasurementUnit SENTRY_NO_INIT -/** Floating point fraction of `1`. */ +/** + * Floating point fraction of @c 1 . g + */ @property (class, readonly, copy) SentryMeasurementUnitFraction *ratio; -/** Ratio expressed as a fraction of `100`. `100%` equals a ratio of `1.0`. */ +/** + * Ratio expressed as a fraction of @c 100 @c 100% equals a ratio of @c 1.0 + */ @property (class, readonly, copy) SentryMeasurementUnitFraction *percent; @end diff --git a/Sources/Sentry/Public/SentryMechanism.h b/Sources/Sentry/Public/SentryMechanism.h index 4c997741c9..eb295e8dc7 100644 --- a/Sources/Sentry/Public/SentryMechanism.h +++ b/Sources/Sentry/Public/SentryMechanism.h @@ -31,7 +31,7 @@ SENTRY_NO_INIT /** * Flag indicating whether the exception has been handled by the user - * (e.g. via ``try..catch``) + * (e.g. via @c try..catch ) */ @property (nonatomic, copy) NSNumber *_Nullable handled; diff --git a/Sources/Sentry/Public/SentryMechanismMeta.h b/Sources/Sentry/Public/SentryMechanismMeta.h index 891f9794b3..6a0099667e 100644 --- a/Sources/Sentry/Public/SentryMechanismMeta.h +++ b/Sources/Sentry/Public/SentryMechanismMeta.h @@ -9,8 +9,7 @@ NS_ASSUME_NONNULL_BEGIN /** * The mechanism metadata usually carries error codes reported by the runtime or operating system, * along with a platform-dependent interpretation of these codes. - * - * See https://develop.sentry.dev/sdk/event-payloads/exception/#meta-information. + * @see https://develop.sentry.dev/sdk/event-payloads/exception/#meta-information. */ NS_SWIFT_NAME(MechanismMeta) @interface SentryMechanismMeta : NSObject @@ -29,7 +28,7 @@ NS_SWIFT_NAME(MechanismMeta) @property (nullable, nonatomic, strong) NSDictionary *machException; /** - * Sentry uses the NSErrors domain and code for grouping. Only domain and code are serialized. + * Sentry uses the @c NSErrors domain and code for grouping. Only domain and code are serialized. */ @property (nullable, nonatomic, strong) SentryNSError *error; diff --git a/Sources/Sentry/Public/SentryMessage.h b/Sources/Sentry/Public/SentryMessage.h index bd61581b3b..68269a6820 100644 --- a/Sources/Sentry/Public/SentryMessage.h +++ b/Sources/Sentry/Public/SentryMessage.h @@ -7,15 +7,13 @@ NS_ASSUME_NONNULL_BEGIN /** * Carries a log message that describes an event or error. Optionally, it can carry a format string * and structured parameters. This can help to group similar messages into the same issue. - * - * For more info checkout: https://develop.sentry.dev/sdk/event-payloads/message/ + * @see https://develop.sentry.dev/sdk/event-payloads/message/ */ @interface SentryMessage : NSObject SENTRY_NO_INIT /** - * Returns a SentyMessage with setting formatted. - * + * Returns a @c SentryMessage with setting formatted. * @param formatted The fully formatted message. If missing, Sentry will try to interpolate the * message. It must not exceed 8192 characters. Longer messages will be truncated. */ diff --git a/Sources/Sentry/Public/SentryNSError.h b/Sources/Sentry/Public/SentryNSError.h index af74383bd2..a4e6fd8d53 100644 --- a/Sources/Sentry/Public/SentryNSError.h +++ b/Sources/Sentry/Public/SentryNSError.h @@ -5,26 +5,25 @@ NS_ASSUME_NONNULL_BEGIN /** - * Sentry representation of an NSError to send to Sentry. + * Sentry representation of an @c NSError to send to Sentry. */ @interface SentryNSError : NSObject SENTRY_NO_INIT /** - * The domain of an NSError. + * The domain of an @c NSError . */ @property (nonatomic, copy) NSString *domain; /** - * The error code of an NSError + * The error code of an @c NSError . */ @property (nonatomic, assign) NSInteger code; /** - * Initializes SentryNSError and sets the domain and code. - * - * @param domain The domain of an NSError. - * @param code The error code of an NSError. + * Initializes @c SentryNSError and sets the domain and code. + * @param domain The domain of an @c NSError. + * @param code The error code of an @c NSError. */ - (instancetype)initWithDomain:(NSString *)domain code:(NSInteger)code; diff --git a/Sources/Sentry/Public/SentryOptions.h b/Sources/Sentry/Public/SentryOptions.h index 782609f45b..6f93464e3b 100644 --- a/Sources/Sentry/Public/SentryOptions.h +++ b/Sources/Sentry/Public/SentryOptions.h @@ -21,12 +21,14 @@ NS_SWIFT_NAME(Options) /** * Turns debug mode on or off. If debug is enabled SDK will attempt to print out useful debugging - * information if something goes wrong. Default is disabled. + * information if something goes wrong. + * @note Default is @c NO. */ @property (nonatomic, assign) BOOL debug; /** - * Minimum LogLevel to be used if debug is enabled. Default is debug. + * Minimum LogLevel to be used if debug is enabled. + * @note Default is @c kSentryLevelDebug. */ @property (nonatomic, assign) SentryLevel diagnosticLevel; @@ -37,79 +39,78 @@ NS_SWIFT_NAME(Options) /** * The distribution of the application. - * * @discussion Distributions are used to disambiguate build or deployment variants of the same - * release of an application. For example, the dist can be the build number of an Xcode build. + * release of an application. For example, the @c dist can be the build number of an Xcode build. * */ @property (nullable, nonatomic, copy) NSString *dist; /** - * The environment used for this event. Default value is "production". + * The environment used for this event. + * @note Default value is @c @"production". */ @property (nonatomic, copy) NSString *environment; /** - * Specifies wether this SDK should send events to Sentry. If set to NO events will be - * dropped in the client and not sent to Sentry. Default is YES. + * Specifies wether this SDK should send events to Sentry. If set to @c NO events will be + * dropped in the client and not sent to Sentry. Default is @c YES. */ @property (nonatomic, assign) BOOL enabled; /** - * Controls the flush duration when calling ``SentrySDK/close``. + * Controls the flush duration when calling @c SentrySDK/close . */ @property (nonatomic, assign) NSTimeInterval shutdownTimeInterval; /** - * When enabled, the SDK sends crashes to Sentry. Default value is YES. - * - * Disabling this feature disables the ``SentryWatchdogTerminationTrackingIntegration``, cause the - * ``SentryWatchdogTerminationTrackingIntegration`` would falsely report every crash as watchdog + * When enabled, the SDK sends crashes to Sentry. + * @note Disabling this feature disables the @c SentryWatchdogTerminationTrackingIntegration , + * because + * @c SentryWatchdogTerminationTrackingIntegration would falsely report every crash as watchdog * termination. + * @note Default value is @c YES . */ @property (nonatomic, assign) BOOL enableCrashHandler; /** * How many breadcrumbs do you want to keep in memory? - * Default is 100. + * @note Default is @c 100 . */ @property (nonatomic, assign) NSUInteger maxBreadcrumbs; /** - * When enabled, the SDK adds breadcrumbs for each network request. Default value is - * YES. As this feature uses swizzling, disabling enableSwizzling also - * disables this feature. - * + * When enabled, the SDK adds breadcrumbs for each network request. As this feature uses swizzling, + * disabling @c enableSwizzling also disables this feature. * @discussion If you want to enable or disable network tracking for performance monitoring, please - * use enableNetworkTracking instead. + * use @c enableNetworkTracking instead. + * @note Default value is @c YES . */ @property (nonatomic, assign) BOOL enableNetworkBreadcrumbs; /** - * The maximum number of envelopes to keep in cache. Default is 30. + * The maximum number of envelopes to keep in cache. + * @note Default is @c 30 . */ @property (nonatomic, assign) NSUInteger maxCacheItems; /** - * This block can be used to modify the event before it will be serialized and - * sent + * This block can be used to modify the event before it will be serialized and sent. */ @property (nullable, nonatomic, copy) SentryBeforeSendEventCallback beforeSend; /** - * This block can be used to modify the event before it will be serialized and - * sent + * This block can be used to modify the event before it will be serialized and sent. */ @property (nullable, nonatomic, copy) SentryBeforeBreadcrumbCallback beforeBreadcrumb; /** - * This gets called shortly after the initialization of the SDK when the last program execution - * terminated with a crash. It is not guaranteed that this is called on the main thread. - * + * A block called shortly after the initialization of the SDK when the last program execution + * terminated with a crash. * @discussion This callback is only executed once during the entire run of the program to avoid * multiple callbacks if there are multiple crash events to send. This can happen when the program - * terminates with a crash before the SDK can send the crash event. You can look into beforeSend if - * you prefer a callback for every event. + * terminates with a crash before the SDK can send the crash event. You can look into @c beforeSend + * if you prefer a callback for every event. + * @warning It is not guaranteed that this is called on the main thread. */ @property (nullable, nonatomic, copy) SentryOnCrashedLastRunCallback onCrashedLastRun; @@ -119,34 +120,37 @@ NS_SWIFT_NAME(Options) @property (nullable, nonatomic, copy) NSArray *integrations; /** - * Array of default integrations. Will be used if integrations are nil + * Array of default integrations. Will be used if @c integrations is @c nil . */ + (NSArray *)defaultIntegrations; /** - * Indicates the percentage of events being sent to Sentry. Setting this to 0 discards all - * events, 1.0 or NIL sends all events, 0.01 collects 1% of all events. The default is 1. The value - * needs to be >= 0.0 and <= 1.0. When setting a value out of range the SDK sets it to the default - * of 1.0. + * Indicates the percentage of events being sent to Sentry. + * @discussion Specifying @c 0 discards all events, @c 1.0 or @c nil sends all events, @c 0.01 + * collects 1% of all events. + * @note The value needs to be >= @c 0.0 and \<= @c 1.0. When setting a value out of range the SDK + * sets it to the default of @c 1.0. + * @note The default is @c 1 . */ @property (nullable, nonatomic, copy) NSNumber *sampleRate; /** - * Whether to enable automatic session tracking or not. Default is YES. + * Whether to enable automatic session tracking or not. + * @note Default is @c YES. */ @property (nonatomic, assign) BOOL enableAutoSessionTracking; /** - * Whether to enable Watchdog Termination tracking or not. Default is YES. - * - * This feature requires the ``SentryCrashIntegration`` being enabled, cause otherwise it would + * Whether to enable Watchdog Termination tracking or not. + * @note This feature requires the @c SentryCrashIntegration being enabled, otherwise it would * falsely report every crash as watchdog termination. + * @note Default is @c YES. */ @property (nonatomic, assign) BOOL enableWatchdogTerminationTracking; /** * The interval to end a session after the App goes to the background. - * The default is 30 seconds. + * @note The default is 30 seconds. */ @property (nonatomic, assign) NSUInteger sessionTrackingIntervalMillis; @@ -154,37 +158,33 @@ NS_SWIFT_NAME(Options) * When enabled, stack traces are automatically attached to all messages logged. Stack traces are * always attached to exceptions but when this is set stack traces are also sent with messages. * Stack traces are only attached for the current thread. - * - * This feature is enabled by default. + * @note This feature is enabled by default. */ @property (nonatomic, assign) BOOL attachStacktrace; /** - * Attention: This is an experimental feature. Turning this feature on can have an impact on - * the grouping of your issues. - * - * When enabled, the SDK stitches stack traces of asynchronous code together. - * - * This feature is disabled by default. + * @warning This is an experimental feature and may still have bugs. Turning this feature on can + * have an impact on the grouping of your issues. + * @brief When enabled, the SDK stitches stack traces of asynchronous code together. + * @note This feature is disabled by default. */ @property (nonatomic, assign) BOOL stitchAsyncCode; /** - * The maximum size for each attachment in bytes. Default is 20 MiB / 20 * 1024 * 1024 bytes. - * - * Please also check the maximum attachment size of relay to make sure your attachments don't get - * discarded there: https://docs.sentry.io/product/relay/options/ + * The maximum size for each attachment in bytes. + * @note Default is 20 MiB (20 ✕ 1024 ✕ 1024 bytes). + * @note Please also check the maximum attachment size of relay to make sure your attachments don't + * get discarded there: https://docs.sentry.io/product/relay/options/ */ @property (nonatomic, assign) NSUInteger maxAttachmentSize; /** - * When enabled, the SDK sends personal identifiable along with events. The default is - * NO. - * + * When enabled, the SDK sends personal identifiable along with events. + * @note The default is @c NO . * @discussion When the user of an event doesn't contain an IP address, and this flag is - * YES, the SDK sets it to {{auto}} to instruct the server to use the + * @c YES, the SDK sets it to @c {{auto}} to instruct the server to use the * connection IP address as the user address. Due to backward compatibility concerns, Sentry set the - * IP address to {{auto}} out of the box for Cocoa. If you want to stop Sentry from + * IP address to @c {{auto}} out of the box for Cocoa. If you want to stop Sentry from * using the connections IP address, you have to enable Prevent Storing of IP Addresses in your * project settings in Sentry. */ @@ -192,59 +192,56 @@ NS_SWIFT_NAME(Options) /** * When enabled, the SDK tracks performance for UIViewController subclasses and HTTP requests - * automatically. It also measures the app start and slow and frozen frames. The default is - * YES. Note: Performance Monitoring must be enabled for this flag to take effect. See: + * automatically. It also measures the app start and slow and frozen frames. + * @note The default is @c YES . + * @note Performance Monitoring must be enabled for this flag to take effect. See: * https://docs.sentry.io/platforms/apple/performance/ */ @property (nonatomic, assign) BOOL enableAutoPerformanceTracing; #if SENTRY_HAS_UIKIT /** - * When enabled, the SDK tracks performance for UIViewController subclasses. The default is - * YES. + * When enabled, the SDK tracks performance for UIViewController subclasses. + * @note The default is @c YES . */ @property (nonatomic, assign) BOOL enableUIViewControllerTracing; /** * Automatically attaches a screenshot when capturing an error or exception. - * - * Default value is NO + * @note Default value is @c NO . */ @property (nonatomic, assign) BOOL attachScreenshot; /** - * This feature is EXPERIMENTAL. - * - * Automatically attaches a textual representation of the view hierarchy when capturing an error - * event. - * - * Default value is NO + * @warning This is an experimental feature and may still have bugs. + * @brief Automatically attaches a textual representation of the view hierarchy when capturing an + * error event. + * @note Default value is @c NO . */ @property (nonatomic, assign) BOOL attachViewHierarchy; /** * When enabled, the SDK creates transactions for UI events like buttons clicks, switch toggles, - * and other ui elements that uses UIControl `sendAction:to:forEvent:`. + * and other ui elements that uses UIControl @c sendAction:to:forEvent: */ @property (nonatomic, assign) BOOL enableUserInteractionTracing; /** * How long an idle transaction waits for new children after all its child spans finished. Only UI - * event transactions are idle transactions. The default is 3 seconds. + * event transactions are idle transactions. + * @note The default is 3 seconds. */ @property (nonatomic, assign) NSTimeInterval idleTimeout; /** - * This feature is EXPERIMENTAL. - * - * Report pre-warmed app starts by dropping the first app start spans if pre-warming paused during - * these steps. This approach will shorten the app start duration, but it represents the duration a - * user has to wait after clicking the app icon until the app is responsive. - * - * You can filter for different app start types in Discover with app_start_type:cold.prewarmed, - * app_start_type:warm.prewarmed, app_start_type:cold, and app_start_type:warm. - * - * Default value is NO + * @warning This is an experimental feature and may still have bugs. + * @brief Report pre-warmed app starts by dropping the first app start spans if pre-warming paused + * during these steps. This approach will shorten the app start duration, but it represents the + * duration a user has to wait after clicking the app icon until the app is responsive. + * @note You can filter for different app start types in Discover with + * @c app_start_type:cold.prewarmed , + * @c app_start_type:warm.prewarmed , @c app_start_type:cold , and @c app_start_type:warm . + * @note Default value is @c NO . */ @property (nonatomic, assign) BOOL enablePreWarmedAppStartTracing; @@ -252,139 +249,144 @@ NS_SWIFT_NAME(Options) /** * When enabled, the SDK tracks performance for HTTP requests if auto performance tracking and - * enableSwizzling are enabled. The default is YES. - * + * @c enableSwizzling are enabled. + * @note The default is @c YES . * @discussion If you want to enable or disable network breadcrumbs, please use - * enableNetworkBreadcrumbs instead. + * @c enableNetworkBreadcrumbs instead. */ @property (nonatomic, assign) BOOL enableNetworkTracking; /** * When enabled, the SDK tracks performance for file IO reads and writes with NSData if auto - * performance tracking and enableSwizzling are enabled. The default is YES. + * performance tracking and enableSwizzling are enabled. + * @note The default is @c YES . */ @property (nonatomic, assign) BOOL enableFileIOTracing; /** * Indicates whether tracing should be enabled. - * Enabling this sets `tracesSampleRate` to 1 if both - * `tracesSampleRate` and `tracesSampler` are nil. - * - * Changing either `tracesSampleRate` or `tracesSampler` to - * a value other then nil will enable this in case this was never changed before. + * @discussion Enabling this sets @c tracesSampleRate to @c 1 if both @c tracesSampleRate and + * @c tracesSampler are @c nil. Changing either @c tracesSampleRate or @c tracesSampler to a value + * other then @c nil will enable this in case this was never changed before. */ @property (nonatomic) BOOL enableTracing; /** - * Indicates the percentage of the tracing data that is collected. Setting this to 0 or NIL discards - * all trace data, 1.0 collects all trace data, 0.01 collects 1% of all trace data. The default is - * 0. The value needs to be >= 0.0 and <= 1.0. When setting a value out of range the SDK sets it to - * the default of 0. + * Indicates the percentage of the tracing data that is collected. + * @discussion Specifying @c 0 or @c nil discards all trace data, @c 1.0 collects all trace data, + * @c 0.01 collects 1% of all trace data. + * @note The value needs to be >= 0.0 and \<= 1.0. When setting a value out of range the SDK sets it + * to the default. + * @note The default is @c 0 . */ @property (nullable, nonatomic, strong) NSNumber *tracesSampleRate; /** - * A callback to a user defined traces sampler function. Returning 0 or NIL discards all trace - * data, 1.0 collects all trace data, 0.01 collects 1% of all trace data. The sample rate needs to - * be >= 0.0 and <= 1.0 or NIL. When returning a value out of range the SDK uses the default of 0. + * A callback to a user defined traces sampler function. + * @discussion Specifying @c 0 or @c nil discards all trace data, @c 1.0 collects all trace data, + * @c 0.01 collects 1% of all trace data. + * @note The value needs to be >= 0.0 and \<= 1.0. When setting a value out of range the SDK sets it + * to the default of @c 0 . */ @property (nullable, nonatomic) SentryTracesSamplerCallback tracesSampler; /** - * If tracing is enabled or not. Returns YES if enabledTracing is YES and either a tracesSampleRate - * > 0 and <=1 or a tracesSampler is set otherwise NO. + * If tracing is enabled or not. + * @discussion @c YES if @c enabledTracing is @c YES and @c tracesSampleRate + * is > @c 0 and \<= @c 1 or a @c tracesSampler is set, otherwise @c NO. */ @property (nonatomic, assign, readonly) BOOL isTracingEnabled; /** - * A list of string prefixes of framework names that belong to the app. This option takes precedence - * over inAppExcludes. Per default this contains CFBundleExecutable to mark it as inApp. + * A list of string prefixes of framework names that belong to the app. + * @note This option takes precedence over @c inAppExcludes. + * @note By default, this contains @c CFBundleExecutable to mark it as "in-app". */ @property (nonatomic, readonly, copy) NSArray *inAppIncludes; /** - * Adds an item to the list of inAppIncludes. - * + * Adds an item to the list of @c inAppIncludes. * @param inAppInclude The prefix of the framework name. */ - (void)addInAppInclude:(NSString *)inAppInclude; /** * A list of string prefixes of framework names that do not belong to the app, but rather to - * third-party frameworks. Frameworks considered not part of the app will be hidden from stack - * traces by default. - * - * This option can be overridden using inAppIncludes. + * third-party frameworks. + * @note By default, frameworks considered not part of the app will be hidden from stack + * traces. + * @note This option can be overridden using @c inAppIncludes. */ @property (nonatomic, readonly, copy) NSArray *inAppExcludes; /** - * Adds an item to the list of inAppExcludes. - * + * Adds an item to the list of @c inAppExcludes. * @param inAppExclude The prefix of the frameworks name. */ - (void)addInAppExclude:(NSString *)inAppExclude; /** - * Set as delegate on the NSURLSession used for all network data-transfer tasks performed by Sentry. + * Set as delegate on the @c NSURLSession used for all network data-transfer tasks performed by + * Sentry. */ @property (nullable, nonatomic, weak) id urlSessionDelegate; /** - * Wether the SDK should use swizzling or not. Default is YES. - * + * Wether the SDK should use swizzling or not. * @discussion When turned off the following features are disabled: breadcrumbs for touch events and - * navigation with UIViewControllers, automatic instrumentation for UIViewControllers, automatic - * instrumentation for HTTP requests, automatic instrumentation for file IO with NSData, and - * automatically added sentry-trace header to HTTP requests for distributed tracing. + * navigation with @c UIViewControllers, automatic instrumentation for @c UIViewControllers, + * automatic instrumentation for HTTP requests, automatic instrumentation for file IO with + * @c NSData, and automatically added sentry-trace header to HTTP requests for distributed tracing. + * @note Default is @c YES. */ @property (nonatomic, assign) BOOL enableSwizzling; /** * When enabled, the SDK tracks the performance of Core Data operations. It requires enabling - * performance monitoring. The default is YES. + * performance monitoring. The default is @c YES. * @see */ @property (nonatomic, assign) BOOL enableCoreDataTracing; #if SENTRY_TARGET_PROFILING_SUPPORTED /** - * This feature is experimental. Profiling is not supported on watchOS or tvOS. - * + * @warning This is a beta feature and may still have bugs. + * @note Profiling is not supported on watchOS or tvOS. * Indicates the percentage profiles being sampled out of the sampled transactions. - * - * The default is 0. The value needs to be >= 0.0 and <= 1.0. When setting a value out of range - * the SDK sets it to the default of 0. - * - * This property is dependent on `tracesSampleRate` -- if `tracesSampleRate` is 0 (default), + * @note The default is @c 0. + * @note The value needs to be >= @c 0.0 and \<= @c 1.0. When setting a value out of range + * the SDK sets it to the default of @c 0. + * This property is dependent on @c tracesSampleRate -- if @c tracesSampleRate is @c 0 (default), * no profiles will be collected no matter what this property is set to. This property is - * used to undersample profiles *relative to* `tracesSampleRate`. + * used to undersample profiles *relative to* @c tracesSampleRate */ @property (nullable, nonatomic, strong) NSNumber *profilesSampleRate; /** - * This feature is experimental. Profiling is not supported on watchOS or tvOS. - * + * @warning This is a beta feature and may still have bugs. + * @note Profiling is not supported on watchOS or tvOS. * A callback to a user defined profiles sampler function. This is similar to setting - * `profilesSampleRate`, but instead of a static value, the callback function will be called to + * @c profilesSampleRate but instead of a static value, the callback function will be called to * determine the sample rate. */ @property (nullable, nonatomic) SentryTracesSamplerCallback profilesSampler; /** - * If profiling should be enabled or not. Returns YES if either a profilesSampleRate > 0 and - * <=1 or a profilesSampler is set otherwise NO. + * @warning This is a beta feature and may still have bugs. + * @note Profiling is not supported on watchOS or tvOS. + * If profiling should be enabled or not. Returns @c YES if either a profilesSampleRate > @c 0 and + * \<= @c 1 or a profilesSampler is set otherwise @c NO. */ @property (nonatomic, assign, readonly) BOOL isProfilingEnabled; /** - * DEPRECATED: Use `profilesSampleRate` instead. Setting `enableProfiling` to YES is the equivalent - * of setting `profilesSampleRate` to `1.0`. If `profilesSampleRate` is set, it will take precedence - * over this setting. - * - * Whether to enable the sampling profiler. Default is NO. - * @note This is a beta feature that is currently not available to all Sentry customers. This - * feature is not supported on watchOS or tvOS. + * @warning This is a beta feature and may still have bugs. + * @brief Whether to enable the sampling profiler. + * @note Profiling is not supported on watchOS or tvOS. + * @deprecated Use @c profilesSampleRate instead. Setting @c enableProfiling to @c YES is the + * equivalent of setting @c profilesSampleRate to @c 1.0 If @c profilesSampleRate is set, it will + * take precedence over this setting. + * @note Default is @c NO. */ @property (nonatomic, assign) BOOL enableProfiling DEPRECATED_MSG_ATTRIBUTE( "Use profilesSampleRate or profilesSampler instead. This property will be removed in a future " @@ -392,81 +394,79 @@ NS_SWIFT_NAME(Options) #endif /** - * Whether to send client reports, which contain statistics about discarded events. The default is - * YES. - * + * Whether to send client reports, which contain statistics about discarded events. + * @note The default is @c YES. * @see */ @property (nonatomic, assign) BOOL sendClientReports; /** * When enabled, the SDK tracks when the application stops responding for a specific amount of - * time defined by the `appHangsTimeoutInterval` option. The default is - * YES + * time defined by the @c appHangsTimeoutInterval option. + * @note The default is @c YES */ @property (nonatomic, assign) BOOL enableAppHangTracking; /** * The minimum amount of time an app should be unresponsive to be classified as an App Hanging. - * The actual amount may be a little longer. - * Avoid using values lower than 100ms, which may cause a lot of app hangs events being transmitted. - * The default value is 2 seconds. + * @note The actual amount may be a little longer. + * @note Avoid using values lower than 100ms, which may cause a lot of app hangs events being + * transmitted. + * @note The default value is 2 seconds. */ @property (nonatomic, assign) NSTimeInterval appHangTimeoutInterval; /** - * When enabled, the SDK adds breadcrumbs for various system events. Default value is YES. + * When enabled, the SDK adds breadcrumbs for various system events. + * @note Default value is @c YES. */ @property (nonatomic, assign) BOOL enableAutoBreadcrumbTracking; /** * An array of hosts or regexes that determines if outgoing HTTP requests will get - * extra `trace_id` and `baggage` headers added. - * - * This array can contain instances of NSString which should match the URL (using `contains`), - * and instances of NSRegularExpression, which will be used to check the whole URL. - * - * The default value adds the header to all outgoing requests. - * + * extra @c trace_id and @c baggage headers added. + * @discussion This array can contain instances of @c NSString which should match the URL (using + * @c contains ), and instances of @c NSRegularExpression, which will be used to check the whole + * URL. + * @note The default value adds the header to all outgoing requests. * @see https://docs.sentry.io/platforms/apple/configuration/options/#trace-propagation-targets */ @property (nonatomic, retain) NSArray *tracePropagationTargets; /** * When enabled, the SDK captures HTTP Client errors. - * This feature requires enableSwizzling enabled as well, Default value is YES. + * @note This feature requires @c enableSwizzling enabled as well. + * @note Default value is @c YES. */ @property (nonatomic, assign) BOOL enableCaptureFailedRequests; /** * The SDK will only capture HTTP Client errors if the HTTP Response status code is within the * defined range. - * - * Defaults to 500 - 599. + * @note Defaults to 500 - 599. */ @property (nonatomic, strong) NSArray *failedRequestStatusCodes; /** * An array of hosts or regexes that determines if HTTP Client errors will be automatically * captured. - * - * This array can contain instances of NSString which should match the URL (using `contains`), - * and instances of NSRegularExpression, which will be used to check the whole URL. - * - * The default value automatically captures HTTP Client errors of all outgoing requests. + * @discussion This array can contain instances of @c NSString which should match the URL (using + * @c contains ), and instances of @c NSRegularExpression, which will be used to check the whole + * URL. + * @note The default value automatically captures HTTP Client errors of all outgoing requests. */ @property (nonatomic, strong) NSArray *failedRequestTargets; #if SENTRY_HAS_METRIC_KIT /** - * ATTENTION: This is an experimental feature. - * - * This feature is disabled by default. When enabled, the SDK sends - * ``MXDiskWriteExceptionDiagnostic``, ``MXCPUExceptionDiagnostic`` and ``MXHangDiagnostic`` to - * Sentry. The SDK supports this feature from iOS 15 and later and macOS 12 and later because, on - * these versions, MetricKit delivers diagnostic reports immediately, which allows the Sentry SDK to - * apply the current data from the scope. + * @warning This is an experimental feature and may still have bugs. + * @brief When enabled, the SDK sends @c MXDiskWriteExceptionDiagnostic, @c MXCPUExceptionDiagnostic + * and + * @c MXHangDiagnostic to Sentry. The SDK supports this feature from iOS 15 and later and macOS 12 + * and later because, on these versions, @c MetricKit delivers diagnostic reports immediately, which + * allows the Sentry SDK to apply the current data from the scope. + * @note This feature is disabled by default. */ @property (nonatomic, assign) BOOL enableMetricKit API_AVAILABLE( ios(15.0), macos(12.0), macCatalyst(15.0)) API_UNAVAILABLE(tvos, watchos); diff --git a/Sources/Sentry/Public/SentrySDK.h b/Sources/Sentry/Public/SentrySDK.h index 6ceee4f6c2..ec2a04547d 100644 --- a/Sources/Sentry/Public/SentrySDK.h +++ b/Sources/Sentry/Public/SentrySDK.h @@ -9,8 +9,7 @@ NS_ASSUME_NONNULL_BEGIN /** * The main entry point for the SentrySDK. - * - * We recommend using `[Sentry startWithConfigureOptions]` to initialize Sentry. + * We recommend using @c +[startWithConfigureOptions:] to initialize Sentry. */ @interface SentrySDK : NSObject SENTRY_NO_INIT @@ -40,21 +39,19 @@ SENTRY_NO_INIT /** * Captures a manually created event and sends it to Sentry. - * * @param event The event to send to Sentry. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. * - * @return The SentryId of the event or SentryId.empty if the event is not sent. */ + (SentryId *)captureEvent:(SentryEvent *)event NS_SWIFT_NAME(capture(event:)); /** * Captures a manually created event and sends it to Sentry. Only the data in this scope object will * be added to the event. The global scope will be ignored. - * * @param event The event to send to Sentry. * @param scope The scope containing event metadata. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. * - * @return The SentryId of the event or SentryId.empty if the event is not sent. */ + (SentryId *)captureEvent:(SentryEvent *)event withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(event:scope:)); @@ -62,21 +59,18 @@ SENTRY_NO_INIT /** * Captures a manually created event and sends it to Sentry. Maintains the global scope but mutates * scope data for only this call. - * * @param event The event to send to Sentry. * @param block The block mutating the scope only for this call. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. * - * @return The SentryId of the event or SentryId.empty if the event is not sent. */ + (SentryId *)captureEvent:(SentryEvent *)event withScopeBlock:(void (^)(SentryScope *scope))block NS_SWIFT_NAME(capture(event:block:)); /** * Creates a transaction, binds it to the hub and returns the instance. - * * @param name The transaction name. * @param operation Short code identifying the type of operation the span is measuring. - * * @return The created transaction. */ + (id)startTransactionWithName:(NSString *)name @@ -85,11 +79,9 @@ SENTRY_NO_INIT /** * Creates a transaction, binds it to the hub and returns the instance. - * * @param name The transaction name. * @param operation Short code identifying the type of operation the span is measuring. * @param bindToScope Indicates whether the SDK should bind the new transaction to the scope. - * * @return The created transaction. */ + (id)startTransactionWithName:(NSString *)name @@ -99,9 +91,7 @@ SENTRY_NO_INIT /** * Creates a transaction, binds it to the hub and returns the instance. - * * @param transactionContext The transaction context. - * * @return The created transaction. */ + (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext @@ -109,10 +99,8 @@ SENTRY_NO_INIT /** * Creates a transaction, binds it to the hub and returns the instance. - * * @param transactionContext The transaction context. * @param bindToScope Indicates whether the SDK should bind the new transaction to the scope. - * * @return The created transaction. */ + (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext @@ -121,11 +109,9 @@ SENTRY_NO_INIT /** * Creates a transaction, binds it to the hub and returns the instance. - * * @param transactionContext The transaction context. * @param bindToScope Indicates whether the SDK should bind the new transaction to the scope. * @param customSamplingContext Additional information about the sampling context. - * * @return The created transaction. */ + (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext @@ -135,10 +121,8 @@ SENTRY_NO_INIT /** * Creates a transaction, binds it to the hub and returns the instance. - * * @param transactionContext The transaction context. * @param customSamplingContext Additional information about the sampling context. - * * @return The created transaction. */ + (id)startTransactionWithContext:(SentryTransactionContext *)transactionContext @@ -147,21 +131,19 @@ SENTRY_NO_INIT /** * Captures an error event and sends it to Sentry. - * * @param error The error to send to Sentry. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. * - * @return The SentryId of the event or SentryId.empty if the event is not sent. */ + (SentryId *)captureError:(NSError *)error NS_SWIFT_NAME(capture(error:)); /** * Captures an error event and sends it to Sentry. Only the data in this scope object will be added * to the event. The global scope will be ignored. - * * @param error The error to send to Sentry. * @param scope The scope containing event metadata. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. * - * @return The SentryId of the event or SentryId.empty if the event is not sent. */ + (SentryId *)captureError:(NSError *)error withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(error:scope:)); @@ -169,32 +151,29 @@ SENTRY_NO_INIT /** * Captures an error event and sends it to Sentry. Maintains the global scope but mutates scope data * for only this call. - * * @param error The error to send to Sentry. * @param block The block mutating the scope only for this call. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. * - * @return The SentryId of the event or SentryId.empty if the event is not sent. */ + (SentryId *)captureError:(NSError *)error withScopeBlock:(void (^)(SentryScope *scope))block NS_SWIFT_NAME(capture(error:block:)); /** * Captures an exception event and sends it to Sentry. - * * @param exception The exception to send to Sentry. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. * - * @return The SentryId of the event or SentryId.empty if the event is not sent. */ + (SentryId *)captureException:(NSException *)exception NS_SWIFT_NAME(capture(exception:)); /** * Captures an exception event and sends it to Sentry. Only the data in this scope object will be * added to the event. The global scope will be ignored. - * * @param exception The exception to send to Sentry. * @param scope The scope containing event metadata. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. * - * @return The SentryId of the event or SentryId.empty if the event is not sent. */ + (SentryId *)captureException:(NSException *)exception withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(exception:scope:)); @@ -202,11 +181,10 @@ SENTRY_NO_INIT /** * Captures an exception event and sends it to Sentry. Maintains the global scope but mutates scope * data for only this call. - * * @param exception The exception to send to Sentry. * @param block The block mutating the scope only for this call. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. * - * @return The SentryId of the event or SentryId.empty if the event is not sent. */ + (SentryId *)captureException:(NSException *)exception withScopeBlock:(void (^)(SentryScope *scope))block @@ -214,21 +192,19 @@ SENTRY_NO_INIT /** * Captures a message event and sends it to Sentry. - * * @param message The message to send to Sentry. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. * - * @return The SentryId of the event or SentryId.empty if the event is not sent. */ + (SentryId *)captureMessage:(NSString *)message NS_SWIFT_NAME(capture(message:)); /** * Captures a message event and sends it to Sentry. Only the data in this scope object will be added * to the event. The global scope will be ignored. - * * @param message The message to send to Sentry. * @param scope The scope containing event metadata. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. * - * @return The SentryId of the event or SentryId.empty if the event is not sent. */ + (SentryId *)captureMessage:(NSString *)message withScope:(SentryScope *)scope NS_SWIFT_NAME(capture(message:scope:)); @@ -236,11 +212,10 @@ SENTRY_NO_INIT /** * Captures a message event and sends it to Sentry. Maintains the global scope but mutates scope * data for only this call. - * * @param message The message to send to Sentry. * @param block The block mutating the scope only for this call. + * @return The @c SentryId of the event or @c SentryId.empty if the event is not sent. * - * @return The SentryId of the event or SentryId.empty if the event is not sent. */ + (SentryId *)captureMessage:(NSString *)message withScopeBlock:(void (^)(SentryScope *scope))block @@ -248,7 +223,6 @@ SENTRY_NO_INIT /** * Captures a manually created user feedback and sends it to Sentry. - * * @param userFeedback The user feedback to send to Sentry. */ + (void)captureUserFeedback:(SentryUserFeedback *)userFeedback @@ -256,8 +230,7 @@ SENTRY_NO_INIT /** * Adds a Breadcrumb to the current Scope of the current Hub. If the total number of breadcrumbs - * exceeds the `SentryOptions.maxBreadcrumbs`, the SDK removes the oldest breadcrumb. - * + * exceeds the @c SentryOptions.maxBreadcrumbs the SDK removes the oldest breadcrumb. * @param crumb The Breadcrumb to add to the current Scope of the current Hub. */ + (void)addBreadcrumb:(SentryBreadcrumb *)crumb NS_SWIFT_NAME(addBreadcrumb(_:)); @@ -265,7 +238,6 @@ SENTRY_NO_INIT /** * Use this method to modify the current Scope of the current Hub. The SDK uses the Scope to attach * contextual data to events. - * * @param callback The callback for configuring the current Scope of the current Hub. */ + (void)configureScope:(void (^)(SentryScope *scope))callback; @@ -277,27 +249,27 @@ SENTRY_NO_INIT /** * Set user to the current Scope of the current Hub. - * * @param user The user to set to the current Scope. */ + (void)setUser:(nullable SentryUser *)user; /** - * Starts a new SentrySession. If there's a running SentrySession, it ends it before starting the - * new one. You can use this method in combination with endSession to manually track SentrySessions. - * The SDK uses SentrySession to inform Sentry about release and project associated project health. + * Starts a new SentrySession. If there's a running @c SentrySession, it ends it before starting the + * new one. You can use this method in combination with endSession to manually track + * @c SentrySessions. The SDK uses SentrySession to inform Sentry about release and project + * associated project health. */ + (void)startSession; /** - * Ends the current SentrySession. You can use this method in combination with startSession to - * manually track SentrySessions. The SDK uses SentrySession to inform Sentry about release and + * Ends the current @c SentrySession. You can use this method in combination with @c startSession to + * manually track @c SentrySessions. The SDK uses SentrySession to inform Sentry about release and * project associated project health. */ + (void)endSession; /** - * This forces a crash, useful to test the SentryCrash integration + * This forces a crash, useful to test the @c SentryCrash integration */ + (void)crash; @@ -305,14 +277,13 @@ SENTRY_NO_INIT * Waits synchronously for the SDK to flush out all queued and cached items for up to the specified * timeout in seconds. If there is no internet connection, the function returns immediately. The SDK * doesn't dispose the client or the hub. - * * @param timeout The time to wait for the SDK to complete the flush. */ + (void)flush:(NSTimeInterval)timeout NS_SWIFT_NAME(flush(timeout:)); /** * Closes the SDK, uninstalls all the integrations, and calls flush with - * ``SentryOptions/shutdownTimeInterval``. + * @c SentryOptions.shutdownTimeInterval . */ + (void)close; diff --git a/Sources/Sentry/Public/SentrySamplingContext.h b/Sources/Sentry/Public/SentrySamplingContext.h index dd16e71457..557d5c2322 100644 --- a/Sources/Sentry/Public/SentrySamplingContext.h +++ b/Sources/Sentry/Public/SentrySamplingContext.h @@ -19,14 +19,12 @@ NS_SWIFT_NAME(SamplingContext) /** * Init a SentryTransactionSamplingContext. - * * @param transactionContext The context of the transaction being sampled. */ - (instancetype)initWithTransactionContext:(SentryTransactionContext *)transactionContext; /** * Init a SentryTransactionSamplingContext. - * * @param transactionContext The context of the transaction being sampled. * @param customSamplingContext Custom data used for sampling. */ diff --git a/Sources/Sentry/Public/SentryScope.h b/Sources/Sentry/Public/SentryScope.h index 8f0f294c4b..85df60ff1f 100644 --- a/Sources/Sentry/Public/SentryScope.h +++ b/Sources/Sentry/Public/SentryScope.h @@ -9,8 +9,7 @@ NS_ASSUME_NONNULL_BEGIN /** * The scope holds useful information that should be sent along with the event. For instance tags or * breadcrumbs are stored on the scope. - * - * For more information see: + * @see * https://docs.sentry.io/platforms/apple/enriching-events/scopes/#whats-a-scope-whats-a-hub */ NS_SWIFT_NAME(Scope) @@ -18,7 +17,6 @@ NS_SWIFT_NAME(Scope) /** * Returns current Span or Transaction. - * * @return current Span or Transaction or null if transaction has not been set. */ @property (nullable, nonatomic, strong) id span; @@ -66,22 +64,22 @@ NS_SWIFT_NAME(Scope) - (void)removeExtraForKey:(NSString *)key NS_SWIFT_NAME(removeExtra(key:)); /** - * Set dist in the scope + * Set @c dist in the scope */ - (void)setDist:(NSString *_Nullable)dist; /** - * Set environment in the scope + * Set @c environment in the scope */ - (void)setEnvironment:(NSString *_Nullable)environment; /** - * Sets the fingerprint in the scope + * Sets the @c fingerprint in the scope */ - (void)setFingerprint:(NSArray *_Nullable)fingerprint; /** - * Sets the level in the scope + * Sets the @c level in the scope */ - (void)setLevel:(enum SentryLevel)level; @@ -118,7 +116,6 @@ NS_SWIFT_NAME(Scope) /** * Adds an attachment to the Scope's list of attachments. The SDK adds the attachment to every event * sent to Sentry. - * * @param attachment The attachment to add to the Scope's list of attachments. */ - (void)addAttachment:(SentryAttachment *)attachment NS_SWIFT_NAME(addAttachment(_:)); @@ -140,7 +137,6 @@ NS_SWIFT_NAME(Scope) /** * Mutates the current transaction atomically. - * * @param callback the SentrySpanCallback. */ - (void)useSpan:(SentrySpanCallback)callback; diff --git a/Sources/Sentry/Public/SentrySpanContext.h b/Sources/Sentry/Public/SentrySpanContext.h index 9fa7bec732..7922dda051 100644 --- a/Sources/Sentry/Public/SentrySpanContext.h +++ b/Sources/Sentry/Public/SentrySpanContext.h @@ -45,36 +45,27 @@ SENTRY_NO_INIT @property (nullable, nonatomic, copy, readonly) NSString *spanDescription; /** - * Init a SentryContext with an operation code, - * traceId and spanId with be randomly created, - * sampled by default is Undecided. - * - * @return SentryContext + * Init a @c SentryContext with an operation code. + * @note @c traceId and @c spanId with be randomly created; @c sampled by default is + * @c kSentrySampleDecisionUndecided . */ - (instancetype)initWithOperation:(NSString *)operation; /** - * Init a SentryContext with an operation code and mark it as sampled or not. + * Init a @c SentryContext with an operation code and mark it as sampled or not. * TraceId and SpanId with be randomly created. - * * @param operation The operation this span is measuring. * @param sampled Determines whether the trace should be sampled. - * - * @return SentryContext */ - (instancetype)initWithOperation:(NSString *)operation sampled:(SentrySampleDecision)sampled; /** - * Init a SentryContext with given traceId, spanId and parentId. - * * @param traceId Determines which trace the Span belongs to. - * @param spanId The Span Id + * @param spanId The Span Id. * @param operation The operation this span is measuring. * @param parentId Id of a parent span. * @param sampled Determines whether the trace should be sampled. - * - * @return SentryContext */ - (instancetype)initWithTraceId:(SentryId *)traceId spanId:(SentrySpanId *)spanId @@ -83,16 +74,12 @@ SENTRY_NO_INIT sampled:(SentrySampleDecision)sampled; /** - * Init a SentryContext with given traceId, spanId and parentId. - * * @param traceId Determines which trace the Span belongs to. - * @param spanId The Span Id + * @param spanId The Span Id. * @param operation The operation this span is measuring. * @param parentId Id of a parent span. - * @param description The span description + * @param description The span description. * @param sampled Determines whether the trace should be sampled. - * - * @return SentryContext */ - (instancetype)initWithTraceId:(SentryId *)traceId spanId:(SentrySpanId *)spanId diff --git a/Sources/Sentry/Public/SentrySpanProtocol.h b/Sources/Sentry/Public/SentrySpanProtocol.h index deffb0af78..c416388e93 100644 --- a/Sources/Sentry/Public/SentrySpanProtocol.h +++ b/Sources/Sentry/Public/SentrySpanProtocol.h @@ -72,9 +72,7 @@ NS_SWIFT_NAME(Span) /** * Starts a child span. - * * @param operation Short code identifying the type of operation the span is measuring. - * * @return SentrySpan */ - (id)startChildWithOperation:(NSString *)operation @@ -82,10 +80,8 @@ NS_SWIFT_NAME(Span) /** * Starts a child span. - * * @param operation Defines the child span operation. * @param description Define the child span description. - * * @return SentrySpan */ - (id)startChildWithOperation:(NSString *)operation @@ -98,7 +94,7 @@ NS_SWIFT_NAME(Span) - (void)setDataValue:(nullable id)value forKey:(NSString *)key NS_SWIFT_NAME(setData(value:key:)); /** - * Use setDataValue instead. This method calls setDataValue, was added by mistake, and will be + * Use @c setDataValue instead. This method calls @c setDataValue, was added by mistake, and will be * removed in a future version. */ - (void)setExtraValue:(nullable id)value @@ -123,10 +119,8 @@ NS_SWIFT_NAME(Span) * Set a measurement without unit. When setting the measurement without the unit, no formatting * will be applied to the measurement value in the Sentry product, and the value will be shown as * is. - * * @discussion Setting a measurement with the same name on the same transaction multiple times only * keeps the last value. - * * @param name the name of the measurement * @param value the value of the measurement */ @@ -135,10 +129,8 @@ NS_SWIFT_NAME(Span) /** * Set a measurement with specific unit. - * * @discussion Setting a measurement with the same name on the same transaction multiple times only * keeps the last value. - * * @param name the name of the measurement * @param value the value of the measurement * @param unit the unit the value is measured in @@ -155,14 +147,12 @@ NS_SWIFT_NAME(Span) /** * Finishes the span by setting the end time and span status. - * * @param status The status of this span * */ - (void)finishWithStatus:(SentrySpanStatus)status NS_SWIFT_NAME(finish(status:)); /** * Returns the trace information that could be sent as a sentry-trace header. - * * @return SentryTraceHeader. */ - (SentryTraceHeader *)toTraceHeader; diff --git a/Sources/Sentry/Public/SentryTraceHeader.h b/Sources/Sentry/Public/SentryTraceHeader.h index 92f3d200cd..7c9801b177 100644 --- a/Sources/Sentry/Public/SentryTraceHeader.h +++ b/Sources/Sentry/Public/SentryTraceHeader.h @@ -26,13 +26,9 @@ SENTRY_NO_INIT @property (nonatomic, readonly) SentrySampleDecision sampled; /** - * Initialize a SentryTraceHeader with given trace id, span id and sample decision. - * * @param traceId The trace id. * @param spanId The span id. * @param sampled The decision made to sample the trace related to this header. - * - * @return A SentryTraceHeader. */ - (instancetype)initWithTraceId:(SentryId *)traceId spanId:(SentrySpanId *)spanId diff --git a/Sources/Sentry/Public/SentryTransactionContext.h b/Sources/Sentry/Public/SentryTransactionContext.h index 16384bf07c..06ca0612d2 100644 --- a/Sources/Sentry/Public/SentryTransactionContext.h +++ b/Sources/Sentry/Public/SentryTransactionContext.h @@ -27,40 +27,28 @@ SENTRY_NO_INIT @property (nonatomic, strong, nullable) NSNumber *sampleRate; /** - * Init a SentryTransactionContext with given name and set other fields by default - * * @param name Transaction name * @param operation The operation this span is measuring. - * * @return SentryTransactionContext */ - (instancetype)initWithName:(NSString *)name operation:(NSString *)operation; /** - * Init a SentryTransactionContext with given name and set other fields by default - * * @param name Transaction name * @param operation The operation this span is measuring. * @param sampled Determines whether the trace should be sampled. - * - * @return SentryTransactionContext */ - (instancetype)initWithName:(NSString *)name operation:(NSString *)operation sampled:(SentrySampleDecision)sampled; /** - * Init a SentryTransactionContext with given name, traceId, SpanId, parentSpanId and whether the - * parent is sampled. - * * @param name Transaction name * @param operation The operation this span is measuring. * @param traceId Trace Id * @param spanId Span Id * @param parentSpanId Parent span id * @param parentSampled Whether the parent is sampled - * - * @return SentryTransactionContext */ - (instancetype)initWithName:(NSString *)name operation:(NSString *)operation diff --git a/Sources/Sentry/Public/SentryUserFeedback.h b/Sources/Sentry/Public/SentryUserFeedback.h index 1878c369e2..430c5dec1f 100644 --- a/Sources/Sentry/Public/SentryUserFeedback.h +++ b/Sources/Sentry/Public/SentryUserFeedback.h @@ -14,7 +14,6 @@ SENTRY_NO_INIT /** * Initializes SentryUserFeedback and sets the required eventId. - * * @param eventId The eventId of the event to which the user feedback is associated. */ - (instancetype)initWithEventId:(SentryId *)eventId; diff --git a/Sources/Sentry/SentryANRTracker.m b/Sources/Sentry/SentryANRTracker.m index e293c45c34..cb08e8746e 100644 --- a/Sources/Sentry/SentryANRTracker.m +++ b/Sources/Sentry/SentryANRTracker.m @@ -89,7 +89,13 @@ - (void)detectANRs if (reported) { SENTRY_LOG_WARN(@"ANR stopped."); - [self ANRStopped]; + + // The ANR stopped, don't block the main thread with calling ANRStopped listeners. + // While the ANR code reports an ANR and collects the stack trace, the ANR might + // stop simultaneously. In that case, the ANRs stack trace would contain the + // following code running on the main thread. To avoid this, we offload work to a + // background thread. + [self.dispatchQueueWrapper dispatchAsyncWithBlock:^{ [self ANRStopped]; }]; } reported = NO; diff --git a/Sources/Sentry/SentryAppStateManager.m b/Sources/Sentry/SentryAppStateManager.m index 68bb9974f6..d50465849f 100644 --- a/Sources/Sentry/SentryAppStateManager.m +++ b/Sources/Sentry/SentryAppStateManager.m @@ -134,10 +134,9 @@ - (void)dealloc /** * It is called when an app is receiving events / it is in the foreground and when we receive a - * SentryHybridSdkDidBecomeActiveNotification. - * - * This also works when using SwiftUI or Scenes, as UIKit posts a didBecomeActiveNotification - * regardless of whether your app uses scenes, see + * @c SentryHybridSdkDidBecomeActiveNotification. + * @discussion This also works when using SwiftUI or Scenes, as UIKit posts a + * @c didBecomeActiveNotification regardless of whether your app uses scenes, see * https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622956-applicationdidbecomeactive. */ - (void)didBecomeActive diff --git a/Sources/Sentry/SentryClient.m b/Sources/Sentry/SentryClient.m index 03145d8467..c9c962a3d1 100644 --- a/Sources/Sentry/SentryClient.m +++ b/Sources/Sentry/SentryClient.m @@ -31,6 +31,7 @@ #import "SentryMessage.h" #import "SentryMeta.h" #import "SentryNSError.h" +#import "SentryNSProcessInfoWrapper.h" #import "SentryOptions+Private.h" #import "SentrySDK+Private.h" #import "SentryScope+Private.h" @@ -63,6 +64,7 @@ @property (nonatomic, strong) SentryUIDeviceWrapper *deviceWrapper; @property (nonatomic, strong) NSLocale *locale; @property (nonatomic, strong) NSTimeZone *timezone; +@property (nonatomic, strong) SentryNSProcessInfoWrapper *processInfoWrapper; @end @@ -171,6 +173,7 @@ - (instancetype)initWithOptions:(SentryOptions *)options self.timezone = timezone; self.attachmentProcessors = [[NSMutableArray alloc] init]; self.deviceWrapper = deviceWrapper; + self.processInfoWrapper = [[SentryNSProcessInfoWrapper alloc] init]; if (deleteOldEnvelopeItems) { [fileManager deleteOldEnvelopeItems]; @@ -794,6 +797,7 @@ - (void)applyExtraDeviceContextToEvent:(SentryEvent *)event block:^(NSMutableDictionary *device) { device[SentryDeviceContextFreeMemoryKey] = @(self.crashWrapper.freeMemorySize); device[@"free_storage"] = @(self.crashWrapper.freeStorageSize); + device[@"processor_count"] = @([self.processInfoWrapper processorCount]); #if TARGET_OS_IOS if (self.deviceWrapper.orientation != UIDeviceOrientationUnknown) { diff --git a/Sources/Sentry/SentryCrashReportConverter.m b/Sources/Sentry/SentryCrashReportConverter.m index d6672fad01..41f2cc49e6 100644 --- a/Sources/Sentry/SentryCrashReportConverter.m +++ b/Sources/Sentry/SentryCrashReportConverter.m @@ -462,27 +462,26 @@ - (void)enhanceValueFromNotableAddresses:(SentryException *)exception * Get the message of fatalError, assert, and precondition to set it as the exception value if the * crashInfo contains the message. * - * Swift puts the messages of fatalError, assert, and precondition into the crashInfo of the - * libswiftCore.dylib. We found somewhat proof that the swift runtime uses __crash_info: fatalError - * (1) calls swift_reportError (2) calls reportOnCrash (3) which uses (4) the __crash_info (5). The - * documentation of Apple and Swift doesn't mention anything about where the __crash_info ends up. - * Trying fatalError, assert, and precondition on iPhone, iPhone simulator, and macOS all showed - * that the message ends up in the crashInfo of the libswiftCore.dylib. For example, on the - * simulator, other binary images also contain a crash_info_message with information about the - * stacktrace. We only care about the message of fatalError, assert, or precondition, and we already - * get the stacktrace from the threads, retrieving it from libswiftCore.dylib seems to be the most - * reliable option. + * Swift puts the messages of fatalError, assert, and precondition into the @c crashInfo of the + * @c libswiftCore.dylib. We found somewhat proof that the swift runtime uses @c __crash_info: + * fatalError (1) calls @c swift_reportError (2) calls @c reportOnCrash (3) which uses (4) the + * @c __crash_info (5). The documentation of Apple and Swift doesn't mention anything about where + * the @c __crash_info ends up. Trying fatalError, assert, and precondition on iPhone, iPhone + * simulator, and macOS all showed that the message ends up in the crashInfo of the + * @c libswiftCore.dylib. For example, on the simulator, other binary images also contain a + * @c crash_info_message with information about the stacktrace. We only care about the message of + * fatalError, assert, or precondition, and we already get the stacktrace from the threads, + * retrieving it from @c libswiftCore.dylib seems to be the most reliable option. * - * Links: - * 1. + * @seealso * https://github.com/apple/swift/blob/d1bb98b11ede375a1cee739f964b7d23b6657aaf/stdlib/public/runtime/Errors.cpp#L365-L377 - * 2. + * @seealso * https://github.com/apple/swift/blob/d1bb98b11ede375a1cee739f964b7d23b6657aaf/stdlib/public/runtime/Errors.cpp#L361 - * 3. + * @seealso * https://github.com/apple/swift/blob/d1bb98b11ede375a1cee739f964b7d23b6657aaf/stdlib/public/runtime/Errors.cpp#L269-L293 - * 4. + * @seealso * https://github.com/apple/swift/blob/d1bb98b11ede375a1cee739f964b7d23b6657aaf/stdlib/public/runtime/Errors.cpp#L264-L293 - * 5. + * @seealso * https://github.com/apple/swift/blob/d1bb98b11ede375a1cee739f964b7d23b6657aaf/include/swift/Runtime/Debug.h#L29-L58 */ - (void)enhanceValueFromCrashInfoMessage:(SentryException *)exception diff --git a/Sources/Sentry/SentryDependencyContainer.m b/Sources/Sentry/SentryDependencyContainer.m index 005cdaca00..77c0f6f051 100644 --- a/Sources/Sentry/SentryDependencyContainer.m +++ b/Sources/Sentry/SentryDependencyContainer.m @@ -8,7 +8,6 @@ #import #import #import -#import #import #import #import @@ -204,7 +203,7 @@ - (SentryANRTracker *)getANRTracker:(NSTimeInterval)timeout initWithTimeoutInterval:timeout currentDateProvider:[SentryDefaultCurrentDateProvider sharedInstance] crashWrapper:self.crashWrapper - dispatchQueueWrapper:[[SentryDispatchQueueWrapper alloc] init] + dispatchQueueWrapper:self.dispatchQueueWrapper threadWrapper:self.threadWrapper]; } } diff --git a/Sources/Sentry/SentryDevice.mm b/Sources/Sentry/SentryDevice.mm index c831c438e0..f27cf1c56d 100644 --- a/Sources/Sentry/SentryDevice.mm +++ b/Sources/Sentry/SentryDevice.mm @@ -26,7 +26,7 @@ /** * @brief Get an iOS hardware model name, or for mac devices, either the hardware model name or CPU * architecture of the device, depending on the option provided. - * @note For an iOS CPU architecture name, `getArchitectureName` must be used. + * @note For an iOS CPU architecture name, @c getArchitectureName must be used. * @discussion The values returned are different between iOS and macOS depending on which option is * provided. Some examples of values returned on different devices: * @code diff --git a/Sources/Sentry/SentryDispatchQueueWrapper.m b/Sources/Sentry/SentryDispatchQueueWrapper.m index 88a89fef3e..9703570dcb 100644 --- a/Sources/Sentry/SentryDispatchQueueWrapper.m +++ b/Sources/Sentry/SentryDispatchQueueWrapper.m @@ -77,6 +77,11 @@ - (void)dispatchOnce:(dispatch_once_t *)predicate block:(void (^)(void))block dispatch_once(predicate, block); } +- (nullable dispatch_block_t)createDispatchBlock:(void (^)(void))block +{ + return dispatch_block_create(0, block); +} + @end NS_ASSUME_NONNULL_END diff --git a/Sources/Sentry/SentryHttpTransport.m b/Sources/Sentry/SentryHttpTransport.m index 6010789f0d..61919c5922 100644 --- a/Sources/Sentry/SentryHttpTransport.m +++ b/Sources/Sentry/SentryHttpTransport.m @@ -39,7 +39,7 @@ * Relay expects the discarded events split by data category and reason; see * https://develop.sentry.dev/sdk/client-reports/#envelope-item-payload. * We could use nested dictionaries, but instead, we use a dictionary with key - * `data-category:reason` and value `SentryDiscardedEvent` because it's easier to read and type. + * @c data-category:reason and value @c SentryDiscardedEvent because it's easier to read and type. */ @property (nonatomic, strong) NSMutableDictionary *discardedEvents; diff --git a/Sources/Sentry/SentryHub.m b/Sources/Sentry/SentryHub.m index 57383ba589..420986fd9c 100644 --- a/Sources/Sentry/SentryHub.m +++ b/Sources/Sentry/SentryHub.m @@ -28,6 +28,7 @@ SentryHub () @property (nullable, nonatomic, strong) SentryClient *client; +@property (nullable, nonatomic, strong) SentrySession *session; @property (nullable, nonatomic, strong) SentryScope *scope; @property (nonatomic, strong) SentryCrashWrapper *crashWrapper; @property (nonatomic, strong) SentryTracesSampler *tracesSampler; @@ -562,9 +563,9 @@ - (void)configureScope:(void (^)(SentryScope *scope))callback } /** - * Checks if a specific Integration (`integrationClass`) has been installed. - * @return BOOL If instance of `integrationClass` exists within - * `SentryHub.installedIntegrations`. + * Checks if a specific Integration (@c integrationClass) has been installed. + * @return @c YES if instance of @c integrationClass exists within + * @c SentryHub.installedIntegrations . */ - (BOOL)isIntegrationInstalled:(Class)integrationClass { diff --git a/Sources/Sentry/SentryMeta.m b/Sources/Sentry/SentryMeta.m index 38285834ba..78f7c75ee5 100644 --- a/Sources/Sentry/SentryMeta.m +++ b/Sources/Sentry/SentryMeta.m @@ -5,7 +5,7 @@ @implementation SentryMeta // Don't remove the static keyword. If you do the compiler adds the constant name to the global // symbol table and it might clash with other constants. When keeping the static keyword the // compiler replaces all occurrences with the value. -static NSString *versionString = @"8.3.1"; +static NSString *versionString = @"8.3.3"; static NSString *sdkName = @"sentry.cocoa"; + (NSString *)versionString diff --git a/Sources/Sentry/SentryMetricKitIntegration.m b/Sources/Sentry/SentryMetricKitIntegration.m index 1050c2d31e..874aaef3b2 100644 --- a/Sources/Sentry/SentryMetricKitIntegration.m +++ b/Sources/Sentry/SentryMetricKitIntegration.m @@ -225,16 +225,16 @@ - (void)captureMXEvent:(SentryMXCallStackTree *)callStackTree } /** - * If callStackPerThread is false, MetricKit organizes the stacktraces in a tree structure. See + * If @c callStackPerThread is @c NO , MetricKit organizes the stacktraces in a tree structure. See * https://developer.apple.com/videos/play/wwdc2020/10078/?time=224. The stacktrace consists of the - * last sibbling leaf frame plus its ancestors. + * last sibling leaf frame plus its ancestors. * * The algorithm adds all frames to a list until it finds a leaf frame being the last sibling. Then * it reports that frame with its siblings and ancestors as a stacktrace. * * In the following example, the algorithm starts with frame 0, continues until frame 6, and reports * a stacktrace. Then it pops all sibling, goes back up to frame 3, and continues the search. - * + * @code * | frame 0 | * | frame 1 | * | frame 2 | @@ -249,6 +249,7 @@ - (void)captureMXEvent:(SentryMXCallStackTree *)callStackTree * | frame 11 | * | frame 12 | * | frame 13 | -> stack trace consists of [10, 11, 12, 13] + * @endcode */ - (void)buildAndCaptureMXEventFor:(NSArray *)rootFrames params:(SentryMXExceptionParams *)params diff --git a/Sources/Sentry/SentryNSURLSessionTaskSearch.m b/Sources/Sentry/SentryNSURLSessionTaskSearch.m index 42eb04104c..192943813f 100644 --- a/Sources/Sentry/SentryNSURLSessionTaskSearch.m +++ b/Sources/Sentry/SentryNSURLSessionTaskSearch.m @@ -19,16 +19,16 @@ @implementation SentryNSURLSessionTaskSearch /** * In order to be able to track a network request, we need to know when it starts and when it - * finishes. NSURLSessionTask has a `resume` method that starts the request, and the only way to - * know when it finishes is to check the task `state`. Using KVO is not working, - * It randomly crashs an app. We hade two issues open because of this, #1328 and #1448. Instead - * we are swizzling `setState:`. From iOS 10 to 13, NSURLSessionTask does not implement - * `setState:` and Apple uses a subclass returned by NSURLSession that implementes `setState:`. - * We need to discover which class to swizzle. + * finishes. @c NSURLSessionTask has a @c resume method that starts the request, and the only + * way to know when it finishes is to check the task @c state. Using KVO is not working, It + * randomly crashes an app. We had two issues open because of this, #1328 and #1448. Instead we + * are swizzling @c setState:. From iOS 10 to 13, @c NSURLSessionTask does not implement + * @c setState: and Apple uses a subclass returned by NSURLSession that implements @c setState: + * . We need to discover which class to swizzle. * - * Apples intermediate classes for iOS does not call [super resume], so we can swizzle both - * classes. This Apple approach may change in the future, we need to have enough tests to detect - * it early. + * Apple's intermediate classes for iOS does not call @c [super @c resume], so we can swizzle + * both classes. This Apple approach may change in the future, we need to have enough tests to + * detect it early. */ // WARNING START diff --git a/Sources/Sentry/SentryOptions.m b/Sources/Sentry/SentryOptions.m index 8f509bc1ac..4828aae3f3 100644 --- a/Sources/Sentry/SentryOptions.m +++ b/Sources/Sentry/SentryOptions.m @@ -223,7 +223,7 @@ - (void)setDsn:(NSString *)dsn } /** - * Populates all `SentryOptions` values from `options` dict using fallbacks/defaults if needed. + * Populates all @c SentryOptions values from @c options dict using fallbacks/defaults if needed. */ - (BOOL)validateOptions:(NSDictionary *)options didFailWithError:(NSError *_Nullable *_Nullable)error @@ -565,11 +565,11 @@ - (BOOL)enableProfiling_DEPRECATED_TEST_ONLY /** * Checks if the passed in block is actually of type block. We can't check if the block matches a - * specific block without some complex objc runtime method calls and therefore we only check if its - * a block or not. Assigning a wrong block to the SentryOption blocks still could lead to crashes at - * runtime, but when someone uses the initWithDict they should better know what they are doing. - * - * Taken from https://gist.github.com/steipete/6ee378bd7d87f276f6e0 + * specific block without some complex objc runtime method calls and therefore we only check if it's + * a block or not. Assigning a wrong block to the @c SentryOptions blocks still could lead to + * crashes at runtime, but when someone uses the @c initWithDict they should better know what they + * are doing. + * @see Taken from https://gist.github.com/steipete/6ee378bd7d87f276f6e0 */ - (BOOL)isBlock:(nullable id)block { diff --git a/Sources/Sentry/SentryReachability.m b/Sources/Sentry/SentryReachability.m index 70d882a31c..75c9108ccc 100644 --- a/Sources/Sentry/SentryReachability.m +++ b/Sources/Sentry/SentryReachability.m @@ -42,8 +42,7 @@ /** * Check whether the connectivity change should be noted or ignored. - * - * @return YES if the connectivity change should be reported + * @return @c YES if the connectivity change should be reported */ BOOL SentryConnectivityShouldReportChange(SCNetworkReachabilityFlags flags) @@ -91,7 +90,7 @@ } /** - * Callback invoked by SCNetworkReachability, which calls an Objective-C block + * Callback invoked by @c SCNetworkReachability, which calls an Objective-C block * that handles the connection change. */ void diff --git a/Sources/Sentry/SentrySDK.m b/Sources/Sentry/SentrySDK.m index f4568f0b3f..c5a5eb875f 100644 --- a/Sources/Sentry/SentrySDK.m +++ b/Sources/Sentry/SentrySDK.m @@ -351,7 +351,7 @@ + (void)endSession } /** - * Install integrations and keeps ref in `SentryHub.integrations` + * Install integrations and keeps ref in @c SentryHub.integrations */ + (void)installIntegrations { diff --git a/Sources/Sentry/SentryScreenshot.m b/Sources/Sentry/SentryScreenshot.m index 9fe1ee45ab..d4b1cb21f0 100644 --- a/Sources/Sentry/SentryScreenshot.m +++ b/Sources/Sentry/SentryScreenshot.m @@ -20,7 +20,7 @@ @implementation SentryScreenshot return result; } -- (void)saveScreenShots:(NSString *)path +- (void)saveScreenShots:(NSString *)imagesDirectoryPath { // This function does not dispatch the screenshot to the main thread. // The caller should be aware of that. @@ -31,7 +31,7 @@ - (void)saveScreenShots:(NSString *)path NSString *name = idx == 0 ? @"screenshot.png" : [NSString stringWithFormat:@"screenshot-%li.png", (unsigned long)idx + 1]; - NSString *fileName = [path stringByAppendingPathComponent:name]; + NSString *fileName = [imagesDirectoryPath stringByAppendingPathComponent:name]; [obj writeToFile:fileName atomically:YES]; }]; } diff --git a/Sources/Sentry/SentrySessionTracker.m b/Sources/Sentry/SentrySessionTracker.m index a668ad15c5..ed8afe8ed9 100644 --- a/Sources/Sentry/SentrySessionTracker.m +++ b/Sources/Sentry/SentrySessionTracker.m @@ -132,18 +132,17 @@ - (void)endCachedSession /** * It is called when an App. is receiving events / It is in the foreground and when we receive a - * SentryHybridSdkDidBecomeActiveNotification. There is no guarantee that this method is called once - * or twice. We need to ensure that we execute it only once. - * - * This also works when using SwiftUI or Scenes, as UIKit posts a didBecomeActiveNotification - * regardless of whether your app uses scenes, see + * @c SentryHybridSdkDidBecomeActiveNotification. There is no guarantee that this method is called + * once or twice. We need to ensure that we execute it only once. + * @discussion This also works when using SwiftUI or Scenes, as UIKit posts a + * @c didBecomeActiveNotification regardless of whether your app uses scenes, see * https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622956-applicationdidbecomeactive. - * - * Hybrid SDKs must only post this notification if they are running in the foreground because the - * auto session tracking logic doesn't support background tasks. Posting the notification from the - * background would mess up the session stats. Hybrid SDKs must only post this notification if they - * are running in the foreground because the auto session tracking logic doesn't support background - * tasks. Posting the notification from the background would mess up the session stats. + * @warning Hybrid SDKs must only post this notification if they are running in the foreground + * because the auto session tracking logic doesn't support background tasks. Posting the + * notification from the background would mess up the session stats. Hybrid SDKs must only post this + * notification if they are running in the foreground because the auto session tracking logic + * doesn't support background tasks. Posting the notification from the background would mess up the + * session stats. */ - (void)didBecomeActive { diff --git a/Sources/Sentry/SentryStacktrace.m b/Sources/Sentry/SentryStacktrace.m index d63b881b76..6c4250f096 100644 --- a/Sources/Sentry/SentryStacktrace.m +++ b/Sources/Sentry/SentryStacktrace.m @@ -18,8 +18,10 @@ - (instancetype)initWithFrames:(NSArray *)frames return self; } -/// This function fixes duplicate frames and removes the first duplicate -/// https://github.com/kstenerud/KSCrash/blob/05cdc801cfc578d256f85de2e72ec7877cbe79f8/Source/KSCrash/Recording/Tools/KSStackCursor_MachineContext.c#L84 +/** + * This function fixes duplicate frames and removes the first duplicate + * https://github.com/kstenerud/KSCrash/blob/05cdc801cfc578d256f85de2e72ec7877cbe79f8/Source/KSCrash/Recording/Tools/KSStackCursor_MachineContext.c#L84 + */ - (void)fixDuplicateFrames { if (self.frames.count < 2 || nil == self.registers) { diff --git a/Sources/Sentry/SentrySysctl.m b/Sources/Sentry/SentrySysctl.m index feaf8ae25e..7b526a704e 100644 --- a/Sources/Sentry/SentrySysctl.m +++ b/Sources/Sentry/SentrySysctl.m @@ -7,16 +7,15 @@ static NSDate *runtimeInit = nil; /** - * * Constructor priority must be bounded between 101 and 65535 inclusive, see * https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Function-Attributes.html and * https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/C_002b_002b-Attributes.html#C_002b_002b-Attributes * The constructor attribute causes the function to be called automatically before execution enters - * main(). The lower the priority number, the sooner the constructor runs, which means 100 runs - * before 101. As we want to be as close to main() as possible, we choose a high number. + * @c main() . The lower the priority number, the sooner the constructor runs, which means 100 runs + * before 101. As we want to be as close to @c main() as possible, we choose a high number. * - * Previously, we used __DATA,__mod_init_func, which leads to compilation errors and runtime crashes - * when enabling the address sanitizer. + * Previously, we used @c __DATA,__mod_init_func , which leads to compilation errors and runtime + * crashes when enabling the address sanitizer. */ __used __attribute__((constructor(60000))) static void sentryModuleInitializationHook() diff --git a/Sources/Sentry/SentryThreadInspector.m b/Sources/Sentry/SentryThreadInspector.m index 82f13ca8ca..e6829a2467 100644 --- a/Sources/Sentry/SentryThreadInspector.m +++ b/Sources/Sentry/SentryThreadInspector.m @@ -119,10 +119,20 @@ - (SentryStacktrace *)stacktraceForCurrentThreadAsyncUnsafe thread_act_array_t suspendedThreads = NULL; mach_msg_type_number_t numSuspendedThreads = 0; - sentrycrashmc_suspendEnvironment(&suspendedThreads, &numSuspendedThreads); + // SentryThreadInspector is crashing when there is too many threads. + // We add a limit of 70 threads because in test with up to 100 threads it seems fine. + // We are giving it an extra safety margin. + sentrycrashmc_suspendEnvironment_upToMaxSupportedThreads( + &suspendedThreads, &numSuspendedThreads, 70); // DANGER: Do not try to allocate memory in the heap or call Objective-C code in this // section Doing so when the threads are suspended may lead to deadlocks or crashes. + // If no threads was suspended we don't need to do anything. + // This may happen if there is more than max amount of threads (70). + if (numSuspendedThreads == 0) { + return threads; + } + SentryThreadInfo threadsInfos[numSuspendedThreads]; for (int i = 0; i < numSuspendedThreads; i++) { diff --git a/Sources/Sentry/SentryTraceContext.m b/Sources/Sentry/SentryTraceContext.m index c6a95b6eed..c6bf936085 100644 --- a/Sources/Sentry/SentryTraceContext.m +++ b/Sources/Sentry/SentryTraceContext.m @@ -1,6 +1,7 @@ #import "SentryTraceContext.h" #import "SentryBaggage.h" #import "SentryDsn.h" +#import "SentryId.h" #import "SentryLog.h" #import "SentryOptions+Private.h" #import "SentryScope+Private.h" diff --git a/Sources/Sentry/SentryTracer.m b/Sources/Sentry/SentryTracer.m index 64b718789f..44245d23f3 100644 --- a/Sources/Sentry/SentryTracer.m +++ b/Sources/Sentry/SentryTracer.m @@ -49,10 +49,10 @@ @property (nonatomic, strong) SentryHub *hub; @property (nonatomic) SentrySpanStatus finishStatus; -/** This property is different from isFinished. While isFinished states if the tracer is actually - * finished, this property tells you if finish was called on the tracer. Calling finish doesn't - * necessarily lead to finishing the tracer, because it could still wait for child spans to finish - * if waitForChildren is YES. */ +/** This property is different from @c isFinished. While @c isFinished states if the tracer is + * actually finished, this property tells you if finish was called on the tracer. Calling + * @c -[finish] doesn't necessarily lead to finishing the tracer, because it could still wait for + * child spans to finish if @c waitForChildren is @c YES . */ @property (nonatomic) BOOL wasFinishCalled; @property (nonatomic) NSTimeInterval idleTimeout; @property (nonatomic, nullable, strong) SentryDispatchQueueWrapper *dispatchQueueWrapper; @@ -217,14 +217,21 @@ - (void)dispatchIdleTimeout [self.dispatchQueueWrapper dispatchCancel:_idleTimeoutBlock]; } __weak SentryTracer *weakSelf = self; - _idleTimeoutBlock = dispatch_block_create(0, ^{ + _idleTimeoutBlock = [self.dispatchQueueWrapper createDispatchBlock:^{ if (weakSelf == nil) { SENTRY_LOG_DEBUG(@"WeakSelf is nil. Not doing anything."); return; } [weakSelf finishInternal]; - }); - [self.dispatchQueueWrapper dispatchAfter:self.idleTimeout block:_idleTimeoutBlock]; + }]; + if (_idleTimeoutBlock == NULL) { + SENTRY_LOG_WARN(@"Couln't create idle time out block. Can't schedule idle timeout. " + @"Finishing transaction"); + // If the transaction has no children, the SDK will discard it. + [self finishInternal]; + } else { + [self.dispatchQueueWrapper dispatchAfter:self.idleTimeout block:_idleTimeoutBlock]; + } } - (BOOL)hasIdleTimeout diff --git a/Sources/Sentry/SentryUIViewControllerPerformanceTracker.m b/Sources/Sentry/SentryUIViewControllerPerformanceTracker.m index 56bac7d833..11000c055a 100644 --- a/Sources/Sentry/SentryUIViewControllerPerformanceTracker.m +++ b/Sources/Sentry/SentryUIViewControllerPerformanceTracker.m @@ -157,9 +157,10 @@ - (void)viewControllerViewDidAppear:(UIViewController *)controller * ‘will’ callback method, you end the process in both the corresponding ‘did’ and the opposite * ‘will’ callback method. * - * As stated above viewWillAppear doesn't need to be followed by a viewDidAppear. A viewWillAppear - * can also be followed by a viewWillDisappear. Therefore, we finish the transaction in - * viewWillDisappear, if it wasn't already finished in viewDidAppear. + * As stated above @c viewWillAppear doesn't need to be followed by a @c viewDidAppear. A + * @c viewWillAppear can also be followed by a @c viewWillDisappear. Therefore, we finish the + * transaction in + * @c viewWillDisappear, if it wasn't already finished in @c viewDidAppear. */ - (void)viewControllerViewWillDisappear:(UIViewController *)controller callbackToOrigin:(void (^)(void))callbackToOrigin diff --git a/Sources/Sentry/SentryUIViewControllerSwizzling.m b/Sources/Sentry/SentryUIViewControllerSwizzling.m index 2b7450f791..427d99359c 100644 --- a/Sources/Sentry/SentryUIViewControllerSwizzling.m +++ b/Sources/Sentry/SentryUIViewControllerSwizzling.m @@ -15,12 +15,12 @@ # import /** - * 'swizzleRootViewControllerFromUIApplication:' requires an object that conforms to - * 'SentryUIApplication' to swizzle it, this way, instead of relying on UIApplication, we can test - * with a mock class. + * @c swizzleRootViewControllerFromUIApplication: requires an object that conforms to + * @c SentryUIApplication to swizzle it, this way, instead of relying on @c UIApplication, we can + * test with a mock class. * - * This category makes UIApplication conform to - * SentryUIApplication in order to be used by 'SentryUIViewControllerSwizzling'. + * This category makes @c UIApplication conform to + * @c SentryUIApplication in order to be used by @c SentryUIViewControllerSwizzling . */ @interface UIApplication (SentryUIApplication) @@ -209,8 +209,8 @@ - (void)swizzleUIViewControllersOfImage:(NSString *)imageName /** * If the iOS version is 13 or newer, and the project does not use a custom Window initialization - * the app uses a UIScenes to manage windows instead of the old AppDelegate. - * We wait for the first scene to connect to the app in order to find the rootViewController. + * the app uses a @c UIScene to manage windows instead of the old AppDelegate. + * We wait for the first scene to connect to the app in order to find the @c rootViewController. */ - (void)swizzleRootViewControllerFromSceneDelegateNotification:(NSNotification *)notification { @@ -306,11 +306,10 @@ - (void)swizzleRootViewControllerAndDescendant:(UIViewController *)rootViewContr } /** - * We need to swizzle UIViewController 'loadView' - * because we can`t do it for controllers that use Nib files - * (see `swizzleLoadView` for more information). - * SentryUIViewControllerPerformanceTracker makes sure we don't get two spans - * if the loadView of an actual UIViewController is swizzled. + * We need to swizzle @c -[UIViewController @c loadView] because we can't do it for controllers that + * use Nib files (see @c swizzleLoadView for more information). + * @c SentryUIViewControllerPerformanceTracker makes sure we don't get two spans + * if the @c -[loadView] of an actual @c UIViewController is swizzled. */ - (void)swizzleUIViewController { diff --git a/Sources/Sentry/SentryUser.m b/Sources/Sentry/SentryUser.m index 4b80d9653e..f6fc00695b 100644 --- a/Sources/Sentry/SentryUser.m +++ b/Sources/Sentry/SentryUser.m @@ -23,15 +23,13 @@ - (id)copyWithZone:(nullable NSZone *)zone { SentryUser *copy = [[SentryUser allocWithZone:zone] init]; - @synchronized(self) { - if (copy != nil) { - copy.userId = self.userId; - copy.email = self.email; - copy.username = self.username; - copy.ipAddress = self.ipAddress; - copy.segment = self.segment; - copy.data = self.data.copy; - } + if (copy != nil) { + copy.userId = self.userId; + copy.email = self.email; + copy.username = self.username; + copy.ipAddress = self.ipAddress; + copy.segment = self.segment; + copy.data = self.data.copy; } return copy; @@ -41,93 +39,83 @@ - (id)copyWithZone:(nullable NSZone *)zone { NSMutableDictionary *serializedData = [[NSMutableDictionary alloc] init]; - @synchronized(self) { - [serializedData setValue:self.userId forKey:@"id"]; - [serializedData setValue:self.email forKey:@"email"]; - [serializedData setValue:self.username forKey:@"username"]; - [serializedData setValue:self.ipAddress forKey:@"ip_address"]; - [serializedData setValue:self.segment forKey:@"segment"]; - [serializedData setValue:[self.data sentry_sanitize] forKey:@"data"]; - } + [serializedData setValue:self.userId forKey:@"id"]; + [serializedData setValue:self.email forKey:@"email"]; + [serializedData setValue:self.username forKey:@"username"]; + [serializedData setValue:self.ipAddress forKey:@"ip_address"]; + [serializedData setValue:self.segment forKey:@"segment"]; + [serializedData setValue:[self.data sentry_sanitize] forKey:@"data"]; return serializedData; } - (BOOL)isEqual:(id _Nullable)other { - @synchronized(self) { - if (other == self) { - return YES; - } - if (!other || ![[other class] isEqual:[self class]]) { - return NO; - } - - return [self isEqualToUser:other]; + + if (other == self) { + return YES; } + if (!other || ![[other class] isEqual:[self class]]) { + return NO; + } + + return [self isEqualToUser:other]; } - (BOOL)isEqualToUser:(SentryUser *)user { - @synchronized(self) { - // We need to get some local copies of the properties, because they could be modified during - // the if statements - - if (self == user) { - return YES; - } - if (user == nil) { - return NO; - } - - NSString *otherUserId = user.userId; - if (self.userId != otherUserId && ![self.userId isEqualToString:otherUserId]) { - return NO; - } - - NSString *otherEmail = user.email; - if (self.email != otherEmail && ![self.email isEqualToString:otherEmail]) { - return NO; - } - - NSString *otherUsername = user.username; - if (self.username != otherUsername && ![self.username isEqualToString:otherUsername]) { - return NO; - } - - NSString *otherIpAdress = user.ipAddress; - if (self.ipAddress != otherIpAdress && ![self.ipAddress isEqualToString:otherIpAdress]) { - return NO; - } - - NSString *otherSegment = user.segment; - if (self.segment != otherSegment && ![self.segment isEqualToString:otherSegment]) { - return NO; - } - - NSDictionary *otherUserData = user.data; - if (self.data != otherUserData && ![self.data isEqualToDictionary:otherUserData]) { - return NO; - } - + if (self == user) { return YES; } + if (user == nil) { + return NO; + } + + NSString *otherUserId = user.userId; + if (self.userId != otherUserId && ![self.userId isEqualToString:otherUserId]) { + return NO; + } + + NSString *otherEmail = user.email; + if (self.email != otherEmail && ![self.email isEqualToString:otherEmail]) { + return NO; + } + + NSString *otherUsername = user.username; + if (self.username != otherUsername && ![self.username isEqualToString:otherUsername]) { + return NO; + } + + NSString *otherIpAdress = user.ipAddress; + if (self.ipAddress != otherIpAdress && ![self.ipAddress isEqualToString:otherIpAdress]) { + return NO; + } + + NSString *otherSegment = user.segment; + if (self.segment != otherSegment && ![self.segment isEqualToString:otherSegment]) { + return NO; + } + + NSDictionary *otherUserData = user.data; + if (self.data != otherUserData && ![self.data isEqualToDictionary:otherUserData]) { + return NO; + } + + return YES; } - (NSUInteger)hash { - @synchronized(self) { - NSUInteger hash = 17; + NSUInteger hash = 17; - hash = hash * 23 + [self.userId hash]; - hash = hash * 23 + [self.email hash]; - hash = hash * 23 + [self.username hash]; - hash = hash * 23 + [self.ipAddress hash]; - hash = hash * 23 + [self.segment hash]; - hash = hash * 23 + [self.data hash]; + hash = hash * 23 + [self.userId hash]; + hash = hash * 23 + [self.email hash]; + hash = hash * 23 + [self.username hash]; + hash = hash * 23 + [self.ipAddress hash]; + hash = hash * 23 + [self.segment hash]; + hash = hash * 23 + [self.data hash]; - return hash; - } + return hash; } @end diff --git a/Sources/Sentry/SentryViewHierarchyIntegration.m b/Sources/Sentry/SentryViewHierarchyIntegration.m index dcef9bf6be..f159349a73 100644 --- a/Sources/Sentry/SentryViewHierarchyIntegration.m +++ b/Sources/Sentry/SentryViewHierarchyIntegration.m @@ -10,10 +10,17 @@ #if SENTRY_HAS_UIKIT +/** + * Function to call through to the ObjC method to save a view hierarchy, which can be passed around + * as a function pointer in the C crash reporting code. + * @param reportDirectoryPath The path to the directory containing crash reporting files, in which a + * new file will be created to store the view hierarchy description. + */ void -saveViewHierarchy(const char *path) +saveViewHierarchy(const char *reportDirectoryPath) { - NSString *reportPath = [NSString stringWithUTF8String:path]; + NSString *reportPath = [[NSString stringWithUTF8String:reportDirectoryPath] + stringByAppendingPathComponent:@"view-hierarchy.json"]; [SentryDependencyContainer.sharedInstance.viewHierarchy saveViewHierarchy:reportPath]; } diff --git a/Sources/Sentry/include/HybridPublic/PrivateSentrySDKOnly.h b/Sources/Sentry/include/HybridPublic/PrivateSentrySDKOnly.h index c09e5d000a..d6a4001914 100644 --- a/Sources/Sentry/include/HybridPublic/PrivateSentrySDKOnly.h +++ b/Sources/Sentry/include/HybridPublic/PrivateSentrySDKOnly.h @@ -1,27 +1,26 @@ #import "PrivatesHeader.h" #import "SentryAppStartMeasurement.h" +#import "SentryEnvelope.h" #import "SentryEnvelopeItemType.h" #import "SentryScreenFrames.h" -@class SentryEnvelope, SentryDebugMeta, SentryAppStartMeasurement, SentryScreenFrames, - SentryOptions; +@class SentryDebugMeta, SentryAppStartMeasurement, SentryScreenFrames, SentryOptions; NS_ASSUME_NONNULL_BEGIN /** - * A callback to be notified when the AppStartMeasurement is available. + * A callback to be notified when the @c AppStartMeasurement is available. */ typedef void (^SentryOnAppStartMeasurementAvailable)( SentryAppStartMeasurement *_Nullable appStartMeasurement); /** - * ATTENTION: This class is reserved for hybrid SDKs. Methods may be changed, renamed or removed + * @warning This class is reserved for hybrid SDKs. Methods may be changed, renamed or removed * without notice. If you want to use one of these methods here please open up an issue and let us * know. - * - * The name of this class is supposed to be a bit weird and ugly. The name starts with private on - * purpose so users don't see it in code completion when typing Sentry. We also add only at the end - * to make it more obvious you shouldn't use it. + * @note The name of this class is supposed to be a bit weird and ugly. The name starts with private + * on purpose so users don't see it in code completion when typing Sentry. We also add only at the + * end to make it more obvious you shouldn't use it. */ @interface PrivateSentrySDKOnly : NSObject @@ -33,13 +32,14 @@ typedef void (^SentryOnAppStartMeasurementAvailable)( + (void)captureEnvelope:(SentryEnvelope *)envelope; /** - * Create an envelope from NSData. Needed for example by Flutter. + * Create an envelope from @c NSData. Needed for example by Flutter. */ + (nullable SentryEnvelope *)envelopeWithData:(NSData *)data; /** - * Returns the current list of debug images. Be aware that the SentryDebugMeta is actually - * describing a debug image. This class should be renamed to SentryDebugImage in a future version. + * Returns the current list of debug images. Be aware that the @c SentryDebugMeta is actually + * describing a debug image. + * @todo This class should be renamed to @c SentryDebugImage in a future version. */ + (NSArray *)getDebugImages; @@ -74,11 +74,12 @@ typedef void (^SentryOnAppStartMeasurementAvailable)( /** * If enabled, the SDK won't send the app start measurement with the first transaction. Instead, if - * enableAutoPerformanceTracing is enabled, the SDK measures the app start and then calls - * onAppStartMeasurementAvailable. Furthermore, the SDK doesn't set all values for the app start + * @c enableAutoPerformanceTracing is enabled, the SDK measures the app start and then calls + * @c onAppStartMeasurementAvailable. Furthermore, the SDK doesn't set all values for the app start * measurement because the HybridSDKs initialize the Cocoa SDK too late to receive all - * notifications. Instead, the SDK sets the appStartDuration to 0 and the - * didFinishLaunchingTimestamp to timeIntervalSinceReferenceDate. Default is NO. + * notifications. Instead, the SDK sets the @c appStartDuration to @c 0 and the + * @c didFinishLaunchingTimestamp to @c timeIntervalSinceReferenceDate. + * @note Default is @c NO. */ @property (class, nonatomic, assign) BOOL appStartMeasurementHybridSDKMode; diff --git a/Sources/Sentry/include/HybridPublic/SentryEnvelope.h b/Sources/Sentry/include/HybridPublic/SentryEnvelope.h index c304cf0b69..dfa3493539 100644 --- a/Sources/Sentry/include/HybridPublic/SentryEnvelope.h +++ b/Sources/Sentry/include/HybridPublic/SentryEnvelope.h @@ -1,8 +1,20 @@ #import "PrivatesHeader.h" -#import "SentryEnvelopeItemHeader.h" +#if __has_include() +# import +#else +# import "SentryEnvelopeItemHeader.h" +#endif -@class SentryEvent, SentrySession, SentrySdkInfo, SentryId, SentryUserFeedback, SentryAttachment, - SentryTransaction, SentryTraceContext, SentryClientReport, SentryEnvelopeItemHeader; +#if COCOAPODS +@class SentrySdkInfo, SentryTraceContext; +#else +# import "SentrySdkInfo.h" +# import "SentryTraceContext.h" + +#endif + +@class SentryEvent, SentrySession, SentryId, SentryUserFeedback, SentryAttachment, + SentryTransaction, SentryClientReport, SentryEnvelopeItemHeader; NS_ASSUME_NONNULL_BEGIN @@ -10,33 +22,29 @@ NS_ASSUME_NONNULL_BEGIN SENTRY_NO_INIT /** - * Initializes an SentryEnvelopeHeader object with the specified eventId. - * - * Sets the sdkInfo from SentryMeta. - * + * Initializes an @c SentryEnvelopeHeader object with the specified eventId. + * @note Sets the @c sdkInfo from @c SentryMeta. * @param eventId The identifier of the event. Can be nil if no event in the envelope or attachment * related to event. */ - (instancetype)initWithId:(SentryId *_Nullable)eventId; /** - * Initializes an SentryEnvelopeHeader object with the specified eventId and traceContext. - * - * @param eventId The identifier of the event. Can be nil if no event in the envelope or attachment - * related to event. + * Initializes a @c SentryEnvelopeHeader object with the specified @c eventId and @c traceContext. + * @param eventId The identifier of the event. Can be @c nil if no event in the envelope or + * attachment related to event. * @param traceContext Current trace state. */ - (instancetype)initWithId:(nullable SentryId *)eventId traceContext:(nullable SentryTraceContext *)traceContext; /** - * Initializes an SentryEnvelopeHeader object with the specified eventId, skdInfo and traceContext. - * - * It is recommended to use initWithId:traceContext: because it sets the sdkInfo for you. - * - * @param eventId The identifier of the event. Can be nil if no event in the envelope or attachment - * related to event. - * @param sdkInfo sdkInfo Describes the Sentry SDK. Can be nil for backwards compatibility. New + * Initializes a @c SentryEnvelopeHeader object with the specified @c eventId, @c skdInfo and + * @c traceContext. It is recommended to use @c initWithId:traceContext: because it sets the + * @c sdkInfo for you. + * @param eventId The identifier of the event. Can be @c nil if no event in the envelope or + * attachment related to event. + * @param sdkInfo Describes the Sentry SDK. Can be @c nil for backwards compatibility. New * instances should always provide a version. * @param traceContext Current trace state. */ @@ -46,8 +54,8 @@ SENTRY_NO_INIT /** * The event identifier, if available. - * An event id exist if the envelope contains an event of items within it are - * related. i.e Attachments + * An event id exist if the envelope contains an event of items within it are related. i.e + * Attachments */ @property (nullable, nonatomic, readonly, copy) SentryId *eventId; @@ -92,25 +100,24 @@ SENTRY_NO_INIT - (instancetype)initWithId:(SentryId *_Nullable)id items:(NSArray *)items; /** - * Initializes a SentryEnvelope with a single session. + * Initializes a @c SentryEnvelope with a single session. * @param session to init the envelope with. - * @return an initialized SentryEnvelope */ - (instancetype)initWithSession:(SentrySession *)session; /** - * Initializes a SentryEnvelope with a list of sessions. - * Can be used when an operations that starts a session closes an ongoing - * session + * Initializes a @c SentryEnvelope with a list of sessions. + * Can be used when an operation that starts a session closes an ongoing session. * @param sessions to init the envelope with. - * @return an initialized SentryEnvelope */ - (instancetype)initWithSessions:(NSArray *)sessions; - (instancetype)initWithHeader:(SentryEnvelopeHeader *)header items:(NSArray *)items NS_DESIGNATED_INITIALIZER; -// Convenience init for a single event +/** + * Convenience init for a single event. + */ - (instancetype)initWithEvent:(SentryEvent *)event; - (instancetype)initWithUserFeedback:(SentryUserFeedback *)userFeedback; diff --git a/Sources/Sentry/include/SentryANRTracker.h b/Sources/Sentry/include/SentryANRTracker.h index 2f2779cad2..2178215b82 100644 --- a/Sources/Sentry/include/SentryANRTracker.h +++ b/Sources/Sentry/include/SentryANRTracker.h @@ -11,15 +11,14 @@ NS_ASSUME_NONNULL_BEGIN * This class detects ANRs with a dedicated watchdog thread. The thread schedules a simple block to * run on the main thread, sleeps for the configured timeout interval, and checks if the main thread * executed this block. - * - * @discussion We decided against using a CFRunLoopObserver or the CADisplayLink, which the - * SentryFramesTracker already uses, because they come with two disadvantages. First, the solution - * is expensive. Quick benchmarks showed that hooking into the main thread's run loop and checking - * for every event to process if the main thread executes it in time added around 0,5 % of CPU - * overhead. Furthermore, if the main thread runs all scheduled events in time, it doesn't mean that - * there is no ANR ongoing. It could be that the run loop of the main thread is busy for 20 seconds, - * and it executes all events in time. Instead, what matters is how long the main thread needs to - * execute a newly added event to the run loop. + * @discussion We decided against using a @c CFRunLoopObserver or the @c CADisplayLink, which the + * @c SentryFramesTracker already uses, because they come with two disadvantages. First, the + * solution is expensive. Quick benchmarks showed that hooking into the main thread's run loop and + * checking for every event to process if the main thread executes it in time added around 0,5 % of + * CPU overhead. Furthermore, if the main thread runs all scheduled events in time, it doesn't mean + * that there is no ANR ongoing. It could be that the run loop of the main thread is busy for 20 + * seconds, and it executes all events in time. Instead, what matters is how long the main thread + * needs to execute a newly added event to the run loop. */ @interface SentryANRTracker : NSObject SENTRY_NO_INIT @@ -39,6 +38,9 @@ SENTRY_NO_INIT @end +/** + * The ``SentryANRTracker`` calls the methods from background threads. + */ @protocol SentryANRTrackerDelegate - (void)anrDetected; diff --git a/Sources/Sentry/include/SentryAppState.h b/Sources/Sentry/include/SentryAppState.h index 1d099734fb..2b853f0563 100644 --- a/Sources/Sentry/include/SentryAppState.h +++ b/Sources/Sentry/include/SentryAppState.h @@ -13,11 +13,9 @@ SENTRY_NO_INIT systemBootTimestamp:(NSDate *)systemBootTimestamp; /** - * Initializes SentryAppState from a JSON object. - * - * @param jsonObject The jsonObject containing the session. - * - * @return The SentrySession or nil if the JSONObject contains an error. + * Initializes @c SentryAppState from a JSON object. + * @param jsonObject The @c jsonObject containing the session. + * @return The @c SentrySession or @c nil if @c jsonObject contains an error. */ - (nullable instancetype)initWithJSONObject:(NSDictionary *)jsonObject; diff --git a/Sources/Sentry/include/SentryAppStateManager.h b/Sources/Sentry/include/SentryAppStateManager.h index c1cb0017d1..0a77e32a4d 100644 --- a/Sources/Sentry/include/SentryAppStateManager.h +++ b/Sources/Sentry/include/SentryAppStateManager.h @@ -27,11 +27,10 @@ SENTRY_NO_INIT /** * Builds the current app state. - * - * @discussion The systemBootTimestamp is calculated by taking the current time and substracting - * NSProcesInfo.systemUptime. NSProcesInfo.systemUptime returns the amount of time the system has - * been awake since the last time it was restarted. This means This is a good enough approximation - * about the timestamp the system booted. + * @discussion The systemBootTimestamp is calculated by taking the current time and subtracting + * @c NSProcesInfo.systemUptime . @c NSProcesInfo.systemUptime returns the amount of time the system + * has been awake since the last time it was restarted. This means This is a good enough + * approximation about the timestamp the system booted. */ - (SentryAppState *)buildCurrentAppState; diff --git a/Sources/Sentry/include/SentryAttachment+Private.h b/Sources/Sentry/include/SentryAttachment+Private.h index 967b62d02e..2a8b7924ac 100644 --- a/Sources/Sentry/include/SentryAttachment+Private.h +++ b/Sources/Sentry/include/SentryAttachment+Private.h @@ -25,11 +25,10 @@ SENTRY_NO_INIT /** * Initializes an attachment with data. - * * @param data The data for the attachment. * @param filename The name of the attachment to display in Sentry. - * @param contentType The content type of the attachment. Default is "application/octet-stream". - * @param attachmentType The type of the attachment. Default is "EventAttachment". + * @param contentType The content type of the attachment. Default is @c "application/octet-stream". + * @param attachmentType The type of the attachment. Default is @c "EventAttachment". */ - (instancetype)initWithData:(NSData *)data filename:(NSString *)filename @@ -38,11 +37,10 @@ SENTRY_NO_INIT /** * Initializes an attachment with data. - * * @param path The path of the file whose contents you want to upload to Sentry. * @param filename The name of the attachment to display in Sentry. - * @param contentType The content type of the attachment. Default is "application/octet-stream". - * @param attachmentType The type of the attachment. Default is "EventAttachment". + * @param contentType The content type of the attachment. Default is @c "application/octet-stream". + * @param attachmentType The type of the attachment. Default is@c "EventAttachment". */ - (instancetype)initWithPath:(NSString *)path filename:(NSString *)filename diff --git a/Sources/Sentry/include/SentryCPU.h b/Sources/Sentry/include/SentryCPU.h index cb91d10543..dcc5ef0ec5 100644 --- a/Sources/Sentry/include/SentryCPU.h +++ b/Sources/Sentry/include/SentryCPU.h @@ -13,7 +13,7 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR diff --git a/Sources/Sentry/include/SentryClient+Private.h b/Sources/Sentry/include/SentryClient+Private.h index 30a891a0f3..a9bcd46981 100644 --- a/Sources/Sentry/include/SentryClient+Private.h +++ b/Sources/Sentry/include/SentryClient+Private.h @@ -2,7 +2,8 @@ #import "SentryDataCategory.h" #import "SentryDiscardReason.h" -@class SentryEnvelopeItem, SentryId, SentryAttachment, SentryThreadInspector, SentryEnvelope; +@class SentrySession, SentryEnvelopeItem, SentryId, SentryAttachment, SentryThreadInspector, + SentryEnvelope; NS_ASSUME_NONNULL_BEGIN @@ -41,6 +42,8 @@ SentryClient () additionalEnvelopeItems:(NSArray *)additionalEnvelopeItems NS_SWIFT_NAME(capture(event:scope:additionalEnvelopeItems:)); +- (void)captureSession:(SentrySession *)session NS_SWIFT_NAME(capture(session:)); + /** * Needed by hybrid SDKs as react-native to synchronously store an envelope to disk. */ diff --git a/Sources/Sentry/include/SentryCompiler.h b/Sources/Sentry/include/SentryCompiler.h index 1d097c011a..e00fc1e43b 100644 --- a/Sources/Sentry/include/SentryCompiler.h +++ b/Sources/Sentry/include/SentryCompiler.h @@ -11,7 +11,7 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR diff --git a/Sources/Sentry/include/SentryCrashReportConverter.h b/Sources/Sentry/include/SentryCrashReportConverter.h index d94ecfb903..a68a339ab4 100644 --- a/Sources/Sentry/include/SentryCrashReportConverter.h +++ b/Sources/Sentry/include/SentryCrashReportConverter.h @@ -11,8 +11,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithReport:(NSDictionary *)report inAppLogic:(SentryInAppLogic *)inAppLogic; /** - * Converts the report to an SentryEvent. - * + * Converts the report to an @c SentryEvent. * @return The converted event or nil if an error occurred during the conversion. */ - (SentryEvent *_Nullable)convertReportToEvent; diff --git a/Sources/Sentry/include/SentryCrashScopeObserver.h b/Sources/Sentry/include/SentryCrashScopeObserver.h index 9e00073e51..f6bd51e25a 100644 --- a/Sources/Sentry/include/SentryCrashScopeObserver.h +++ b/Sources/Sentry/include/SentryCrashScopeObserver.h @@ -4,17 +4,16 @@ NS_ASSUME_NONNULL_BEGIN /** - * This class performs a fine-grained sync of the Scope to C memory, as when SentryCrash writes a - * crash report, we can't call Objective-C methods; see SentryCrash.onCrash. For every change to the - * Scope, this class serializes only the changed property to JSON and stores it in C memory. When a - * crash happens, the SentryCrashReport picks up the JSON of all properties and adds it to the crash - * report. - * - * Previously, the SDK used SentryCrash.setUserInfo, which required the serialization of the whole - * Scope on every modification of it. When having much data in the Scope this slowed down the caller - * of the scope change. Therefore, we had to move the Scope sync to a background thread. This has - * the downside of the scope not being 100% up to date when a crash happens and, of course, lots of - * CPU overhead. + * This class performs a fine-grained sync of the Scope to C memory, as when @c SentryCrash writes a + * crash report, we can't call Objective-C methods; see @c SentryCrash.onCrash. For every change to + * the Scope, this class serializes only the changed property to JSON and stores it in C memory. + * When a crash happens, the @c SentryCrashReport picks up the JSON of all properties and adds it to + * the crash report. + * @discussion Previously, the SDK used @c SentryCrash.setUserInfo, which required the serialization + * of the whole Scope on every modification of it. When having much data in the Scope this slowed + * down the caller of the scope change. Therefore, we had to move the Scope sync to a background + * thread. This has the downside of the scope not being 100% up to date when a crash happens and, of + * course, lots of CPU overhead. */ @interface SentryCrashScopeObserver : NSObject SENTRY_NO_INIT diff --git a/Sources/Sentry/include/SentryCrashStackEntryMapper.h b/Sources/Sentry/include/SentryCrashStackEntryMapper.h index 4dec4fc3cc..f7679c97b4 100644 --- a/Sources/Sentry/include/SentryCrashStackEntryMapper.h +++ b/Sources/Sentry/include/SentryCrashStackEntryMapper.h @@ -14,15 +14,13 @@ SENTRY_NO_INIT /** * Maps the stackEntry of a SentryCrashStackCursor to SentryFrame. - * - * @param stackCursor An with SentryCrash initialized stackCursor. You can use for example - * sentrycrashsc_initSelfThread. + * @param stackCursor An with @c SentryCrash initialized @c stackCursor. You can use for example + * @c sentrycrashsc_initSelfThread. */ - (SentryFrame *)mapStackEntryWithCursor:(SentryCrashStackCursor)stackCursor; /** - * Maps a SentryCrashStackEntry to SentryFrame. - * + * Maps a @c SentryCrashStackEntry to @c SentryFrame. * @param stackEntry A stack entry retrieved from a thread. */ - (SentryFrame *)sentryCrashStackEntryToSentryFrame:(SentryCrashStackEntry)stackEntry; diff --git a/Sources/Sentry/SentryDefaultObjCRuntimeWrapper.h b/Sources/Sentry/include/SentryDefaultObjCRuntimeWrapper.h similarity index 100% rename from Sources/Sentry/SentryDefaultObjCRuntimeWrapper.h rename to Sources/Sentry/include/SentryDefaultObjCRuntimeWrapper.h diff --git a/Sources/Sentry/include/SentryDispatchQueueWrapper.h b/Sources/Sentry/include/SentryDispatchQueueWrapper.h index 06bcfaba1e..0a7948fedc 100644 --- a/Sources/Sentry/include/SentryDispatchQueueWrapper.h +++ b/Sources/Sentry/include/SentryDispatchQueueWrapper.h @@ -21,6 +21,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)dispatchOnce:(dispatch_once_t *)predicate block:(void (^)(void))block; +- (nullable dispatch_block_t)createDispatchBlock:(void (^)(void))block; + @end NS_ASSUME_NONNULL_END diff --git a/Sources/Sentry/include/SentryFileManager.h b/Sources/Sentry/include/SentryFileManager.h index 85ab66f047..0f5ae265cd 100644 --- a/Sources/Sentry/include/SentryFileManager.h +++ b/Sources/Sentry/include/SentryFileManager.h @@ -52,15 +52,14 @@ SENTRY_NO_INIT - (void)deleteOldEnvelopeItems; /** - * Get all envelopes sorted ascending by the timeIntervalSince1970 the envelope was stored and if + * Get all envelopes sorted ascending by the @c timeIntervalSince1970 the envelope was stored and if * two envelopes are stored at the same time sorted by the order they were stored. */ - (NSArray *)getAllEnvelopes; /** - * Gets the oldest stored envelope. For the order see getAllEnvelopes. - * - * @return SentryFileContens if there is an envelope and nil if there are no envelopes. + * Gets the oldest stored envelope. For the order see @c getAllEnvelopes. + * @return @c SentryFileContents if there is an envelope and @c nil if there are no envelopes. */ - (SentryFileContents *_Nullable)getOldestEnvelope; diff --git a/Sources/Sentry/include/SentryFrameRemover.h b/Sources/Sentry/include/SentryFrameRemover.h index 77b8708394..16b5e315d7 100644 --- a/Sources/Sentry/include/SentryFrameRemover.h +++ b/Sources/Sentry/include/SentryFrameRemover.h @@ -8,12 +8,11 @@ NS_ASSUME_NONNULL_BEGIN /** * Removes Sentry SDK frames until a frame from a different package is found. - * - * When a user includes Sentry as a static library, the package is the same as the application. - * Therefore removing frames with a package containing "sentry" doesn't work. We can't look into the - * function name as in release builds, the function name can be obfuscated, or we remove functions - * that are not from this SDK and contain "sentry". Therefore this logic only works for apps - * including Sentry dynamically. + * @discussion When a user includes Sentry as a static library, the package is the same as the + * application. Therefore removing frames with a package containing "sentry" doesn't work. We can't + * look into the function name as in release builds, the function name can be obfuscated, or we + * remove functions that are not from this SDK and contain "sentry". Therefore this logic only works + * for apps including Sentry dynamically. */ + (NSArray *)removeNonSdkFrames:(NSArray *)frames; diff --git a/Sources/Sentry/include/SentryInAppLogic.h b/Sources/Sentry/include/SentryInAppLogic.h index 01b734f860..9afa5a1b8f 100644 --- a/Sources/Sentry/include/SentryInAppLogic.h +++ b/Sources/Sentry/include/SentryInAppLogic.h @@ -7,22 +7,23 @@ NS_ASSUME_NONNULL_BEGIN * This class detects whether a framework belongs to the app or not. We differentiate between three * different types of frameworks. * - * First, the main executable of the app, which's name can be retrieved by CFBundleExecutable. To - * mark this framework as inApp the caller needs to pass in the CFBundleExecutable to InAppIncludes. + * First, the main executable of the app, which's name can be retrieved by @c CFBundleExecutable. To + * mark this framework as "in-app" the caller needs to pass in the @c CFBundleExecutable to + * @c inAppIncludes. * * Next, there are private frameworks embedded in the application bundle. Both app supporting * frameworks as CocoaLumberJack, Sentry, RXSwift, etc., and frameworks written by the user fall - * into this category. These frameworks can be both inApp or not. As we expect most frameworks of - * this category to be supporting frameworks, we mark them not as inApp. If a user wants such a - * framework to be inApp, they need to pass the name into inAppInclude. For dynamic frameworks, the - * location is usually in the bundle under /Frameworks/FrameworkName.framework/FrameworkName. As for - * static frameworks, the location is the same as the main executable; this class marks all static - * frameworks as inApp. To remove static frameworks from being inApp, Sentry uses stack trace - * grouping rules on the server. + * into this category. These frameworks can be both "in-app" or not. As we expect most frameworks of + * this category to be supporting frameworks, we mark them not as "in-app". If a user wants such a + * framework to be "in-app", they need to pass the name into @c inAppIncludes. For dynamic + * frameworks, the location is usually in the bundle under + * /Frameworks/FrameworkName.framework/FrameworkName. As for static frameworks, the location is the + * same as the main executable; this class marks all static frameworks as "in-app". To remove static + * frameworks from being "in-app", Sentry uses stack trace grouping rules on the server. * - * Last, this class marks all public frameworks as not inApp. Such frameworks are bound dynamically - * and are usually located at /Library/Frameworks or ~/Library/Frameworks. For simulators, the - * location can be something like + * Last, this class marks all public frameworks as not "in-app". Such frameworks are bound + * dynamically and are usually located at /Library/Frameworks or ~/Library/Frameworks. For + * simulators, the location can be something like * /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/... * */ @@ -30,13 +31,13 @@ NS_ASSUME_NONNULL_BEGIN SENTRY_NO_INIT /** - * Initializes SentryInAppLogic with inAppIncludes and inAppExcludes. + * Initializes @c SentryInAppLogic with @c inAppIncludes and @c inAppExcludes. * - * To work properly for Apple applications the inAppIncludes should contain the CFBundleExecutable, - * which is the name of the bundle’s executable file. + * To work properly for Apple applications the @c inAppIncludes should contain the + * @c CFBundleExecutable, which is the name of the bundle’s executable file. * * @param inAppIncludes A list of string prefixes of framework names that belong to the app. This - * option takes precedence over inAppExcludes. + * option takes precedence over @c inAppExcludes. * @param inAppExcludes A list of string prefixes of framework names that do not belong to the app, * but rather to third-party packages. Modules considered not part of the app will be hidden from * stack traces by default. @@ -45,25 +46,29 @@ SENTRY_NO_INIT inAppExcludes:(NSArray *)inAppExcludes; /** - * Determines if the framework belongs to the app by using inAppIncludes and inAppExcludes. Before - * checking this method lowercases the strings and uses only the lastPathComponent of the imagePath. + * Determines if the framework belongs to the app by using @c inAppIncludes and @c inAppExcludes. + * Before checking this method lowercases the strings and uses only the @c lastPathComponent of the + * @c imagePath. * * @param imagePath the full path of the binary image. * - * @return YES if the framework located at the imagePath starts with a prefix of inAppIncludes. NO - * if the framework located at the imagePath doesn't start with a prefix of inAppIncludes or start - * with a prefix of inAppExcludes. + * @return @c YES if the framework located at the @c imagePath starts with a prefix of + * @c inAppIncludes. @c NO if the framework located at the @c imagePath doesn't start with a prefix + * of + * @c inAppIncludes or start with a prefix of @c inAppExcludes. */ - (BOOL)isInApp:(nullable NSString *)imagePath; /** - * Determines if the class belongs to the app by getting its framework and checking with `isInApp:`. + * Determines if the class belongs to the app by getting its framework and checking with + * @c -[isInApp:] * * @param targetClass the class to check. * - * @return YES if the targetClass belongs to a framework included in inAppIncludes. - * NO if targetClass does not belong to a framework in inAppIncludes or belongs to a framework in - * inAppExcludes. + * @return @c YES if the @c targetClass belongs to a framework included in @c inAppIncludes. + * @c NO if targetClass does not belong to a framework in @c inAppIncludes or belongs to a framework + * in + * @c inAppExcludes. */ - (BOOL)isClassInApp:(Class)targetClass; diff --git a/Sources/Sentry/include/SentryLog.h b/Sources/Sentry/include/SentryLog.h index 0e2b502933..2cb2619e7c 100644 --- a/Sources/Sentry/include/SentryLog.h +++ b/Sources/Sentry/include/SentryLog.h @@ -11,8 +11,10 @@ SENTRY_NO_INIT + (void)logWithMessage:(NSString *)message andLevel:(SentryLevel)level; -/** @return @c YES if the current logging configuration will log statements at the current level, @c - * NO if not. */ +/** + * @return @c YES if the current logging configuration will log statements at the current level, + * @c NO if not. + */ + (BOOL)willLogAtLevel:(SentryLevel)level; @end @@ -31,8 +33,8 @@ NS_ASSUME_NONNULL_END #define SENTRY_LOG_FATAL(...) SENTRY_LOG(kSentryLevelFatal, __VA_ARGS__) /** - * If `errno` is set to a non-zero value after `statement` finishes executing, - * the error value is logged, and the original return value of `statement` is + * If @c errno is set to a non-zero value after @c statement finishes executing, + * the error value is logged, and the original return value of @c statement is * returned. */ #define SENTRY_LOG_ERRNO(statement) \ diff --git a/Sources/Sentry/include/SentryMetricProfiler.h b/Sources/Sentry/include/SentryMetricProfiler.h index 78655bf3b9..a644735ac6 100644 --- a/Sources/Sentry/include/SentryMetricProfiler.h +++ b/Sources/Sentry/include/SentryMetricProfiler.h @@ -23,14 +23,14 @@ SENTRY_EXTERN NSString *const kSentryMetricProfilerSerializationUnitPercentage; /** * A structure to hold a single metric reading and the time it was taken, as a dictionary with keyed - * values either of type NSNumber for the reading value, or NSString for the timestamp (we just - * encode @cuint64\_t as a string since JSON doesn't officially support it). + * values either of type @c NSNumber for the reading value, or @c NSString for the timestamp (we + * just encode @c uint64_t as a string since JSON doesn't officially support it). */ typedef NSDictionary */> SentrySerializedMetricReading; /** * A structure containing the timeseries of values for a particular metric type, as a dictionary - * with keyed values either of type NSString, for unit names, or an array of metrics entries + * with keyed values either of type @c NSString, for unit names, or an array of metrics entries * containing the values and timestamps in the above typedef. */ typedef NSDictionary> */> @@ -50,8 +50,7 @@ typedef NSDictionary": @{ * @"unit": @"", diff --git a/Sources/Sentry/include/SentryMigrateSessionInit.h b/Sources/Sentry/include/SentryMigrateSessionInit.h index e6d2e23ae3..4c0f447276 100644 --- a/Sources/Sentry/include/SentryMigrateSessionInit.h +++ b/Sources/Sentry/include/SentryMigrateSessionInit.h @@ -6,11 +6,12 @@ NS_ASSUME_NONNULL_BEGIN /** * For proper statistics in release health, we need to make sure we don't send session updates - without sending a session init first. In other words, we can't drop a session init. The -  SentryFileManager deletes an envelope once the maximum amount of envelopes is stored. When this - happens and the envelope to delete contains a session init we look for the next envelope containing - a session update for the same session. If such a session envelope is found we migrate the init - flag. If none is found we delete the envelope. We don't migrate other envelope items as events. + * without sending a session init first. In other words, we can't drop a session init. The + * @c SentryFileManager deletes an envelope once the maximum amount of envelopes is stored. When + * this happens and the envelope to delete contains a session init we look for the next envelope + * containing a session update for the same session. If such a session envelope is found we migrate + * the init flag. If none is found we delete the envelope. We don't migrate other envelope items as + * events. */ @interface SentryMigrateSessionInit : NSObject SENTRY_NO_INIT @@ -18,15 +19,13 @@ SENTRY_NO_INIT /** * Checks if the envelope of the passed file path contains an envelope item with a session init. If * it does it iterates over all envelopes and looks for a session with the same session id. If such - * a session is found the init flag is set to YES, the envelope is updated with keeping other + * a session is found the init flag is set to @c YES, the envelope is updated with keeping other * envelope items and headers, and the updated envelope is stored to the disk keeping its path. - * * @param envelope The envelope to delete * @param envelopesDirPath The path of the directory where the envelopes are stored. * @param envelopeFilePaths An array containing the file paths of envelopes to check if they contain * a session init. - * - * @return YES if the function migrated the session init. NO if not. + * @return @c YES if the function migrated the session init. @c NO if not. */ + (BOOL)migrateSessionInit:(SentryEnvelope *)envelope envelopesDirPath:(NSString *)envelopesDirPath diff --git a/Sources/Sentry/include/SentryNSNotificationCenterWrapper.h b/Sources/Sentry/include/SentryNSNotificationCenterWrapper.h index 0bb69def33..070f03384b 100644 --- a/Sources/Sentry/include/SentryNSNotificationCenterWrapper.h +++ b/Sources/Sentry/include/SentryNSNotificationCenterWrapper.h @@ -3,12 +3,12 @@ NS_ASSUME_NONNULL_BEGIN /** - * A wrapper around NSNotificationCenter functions for testability. - * - * Testing with NSNotificationCenter in CI leads to flaky tests for some classes. Therefore, we can - * use a wrapper around NSNotificationCenter to not depend on it. Instead, we call the methods - * NSNotificationCenter would call with Dynamic and ensure that sut properly subscribes to - * NSNotificationCenter. + * A wrapper around @c NSNotificationCenter functions for testability. + * @discussion Testing with @c NSNotificationCenter in CI leads to flaky tests for some classes. + * Therefore, we can use a wrapper around @c NSNotificationCenter to not depend on it. Instead, we + * call the methods + * @c NSNotificationCenter would call with Dynamic and ensure that sut properly subscribes to + * @c NSNotificationCenter. */ @interface SentryNSNotificationCenterWrapper : NSObject diff --git a/Sources/Sentry/SentryNoOpSpan.h b/Sources/Sentry/include/SentryNoOpSpan.h similarity index 100% rename from Sources/Sentry/SentryNoOpSpan.h rename to Sources/Sentry/include/SentryNoOpSpan.h diff --git a/Sources/Sentry/include/SentryPerformanceTracker.h b/Sources/Sentry/include/SentryPerformanceTracker.h index 6aac41c35e..6f43d141d0 100644 --- a/Sources/Sentry/include/SentryPerformanceTracker.h +++ b/Sources/Sentry/include/SentryPerformanceTracker.h @@ -7,8 +7,8 @@ NS_ASSUME_NONNULL_BEGIN @class SentrySpanId; /** - * Tracks performance synchronizing span with its childs. - * A span will be finished only when all its children are finished. + * Tracks performance synchronizing span with its child's. + * @note A span will be finished only when all its children are finished. */ @interface SentryPerformanceTracker : NSObject @@ -18,31 +18,24 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, class, readonly) SentryPerformanceTracker *shared; /** - * Starts a new span if no span is active, - * then bind it to the scope if no span is binded. - * If there`s an active span, starts a child of the active span. - * + * Starts a new span if no span is active, then bind it to the scope if no span is bound. + * @note If there's an active span, starts a child of the active span. * @param name Span name. * @param operation Span operation. - * * @return The span id. */ - (SentrySpanId *)startSpanWithName:(NSString *)name operation:(NSString *)operation; /** - * Activate the span with `spanId` - * to create any call to startSpan as a child. - * If the there is no span with the fiven spanId - * block is executed anyway. - * + * Activate the span with @c spanId to create any call to @c startSpan as a child. + * @note If the there is no span with @c spanId , @c block is executed anyway. * @param spanId Id of the span to activate * @param block Block to invoke while span is active */ - (void)activateSpan:(SentrySpanId *)spanId duringBlock:(void (^)(void))block; /** - * Measure the given block execution. - * + * Measure the given @c block execution. * @param description The description of the span. * @param operation Span operation. * @param block Block to be measured. @@ -52,11 +45,8 @@ NS_ASSUME_NONNULL_BEGIN inBlock:(void (^)(void))block; /** - * Measure the given block execution - * adding it as a child of given parent span. - * If parentSpanId does not exist this - * measurement is not performed. - * + * Measure the given @c block execution adding it as a child of given parent span. + * @note If @c parentSpanId does not exist this measurement is not performed. * @param description The description of the span. * @param operation Span operation. * @param parentSpanId Id of the span to use as parent. @@ -74,18 +64,16 @@ NS_ASSUME_NONNULL_BEGIN /** * Marks a span to be finished. - * If the given span has no child it is finished immediately, - * otherwise it waits until all children are finished. - * + * If the given span has no child it is finished immediately, otherwise it waits until all children + * are finished. * @param spanId Id of the span to finish. */ - (void)finishSpan:(SentrySpanId *)spanId; /** * Marks a span to be finished with given status. - * If the given span has no child it is finished immediately, - * otherwise it waits until all children are finished. - * + * If the given span has no child it is finished immediately, otherwise it waits until all children + * are finished. * @param spanId Id of the span to finish. * @param status Span finish status. */ @@ -93,18 +81,14 @@ NS_ASSUME_NONNULL_BEGIN /** * Checks if given span is waiting to be finished. - * * @param spanId Id of the span to be checked. - * * @return A boolean value indicating whether the span still waiting to be finished. */ - (BOOL)isSpanAlive:(SentrySpanId *)spanId; /** * Return the SentrySpan associated with the given spanId. - * * @param spanId Id of the span to return. - * * @return SentrySpan */ - (nullable id)getSpan:(SentrySpanId *)spanId; diff --git a/Sources/Sentry/include/SentryPerformanceTrackingIntegration.h b/Sources/Sentry/include/SentryPerformanceTrackingIntegration.h index dcce55eb22..4c9861d406 100644 --- a/Sources/Sentry/include/SentryPerformanceTrackingIntegration.h +++ b/Sources/Sentry/include/SentryPerformanceTrackingIntegration.h @@ -6,10 +6,8 @@ NS_ASSUME_NONNULL_BEGIN /** * Integration to setup automatic performance tracking. - * - * Automatic UI performance setup can be avoided by setting - * enableAutoPerformanceTracing to NO - * in SentryOptions during SentrySDK initialization. + * Automatic UI performance setup can be avoided by setting @c enableAutoPerformanceTracing to @c NO + * in @c SentryOptions during SentrySDK initialization. */ @interface SentryPerformanceTrackingIntegration : SentryBaseIntegration diff --git a/Sources/Sentry/include/SentryProfiler.h b/Sources/Sentry/include/SentryProfiler.h index 1412a47e27..1a9116a06e 100644 --- a/Sources/Sentry/include/SentryProfiler.h +++ b/Sources/Sentry/include/SentryProfiler.h @@ -30,15 +30,16 @@ SENTRY_EXTERN NSString *const kSentryProfilerSerializationKeyFrameRates; SENTRY_EXTERN_C_BEGIN -/* - * Parses a symbol that is returned from `backtrace_symbols()`, which encodes information - * like the frame index, image name, function name, and offset in a single string. e.g. - * For the input: - * 2 UIKitCore 0x00000001850d97ac -[UIFieldEditor - * _fullContentInsetsFromFonts] + 160 This function would return: -[UIFieldEditor - * _fullContentInsetsFromFonts] - * - * If the format does not match the expected format, this returns the input string. +/** + * Parses a symbol that is returned from @c backtrace_symbols() which encodes information + * like the frame index, image name, function name, and offset in a single string. + * @discussion For the input: + * @code + * 2 UIKitCore 0x00000001850d97ac -[UIFieldEditor _fullContentInsetsFromFonts] + 160 + * @endcode + * This function would return: + * @code -[UIFieldEditor _fullContentInsetsFromFonts] @endcode + * @note If the format does not match the expected format, this returns the input string. */ NSString *parseBacktraceSymbolsFunctionName(const char *symbol); @@ -47,21 +48,28 @@ NSString *profilerTruncationReasonName(SentryProfilerTruncationReason reason); SENTRY_EXTERN_C_END /** - * @warning: A main assumption is that profile start/stop must be contained within range of time of + * A wrapper around the low-level components used to gather sampled backtrace profiles. + * @warning A main assumption is that profile start/stop must be contained within range of time of * the first concurrent transaction's start time and last one's end time. */ @interface SentryProfiler : NSObject -/** Start the profiler, if it isn't already running. */ +/** + * Start the profiler, if it isn't already running. + */ + (void)startWithHub:(SentryHub *)hub; -/** Stop the profiler if it is running. */ +/** + * Stop the profiler if it is running. + */ + (void)stop; + (BOOL)isRunning; -/** Given a transaction, return an envelope item containing any corresponding profile data to be - * attached to the transaction envelope. */ +/** + * Given a transaction, return an envelope item containing any corresponding profile data to be + * attached to the transaction envelope. + * */ + (nullable SentryEnvelopeItem *)createProfilingEnvelopeItemForTransaction: (SentryTransaction *)transaction; diff --git a/Sources/Sentry/SentryProfilesSampler.h b/Sources/Sentry/include/SentryProfilesSampler.h similarity index 100% rename from Sources/Sentry/SentryProfilesSampler.h rename to Sources/Sentry/include/SentryProfilesSampler.h diff --git a/Sources/Sentry/include/SentryRateLimits.h b/Sources/Sentry/include/SentryRateLimits.h index bfe7fc4ee4..bf39528757 100644 --- a/Sources/Sentry/include/SentryRateLimits.h +++ b/Sources/Sentry/include/SentryRateLimits.h @@ -4,26 +4,24 @@ NS_ASSUME_NONNULL_BEGIN /** - Parses HTTP responses from the Sentry server for rate limits. - When a rate limit is reached the SDK should stop data transmission - until the rate limit has expired. -*/ + * Parses HTTP responses from the Sentry server for rate limits. + * @discussion When a rate limit is reached, the SDK should stop data transmission + * until the rate limit has expired. + */ NS_SWIFT_NAME(RateLimits) @protocol SentryRateLimits /** -Check if a data category has reached a rate limit. - @param category the type e.g. event, error, session, transaction, etc. - - @return BOOL YES if limit is reached, NO otherwise. + * Check if a data category has reached a rate limit. + * @param category the type e.g. event, error, session, transaction, etc. + * @return @c YES if limit is reached, @c NO otherwise. */ - (BOOL)isRateLimitActive:(SentryDataCategory)category; /** -Should be called for each HTTP response of the Sentry - server. It checks the response for any communicated rate limits. - - @param response The response from the server + * Should be called for each HTTP response of the Sentry server. It checks the response for any + * communicated rate limits. + * @param response The response from the server */ - (void)update:(NSHTTPURLResponse *)response; diff --git a/Sources/Sentry/include/SentryReachability.h b/Sources/Sentry/include/SentryReachability.h index 06abc3ead2..539ba198c9 100644 --- a/Sources/Sentry/include/SentryReachability.h +++ b/Sources/Sentry/include/SentryReachability.h @@ -41,15 +41,14 @@ BOOL SentryConnectivityShouldReportChange(SCNetworkReachabilityFlags flags); #endif /** - * Function signature to connectivity monitoring callback of SentryReachability - * - * @param connected YES if the monitored URL is reachable + * Function signature to connectivity monitoring callback of @c SentryReachability + * @param connected @c YES if the monitored URL is reachable * @param typeDescription a textual representation of the connection type */ typedef void (^SentryConnectivityChangeBlock)(BOOL connected, NSString *typeDescription); /** - * Monitors network connectivity using SCNetworkReachability callbacks, + * Monitors network connectivity using @c SCNetworkReachability callbacks, * providing a customizable callback block invoked when connectivity changes. */ @interface SentryReachability : NSObject @@ -57,15 +56,14 @@ typedef void (^SentryConnectivityChangeBlock)(BOOL connected, NSString *typeDesc #if !TARGET_OS_WATCH /** * Invoke a block each time network connectivity changes - * - * @param URL The URL monitored for changes. Should be equivalent to - * BugsnagConfiguration.notifyURL + * @param URL The URL monitored for changes. Should be equivalent to + * @c BugsnagConfiguration.notifyURL . * @param block The block called when connectivity changes */ - (void)monitorURL:(NSURL *)URL usingCallback:(SentryConnectivityChangeBlock)block; /** - * Stop monitoring the URL previously configured with monitorURL:usingCallback: + * Stop monitoring the URL previously configured with @c monitorURL:usingCallback: */ - (void)stopMonitoring; diff --git a/Sources/Sentry/include/SentryScreenshot.h b/Sources/Sentry/include/SentryScreenshot.h index 32d4fdcd55..42e9c2f16b 100644 --- a/Sources/Sentry/include/SentryScreenshot.h +++ b/Sources/Sentry/include/SentryScreenshot.h @@ -8,12 +8,17 @@ NS_ASSUME_NONNULL_BEGIN /** * Get a screenshot of every open window in the app. - * - * @return An array of NSData containing a PNG image + * @return An array of @c NSData instances containing PNG images. */ - (nullable NSArray *)appScreenshots; -- (void)saveScreenShots:(NSString *)path; +/** + * Save the current app screen shots in the given directory. + * If an app has more than one screen, one image for each screen will be saved. + * + * @param imagesDirectoryPath The path where the images should be saved. + */ +- (void)saveScreenShots:(NSString *)imagesDirectoryPath; - (NSArray *)takeScreenshots; @end diff --git a/Sources/Sentry/include/SentrySdkInfo.h b/Sources/Sentry/include/SentrySdkInfo.h index ef80f2cabc..15f58393bc 100644 --- a/Sources/Sentry/include/SentrySdkInfo.h +++ b/Sources/Sentry/include/SentrySdkInfo.h @@ -1,30 +1,30 @@ -#import "SentrySerializable.h" #import +#if __has_include() +# import +#else +# import "SentrySerializable.h" +#endif + NS_ASSUME_NONNULL_BEGIN /** * Describes the Sentry SDK and its configuration used to capture and transmit an event. - * - * Both name and version are required. - * - * For more info checkout: https://develop.sentry.dev/sdk/event-payloads/sdk/ + * @note Both name and version are required. + * @see https://develop.sentry.dev/sdk/event-payloads/sdk/ */ @interface SentrySdkInfo : NSObject SENTRY_NO_INIT /** - * The name of the SDK. - * - * Examples: sentry.cocoa, sentry.cocoa.vapor, ... + * The name of the SDK. Examples: sentry.cocoa, sentry.cocoa.vapor, ... */ @property (nonatomic, readonly, copy) NSString *name; /** * The version of the SDK. It should have the Semantic Versioning format MAJOR.MINOR.PATCH, without - * any prefix (no v or anything else in front of the major version number). - * - * Examples: 0.1.0, 1.0.0, 2.0.0-beta0 + * any prefix (no v or anything else in front of the major version number). Examples: + * 0.1.0, 1.0.0, 2.0.0-beta0 */ @property (nonatomic, readonly, copy) NSString *version; diff --git a/Sources/Sentry/include/SentrySession.h b/Sources/Sentry/include/SentrySession.h index 4ecea99c97..43820850ae 100644 --- a/Sources/Sentry/include/SentrySession.h +++ b/Sources/Sentry/include/SentrySession.h @@ -21,11 +21,9 @@ SENTRY_NO_INIT - (instancetype)initWithReleaseName:(NSString *)releaseName; /** - * Initializes SentrySession from a JSON object. - * - * @param jsonObject The jsonObject containing the session. - * - * @return The SentrySession or nil if the JSONObject contains an error. + * Initializes @c SentrySession from a JSON object. + * @param jsonObject The @c jsonObject containing the session. + * @return The @c SentrySession or @c nil if @c jsonObject contains an error. */ - (nullable instancetype)initWithJSONObject:(NSDictionary *)jsonObject; @@ -42,7 +40,7 @@ SENTRY_NO_INIT @property (nonatomic, readonly) NSUInteger sequence; @property (nonatomic, readonly, strong) NSString *distinctId; /** - We can't use init because it overlaps with NSObject.init + * We can't use @c init because it overlaps with @c NSObject.init . */ @property (nonatomic, readonly, copy) NSNumber *_Nullable flagInit; @property (nonatomic, readonly, strong) NSDate *_Nullable timestamp; diff --git a/Sources/Sentry/include/SentrySpan.h b/Sources/Sentry/include/SentrySpan.h index 2c460893b7..bee51689b5 100644 --- a/Sources/Sentry/include/SentrySpan.h +++ b/Sources/Sentry/include/SentrySpan.h @@ -71,21 +71,15 @@ SENTRY_NO_INIT @property (nullable, nonatomic, strong) NSArray *frames; /** - * Init a SentrySpan with given transaction and context. - * + * Init a @c SentrySpan with given transaction and context. * @param transaction The @c SentryTracer managing the transaction this span is associated with. * @param context This span context information. - * - * @return SentrySpan */ - (instancetype)initWithTracer:(SentryTracer *)transaction context:(SentrySpanContext *)context; /** - * Init a SentrySpan with given context. - * + * Init a @c SentrySpan with given context. * @param context This span context information. - * - * @return SentrySpan */ - (instancetype)initWithContext:(SentrySpanContext *)context; diff --git a/Sources/Sentry/SentrySubClassFinder.h b/Sources/Sentry/include/SentrySubClassFinder.h similarity index 82% rename from Sources/Sentry/SentrySubClassFinder.h rename to Sources/Sentry/include/SentrySubClassFinder.h index 6a65ad7074..889fdbaf0e 100644 --- a/Sources/Sentry/SentrySubClassFinder.h +++ b/Sources/Sentry/include/SentrySubClassFinder.h @@ -13,12 +13,11 @@ SENTRY_NO_INIT objcRuntimeWrapper:(id)objcRuntimeWrapper; /** - * Fetch all subclasses of UIViewController from given objc Image on a background thread and then + * Fetch all subclasses of @c UIViewController from given objc Image on a background thread and then * act on them on the main thread. As there is no straightforward way to get all sub-classes in * Objective-C, the code first retrieves all classes from the Image, iterates over all classes, and - * checks for every class if the parentClass is a UIViewController. Cause loading all classes can + * checks for every class if the parentClass is a @c UIViewController. Cause loading all classes can * take a few milliseconds, do this on a background thread. - * * @param imageName The objc Image (library) to get all subclasses for. * @param block The block to execute for each subclass. This block runs on the main thread. */ diff --git a/Sources/Sentry/include/SentrySwizzle.h b/Sources/Sentry/include/SentrySwizzle.h index 8efb795936..d0d8f5a7cb 100644 --- a/Sources/Sentry/include/SentrySwizzle.h +++ b/Sources/Sentry/include/SentrySwizzle.h @@ -2,74 +2,80 @@ #pragma mark - Macros Based API -/// A macro for wrapping the return type of the swizzled method. +/** + * A macro for wrapping the return type of the swizzled method. + */ #define SentrySWReturnType(type) type -/// A macro for wrapping arguments of the swizzled method. +/** + * A macro for wrapping arguments of the swizzled method. + */ #define SentrySWArguments(arguments...) _SentrySWArguments(arguments) -/// A macro for wrapping the replacement code for the swizzled method. +/** + * A macro for wrapping the replacement code for the swizzled method. + */ #define SentrySWReplacement(code...) code -/// A macro for casting and calling original implementation. -/// May be used only in SentrySwizzleInstanceMethod or SentrySwizzleClassMethod -/// macros. +/** + * A macro for casting and calling original implementation. + * @note May be used only in @c SentrySwizzleInstanceMethod or @c SentrySwizzleClassMethod macros. + */ #define SentrySWCallOriginal(arguments...) _SentrySWCallOriginal(arguments) #pragma mark └ Swizzle Instance Method /** - Swizzles the instance method of the class with the new implementation. - - Example for swizzling `-(int)calculate:(int)number;` method: - - @code - - SentrySwizzleInstanceMethod(classToSwizzle, - @selector(calculate:), - SentrySWReturnType(int), - SentrySWArguments(int number), - SentrySWReplacement( - { - // Calling original implementation. - int res = SentrySWCallOriginal(number); - // Returning modified return value. - return res + 1; - }), 0, NULL); - - @endcode - - Swizzling frequently goes along with checking whether this particular class (or - one of its superclasses) has been already swizzled. Here the - `SentrySwizzleMode` and `key` parameters can help. See +[SentrySwizzle - swizzleInstanceMethod:inClass:newImpFactory:mode:key:] for details. - - Swizzling is fully thread-safe. - - @param classToSwizzle The class with the method that should be swizzled. - - @param selector Selector of the method that should be swizzled. - - @param SentrySWReturnType The return type of the swizzled method wrapped in the - SentrySWReturnType macro. - - @param SentrySWArguments The arguments of the swizzled method wrapped in the - SentrySWArguments macro. - - @param SentrySWReplacement The code of the new implementation of the swizzled - method wrapped in the SentrySWReplacement macro. - - @param SentrySwizzleMode The mode is used in combination with the key to - indicate whether the swizzling should be done for the given class. You can pass - 0 for SentrySwizzleModeAlways. - - @param key The key is used in combination with the mode to indicate whether the - swizzling should be done for the given class. May be NULL if the mode is - SentrySwizzleModeAlways. - - @return YES if successfully swizzled and NO if swizzling has been already done - for given key and class (or one of superclasses, depends on the mode). - + * Swizzles the instance method of the class with the new implementation. + * + * Example for swizzling @c -(int)calculate:(int)number; method: + * + * @code + * + * SentrySwizzleInstanceMethod(classToSwizzle, + * @selector(calculate:), + * SentrySWReturnType(int), + * SentrySWArguments(int number), + * SentrySWReplacement( + * { + * // Calling original implementation. + * int res = SentrySWCallOriginal(number); + * // Returning modified return value. + * return res + 1; + * }), 0, NULL); + * + * @endcode + * + * Swizzling frequently goes along with checking whether this particular class (or + * one of its superclasses) has been already swizzled. Here the + * @c SentrySwizzleMode and @c key parameters can help. + * @see @code +[SentrySwizzle swizzleInstanceMethod:inClass:newImpFactory:mode:key:] @endcode + * + * Swizzling is fully thread-safe. + * + * @param classToSwizzle The class with the method that should be swizzled. + * + * @param selector Selector of the method that should be swizzled. + * + * @param SentrySWReturnType The return type of the swizzled method wrapped in the + * @c SentrySWReturnType macro. + * + * @param SentrySWArguments The arguments of the swizzled method wrapped in the + * @c SentrySWArguments macro. + * + * @param SentrySWReplacement The code of the new implementation of the swizzled + * method wrapped in the @c SentrySWReplacement macro. + * + * @param SentrySwizzleMode The mode is used in combination with the key to + * indicate whether the swizzling should be done for the given class. You can pass + * @c 0 for @c SentrySwizzleModeAlways. + * + * @param key The key is used in combination with the mode to indicate whether the + * swizzling should be done for the given class. May be @c NULL if the mode is + * @c SentrySwizzleModeAlways. + * + * @return @c YES if successfully swizzled and @c NO if swizzling has been already done + * for given key and class (or one of superclasses, depends on the mode). */ #define SentrySwizzleInstanceMethod(classToSwizzle, selector, SentrySWReturnType, \ SentrySWArguments, SentrySWReplacement, SentrySwizzleMode, key) \ @@ -80,41 +86,40 @@ #pragma mark └ Swizzle Class Method /** - Swizzles the class method of the class with the new implementation. - - Example for swizzling `+(int)calculate:(int)number;` method: - - @code - - SentrySwizzleClassMethod(classToSwizzle, - @selector(calculate:), - SentrySWReturnType(int), - SentrySWArguments(int number), - SentrySWReplacement( - { - // Calling original implementation. - int res = SentrySWCallOriginal(number); - // Returning modified return value. - return res + 1; - })); - - @endcode - - Swizzling is fully thread-safe. - - @param classToSwizzle The class with the method that should be swizzled. - - @param selector Selector of the method that should be swizzled. - - @param SentrySWReturnType The return type of the swizzled method wrapped in the - SentrySWReturnType macro. - - @param SentrySWArguments The arguments of the swizzled method wrapped in the - SentrySWArguments macro. - - @param SentrySWReplacement The code of the new implementation of the swizzled - method wrapped in the SentrySWReplacement macro. - + * Swizzles the class method of the class with the new implementation. + * + * Example for swizzling @c +(int)calculate:(int)number; method: + * + * @code + * + * SentrySwizzleClassMethod(classToSwizzle, + * @selector(calculate:), + * SentrySWReturnType(int), + * SentrySWArguments(int number), + * SentrySWReplacement( + * { + * // Calling original implementation. + * int res = SentrySWCallOriginal(number); + * // Returning modified return value. + * return res + 1; + * })); + * + * @endcode + * + * Swizzling is fully thread-safe. + * + * @param classToSwizzle The class with the method that should be swizzled. + * + * @param selector Selector of the method that should be swizzled. + * + * @param SentrySWReturnType The return type of the swizzled method wrapped in the + * SentrySWReturnType macro. + * + * @param SentrySWArguments The arguments of the swizzled method wrapped in the + * SentrySWArguments macro. + * + * @param SentrySWReplacement The code of the new implementation of the swizzled + * method wrapped in the SentrySWReplacement macro. */ #define SentrySwizzleClassMethod( \ classToSwizzle, selector, SentrySWReturnType, SentrySWArguments, SentrySWReplacement) \ @@ -124,69 +129,79 @@ #pragma mark - Main API /** - A function pointer to the original implementation of the swizzled method. + * A function pointer to the original implementation of the swizzled method. */ typedef void (*SentrySwizzleOriginalIMP)(void /* id, SEL, ... */); /** - SentrySwizzleInfo is used in the new implementation block to get and call - original implementation of the swizzled method. + * @c SentrySwizzleInfo is used in the new implementation block to get and call + * original implementation of the swizzled method. */ @interface SentrySwizzleInfo : NSObject /** - Returns the original implementation of the swizzled method. - - It is actually either an original implementation if the swizzled class - implements the method itself; or a super implementation fetched from one of the - superclasses. - - @note You must always cast returned implementation to the appropriate function - pointer when calling. - - @return A function pointer to the original implementation of the swizzled - method. + * Returns the original implementation of the swizzled method. + * + * It is actually either an original implementation if the swizzled class + * implements the method itself; or a super implementation fetched from one of the + * superclasses. + * + * @note You must always cast returned implementation to the appropriate function + * pointer when calling. + * + * @return A function pointer to the original implementation of the swizzled + * method. */ - (SentrySwizzleOriginalIMP)getOriginalImplementation; -/// The selector of the swizzled method. +/** + * The selector of the swizzled method. + */ @property (nonatomic, readonly) SEL selector; #if TEST -// A flag to check whether the original implementation was called. +/** + * A flag to check whether the original implementation was called. + */ @property (nonatomic) BOOL originalCalled; #endif @end /** - A factory block returning the block for the new implementation of the swizzled - method. - - You must always obtain original implementation with swizzleInfo and call it - from the new implementation. - - @param swizzleInfo An info used to get and call the original implementation of - the swizzled method. - - @return A block that implements a method. - Its signature should be: `method_return_type ^(id self, method_args...)`. - The selector is not available as a parameter to this block. + * A factory block returning the block for the new implementation of the swizzled + * method. + * + * You must always obtain original implementation with @c swizzleInfo and call it + * from the new implementation. + * + * @param swizzleInfo An info used to get and call the original implementation of + * the swizzled method. + * + * @return A block providing an implementation for the swizzled method. The selector is not + * available as a parameter to this block. Its signature should be: @code method_return_type ^(id + * self, method_args...) @endcode */ typedef id (^SentrySwizzleImpFactoryBlock)(SentrySwizzleInfo *swizzleInfo); typedef NS_ENUM(NSUInteger, SentrySwizzleMode) { - /// SentrySwizzle always does swizzling. + /** + * @c SentrySwizzle always does swizzling. + */ SentrySwizzleModeAlways = 0, - /// SentrySwizzle does not do swizzling if the same class has been swizzled - /// earlier with the same key. + /** + * @c SentrySwizzle does not do swizzling if the same class has been swizzled + * earlier with the same key. + */ SentrySwizzleModeOncePerClass = 1, - /// SentrySwizzle does not do swizzling if the same class or one of its - /// superclasses have been swizzled earlier with the same key. - /// @note There is no guarantee that your implementation will be called only - /// once per method call. If the order of swizzling is: first inherited - /// class, second superclass, then both swizzlings will be done and the new - /// implementation will be called twice. + /** + * @c SentrySwizzle does not do swizzling if the same class or one of its + * superclasses have been swizzled earlier with the same key. + * @note There is no guarantee that your implementation will be called only + * once per method call. If the order of swizzling is: first inherited + * class, second superclass, then both swizzlings will be done and the new + * implementation will be called twice. + */ SentrySwizzleModeOncePerClassAndSuperclasses = 2 }; @@ -195,91 +210,91 @@ typedef NS_ENUM(NSUInteger, SentrySwizzleMode) { #pragma mark └ Swizzle Instance Method /** - Swizzles the instance method of the class with the new implementation. - - Original implementation must always be called from the new implementation. And - because of the the fact that for safe and robust swizzling original - implementation must be dynamically fetched at the time of calling and not at - the time of swizzling, swizzling API is a little bit complicated. - - You should pass a factory block that returns the block for the new - implementation of the swizzled method. And use swizzleInfo argument to retrieve - and call original implementation. - - Example for swizzling `-(int)calculate:(int)number;` method: - - @code - - SEL selector = @selector(calculate:); - [SentrySwizzle - swizzleInstanceMethod:selector - inClass:classToSwizzle - newImpFactory:^id(SentrySwizzleInfo *swizzleInfo) { - // This block will be used as the new implementation. - return ^int(__unsafe_unretained id self, int num){ - // You MUST always cast implementation to the correct function - pointer. int (*originalIMP)(__unsafe_unretained id, SEL, int); originalIMP = - (__typeof(originalIMP))[swizzleInfo getOriginalImplementation]; - // Calling original implementation. - int res = originalIMP(self,selector,num); - // Returning modified return value. - return res + 1; - }; - } - mode:SentrySwizzleModeAlways - key:NULL]; - - @endcode - - Swizzling frequently goes along with checking whether this particular class (or - one of its superclasses) has been already swizzled. Here the `mode` and `key` - parameters can help. - - Here is an example of swizzling `-(void)dealloc;` only in case when neither - class and no one of its superclasses has been already swizzled with our key. - However "Deallocating ..." message still may be logged multiple times per - method call if swizzling was called primarily for an inherited class and later - for one of its superclasses. - - @code - - static const void *key = &key; - SEL selector = NSSelectorFromString(@"dealloc"); - [SentrySwizzle - swizzleInstanceMethod:selector - inClass:classToSwizzle - newImpFactory:^id(SentrySwizzleInfo *swizzleInfo) { - return ^void(__unsafe_unretained id self){ - NSLog(@"Deallocating %@.",self); - - void (*originalIMP)(__unsafe_unretained id, SEL); - originalIMP = (__typeof(originalIMP))[swizzleInfo - getOriginalImplementation]; originalIMP(self,selector); - }; - } - mode:SentrySwizzleModeOncePerClassAndSuperclasses - key:key]; - - @endcode - - Swizzling is fully thread-safe. - - @param selector Selector of the method that should be swizzled. - - @param classToSwizzle The class with the method that should be swizzled. - - @param factoryBlock The factory block returning the block for the new - implementation of the swizzled method. - - @param mode The mode is used in combination with the key to indicate whether - the swizzling should be done for the given class. - - @param key The key is used in combination with the mode to indicate whether the - swizzling should be done for the given class. May be NULL if the mode is - SentrySwizzleModeAlways. - - @return YES if successfully swizzled and NO if swizzling has been already done - for given key and class (or one of superclasses, depends on the mode). + * Swizzles the instance method of the class with the new implementation. + * + * Original implementation must always be called from the new implementation. And + * because of the the fact that for safe and robust swizzling original + * implementation must be dynamically fetched at the time of calling and not at + * the time of swizzling, swizzling API is a little bit complicated. + * + * You should pass a factory block that returns the block for the new + * implementation of the swizzled method. And use swizzleInfo argument to retrieve + * and call original implementation. + * + * Example for swizzling @c -(int)calculate:(int)number; method: + * + * @code + * + * SEL selector = @selector(calculate:); + * [SentrySwizzle + * swizzleInstanceMethod:selector + * inClass:classToSwizzle + * newImpFactory:^id(SentrySwizzleInfo *swizzleInfo) { + * // This block will be used as the new implementation. + * return ^int(__unsafe_unretained id self, int num){ + * // You MUST always cast implementation to the correct function + * pointer. int (*originalIMP)(__unsafe_unretained id, SEL, int); originalIMP = + * (__typeof(originalIMP))[swizzleInfo getOriginalImplementation]; + * // Calling original implementation. + * int res = originalIMP(self,selector,num); + * // Returning modified return value. + * return res + 1; + * }; + * } + * mode:SentrySwizzleModeAlways + * key:NULL]; + * + * @endcode + * + * Swizzling frequently goes along with checking whether this particular class (or + * one of its superclasses) has been already swizzled. Here the @c mode and @c key + * parameters can help. + * + * Here is an example of swizzling @c -(void)dealloc; only in case when neither + * class and no one of its superclasses has been already swizzled with our key. + * However "Deallocating ..." message still may be logged multiple times per + * method call if swizzling was called primarily for an inherited class and later + * for one of its superclasses. + * + * @code + * + * static const void *key = &key; + * SEL selector = NSSelectorFromString(@"dealloc"); + * [SentrySwizzle + * swizzleInstanceMethod:selector + * inClass:classToSwizzle + * newImpFactory:^id(SentrySwizzleInfo *swizzleInfo) { + * return ^void(__unsafe_unretained id self){ + * NSLog(@"Deallocating %@.",self); + * + * void (*originalIMP)(__unsafe_unretained id, SEL); + * originalIMP = (__typeof(originalIMP))[swizzleInfo + * getOriginalImplementation]; originalIMP(self,selector); + * }; + * } + * mode:SentrySwizzleModeOncePerClassAndSuperclasses + * key:key]; + * + * @endcode + * + * Swizzling is fully thread-safe. + * + * @param selector Selector of the method that should be swizzled. + * + * @param classToSwizzle The class with the method that should be swizzled. + * + * @param factoryBlock The factory block returning the block for the new + * implementation of the swizzled method. + * + * @param mode The mode is used in combination with the key to indicate whether + * the swizzling should be done for the given class. + * + * @param key The key is used in combination with the mode to indicate whether the + * swizzling should be done for the given class. May be @c NULL if the mode is + * SentrySwizzleModeAlways. + * + * @return @c YES if successfully swizzled and @c NO if swizzling has been already done + * for given key and class (or one of superclasses, depends on the mode). */ + (BOOL)swizzleInstanceMethod:(SEL)selector inClass:(Class)classToSwizzle @@ -290,48 +305,48 @@ typedef NS_ENUM(NSUInteger, SentrySwizzleMode) { #pragma mark └ Swizzle Class method /** - Swizzles the class method of the class with the new implementation. - - Original implementation must always be called from the new implementation. And - because of the the fact that for safe and robust swizzling original - implementation must be dynamically fetched at the time of calling and not at - the time of swizzling, swizzling API is a little bit complicated. - - You should pass a factory block that returns the block for the new - implementation of the swizzled method. And use swizzleInfo argument to retrieve - and call original implementation. - - Example for swizzling `+(int)calculate:(int)number;` method: - - @code - - SEL selector = @selector(calculate:); - [SentrySwizzle - swizzleClassMethod:selector - inClass:classToSwizzle - newImpFactory:^id(SentrySwizzleInfo *swizzleInfo) { - // This block will be used as the new implementation. - return ^int(__unsafe_unretained id self, int num){ - // You MUST always cast implementation to the correct function - pointer. int (*originalIMP)(__unsafe_unretained id, SEL, int); originalIMP = - (__typeof(originalIMP))[swizzleInfo getOriginalImplementation]; - // Calling original implementation. - int res = originalIMP(self,selector,num); - // Returning modified return value. - return res + 1; - }; - }]; - - @endcode - - Swizzling is fully thread-safe. - - @param selector Selector of the method that should be swizzled. - - @param classToSwizzle The class with the method that should be swizzled. - - @param factoryBlock The factory block returning the block for the new - implementation of the swizzled method. + * Swizzles the class method of the class with the new implementation. + * + * Original implementation must always be called from the new implementation. And + * because of the the fact that for safe and robust swizzling original + * implementation must be dynamically fetched at the time of calling and not at + * the time of swizzling, swizzling API is a little bit complicated. + * + * You should pass a factory block that returns the block for the new + * implementation of the swizzled method. And use @c swizzleInfo argument to retrieve + * and call original implementation. + * + * Example for swizzling @c +(int)calculate:(int)number; method: + * + * @code + * + * SEL selector = @selector(calculate:); + * [SentrySwizzle + * swizzleClassMethod:selector + * inClass:classToSwizzle + * newImpFactory:^id(SentrySwizzleInfo *swizzleInfo) { + * // This block will be used as the new implementation. + * return ^int(__unsafe_unretained id self, int num){ + * // You MUST always cast implementation to the correct function + * pointer. int (*originalIMP)(__unsafe_unretained id, SEL, int); originalIMP = + * (__typeof(originalIMP))[swizzleInfo getOriginalImplementation]; + * // Calling original implementation. + * int res = originalIMP(self,selector,num); + * // Returning modified return value. + * return res + 1; + * }; + * }]; + * + * @endcode + * + * Swizzling is fully thread-safe. + * + * @param selector Selector of the method that should be swizzled. + * + * @param classToSwizzle The class with the method that should be swizzled. + * + * @param factoryBlock The factory block returning the block for the new + * implementation of the swizzled method. */ + (void)swizzleClassMethod:(SEL)selector inClass:(Class)classToSwizzle diff --git a/Sources/Sentry/include/SentrySystemWrapper.h b/Sources/Sentry/include/SentrySystemWrapper.h index 03ecc7d52f..09d01a67d1 100644 --- a/Sources/Sentry/include/SentrySystemWrapper.h +++ b/Sources/Sentry/include/SentrySystemWrapper.h @@ -12,8 +12,8 @@ typedef void (^SentryMemoryPressureNotification)(uintptr_t); typedef mach_vm_size_t SentryRAMBytes; /** - * A wrapper around low-level system APIs that are found in headers such as @c and @c - * . + * A wrapper around low-level system APIs that are found in headers such as @c and + * @c . */ @interface SentrySystemWrapper : NSObject diff --git a/Sources/Sentry/include/SentryTime.h b/Sources/Sentry/include/SentryTime.h index 1fa8586c2b..d236fc38de 100644 --- a/Sources/Sentry/include/SentryTime.h +++ b/Sources/Sentry/include/SentryTime.h @@ -6,8 +6,8 @@ SENTRY_EXTERN_C_BEGIN /** - * Given a fractional amount of seconds in a @c double from a Cocoa API like @c -[NSDate @c - * timeIntervalSinceDate:], return an integer representing the amount of nanoseconds. + * Given a fractional amount of seconds in a @c double from a Cocoa API like @c -[NSDate + * @c timeIntervalSinceDate:], return an integer representing the amount of nanoseconds. */ uint64_t timeIntervalToNanoseconds(double seconds); diff --git a/Sources/Sentry/include/SentryTraceContext.h b/Sources/Sentry/include/SentryTraceContext.h index 0958e406ac..3fd1b49192 100644 --- a/Sources/Sentry/include/SentryTraceContext.h +++ b/Sources/Sentry/include/SentryTraceContext.h @@ -1,5 +1,14 @@ -#import "SentryId.h" -#import "SentrySerializable.h" +#if __has_include() +# import +#else +# import "SentrySerializable.h" +#endif + +#if __has_include() +# import +#else +# import "SentryId.h" +#endif NS_ASSUME_NONNULL_BEGIN diff --git a/Sources/Sentry/include/SentryTracer.h b/Sources/Sentry/include/SentryTracer.h index 8999c467e4..1e1bd2377c 100644 --- a/Sources/Sentry/include/SentryTracer.h +++ b/Sources/Sentry/include/SentryTracer.h @@ -28,7 +28,7 @@ static NSTimeInterval const SentryTracerDefaultTimeout = 3.0; /** * Indicates whether this tracer will be finished only if all children have been finished. - * If this property is YES and the finish function is called before all children are finished + * If this property is @c YES and the finish function is called before all children are finished * the tracer will automatically finish when the last child finishes. */ @property (readonly) BOOL waitForChildren; @@ -38,12 +38,12 @@ static NSTimeInterval const SentryTracerDefaultTimeout = 3.0; */ @property (nonatomic, readonly) SentryTraceContext *traceContext; -/* - All the spans that where created with this tracer but rootSpan. +/** + * All the spans that where created with this tracer but rootSpan. */ @property (nonatomic, readonly) NSArray> *children; -/* +/** * A delegate that provides extra information for the transaction. */ @property (nullable, nonatomic, weak) id delegate; @@ -59,41 +59,32 @@ static NSTimeInterval const SentryTracerDefaultTimeout = 3.0; @property (strong, nonatomic, readonly) NSDate *originalStartTimestamp; /** - * Init a SentryTracer with given transaction context and hub and set other fields by default - * + * Init a @c SentryTracer with given transaction context and hub and set other fields by default * @param transactionContext Transaction context * @param hub A hub to bind this transaction - * - * @return SentryTracer */ - (instancetype)initWithTransactionContext:(SentryTransactionContext *)transactionContext hub:(nullable SentryHub *)hub; /** - * Init a SentryTracer with given transaction context, hub and whether the tracer should wait + * Init a @c SentryTracer with given transaction context, hub and whether the tracer should wait * for all children to finish before it finishes. - * * @param transactionContext Transaction context * @param hub A hub to bind this transaction * @param waitForChildren Whether this tracer should wait all children to finish. - * - * @return SentryTracer */ - (instancetype)initWithTransactionContext:(SentryTransactionContext *)transactionContext hub:(nullable SentryHub *)hub waitForChildren:(BOOL)waitForChildren; /** - * Init a SentryTracer with given transaction context, hub and whether the tracer should wait + * Init a @c SentryTracer with given transaction context, hub and whether the tracer should wait * for all children to finish before it finishes. - * * @param transactionContext Transaction context - * @param hub A hub to bind this transaction - * @param profilesSamplerDecision Whether to sample a profile corresponding to this transaction + * @param hub A hub to bind this transaction. + * @param profilesSamplerDecision Whether to sample a profile corresponding to this transaction. * @param waitForChildren Whether this tracer should wait all children to finish. - * @param timerWrapper A writer around NSTimer, to make it testable - * - * @return SentryTracer + * @param timerWrapper A wrapper around @c NSTimer, to make it testable. */ - (instancetype)initWithTransactionContext:(SentryTransactionContext *)transactionContext hub:(nullable SentryHub *)hub @@ -103,15 +94,12 @@ static NSTimeInterval const SentryTracerDefaultTimeout = 3.0; timerWrapper:(nullable SentryNSTimerWrapper *)timerWrapper; /** - * Init a SentryTracer with given transaction context, hub and whether the tracer should wait + * Init a @c SentryTracer with given transaction context, hub and whether the tracer should wait * for all children to finish before it finishes. - * * @param transactionContext Transaction context * @param hub A hub to bind this transaction * @param profilesSamplerDecision Whether to sample a profile corresponding to this transaction * @param idleTimeout The idle time to wait until to finish the transaction. - * - * @return SentryTracer */ - (instancetype)initWithTransactionContext:(SentryTransactionContext *)transactionContext hub:(nullable SentryHub *)hub diff --git a/Sources/Sentry/include/SentryUIViewControllerPerformanceTracker.h b/Sources/Sentry/include/SentryUIViewControllerPerformanceTracker.h index cd534248f1..d6b7d1446b 100644 --- a/Sources/Sentry/include/SentryUIViewControllerPerformanceTracker.h +++ b/Sources/Sentry/include/SentryUIViewControllerPerformanceTracker.h @@ -25,33 +25,30 @@ static NSString *const SENTRY_UI_PERFORMANCE_TRACKER_SPANS_IN_EXECUTION_SET @property (nonatomic, readonly, class) SentryUIViewControllerPerformanceTracker *shared; /** - * Measures viewController`s loadView method. - * This method starts a span that will be finished when - * viewControllerDidAppear:callBackToOrigin: is called. - * - * @param controller UIViewController to be measured - * @param callback A callback that indicates the swizzler to call the original view controller - * LoadView method. + * Measures @c controller's @c loadView method. + * This method starts a span that will be finished when @c viewControllerDidAppear:callBackToOrigin: + * is called. + * @param controller @c UIViewController to be measured + * @param callback A callback that indicates the swizzler to call @c controller's original + * @c loadView method. */ - (void)viewControllerLoadView:(UIViewController *)controller callbackToOrigin:(void (^)(void))callback; /** - * Measures viewController`s viewDidLoad method. - * - * @param controller UIViewController to be measured - * @param callback A callback that indicates the swizzler to call the original view controller - * viewDidLoad method. + * Measures @c controller's @c viewDidLoad method. + * @param controller @c UIViewController to be measured + * @param callback A callback that indicates the swizzler to call @c controller's original + * @c viewDidLoad method. */ - (void)viewControllerViewDidLoad:(UIViewController *)controller callbackToOrigin:(void (^)(void))callback; /** - * Measures viewController`s viewWillAppear: method. - * - * @param controller UIViewController to be measured - * @param callback A callback that indicates the swizzler to call the original view controller - * viewWillAppear: method. + * Measures @c controller's @c viewWillAppear: method. + * @param controller @c UIViewController to be measured + * @param callback A callback that indicates the swizzler to call @c controller's original + * @c viewWillAppear: method. */ - (void)viewControllerViewWillAppear:(UIViewController *)controller callbackToOrigin:(void (^)(void))callback; @@ -60,39 +57,36 @@ static NSString *const SENTRY_UI_PERFORMANCE_TRACKER_SPANS_IN_EXECUTION_SET callbackToOrigin:(void (^)(void))callbackToOrigin; /** - * Measures viewController`s viewDidAppear: method. + * Measures @c controller's @c viewDidAppear: method. * This method also finishes the span created at - * viewControllerLoadView:callbackToOrigin: allowing + * @c viewControllerLoadView:callbackToOrigin: allowing * the transaction to be send to Sentry when all spans are finished. - * - * @param controller UIViewController to be measured - * @param callback A callback that indicates the swizzler to call the original view controller - * viewDidAppear: method. + * @param controller @c UIViewController to be measured + * @param callback A callback that indicates the swizzler to call @c controller's original + * @c viewDidAppear: method. */ - (void)viewControllerViewDidAppear:(UIViewController *)controller callbackToOrigin:(void (^)(void))callback; /** - * Measures viewController`s viewWillLayoutSubViews method. + * Measures @c controller's @c viewWillLayoutSubViews method. * This method starts a span that is only finish when - * viewControllerViewDidLayoutSubViews:callbackToOrigin: is called. - * + * @c viewControllerViewDidLayoutSubViews:callbackToOrigin: is called. * @param controller UIViewController to be measured - * @param callback A callback that indicates the swizzler to call the original view controller - * viewWillLayoutSubViews method. + * @param callback A callback that indicates the swizzler to call @c controller's original + * @c viewWillLayoutSubViews method. */ - (void)viewControllerViewWillLayoutSubViews:(UIViewController *)controller callbackToOrigin:(void (^)(void))callback; /** - * Measures viewController`s viewDidLayoutSubViews method. + * Measures @c controller's @c viewDidLayoutSubViews method. * This method also finished the span created at - * viewControllerViewWillLayoutSubViews:callbackToOrigin: + * @c viewControllerViewWillLayoutSubViews:callbackToOrigin: * that measures all work done in views between this two methods. - * * @param controller UIViewController to be measured - * @param callback A callback that indicates the swizzler to call the original view controller - * viewDidLayoutSubViews method. + * @param callback A callback that indicates the swizzler to call @c controller's original + * @c viewDidLayoutSubViews method. */ - (void)viewControllerViewDidLayoutSubViews:(UIViewController *)controller callbackToOrigin:(void (^)(void))callback; diff --git a/Sources/Sentry/include/SentryViewHierarchy.h b/Sources/Sentry/include/SentryViewHierarchy.h index 81bc1246e9..5051d06805 100644 --- a/Sources/Sentry/include/SentryViewHierarchy.h +++ b/Sources/Sentry/include/SentryViewHierarchy.h @@ -8,6 +8,11 @@ NS_ASSUME_NONNULL_BEGIN - (nullable NSData *)fetchViewHierarchy; +/** + * Save the current app view hierarchy in the given file path. + * + * @param filePath The full path where the view hierarchy should be saved. + */ - (BOOL)saveViewHierarchy:(NSString *)filePath; @end diff --git a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor.c b/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor.c index f80c27b72b..28b8bc9477 100644 --- a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor.c +++ b/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor.c @@ -35,7 +35,6 @@ #include "SentryCrashMonitor_NSException.h" #include "SentryCrashMonitor_Signal.h" #include "SentryCrashMonitor_System.h" -#include "SentryCrashMonitor_Zombie.h" #include "SentryCrashSystemCapabilities.h" #include "SentryCrashThread.h" @@ -71,10 +70,6 @@ static Monitor g_monitors[] = { .monitorType = SentryCrashMonitorTypeNSException, .getAPI = sentrycrashcm_nsexception_getAPI, }, - { - .monitorType = SentryCrashMonitorTypeZombie, - .getAPI = sentrycrashcm_zombie_getAPI, - }, #endif { .monitorType = SentryCrashMonitorTypeCPPException, diff --git a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorType.c b/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorType.c index c8a9d8196b..86481cc3b1 100644 --- a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorType.c +++ b/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorType.c @@ -40,7 +40,6 @@ static const struct { MONITORTYPE(SentryCrashMonitorTypeNSException), MONITORTYPE(SentryCrashMonitorTypeSystem), MONITORTYPE(SentryCrashMonitorTypeApplicationState), - MONITORTYPE(SentryCrashMonitorTypeZombie), }; static const int g_monitorTypesCount = sizeof(g_monitorTypes) / sizeof(*g_monitorTypes); diff --git a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorType.h b/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorType.h index 3370d24de3..7a388a4209 100644 --- a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorType.h +++ b/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitorType.h @@ -56,15 +56,12 @@ typedef enum { /* Keeps track of and injects application state. */ SentryCrashMonitorTypeApplicationState = 0x80, - /* Keeps track of zombies, and injects the last zombie NSException. */ - SentryCrashMonitorTypeZombie = 0x100, } SentryCrashMonitorType; #define SentryCrashMonitorTypeAll \ (SentryCrashMonitorTypeMachException | SentryCrashMonitorTypeSignal \ | SentryCrashMonitorTypeCPPException | SentryCrashMonitorTypeNSException \ - | SentryCrashMonitorTypeSystem | SentryCrashMonitorTypeApplicationState \ - | SentryCrashMonitorTypeZombie) + | SentryCrashMonitorTypeSystem | SentryCrashMonitorTypeApplicationState) #define SentryCrashMonitorTypeDebuggerUnsafe \ (SentryCrashMonitorTypeMachException | SentryCrashMonitorTypeSignal \ @@ -73,8 +70,6 @@ typedef enum { #define SentryCrashMonitorTypeAsyncSafe \ (SentryCrashMonitorTypeMachException | SentryCrashMonitorTypeSignal) -#define SentryCrashMonitorTypeOptional (SentryCrashMonitorTypeZombie) - #define SentryCrashMonitorTypeAsyncUnsafe \ (SentryCrashMonitorTypeAll & (~SentryCrashMonitorTypeAsyncSafe)) @@ -87,9 +82,8 @@ typedef enum { */ #define SentryCrashMonitorTypeProductionSafe (SentryCrashMonitorTypeAll) -/** Production safe monitors, minus the optional ones. */ -#define SentryCrashMonitorTypeProductionSafeMinimal \ - (SentryCrashMonitorTypeProductionSafe & (~SentryCrashMonitorTypeOptional)) +/** Production safe monitors */ +#define SentryCrashMonitorTypeProductionSafeMinimal (SentryCrashMonitorTypeProductionSafe) /** Monitors that are required for proper operation. * These add essential information to the reports, but do not trigger reporting. diff --git a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Zombie.c b/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Zombie.c deleted file mode 100644 index c2bdbcb6f0..0000000000 --- a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Zombie.c +++ /dev/null @@ -1,247 +0,0 @@ -// -// SentryCrashZombie.m -// -// Created by Karl Stenerud on 2012-09-15. -// -// Copyright (c) 2012 Karl Stenerud. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall remain in place -// in this source code. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -#include "SentryCrashMonitor_Zombie.h" -#include "SentryCrashLogger.h" -#include "SentryCrashMonitorContext.h" -#include "SentryCrashObjC.h" - -#include -#include - -#define CACHE_SIZE 0x8000 - -// Compiler hints for "if" statements -#define likely_if(x) if (__builtin_expect(x, 1)) -#define unlikely_if(x) if (__builtin_expect(x, 0)) - -typedef struct { - const void *object; - const char *className; -} Zombie; - -static volatile Zombie *g_zombieCache; -static unsigned g_zombieHashMask; - -static volatile bool g_isEnabled = false; - -static struct { - Class class; - const void *address; - char name[100]; - char reason[900]; -} g_lastDeallocedException; - -static inline unsigned -hashIndex(const void *object) -{ - uintptr_t objPtr = (uintptr_t)object; - objPtr >>= (sizeof(object) - 1); - return objPtr & g_zombieHashMask; -} - -static bool -copyStringIvar(const void *self, const char *ivarName, char *buffer, int bufferLength) -{ - Class class = object_getClass((id)self); - SentryCrashObjCIvar ivar = { 0 }; - likely_if(sentrycrashobjc_ivarNamed(class, ivarName, &ivar)) - { - void *pointer; - likely_if(sentrycrashobjc_ivarValue(self, ivar.index, &pointer)) - { - likely_if(sentrycrashobjc_isValidObject(pointer)) - { - likely_if(sentrycrashobjc_copyStringContents(pointer, buffer, bufferLength) > 0) - { - return true; - } - else - { - SentryCrashLOG_DEBUG("sentrycrashobjc_copyStringContents %s failed", ivarName); - } - } - else - { - SentryCrashLOG_DEBUG("sentrycrashobjc_isValidObject %s failed", ivarName); - } - } - else - { - SentryCrashLOG_DEBUG("sentrycrashobjc_ivarValue %s failed", ivarName); - } - } - else - { - SentryCrashLOG_DEBUG("sentrycrashobjc_ivarNamed %s failed", ivarName); - } - return false; -} - -static void -storeException(const void *exception) -{ - g_lastDeallocedException.address = exception; - copyStringIvar( - exception, "name", g_lastDeallocedException.name, sizeof(g_lastDeallocedException.name)); - copyStringIvar(exception, "reason", g_lastDeallocedException.reason, - sizeof(g_lastDeallocedException.reason)); -} - -static inline void -handleDealloc(const void *self) -{ - volatile Zombie *cache = g_zombieCache; - likely_if(cache != NULL) - { - Zombie *zombie = (Zombie *)cache + hashIndex(self); - zombie->object = self; - Class class = object_getClass((id)self); - zombie->className = class_getName(class); - for (; class != nil; class = class_getSuperclass(class)) { - unlikely_if(class == g_lastDeallocedException.class) { storeException(self); } - } - } -} - -#define CREATE_ZOMBIE_HANDLER_INSTALLER(CLASS) \ - static IMP g_originalDealloc_##CLASS; \ - static void handleDealloc_##CLASS(id self, SEL _cmd) \ - { \ - handleDealloc(self); \ - typedef void (*fn)(id, SEL); \ - fn f = (fn)g_originalDealloc_##CLASS; \ - f(self, _cmd); \ - } \ - static void installDealloc_##CLASS() \ - { \ - Method method \ - = class_getInstanceMethod(objc_getClass(#CLASS), sel_registerName("dealloc")); \ - g_originalDealloc_##CLASS = method_getImplementation(method); \ - method_setImplementation(method, (IMP)handleDealloc_##CLASS); \ - } -// TODO: Uninstall doesn't work. -// static void uninstallDealloc_ ## CLASS() \ -//{ \ -// method_setImplementation(class_getInstanceMethod(objc_getClass(#CLASS), -// sel_registerName("dealloc")), g_originalDealloc_ ## CLASS); \ -//} - -CREATE_ZOMBIE_HANDLER_INSTALLER(NSObject) -CREATE_ZOMBIE_HANDLER_INSTALLER(NSProxy) - -static void -install() -{ - unsigned cacheSize = CACHE_SIZE; - g_zombieHashMask = cacheSize - 1; - g_zombieCache = calloc(cacheSize, sizeof(*g_zombieCache)); - if (g_zombieCache == NULL) { - SentryCrashLOG_ERROR("Error: Could not allocate %u bytes of memory. " - "SentryCrashZombie NOT installed!", - cacheSize * sizeof(*g_zombieCache)); - return; - } - - g_lastDeallocedException.class = objc_getClass("NSException"); - g_lastDeallocedException.address = NULL; - g_lastDeallocedException.name[0] = 0; - g_lastDeallocedException.reason[0] = 0; - - installDealloc_NSObject(); - installDealloc_NSProxy(); -} - -// TODO: Uninstall doesn't work. -// static void uninstall(void) -//{ -// uninstallDealloc_NSObject(); -// uninstallDealloc_NSProxy(); -// -// void* ptr = (void*)g_zombieCache; -// g_zombieCache = NULL; -// dispatch_time_t tenSeconds = dispatch_time(DISPATCH_TIME_NOW, -// (int64_t)(10.0 * NSEC_PER_SEC)); dispatch_after(tenSeconds, -// dispatch_get_main_queue(), ^ -// { -// free(ptr); -// }); -//} - -const char * -sentrycrashzombie_className(const void *object) -{ - volatile Zombie *cache = g_zombieCache; - if (cache == NULL || object == NULL) { - return NULL; - } - - Zombie *zombie = (Zombie *)cache + hashIndex(object); - if (zombie->object == object) { - return zombie->className; - } - return NULL; -} - -static void -setEnabled(bool isEnabled) -{ - if (isEnabled != g_isEnabled) { - g_isEnabled = isEnabled; - if (isEnabled) { - install(); - } else { - // TODO: Uninstall doesn't work. - g_isEnabled = true; - // uninstall(); - } - } -} - -static bool -isEnabled() -{ - return g_isEnabled; -} - -static void -addContextualInfoToEvent(SentryCrash_MonitorContext *eventContext) -{ - if (g_isEnabled) { - eventContext->ZombieException.address = (uintptr_t)g_lastDeallocedException.address; - eventContext->ZombieException.name = g_lastDeallocedException.name; - eventContext->ZombieException.reason = g_lastDeallocedException.reason; - } -} - -SentryCrashMonitorAPI * -sentrycrashcm_zombie_getAPI() -{ - static SentryCrashMonitorAPI api = { .setEnabled = setEnabled, - .isEnabled = isEnabled, - .addContextualInfoToEvent = addContextualInfoToEvent }; - return &api; -} diff --git a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Zombie.h b/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Zombie.h deleted file mode 100644 index dc3ec7c929..0000000000 --- a/Sources/SentryCrash/Recording/Monitors/SentryCrashMonitor_Zombie.h +++ /dev/null @@ -1,67 +0,0 @@ -// -// SentryCrashMonitor_Zombie.h -// -// Created by Karl Stenerud on 2012-09-15. -// -// Copyright (c) 2012 Karl Stenerud. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall remain in place -// in this source code. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// - -/* Poor man's zombie tracking. - * - * Benefits: - * - Very low CPU overhead. - * - Low memory overhead. - * - * Limitations: - * - Not guaranteed to catch all zombies. - * - Can generate false positives or incorrect class names. - * - SentryCrashZombie itself must be compiled with ARC disabled. You can enable - * ARC in your app, but SentryCrashZombie must be compiled in a separate library - * if you do. - */ - -#ifndef HDR_SentryCrashZombie_h -#define HDR_SentryCrashZombie_h - -#ifdef __cplusplus -extern "C" { -#endif - -#include "SentryCrashMonitor.h" -#include - -/** Get the class of a deallocated object pointer, if it was tracked. - * - * @param object A pointer to a deallocated object. - * - * @return The object's class name, or NULL if it wasn't found. - */ -const char *sentrycrashzombie_className(const void *object); - -/** Access the Monitor API. - */ -SentryCrashMonitorAPI *sentrycrashcm_zombie_getAPI(void); - -#ifdef __cplusplus -} -#endif - -#endif // HDR_SentryCrashZombie_h diff --git a/Sources/SentryCrash/Recording/SentryCrash.h b/Sources/SentryCrash/Recording/SentryCrash.h index a78363d5a2..1ba6b77595 100644 --- a/Sources/SentryCrash/Recording/SentryCrash.h +++ b/Sources/SentryCrash/Recording/SentryCrash.h @@ -100,13 +100,6 @@ static NSString *const SENTRYCRASH_REPORT_ATTACHMENTS_ITEM = @"attachments"; */ @property (nonatomic, readwrite, assign) BOOL introspectMemory; -/** If YES, monitor all Objective-C/Swift deallocations and keep track of any - * accesses after deallocation. - * - * Default: NO - */ -@property (nonatomic, readwrite, assign) BOOL catchZombies; - /** List of Objective-C classes that should never be introspected. * Whenever a class in this list is encountered, only the class name will be * recorded. This can be useful for information security concerns. diff --git a/Sources/SentryCrash/Recording/SentryCrash.m b/Sources/SentryCrash/Recording/SentryCrash.m index bda3b8cc02..644b471951 100644 --- a/Sources/SentryCrash/Recording/SentryCrash.m +++ b/Sources/SentryCrash/Recording/SentryCrash.m @@ -105,7 +105,6 @@ @implementation SentryCrash @synthesize bundleName = _bundleName; @synthesize basePath = _basePath; @synthesize introspectMemory = _introspectMemory; -@synthesize catchZombies = _catchZombies; @synthesize doNotIntrospectClasses = _doNotIntrospectClasses; @synthesize demangleLanguages = _demangleLanguages; @synthesize maxReportCount = _maxReportCount; @@ -141,7 +140,6 @@ - (id)initWithBasePath:(NSString *)basePath } self.deleteBehaviorAfterSendAll = SentryCrashCDeleteAlways; self.introspectMemory = YES; - self.catchZombies = NO; self.maxReportCount = 5; self.monitoring = SentryCrashMonitorTypeProductionSafeMinimal; self.monitoringFromUninstalledToRestore = NO; @@ -196,12 +194,6 @@ - (void)setIntrospectMemory:(BOOL)introspectMemory sentrycrash_setIntrospectMemory(introspectMemory); } -- (void)setCatchZombies:(BOOL)catchZombies -{ - _catchZombies = catchZombies; - self.monitoring |= SentryCrashMonitorTypeZombie; -} - - (void)setDoNotIntrospectClasses:(NSArray *)doNotIntrospectClasses { _doNotIntrospectClasses = doNotIntrospectClasses; @@ -385,10 +377,7 @@ - (void)deleteReportWithID:(NSNumber *)reportID // ============================================================================ #define SYNTHESIZE_CRASH_STATE_PROPERTY(TYPE, NAME) \ - -(TYPE)NAME \ - { \ - return sentrycrashstate_currentState()->NAME; \ - } + -(TYPE)NAME { return sentrycrashstate_currentState()->NAME; } SYNTHESIZE_CRASH_STATE_PROPERTY(NSTimeInterval, activeDurationSinceLastCrash) SYNTHESIZE_CRASH_STATE_PROPERTY(NSTimeInterval, backgroundDurationSinceLastCrash) diff --git a/Sources/SentryCrash/Recording/SentryCrashC.c b/Sources/SentryCrash/Recording/SentryCrashC.c index 1ecd32fbfe..f2d073e534 100644 --- a/Sources/SentryCrash/Recording/SentryCrashC.c +++ b/Sources/SentryCrash/Recording/SentryCrashC.c @@ -31,7 +31,6 @@ #include "SentryCrashMonitorContext.h" #include "SentryCrashMonitor_AppState.h" #include "SentryCrashMonitor_System.h" -#include "SentryCrashMonitor_Zombie.h" #include "SentryCrashObjC.h" #include "SentryCrashReport.h" #include "SentryCrashReportFixer.h" diff --git a/Sources/SentryCrash/Recording/SentryCrashC.h b/Sources/SentryCrash/Recording/SentryCrashC.h index 660a4ff84a..eeba4f817e 100644 --- a/Sources/SentryCrash/Recording/SentryCrashC.h +++ b/Sources/SentryCrash/Recording/SentryCrashC.h @@ -111,20 +111,32 @@ void sentrycrash_setCrashNotifyCallback(const SentryCrashReportWriteCallback onC */ void sentrycrash_setMaxReportCount(int maxReportCount); +/** + * @typedef SaveAttachmentCallback + * + * This typedef defines a function pointer to a callback that will be called during crashes + * to request extra attachments to be saved. + * + * @param directoryPath The path to a directory where the view hierarchy should be saved. + */ +typedef void (*SaveAttachmentCallback)(const char *directoryPath); + /** * Set the callback to be called at the end of a crash to make the app save a screenshot; * - * @param callback function pointer that will be called with a give path. + * @param callback function pointer that will be called with a path to a directory where the screen + * shot should be saved. */ -void sentrycrash_setSaveScreenshots(void (*callback)(const char *)); +void sentrycrash_setSaveScreenshots(SaveAttachmentCallback callback); /** * Set the callback to be called at the end of a crash to make the app save the view hierarchy * descriptions; * - * @param callback function pointer that will be called with a give path. + * @param callback function pointer that will be called with a path to a directory where the view + * hierarchy should be saved. */ -void sentrycrash_setSaveViewHierarchy(void (*callback)(const char *)); +void sentrycrash_setSaveViewHierarchy(SaveAttachmentCallback callback); /** Report a custom, user defined exception. * This can be useful when dealing with scripting languages. diff --git a/Sources/SentryCrash/Recording/SentryCrashReport.c b/Sources/SentryCrash/Recording/SentryCrashReport.c index 58c56a6c0a..41c7379403 100644 --- a/Sources/SentryCrash/Recording/SentryCrashReport.c +++ b/Sources/SentryCrash/Recording/SentryCrashReport.c @@ -33,7 +33,6 @@ #include "SentryCrashJSONCodec.h" #include "SentryCrashMach.h" #include "SentryCrashMemory.h" -#include "SentryCrashMonitor_Zombie.h" #include "SentryCrashObjC.h" #include "SentryCrashReportFields.h" #include "SentryCrashReportVersion.h" @@ -605,19 +604,6 @@ isRestrictedClass(const char *name) return false; } -static void -writeZombieIfPresent( - const SentryCrashReportWriter *const writer, const char *const key, const uintptr_t address) -{ -#if SentryCrashCRASH_HAS_OBJC - const void *object = (const void *)address; - const char *zombieClassName = sentrycrashzombie_className(object); - if (zombieClassName != NULL) { - writer->addStringElement(writer, key, zombieClassName); - } -#endif -} - static bool writeObjCObject(const SentryCrashReportWriter *const writer, const uintptr_t address, int *limit) { @@ -700,7 +686,6 @@ writeMemoryContents(const SentryCrashReportWriter *const writer, const char *con writer->beginObject(writer, key); { writer->addUIntegerElement(writer, SentryCrashField_Address, address); - writeZombieIfPresent(writer, SentryCrashField_LastDeallocObject, address); if (!writeObjCObject(writer, address, limit)) { if (object == NULL) { writer->addStringElement( @@ -744,10 +729,6 @@ isNotableAddress(const uintptr_t address) const void *object = (const void *)address; #if SentryCrashCRASH_HAS_OBJC - if (sentrycrashzombie_className(object) != NULL) { - return true; - } - if (sentrycrashobjc_objectType(object) != SentryCrashObjCTypeUnknown) { return true; } @@ -1352,7 +1333,6 @@ writeError(const SentryCrashReportWriter *const writer, const char *const key, case SentryCrashMonitorTypeSystem: case SentryCrashMonitorTypeApplicationState: - case SentryCrashMonitorTypeZombie: SentryCrashLOG_ERROR( "Crash monitor type 0x%x shouldn't be able to cause events!", crash->crashType); break; diff --git a/Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c b/Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c index fab1ff8c90..66bb6c1e06 100644 --- a/Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c +++ b/Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.c @@ -146,6 +146,14 @@ sentrycrashmc_getContextForSignal( void sentrycrashmc_suspendEnvironment( thread_act_array_t *suspendedThreads, mach_msg_type_number_t *numSuspendedThreads) +{ + sentrycrashmc_suspendEnvironment_upToMaxSupportedThreads( + suspendedThreads, numSuspendedThreads, UINT32_MAX); +} + +void +sentrycrashmc_suspendEnvironment_upToMaxSupportedThreads(thread_act_array_t *suspendedThreads, + mach_msg_type_number_t *numSuspendedThreads, mach_msg_type_number_t maxSupportedThreads) { #if SentryCrashCRASH_HAS_THREADS_API SentryCrashLOG_DEBUG("Suspending environment."); @@ -158,6 +166,12 @@ sentrycrashmc_suspendEnvironment( return; } + if (*numSuspendedThreads > maxSupportedThreads) { + *numSuspendedThreads = 0; + SentryCrashLOG_DEBUG("Too many threads to suspend. Aborting operation."); + return; + } + for (mach_msg_type_number_t i = 0; i < *numSuspendedThreads; i++) { thread_t thread = (*suspendedThreads)[i]; if (thread != thisThread && !sentrycrashcm_isReservedThread(thread)) { diff --git a/Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.h b/Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.h index 798e6bfd3d..fb494eeff2 100644 --- a/Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.h +++ b/Sources/SentryCrash/Recording/Tools/SentryCrashMachineContext.h @@ -40,6 +40,13 @@ extern "C" { void sentrycrashmc_suspendEnvironment( thread_act_array_t *suspendedThreads, mach_msg_type_number_t *numSuspendedThreads); +/** + Suspend the runtime environment only if the amount of threads is not higher than + maxSupportedThreads. + */ +void sentrycrashmc_suspendEnvironment_upToMaxSupportedThreads(thread_act_array_t *suspendedThreads, + mach_msg_type_number_t *numSuspendedThreads, mach_msg_type_number_t maxSupportedThreads); + /** Resume the runtime environment. */ void sentrycrashmc_resumeEnvironment(thread_act_array_t threads, mach_msg_type_number_t numThreads); diff --git a/Sources/SentrySwiftUI/SentryTracedView.swift b/Sources/SentrySwiftUI/SentryTracedView.swift index 36ca4afc72..f1a791a563 100644 --- a/Sources/SentrySwiftUI/SentryTracedView.swift +++ b/Sources/SentrySwiftUI/SentryTracedView.swift @@ -5,8 +5,7 @@ import SwiftUI import SentryInternal #endif -/// -/// This feature is EXPERIMENTAL. +/// - warning: This is an experimental feature and may still have bugs. /// /// A control to measure the performance of your views and send the result as a transaction to Sentry.io. /// @@ -93,11 +92,9 @@ public struct SentryTracedView: View { } } -/// -/// This feature is EXPERIMENTAL. -/// @available(iOS 13, macOS 10.15, tvOS 13, watchOS 6.0, *) public extension View { + /// - warning: This is an experimental feature and may still have bugs. func sentryTrace(_ viewName: String? = nil) -> some View { return SentryTracedView(viewName) { return self diff --git a/Tests/SentryTests/Integrations/ANR/SentryANRTrackerTests.swift b/Tests/SentryTests/Integrations/ANR/SentryANRTrackerTests.swift index 078984cfa5..844ac8c05b 100644 --- a/Tests/SentryTests/Integrations/ANR/SentryANRTrackerTests.swift +++ b/Tests/SentryTests/Integrations/ANR/SentryANRTrackerTests.swift @@ -90,8 +90,9 @@ class SentryANRTrackerTests: XCTestCase, SentryANRTrackerDelegate { func testMultipleANRs_MultipleReported() { anrDetectedExpectation.expectedFulfillmentCount = 3 + let expectedANRStoppedInvocations = 2 anrStoppedExpectation.isInverted = false - anrStoppedExpectation.expectedFulfillmentCount = 2 + anrStoppedExpectation.expectedFulfillmentCount = expectedANRStoppedInvocations fixture.dispatchQueue.blockBeforeMainBlock = { self.advanceTime(bySeconds: self.fixture.timeoutInterval) @@ -105,6 +106,7 @@ class SentryANRTrackerTests: XCTestCase, SentryANRTrackerDelegate { start() wait(for: [anrDetectedExpectation, anrStoppedExpectation], timeout: waitTimeout) + XCTAssertEqual(expectedANRStoppedInvocations, fixture.dispatchQueue.dispatchAsyncInvocations.count) } func testAppSuspended_NoANR() { diff --git a/Tests/SentryTests/Integrations/Performance/Network/SentryNetworkTrackerTests.swift b/Tests/SentryTests/Integrations/Performance/Network/SentryNetworkTrackerTests.swift index 5230baaa55..8b24de0ada 100644 --- a/Tests/SentryTests/Integrations/Performance/Network/SentryNetworkTrackerTests.swift +++ b/Tests/SentryTests/Integrations/Performance/Network/SentryNetworkTrackerTests.swift @@ -473,8 +473,6 @@ class SentryNetworkTrackerTests: XCTestCase { assertOneSpanCreated(transaction) } - // Although we only run this test above the below specified versions, we expect the - // implementation to be thread safe func testResumeCalledMultipleTimesConcurrent_OneSpanCreated() { let task = createDataTask() let sut = fixture.getSut() @@ -498,8 +496,6 @@ class SentryNetworkTrackerTests: XCTestCase { assertOneSpanCreated(transaction) } - // Although we only run this test above the below specified versions, we expect the - // implementation to be thread safe func testChangeStateMultipleTimesConcurrent_OneSpanFinished() { let task = createDataTask() let sut = fixture.getSut() diff --git a/Tests/SentryTests/Integrations/ViewHierarchy/SentryViewHierarchyIntegrationTests.swift b/Tests/SentryTests/Integrations/ViewHierarchy/SentryViewHierarchyIntegrationTests.swift index 8c3243b68b..e157894146 100644 --- a/Tests/SentryTests/Integrations/ViewHierarchy/SentryViewHierarchyIntegrationTests.swift +++ b/Tests/SentryTests/Integrations/ViewHierarchy/SentryViewHierarchyIntegrationTests.swift @@ -53,6 +53,12 @@ class SentryViewHierarchyIntegrationTests: XCTestCase { XCTAssertFalse(sentrycrash_hasSaveViewHierarchyCallback()) } + func test_integrationAddFileName() { + SentrySDK.start { $0.attachViewHierarchy = true } + saveViewHierarchy("/test/path") + XCTAssertEqual("/test/path/view-hierarchy.json", fixture.viewHierarchy.saveFilePathUsed) + } + func test_processAttachments() { let sut = fixture.getSut() let event = Event(error: NSError(domain: "", code: -1)) diff --git a/Tests/SentryTests/Integrations/ViewHierarchy/TestSentryViewHierarchy.h b/Tests/SentryTests/Integrations/ViewHierarchy/TestSentryViewHierarchy.h index 92ef21291e..9f5ded4a11 100644 --- a/Tests/SentryTests/Integrations/ViewHierarchy/TestSentryViewHierarchy.h +++ b/Tests/SentryTests/Integrations/ViewHierarchy/TestSentryViewHierarchy.h @@ -3,6 +3,9 @@ #import "SentryViewHierarchy.h" #if SENTRY_HAS_UIKIT + +void saveViewHierarchy(const char *path); + @interface SentryViewHierarchy (Test) - (int)viewHierarchyFromView:(UIView *)view intoContext:(SentryCrashJSONEncodeContext *)context; diff --git a/Tests/SentryTests/Integrations/ViewHierarchy/TestSentryViewHierarchy.swift b/Tests/SentryTests/Integrations/ViewHierarchy/TestSentryViewHierarchy.swift index eb5e714594..02d2d60e93 100644 --- a/Tests/SentryTests/Integrations/ViewHierarchy/TestSentryViewHierarchy.swift +++ b/Tests/SentryTests/Integrations/ViewHierarchy/TestSentryViewHierarchy.swift @@ -6,6 +6,7 @@ class TestSentryViewHierarchy: SentryViewHierarchy { var result: Data? var viewHierarchyResult: Int32 = 0 var processViewHierarchyCallback: (() -> Void)? + var saveFilePathUsed: String? override func fetch() -> Data? { guard let result = self.result @@ -15,6 +16,11 @@ class TestSentryViewHierarchy: SentryViewHierarchy { return result } + override func save(_ filePath: String) -> Bool { + saveFilePathUsed = filePath + return true + } + override func viewHierarchy(from view: UIView!, into context: UnsafeMutablePointer!) -> Int32 { return viewHierarchyResult != 0 ? viewHierarchyResult : super.viewHierarchy(from: view, into: context) } diff --git a/Tests/SentryTests/Performance/SentryTracerTests.swift b/Tests/SentryTests/Performance/SentryTracerTests.swift index 6d79b6d136..2e870726a6 100644 --- a/Tests/SentryTests/Performance/SentryTracerTests.swift +++ b/Tests/SentryTests/Performance/SentryTracerTests.swift @@ -224,6 +224,26 @@ class SentryTracerTests: XCTestCase { XCTAssertEqual(status, sut.status) } + func testIdleTransaction_CreatingDispatchBlockFails_NoTransactionCaptured() { + fixture.dispatchQueue.createDispatchBlockReturnsNULL = true + + let sut = fixture.getSut(idleTimeout: fixture.idleTimeout, dispatchQueueWrapper: fixture.dispatchQueue) + + assertTransactionNotCaptured(sut) + } + + func testIdleTransaction_CreatingDispatchBlockFailsForFirstChild_FinishesTransaction() { + let sut = fixture.getSut(idleTimeout: fixture.idleTimeout, dispatchQueueWrapper: fixture.dispatchQueue) + + fixture.dispatchQueue.createDispatchBlockReturnsNULL = true + + let child = sut.startChild(operation: fixture.transactionOperation) + advanceTime(bySeconds: 0.1) + child.finish() + + assertOneTransactionCaptured(sut) + } + func testWaitForChildrenTransactionWithStatus_OverwriteStatusInFinish() { let sut = fixture.getSut() sut.status = .aborted diff --git a/Tests/SentryTests/Protocol/SentryUserTests.swift b/Tests/SentryTests/Protocol/SentryUserTests.swift index ccc1afd857..54bd77c34f 100644 --- a/Tests/SentryTests/Protocol/SentryUserTests.swift +++ b/Tests/SentryTests/Protocol/SentryUserTests.swift @@ -88,11 +88,8 @@ class SentryUserTests: XCTestCase { XCTAssertEqual(TestData.user, copiedUser) } - // Although we only run this test above the below specified versions, we expect the - // implementation to be thread safe - // With this test we test if modifications from multiple threads don't lead to a crash. func testModifyingFromMultipleThreads() { - let queue = DispatchQueue(label: "SentryScopeTests", qos: .userInteractive, attributes: [.concurrent, .initiallyInactive]) + let queue = DispatchQueue(label: "SentryUserTests", qos: .userInteractive, attributes: [.concurrent, .initiallyInactive]) let group = DispatchGroup() let user = TestData.user.copy() as! User diff --git a/Tests/SentryTests/SentryClientTests.swift b/Tests/SentryTests/SentryClientTests.swift index bca1f80c62..4d91e2d19c 100644 --- a/Tests/SentryTests/SentryClientTests.swift +++ b/Tests/SentryTests/SentryClientTests.swift @@ -607,9 +607,14 @@ class SentryClientTest: XCTestCase { } } - func testCaptureEvent_AddCurrentMemoryAndStorage() { + func testCaptureEvent_AddCurrentMemoryStorageAndCPUCoreCount() { - fixture.getSut().capture(event: TestData.event) + let sut = fixture.getSut() + let testProcessWrapper = TestSentryNSProcessInfoWrapper() + testProcessWrapper.overrides.processorCount = 12 + Dynamic(sut).processInfoWrapper = testProcessWrapper + + sut.capture(event: TestData.event) assertLastSentEvent { actual in let eventFreeMemory = actual.context?["device"]?[SentryDeviceContextFreeMemoryKey] as? Int @@ -620,6 +625,9 @@ class SentryClientTest: XCTestCase { let eventFreeStorage = actual.context?["device"]?["free_storage"] as? Int XCTAssertEqual(eventFreeStorage, 345_678) + + let cpuCoreCount = actual.context?["device"]?["processor_count"] as? UInt + XCTAssertEqual(testProcessWrapper.processorCount, cpuCoreCount) } } diff --git a/Tests/SentryTests/SentryCrash/SentryCrashReportStore_Tests.m b/Tests/SentryTests/SentryCrash/SentryCrashReportStore_Tests.m index 961bb5ca16..8cb62e67fa 100644 --- a/Tests/SentryTests/SentryCrash/SentryCrashReportStore_Tests.m +++ b/Tests/SentryTests/SentryCrash/SentryCrashReportStore_Tests.m @@ -57,6 +57,7 @@ - (int64_t)getReportIDFromPath:(NSString *)path int64_t reportID = 0; sscanf(filename, scanFormat, &reportID); + return reportID; } diff --git a/Tests/SentryTests/SentryCrash/SentryThreadInspectorTests.swift b/Tests/SentryTests/SentryCrash/SentryThreadInspectorTests.swift index bbc315bb40..c9f58cbd49 100644 --- a/Tests/SentryTests/SentryCrash/SentryThreadInspectorTests.swift +++ b/Tests/SentryTests/SentryCrash/SentryThreadInspectorTests.swift @@ -5,6 +5,7 @@ class SentryThreadInspectorTests: XCTestCase { private class Fixture { var testMachineContextWrapper = TestMachineContextWrapper() var stacktraceBuilder = TestSentryStacktraceBuilder(crashStackEntryMapper: SentryCrashStackEntryMapper(inAppLogic: SentryInAppLogic(inAppIncludes: [], inAppExcludes: []))) + var keepThreadAlive = true func getSut(testWithRealMachineContextWrapper: Bool = false) -> SentryThreadInspector { @@ -80,6 +81,27 @@ class SentryThreadInspectorTests: XCTestCase { wait(for: [expect], timeout: 10) } + func testGetCurrentThreadWithStackTrack_TooManyThreads() { + let expect = expectation(description: "Wait all Threads") + expect.expectedFulfillmentCount = 70 + + let sut = self.fixture.getSut(testWithRealMachineContextWrapper: true) + + for _ in 0.. -#import - -NS_ASSUME_NONNULL_BEGIN - -/** - * Report failing tests to Sentry. - */ -@interface SentryTestObserver : NSObject - -@end - -NS_ASSUME_NONNULL_END diff --git a/Tests/SentryTests/TestUtils/SentryTestObserver.m b/Tests/SentryTests/TestUtils/SentryTestObserver.m deleted file mode 100644 index 439cf61203..0000000000 --- a/Tests/SentryTests/TestUtils/SentryTestObserver.m +++ /dev/null @@ -1,100 +0,0 @@ -#import "SentryTestObserver.h" -#import "SentryBreadcrumb.h" -#import "SentryClient.h" -#import "SentryCrashIntegration.h" -#import "SentryCrashWrapper.h" -#import "SentryCurrentDate.h" -#import "SentryDefaultCurrentDateProvider.h" -#import "SentryHub.h" -#import "SentryLog+TestInit.h" -#import "SentryOptions.h" -#import "SentryScope.h" -#import "SentrySdk+Private.h" -#import "XCTest/XCTIssue.h" -#import "XCTest/XCTest.h" -#import "XCTest/XCTestCase.h" -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface -SentryTestObserver () - -@property (nonatomic, strong) SentryOptions *options; -@property (nonatomic, strong) SentryScope *scope; - -@end - -@implementation SentryTestObserver - -+ (void)load -{ -#if defined(TESTCI) - [[XCTestObservationCenter sharedTestObservationCenter] - addTestObserver:[[SentryTestObserver alloc] init]]; -#endif -} - -- (instancetype)init -{ - if (self = [super init]) { - SentryOptions *options = [[SentryOptions alloc] init]; - options.dsn = @"https://6cc9bae94def43cab8444a99e0031c28@o447951.ingest.sentry.io/5428557"; - options.environment = @"unit-tests"; - options.debug = YES; - options.enableAutoSessionTracking = NO; - options.maxBreadcrumbs = 5000; - - // The SentryCrashIntegration enriches the scope. We need to install the integration - // once to get the scope data. - [SentrySDK startWithOptions:options]; - - self.scope = [[SentryScope alloc] init]; - [SentryCrashIntegration enrichScope:self.scope - crashWrapper:[SentryCrashWrapper sharedInstance]]; - - self.options = options; - } - return self; -} - -#pragma mark - XCTestObservation - -- (void)testCaseWillStart:(XCTestCase *)testCase -{ - SentryBreadcrumb *crumb = [[SentryBreadcrumb alloc] initWithLevel:kSentryLevelDebug - category:@"test.started"]; - [crumb setMessage:testCase.name]; - // The tests might have a different time set - [crumb setTimestamp:[NSDate new]]; - [self.scope addBreadcrumb:crumb]; -} - -- (void)testBundleDidFinish:(NSBundle *)testBundle -{ - [SentrySDK flush:5.0]; -} - -- (void)testCase:(XCTestCase *)testCase didRecordIssue:(XCTIssue *)issue -{ - // Tests set a fixed time. We want to use the current time for sending - // the test result to Sentry. - id currentDateProvider = [SentryCurrentDate getCurrentDateProvider]; - [SentryCurrentDate setCurrentDateProvider:[SentryDefaultCurrentDateProvider sharedInstance]]; - - // The tests might mess up the files or something else. Therefore, we create a fresh client and - // hub to make sure the sending works. - SentryClient *client = [[SentryClient alloc] initWithOptions:self.options]; - // We create our own hub here, because we don't know the state of the SentrySDK. - SentryHub *hub = [[SentryHub alloc] initWithClient:client andScope:self.scope]; - NSException *exception = [[NSException alloc] initWithName:testCase.name - reason:issue.description - userInfo:nil]; - [hub captureException:exception withScope:hub.scope]; - - [SentryCurrentDate setCurrentDateProvider:currentDateProvider]; -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/develop-docs/README.md b/develop-docs/README.md index ad817bf73a..651278ff8c 100644 --- a/develop-docs/README.md +++ b/develop-docs/README.md @@ -196,3 +196,7 @@ Date: January 18th, 2023 Contributors: @brustolin and @philipphofmann We release experimental SentrySwiftUI cocoa package with the version 8.0.0 because all podspecs file in a repo need to have the same version. + +## Usage of `__has_include` + +Some private headers add a dependency of a public header, when those private headers are used in a sample project, or referenced from a hybrid SDK, it is treated as part of the project using it, therefore, if it points to a header that is not part of said project, a compilation error will occur. To solve this we make use of `__has_include` to try to point to the SDK version of the header, or to fallback to the direct reference when compiling the SDK. diff --git a/scripts/no-changes-in-high-risk-files.sh b/scripts/no-changes-in-high-risk-files.sh index 34ea684b51..714f165415 100755 --- a/scripts/no-changes-in-high-risk-files.sh +++ b/scripts/no-changes-in-high-risk-files.sh @@ -4,12 +4,12 @@ set -euo pipefail # To update the sha run shasum -a 256 ./Sources/Sentry/SentryNSURLSessionTaskSearch.m and copy the result in EXPECTED. ACTUAL=$(shasum -a 256 ./Sources/Sentry/SentryNSURLSessionTaskSearch.m) -EXPECTED="54a41f19ca05866605bf05da4d27f4df34143701c2d70a82221d52fc7c895ebc ./Sources/Sentry/SentryNSURLSessionTaskSearch.m" +EXPECTED="819d5ca5e3db2ac23c859b14c149b7f0754d3ae88bea1dba92c18f49a81da0e1 ./Sources/Sentry/SentryNSURLSessionTaskSearch.m" if [ "$ACTUAL" = "$EXPECTED" ]; then echo "No changes in high risk files." exit 0 else - echo "Changes in high risk files. If your changes are intended please update the sha in ./scripts/no-changes-in-high-risk-files.sh." + echo "Changes in high risk files. If your changes are intended please update the sha in ./scripts/no-changes-in-high-risk-files.sh to $ACTUAL." exit 1 fi