diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2bc28c7d5e..d8d6640e8e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,8 +10,11 @@ This version adds a dependency on Swift.
### Fixes
-- Errors shortly after SentrySDK.init now affect the session (#2430)
+- Errors shortly after `SentrySDK.init` now affect the session (#2430)
- Use the same default environment for events and sessions (#2447)
+- Increase `SentryCrashMAX_STRINGBUFFERSIZE` to reduce the instances where we're dropping a crash due to size limit (#2465)
+- `SentryAppStateManager` correctly unsubscribes from `NSNotificationCenter` when closing the SDK (#2460)
+- The SDK no longer reports an OOM when a crash happens after closing the SDK (#2468)
### Breaking Changes
@@ -42,6 +45,7 @@ This version adds a dependency on Swift.
- Rename `SentryOptions.enablePreWarmedAppStartTracking` to `enablePreWarmedAppStartTracing`
- Rename `SentryOptions.enableFileIOTracking` to `enableFileIOTracing`
- Rename `SentryOptions.enableCoreDataTracking` to `enableCoreDataTracing`
+- SentrySDK.close calls flush, which is a blocking call (#2453)
## 7.31.3
diff --git a/Package.swift b/Package.swift
index b9e1d96e38..361dc3cf3a 100644
--- a/Package.swift
+++ b/Package.swift
@@ -27,6 +27,7 @@ let package = Package(
cxxSettings: [
.define("GCC_ENABLE_CPP_EXCEPTIONS", to: "YES"),
.headerSearchPath("Sentry/include"),
+ .headerSearchPath("Sentry/include/HybridPublic"),
.headerSearchPath("Sentry/Public"),
.headerSearchPath("SentryCrash/Installations"),
.headerSearchPath("SentryCrash/Recording"),
diff --git a/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard b/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard
index 029585c65a..f835a85963 100644
--- a/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard
+++ b/Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard
@@ -122,31 +122,31 @@
-
+
+
@@ -402,14 +410,14 @@
-
+
-
+
diff --git a/Samples/iOS-Swift/iOS-Swift/ViewController.swift b/Samples/iOS-Swift/iOS-Swift/ViewController.swift
index b74e9c1d00..2c9f13af7c 100644
--- a/Samples/iOS-Swift/iOS-Swift/ViewController.swift
+++ b/Samples/iOS-Swift/iOS-Swift/ViewController.swift
@@ -158,7 +158,15 @@ class ViewController: UIViewController {
@IBAction func crash(_ sender: Any) {
SentrySDK.crash()
}
-
+
+ // swiftlint:disable force_unwrapping
+ @IBAction func unwrapCrash(_ sender: Any) {
+ let a: String! = nil
+ let b: String = a!
+ print(b)
+ }
+ // swiftlint:enable force_unwrapping
+
@IBAction func asyncCrash(_ sender: Any) {
DispatchQueue.main.async {
self.asyncCrash1()
diff --git a/Sentry.podspec b/Sentry.podspec
index 7167eead87..2418fece37 100644
--- a/Sentry.podspec
+++ b/Sentry.podspec
@@ -41,6 +41,6 @@ Pod::Spec.new do |s|
"Sources/SentryCrash/**/*.{h,hpp,m,mm,c,cpp}", "Sources/Swift/Sentry.swift"
sp.public_header_files =
- "Sources/Sentry/Public/*.h", "Sources/Sentry/include/PrivateSentrySDKOnly.h"
+ "Sources/Sentry/Public/*.h", "Sources/Sentry/include/HybridPublic/*.h"
end
end
diff --git a/Sentry.xcodeproj/project.pbxproj b/Sentry.xcodeproj/project.pbxproj
index 36b53438c1..1bb1b09f0e 100644
--- a/Sentry.xcodeproj/project.pbxproj
+++ b/Sentry.xcodeproj/project.pbxproj
@@ -79,7 +79,7 @@
15360CF02433A16D00112302 /* SentryInstallation.h in Headers */ = {isa = PBXBuildFile; fileRef = 15360CEF2433A16D00112302 /* SentryInstallation.h */; };
15360CF52433C59B00112302 /* SentryInstallationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 15360CF22433C59500112302 /* SentryInstallationTests.m */; };
15D0AC882459EE4D006541C2 /* SentryNSURLRequestTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15D0AC872459EE4D006541C2 /* SentryNSURLRequestTests.swift */; };
- 15E0A8E1240C41CE00F044E3 /* SentryEnvelope.h in Headers */ = {isa = PBXBuildFile; fileRef = 15E0A8E0240C41CE00F044E3 /* SentryEnvelope.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 15E0A8E1240C41CE00F044E3 /* SentryEnvelope.h in Headers */ = {isa = PBXBuildFile; fileRef = 15E0A8E0240C41CE00F044E3 /* SentryEnvelope.h */; settings = {ATTRIBUTES = (Private, ); }; };
15E0A8E5240C457D00F044E3 /* SentryEnvelope.m in Sources */ = {isa = PBXBuildFile; fileRef = 15E0A8E4240C457D00F044E3 /* SentryEnvelope.m */; };
15E0A8EA240F2C9000F044E3 /* SentrySerialization.h in Headers */ = {isa = PBXBuildFile; fileRef = 15E0A8E9240F2C8F00F044E3 /* SentrySerialization.h */; };
15E0A8ED240F2CB000F044E3 /* SentrySerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 15E0A8EC240F2CB000F044E3 /* SentrySerialization.m */; };
@@ -384,7 +384,7 @@
7B77BE3727EC8460003C9020 /* SentryDiscardReasonMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B77BE3627EC8460003C9020 /* SentryDiscardReasonMapper.m */; };
7B7A30C624B48321005A4C6E /* SentryCrashWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B7A30C524B48321005A4C6E /* SentryCrashWrapper.h */; };
7B7A30C824B48389005A4C6E /* SentryCrashWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B7A30C724B48389005A4C6E /* SentryCrashWrapper.m */; };
- 7B7A599526B692540060A676 /* SentryScreenFrames.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B7A599426B692540060A676 /* SentryScreenFrames.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 7B7A599526B692540060A676 /* SentryScreenFrames.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B7A599426B692540060A676 /* SentryScreenFrames.h */; settings = {ATTRIBUTES = (Private, ); }; };
7B7A599726B692F00060A676 /* SentryScreenFrames.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B7A599626B692F00060A676 /* SentryScreenFrames.m */; };
7B7D872C2486480B00D2ECFF /* SentryStacktraceBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B7D872B2486480B00D2ECFF /* SentryStacktraceBuilder.h */; };
7B7D872E2486482600D2ECFF /* SentryStacktraceBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B7D872D2486482600D2ECFF /* SentryStacktraceBuilder.m */; };
@@ -501,7 +501,7 @@
7BC852332458802C005A70F0 /* SentryDataCategoryMapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BC852322458802C005A70F0 /* SentryDataCategoryMapper.h */; };
7BC85235245880AE005A70F0 /* SentryDataCategoryMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BC85234245880AE005A70F0 /* SentryDataCategoryMapper.m */; };
7BC8523724588115005A70F0 /* SentryDataCategory.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BC8523624588115005A70F0 /* SentryDataCategory.h */; };
- 7BC852392458830A005A70F0 /* SentryEnvelopeItemType.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BC852382458830A005A70F0 /* SentryEnvelopeItemType.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 7BC852392458830A005A70F0 /* SentryEnvelopeItemType.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BC852382458830A005A70F0 /* SentryEnvelopeItemType.h */; settings = {ATTRIBUTES = (Private, ); }; };
7BC8523B2458849E005A70F0 /* SentryDataCategoryMapperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BC8523A2458849E005A70F0 /* SentryDataCategoryMapperTests.swift */; };
7BC9A20028F41016001E7C4C /* SentryMeasurementValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BC9A1FF28F41016001E7C4C /* SentryMeasurementValue.h */; };
7BC9A20228F41350001E7C4C /* SentryMeasurementUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BC9A20128F41350001E7C4C /* SentryMeasurementUnit.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -529,7 +529,7 @@
7BD86EC7264A641D005439DB /* SentrySysctl.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BD86EC6264A641D005439DB /* SentrySysctl.m */; };
7BD86ECB264A6DB5005439DB /* TestSysctl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD86ECA264A6DB5005439DB /* TestSysctl.swift */; };
7BD86ECD264A78A6005439DB /* SentryAppStartTrackerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD86ECC264A78A6005439DB /* SentryAppStartTrackerTests.swift */; };
- 7BD86ECF264A7C77005439DB /* SentryAppStartMeasurement.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BD86ECE264A7C77005439DB /* SentryAppStartMeasurement.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 7BD86ECF264A7C77005439DB /* SentryAppStartMeasurement.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BD86ECE264A7C77005439DB /* SentryAppStartMeasurement.h */; settings = {ATTRIBUTES = (Private, ); }; };
7BD86ED1264A7CF6005439DB /* SentryAppStartMeasurement.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BD86ED0264A7CF6005439DB /* SentryAppStartMeasurement.m */; };
7BDB03B7251364F800BAE198 /* SentryDispatchQueueWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BDB03B6251364F800BAE198 /* SentryDispatchQueueWrapper.h */; };
7BDB03BB2513652900BAE198 /* SentryDispatchQueueWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BDB03BA2513652900BAE198 /* SentryDispatchQueueWrapper.m */; };
@@ -722,6 +722,7 @@
D8B76B062808066D000A58C4 /* SentryScreenshotIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8B76B042808060E000A58C4 /* SentryScreenshotIntegrationTests.swift */; };
D8B76B0828081461000A58C4 /* TestSentryScreenShot.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8B76B0728081461000A58C4 /* TestSentryScreenShot.swift */; };
D8BBD32728FD9FC00011F850 /* SentrySwift.h in Headers */ = {isa = PBXBuildFile; fileRef = D8BBD32628FD9FBF0011F850 /* SentrySwift.h */; };
+ D8BD2E6829361A0F00D96C6A /* PrivatesHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = D8BD2E67293619F600D96C6A /* PrivatesHeader.h */; settings = {ATTRIBUTES = (Private, ); }; };
D8C67E9B28000E24007E326E /* SentryUIApplication.h in Headers */ = {isa = PBXBuildFile; fileRef = D8C67E9928000E23007E326E /* SentryUIApplication.h */; };
D8C67E9C28000E24007E326E /* SentryScreenshot.h in Headers */ = {isa = PBXBuildFile; fileRef = D8C67E9A28000E23007E326E /* SentryScreenshot.h */; };
D8CE69BC277E39C700C6EC5C /* SentryFileIOTrackingIntegrationObjCTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D8CE69BB277E39C700C6EC5C /* SentryFileIOTrackingIntegrationObjCTests.m */; };
@@ -828,7 +829,7 @@
15360CEF2433A16D00112302 /* SentryInstallation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryInstallation.h; path = include/SentryInstallation.h; sourceTree = ""; };
15360CF22433C59500112302 /* SentryInstallationTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryInstallationTests.m; sourceTree = ""; };
15D0AC872459EE4D006541C2 /* SentryNSURLRequestTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryNSURLRequestTests.swift; sourceTree = ""; };
- 15E0A8E0240C41CE00F044E3 /* SentryEnvelope.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryEnvelope.h; path = Public/SentryEnvelope.h; sourceTree = ""; };
+ 15E0A8E0240C41CE00F044E3 /* SentryEnvelope.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryEnvelope.h; path = include/HybridPublic/SentryEnvelope.h; sourceTree = ""; };
15E0A8E4240C457D00F044E3 /* SentryEnvelope.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryEnvelope.m; sourceTree = ""; };
15E0A8E9240F2C8F00F044E3 /* SentrySerialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentrySerialization.h; path = include/SentrySerialization.h; sourceTree = ""; };
15E0A8EC240F2CB000F044E3 /* SentrySerialization.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SentrySerialization.m; sourceTree = ""; };
@@ -1154,7 +1155,7 @@
7B7A30C524B48321005A4C6E /* SentryCrashWrapper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryCrashWrapper.h; path = include/SentryCrashWrapper.h; sourceTree = ""; };
7B7A30C724B48389005A4C6E /* SentryCrashWrapper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryCrashWrapper.m; sourceTree = ""; };
7B7A30C924B48523005A4C6E /* SentryHub+TestInit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SentryHub+TestInit.h"; sourceTree = ""; };
- 7B7A599426B692540060A676 /* SentryScreenFrames.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryScreenFrames.h; path = Public/SentryScreenFrames.h; sourceTree = ""; };
+ 7B7A599426B692540060A676 /* SentryScreenFrames.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryScreenFrames.h; path = include/HybridPublic/SentryScreenFrames.h; sourceTree = ""; };
7B7A599626B692F00060A676 /* SentryScreenFrames.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryScreenFrames.m; sourceTree = ""; };
7B7D872B2486480B00D2ECFF /* SentryStacktraceBuilder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryStacktraceBuilder.h; path = include/SentryStacktraceBuilder.h; sourceTree = ""; };
7B7D872D2486482600D2ECFF /* SentryStacktraceBuilder.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryStacktraceBuilder.m; sourceTree = ""; };
@@ -1275,7 +1276,7 @@
7BC852322458802C005A70F0 /* SentryDataCategoryMapper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryDataCategoryMapper.h; path = include/SentryDataCategoryMapper.h; sourceTree = ""; };
7BC85234245880AE005A70F0 /* SentryDataCategoryMapper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryDataCategoryMapper.m; sourceTree = ""; };
7BC8523624588115005A70F0 /* SentryDataCategory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryDataCategory.h; path = include/SentryDataCategory.h; sourceTree = ""; };
- 7BC852382458830A005A70F0 /* SentryEnvelopeItemType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryEnvelopeItemType.h; path = Public/SentryEnvelopeItemType.h; sourceTree = ""; };
+ 7BC852382458830A005A70F0 /* SentryEnvelopeItemType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryEnvelopeItemType.h; path = include/HybridPublic/SentryEnvelopeItemType.h; sourceTree = ""; };
7BC8523A2458849E005A70F0 /* SentryDataCategoryMapperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryDataCategoryMapperTests.swift; sourceTree = ""; };
7BC9A1FF28F41016001E7C4C /* SentryMeasurementValue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryMeasurementValue.h; path = include/SentryMeasurementValue.h; sourceTree = ""; };
7BC9A20128F41350001E7C4C /* SentryMeasurementUnit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryMeasurementUnit.h; path = Public/SentryMeasurementUnit.h; sourceTree = ""; };
@@ -1305,7 +1306,7 @@
7BD86EC6264A641D005439DB /* SentrySysctl.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentrySysctl.m; sourceTree = ""; };
7BD86ECA264A6DB5005439DB /* TestSysctl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestSysctl.swift; sourceTree = ""; };
7BD86ECC264A78A6005439DB /* SentryAppStartTrackerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryAppStartTrackerTests.swift; sourceTree = ""; };
- 7BD86ECE264A7C77005439DB /* SentryAppStartMeasurement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryAppStartMeasurement.h; path = Public/SentryAppStartMeasurement.h; sourceTree = ""; };
+ 7BD86ECE264A7C77005439DB /* SentryAppStartMeasurement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryAppStartMeasurement.h; path = include/HybridPublic/SentryAppStartMeasurement.h; sourceTree = ""; };
7BD86ED0264A7CF6005439DB /* SentryAppStartMeasurement.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryAppStartMeasurement.m; sourceTree = ""; };
7BDB03B6251364F800BAE198 /* SentryDispatchQueueWrapper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryDispatchQueueWrapper.h; path = include/SentryDispatchQueueWrapper.h; sourceTree = ""; };
7BDB03BA2513652900BAE198 /* SentryDispatchQueueWrapper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryDispatchQueueWrapper.m; sourceTree = ""; };
@@ -1493,7 +1494,7 @@
D808FB90281BF6E9009A2A33 /* SentryUIEventTrackingIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryUIEventTrackingIntegrationTests.swift; sourceTree = ""; };
D8137D52272B53070082656C /* TestSentrySpan.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestSentrySpan.h; sourceTree = ""; };
D8137D53272B53070082656C /* TestSentrySpan.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestSentrySpan.m; sourceTree = ""; };
- D81A346B291AECC7005A27A9 /* PrivateSentrySDKOnly.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PrivateSentrySDKOnly.h; path = include/PrivateSentrySDKOnly.h; sourceTree = ""; };
+ D81A346B291AECC7005A27A9 /* PrivateSentrySDKOnly.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PrivateSentrySDKOnly.h; path = include/HybridPublic/PrivateSentrySDKOnly.h; sourceTree = ""; };
D81A3488291D0AC0005A27A9 /* SentryPrivate.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SentryPrivate.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D81A349B291D0C0B005A27A9 /* Sentry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sentry.swift; sourceTree = ""; };
D81A349F291D5568005A27A9 /* SentryPrivate.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; path = SentryPrivate.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
@@ -1540,6 +1541,7 @@
D8B76B0728081461000A58C4 /* TestSentryScreenShot.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestSentryScreenShot.swift; sourceTree = ""; };
D8BBD32628FD9FBF0011F850 /* SentrySwift.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentrySwift.h; path = include/SentrySwift.h; sourceTree = ""; };
D8BD2E27292D1F7300D96C6A /* SDK.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = SDK.xcconfig; sourceTree = ""; };
+ D8BD2E67293619F600D96C6A /* PrivatesHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PrivatesHeader.h; path = include/HybridPublic/PrivatesHeader.h; sourceTree = ""; };
D8C67E9928000E23007E326E /* SentryUIApplication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryUIApplication.h; path = include/SentryUIApplication.h; sourceTree = ""; };
D8C67E9A28000E23007E326E /* SentryScreenshot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SentryScreenshot.h; path = include/SentryScreenshot.h; sourceTree = ""; };
D8CE69BB277E39C700C6EC5C /* SentryFileIOTrackingIntegrationObjCTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryFileIOTrackingIntegrationObjCTests.m; sourceTree = ""; };
@@ -1864,6 +1866,7 @@
isa = PBXGroup;
children = (
63AA76951EB9C1C200D153DE /* SentryDefines.h */,
+ D8BD2E67293619F600D96C6A /* PrivatesHeader.h */,
63AA769B1EB9C57A00D153DE /* SentryError.h */,
63AA769C1EB9C57A00D153DE /* SentryError.m */,
7B42C47F27E08F33009B58C2 /* SentryDependencyContainer.h */,
@@ -3167,6 +3170,7 @@
03F84D2027DD414C008FE43F /* SentryStackBounds.hpp in Headers */,
8E5D38E3261D4B57000D363D /* SentryPerformanceTrackingIntegration.h in Headers */,
63FE70F920DA4C1000CDBAE8 /* SentryCrashMonitor.h in Headers */,
+ D8BD2E6829361A0F00D96C6A /* PrivatesHeader.h in Headers */,
7B98D7CB25FB64EC00C5A389 /* SentryOutOfMemoryTrackingIntegration.h in Headers */,
63FE710920DA4C1000CDBAE8 /* SentryCrashFileUtils.h in Headers */,
03F84D1F27DD414C008FE43F /* SentryAsyncSafeLogging.h in Headers */,
diff --git a/Sources/Sentry/Public/Sentry.h b/Sources/Sentry/Public/Sentry.h
index 0edc354719..349e0e51ab 100644
--- a/Sources/Sentry/Public/Sentry.h
+++ b/Sources/Sentry/Public/Sentry.h
@@ -6,7 +6,6 @@ FOUNDATION_EXPORT double SentryVersionNumber;
//! Project version string for Sentry.
FOUNDATION_EXPORT const unsigned char SentryVersionString[];
-#import "SentryAppStartMeasurement.h"
#import "SentryAttachment.h"
#import "SentryBreadcrumb.h"
#import "SentryClient.h"
@@ -15,8 +14,6 @@ FOUNDATION_EXPORT const unsigned char SentryVersionString[];
#import "SentryDebugMeta.h"
#import "SentryDefines.h"
#import "SentryDsn.h"
-#import "SentryEnvelope.h"
-#import "SentryEnvelopeItemType.h"
#import "SentryError.h"
#import "SentryEvent.h"
#import "SentryException.h"
@@ -37,6 +34,7 @@ FOUNDATION_EXPORT const unsigned char SentryVersionString[];
#import "SentrySamplingContext.h"
#import "SentryScope.h"
#import "SentryScreenFrames.h"
+#import "SentrySdkInfo.h"
#import "SentrySerializable.h"
#import "SentrySpanContext.h"
#import "SentrySpanId.h"
diff --git a/Sources/Sentry/Public/SentryClient.h b/Sources/Sentry/Public/SentryClient.h
index ba2042b1d5..399e348b1e 100644
--- a/Sources/Sentry/Public/SentryClient.h
+++ b/Sources/Sentry/Public/SentryClient.h
@@ -8,6 +8,8 @@ NS_ASSUME_NONNULL_BEGIN
@interface SentryClient : NSObject
SENTRY_NO_INIT
+@property (nonatomic, assign, readonly) BOOL isEnabled;
+
@property (nonatomic, strong) SentryOptions *options;
/**
@@ -119,6 +121,11 @@ SENTRY_NO_INIT
*/
- (void)flush:(NSTimeInterval)timeout NS_SWIFT_NAME(flush(timeout:));
+/**
+ * Disables the client and calls flush with ``SentryOptions/shutdownTimeInterval``.
+ */
+- (void)close;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/Sources/Sentry/Public/SentryHub.h b/Sources/Sentry/Public/SentryHub.h
index 9a5bb369b9..88609c6f4a 100644
--- a/Sources/Sentry/Public/SentryHub.h
+++ b/Sources/Sentry/Public/SentryHub.h
@@ -268,6 +268,11 @@ SENTRY_NO_INIT
*/
- (void)flush:(NSTimeInterval)timeout NS_SWIFT_NAME(flush(timeout:));
+/**
+ * Calls flush with ``SentryOptions/shutdownTimeInterval``.
+ */
+- (void)close;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/Sources/Sentry/Public/SentryOptions.h b/Sources/Sentry/Public/SentryOptions.h
index 926cfd3e5f..ff8d85a953 100644
--- a/Sources/Sentry/Public/SentryOptions.h
+++ b/Sources/Sentry/Public/SentryOptions.h
@@ -58,6 +58,11 @@ NS_SWIFT_NAME(Options)
*/
@property (nonatomic, assign) BOOL enabled;
+/**
+ * Controls the flush duration when calling ``SentrySDK/close``.
+ */
+@property (nonatomic, assign) NSTimeInterval shutdownTimeInterval;
+
/**
* When enabled, the SDK sends crashes to Sentry. Default value is YES.
*/
diff --git a/Sources/Sentry/Public/SentrySDK.h b/Sources/Sentry/Public/SentrySDK.h
index 595bd6cea1..6ceee4f6c2 100644
--- a/Sources/Sentry/Public/SentrySDK.h
+++ b/Sources/Sentry/Public/SentrySDK.h
@@ -311,7 +311,8 @@ SENTRY_NO_INIT
+ (void)flush:(NSTimeInterval)timeout NS_SWIFT_NAME(flush(timeout:));
/**
- * Closes the SDK and uninstalls all the integrations.
+ * Closes the SDK, uninstalls all the integrations, and calls flush with
+ * ``SentryOptions/shutdownTimeInterval``.
*/
+ (void)close;
diff --git a/Sources/Sentry/SentryAppState.m b/Sources/Sentry/SentryAppState.m
index 9c339e9a3b..cef2a8e709 100644
--- a/Sources/Sentry/SentryAppState.m
+++ b/Sources/Sentry/SentryAppState.m
@@ -25,6 +25,7 @@ - (instancetype)initWithReleaseName:(NSString *)releaseName
_isActive = NO;
_wasTerminated = NO;
_isANROngoing = NO;
+ _isSDKRunning = YES;
}
return self;
}
@@ -89,6 +90,15 @@ - (nullable instancetype)initWithJSONObject:(NSDictionary *)jsonObject
} else {
_isANROngoing = [isANROngoing boolValue];
}
+
+ id isSDKRunning = [jsonObject valueForKey:@"is_sdk_running"];
+ if (isSDKRunning == nil || ![isSDKRunning isKindOfClass:[NSNumber class]]) {
+ // This property was added later so instead of returning nil,
+ // we're setting it to the default value.
+ _isSDKRunning = YES;
+ } else {
+ _isSDKRunning = [isSDKRunning boolValue];
+ }
}
return self;
}
@@ -106,6 +116,7 @@ - (nullable instancetype)initWithJSONObject:(NSDictionary *)jsonObject
[data setValue:@(self.isActive) forKey:@"is_active"];
[data setValue:@(self.wasTerminated) forKey:@"was_terminated"];
[data setValue:@(self.isANROngoing) forKey:@"is_anr_ongoing"];
+ [data setValue:@(self.isSDKRunning) forKey:@"is_sdk_running"];
return data;
}
diff --git a/Sources/Sentry/SentryAppStateManager.m b/Sources/Sentry/SentryAppStateManager.m
index 0302320f5e..fb187df795 100644
--- a/Sources/Sentry/SentryAppStateManager.m
+++ b/Sources/Sentry/SentryAppStateManager.m
@@ -7,6 +7,7 @@
#import
#import
#import
+#import
#import
#if SENTRY_HAS_UIKIT
@@ -24,6 +25,7 @@
@property (nonatomic, strong) id currentDate;
@property (nonatomic, strong) SentrySysctl *sysctl;
@property (nonatomic, strong) SentryDispatchQueueWrapper *dispatchQueue;
+@property (nonatomic, strong) SentryNSNotificationCenterWrapper *notificationCenterWrapper;
@property (nonatomic) NSInteger startCount;
@end
@@ -36,6 +38,7 @@ - (instancetype)initWithOptions:(SentryOptions *)options
currentDateProvider:(id)currentDateProvider
sysctl:(SentrySysctl *)sysctl
dispatchQueueWrapper:(SentryDispatchQueueWrapper *)dispatchQueueWrapper
+ notificationCenterWrapper:(SentryNSNotificationCenterWrapper *)notificationCenterWrapper
{
if (self = [super init]) {
self.options = options;
@@ -44,6 +47,7 @@ - (instancetype)initWithOptions:(SentryOptions *)options
self.currentDate = currentDateProvider;
self.sysctl = sysctl;
self.dispatchQueue = dispatchQueueWrapper;
+ self.notificationCenterWrapper = notificationCenterWrapper;
self.startCount = 0;
}
return self;
@@ -54,29 +58,24 @@ - (instancetype)initWithOptions:(SentryOptions *)options
- (void)start
{
if (self.startCount == 0) {
- [NSNotificationCenter.defaultCenter
+ [self.notificationCenterWrapper
addObserver:self
selector:@selector(didBecomeActive)
- name:SentryNSNotificationCenterWrapper.didBecomeActiveNotificationName
- object:nil];
+ name:SentryNSNotificationCenterWrapper.didBecomeActiveNotificationName];
- [NSNotificationCenter.defaultCenter
- addObserver:self
- selector:@selector(didBecomeActive)
- name:SentryHybridSdkDidBecomeActiveNotificationName
- object:nil];
+ [self.notificationCenterWrapper addObserver:self
+ selector:@selector(didBecomeActive)
+ name:SentryHybridSdkDidBecomeActiveNotificationName];
- [NSNotificationCenter.defaultCenter
+ [self.notificationCenterWrapper
addObserver:self
selector:@selector(willResignActive)
- name:SentryNSNotificationCenterWrapper.willResignActiveNotificationName
- object:nil];
+ name:SentryNSNotificationCenterWrapper.willResignActiveNotificationName];
- [NSNotificationCenter.defaultCenter
+ [self.notificationCenterWrapper
addObserver:self
selector:@selector(willTerminate)
- name:SentryNSNotificationCenterWrapper.willTerminateNotificationName
- object:nil];
+ name:SentryNSNotificationCenterWrapper.willTerminateNotificationName];
[self storeCurrentAppState];
}
@@ -85,35 +84,44 @@ - (void)start
}
- (void)stop
+{
+ [self stopWithForce:NO];
+}
+
+// forceStop is YES when the SDK gets closed
+- (void)stopWithForce:(BOOL)forceStop
{
if (self.startCount <= 0) {
return;
}
- self.startCount -= 1;
+ if (forceStop) {
+ [self
+ updateAppStateInBackground:^(SentryAppState *appState) { appState.isSDKRunning = NO; }];
+
+ self.startCount = 0;
+ } else {
+ self.startCount -= 1;
+ }
if (self.startCount == 0) {
// Remove the observers with the most specific detail possible, see
// https://developer.apple.com/documentation/foundation/nsnotificationcenter/1413994-removeobserver
- [NSNotificationCenter.defaultCenter
+ [self.notificationCenterWrapper
removeObserver:self
- name:SentryNSNotificationCenterWrapper.didBecomeActiveNotificationName
- object:nil];
+ name:SentryNSNotificationCenterWrapper.didBecomeActiveNotificationName];
- [NSNotificationCenter.defaultCenter
+ [self.notificationCenterWrapper
removeObserver:self
- name:SentryHybridSdkDidBecomeActiveNotificationName
- object:nil];
+ name:SentryHybridSdkDidBecomeActiveNotificationName];
- [NSNotificationCenter.defaultCenter
+ [self.notificationCenterWrapper
removeObserver:self
- name:SentryNSNotificationCenterWrapper.willResignActiveNotificationName
- object:nil];
+ name:SentryNSNotificationCenterWrapper.willResignActiveNotificationName];
- [NSNotificationCenter.defaultCenter
+ [self.notificationCenterWrapper
removeObserver:self
- name:SentryNSNotificationCenterWrapper.willTerminateNotificationName
- object:nil];
+ name:SentryNSNotificationCenterWrapper.willTerminateNotificationName];
}
}
@@ -121,7 +129,7 @@ - (void)dealloc
{
// In dealloc it's safe to unsubscribe for all, see
// https://developer.apple.com/documentation/foundation/nsnotificationcenter/1413994-removeobserver
- [NSNotificationCenter.defaultCenter removeObserver:self];
+ [self.notificationCenterWrapper removeObserver:self];
}
/**
diff --git a/Sources/Sentry/SentryClient.m b/Sources/Sentry/SentryClient.m
index 87427ab9d3..8e0b30019f 100644
--- a/Sources/Sentry/SentryClient.m
+++ b/Sources/Sentry/SentryClient.m
@@ -162,6 +162,7 @@ - (instancetype)initWithOptions:(SentryOptions *)options
timezone:(NSTimeZone *)timezone
{
if (self = [super init]) {
+ _isEnabled = YES;
self.options = options;
self.transportAdapter = transportAdapter;
self.fileManager = fileManager;
@@ -501,6 +502,12 @@ - (void)flush:(NSTimeInterval)timeout
[self.transportAdapter flush:timeout];
}
+- (void)close
+{
+ _isEnabled = NO;
+ [self flush:self.options.shutdownTimeInterval];
+}
+
- (SentryEvent *_Nullable)prepareEvent:(SentryEvent *)event
withScope:(SentryScope *)scope
alwaysAttachStacktrace:(BOOL)alwaysAttachStacktrace
@@ -632,7 +639,7 @@ - (BOOL)isSampled:(NSNumber *)sampleRate
- (BOOL)isDisabled
{
- return !self.options.enabled || nil == self.options.parsedDsn;
+ return !_isEnabled || !self.options.enabled || nil == self.options.parsedDsn;
}
- (void)logDisabledMessage
diff --git a/Sources/Sentry/SentryDependencyContainer.m b/Sources/Sentry/SentryDependencyContainer.m
index 17df37182b..1cf121063f 100644
--- a/Sources/Sentry/SentryDependencyContainer.m
+++ b/Sources/Sentry/SentryDependencyContainer.m
@@ -63,12 +63,13 @@ - (SentryAppStateManager *)appStateManager
if (_appStateManager == nil) {
SentryOptions *options = [[[SentrySDK currentHub] getClient] options];
_appStateManager = [[SentryAppStateManager alloc]
- initWithOptions:options
- crashWrapper:self.crashWrapper
- fileManager:self.fileManager
- currentDateProvider:[SentryDefaultCurrentDateProvider sharedInstance]
- sysctl:[[SentrySysctl alloc] init]
- dispatchQueueWrapper:self.dispatchQueueWrapper];
+ initWithOptions:options
+ crashWrapper:self.crashWrapper
+ fileManager:self.fileManager
+ currentDateProvider:[SentryDefaultCurrentDateProvider sharedInstance]
+ sysctl:[[SentrySysctl alloc] init]
+ dispatchQueueWrapper:self.dispatchQueueWrapper
+ notificationCenterWrapper:self.notificationCenterWrapper];
}
return _appStateManager;
}
diff --git a/Sources/Sentry/SentryHub.m b/Sources/Sentry/SentryHub.m
index 3b79664304..aa9bd29791 100644
--- a/Sources/Sentry/SentryHub.m
+++ b/Sources/Sentry/SentryHub.m
@@ -672,6 +672,11 @@ - (void)flush:(NSTimeInterval)timeout
}
}
+- (void)close
+{
+ [_client close];
+}
+
@end
NS_ASSUME_NONNULL_END
diff --git a/Sources/Sentry/SentryOptions.m b/Sources/Sentry/SentryOptions.m
index 4596cb6b0f..86c47bad49 100644
--- a/Sources/Sentry/SentryOptions.m
+++ b/Sources/Sentry/SentryOptions.m
@@ -47,6 +47,7 @@ - (instancetype)init
{
if (self = [super init]) {
self.enabled = YES;
+ self.shutdownTimeInterval = 2.0;
self.enableCrashHandler = YES;
self.diagnosticLevel = kSentryLevelDebug;
self.debug = NO;
diff --git a/Sources/Sentry/SentryOutOfMemoryLogic.m b/Sources/Sentry/SentryOutOfMemoryLogic.m
index 95fa5a4c1c..c0265dc965 100644
--- a/Sources/Sentry/SentryOutOfMemoryLogic.m
+++ b/Sources/Sentry/SentryOutOfMemoryLogic.m
@@ -44,7 +44,7 @@ - (BOOL)isOOM
SentryAppState *currentAppState = [self.appStateManager buildCurrentAppState];
// If there is no previous app state, we can't do anything.
- if (nil == previousAppState) {
+ if (previousAppState == nil) {
return NO;
}
@@ -84,6 +84,11 @@ - (BOOL)isOOM
return NO;
}
+ // The SDK wasn't running, so *any* crash after the SDK got closed would be seen as OOM.
+ if (!previousAppState.isSDKRunning) {
+ return NO;
+ }
+
// Was the app in foreground/active ?
// If the app was in background we can't reliably tell if it was an OOM or not.
if (!previousAppState.isActive) {
diff --git a/Sources/Sentry/SentrySDK.m b/Sources/Sentry/SentrySDK.m
index 2d036a9bb1..f4568f0b3f 100644
--- a/Sources/Sentry/SentrySDK.m
+++ b/Sources/Sentry/SentrySDK.m
@@ -1,6 +1,7 @@
#import "SentrySDK.h"
#import "PrivateSentrySDKOnly.h"
#import "SentryAppStartMeasurement.h"
+#import "SentryAppStateManager.h"
#import "SentryBreadcrumb.h"
#import "SentryClient+Private.h"
#import "SentryCrash.h"
@@ -403,9 +404,13 @@ + (void)close
}
[hub removeAllIntegrations];
- // close the client
- SentryClient *client = [hub getClient];
- client.options.enabled = NO;
+#if SENTRY_HAS_UIKIT
+ // force the AppStateManager to unsubscribe, see
+ // https://github.com/getsentry/sentry-cocoa/issues/2455
+ [[SentryDependencyContainer sharedInstance].appStateManager stopWithForce:YES];
+#endif
+
+ [hub close];
[hub bindClient:nil];
[SentrySDK setCurrentHub:nil];
diff --git a/Sources/Sentry/include/PrivateSentrySDKOnly.h b/Sources/Sentry/include/HybridPublic/PrivateSentrySDKOnly.h
similarity index 91%
rename from Sources/Sentry/include/PrivateSentrySDKOnly.h
rename to Sources/Sentry/include/HybridPublic/PrivateSentrySDKOnly.h
index b4ed92270f..6931448148 100644
--- a/Sources/Sentry/include/PrivateSentrySDKOnly.h
+++ b/Sources/Sentry/include/HybridPublic/PrivateSentrySDKOnly.h
@@ -1,11 +1,8 @@
-// We need this because if Sentry library is added as a Framework
-// the reference should be in the form of .
-// Otherwise, the reference is direct.
-#if __has_include()
-# import
-#else
-# import "SentryDefines.h"
-#endif
+#import "PrivatesHeader.h"
+#import "SentryAppStartMeasurement.h"
+#import "SentryEnvelope.h"
+#import "SentryEnvelopeItemType.h"
+#import "SentryScreenFrames.h"
@class SentryEnvelope, SentryDebugMeta, SentryAppStartMeasurement, SentryScreenFrames,
SentryOptions;
diff --git a/Sources/Sentry/include/HybridPublic/PrivatesHeader.h b/Sources/Sentry/include/HybridPublic/PrivatesHeader.h
new file mode 100644
index 0000000000..05bdfa7be9
--- /dev/null
+++ b/Sources/Sentry/include/HybridPublic/PrivatesHeader.h
@@ -0,0 +1,14 @@
+// We need this because if Sentry library is added as a Framework
+// the reference should be in the form of .
+// Otherwise, the reference is direct.
+#if __has_include()
+# import
+#else
+# import "SentryDefines.h"
+#endif
+
+#if __has_include()
+# import
+#else
+# import "SentryProfilingConditionals.h"
+#endif
diff --git a/Sources/Sentry/Public/SentryAppStartMeasurement.h b/Sources/Sentry/include/HybridPublic/SentryAppStartMeasurement.h
similarity index 98%
rename from Sources/Sentry/Public/SentryAppStartMeasurement.h
rename to Sources/Sentry/include/HybridPublic/SentryAppStartMeasurement.h
index f908e25b21..729da075e1 100644
--- a/Sources/Sentry/Public/SentryAppStartMeasurement.h
+++ b/Sources/Sentry/include/HybridPublic/SentryAppStartMeasurement.h
@@ -1,4 +1,4 @@
-#import "SentryDefines.h"
+#import "PrivatesHeader.h"
NS_ASSUME_NONNULL_BEGIN
diff --git a/Sources/Sentry/Public/SentryEnvelope.h b/Sources/Sentry/include/HybridPublic/SentryEnvelope.h
similarity index 99%
rename from Sources/Sentry/Public/SentryEnvelope.h
rename to Sources/Sentry/include/HybridPublic/SentryEnvelope.h
index e99f59447d..6f7aef795d 100644
--- a/Sources/Sentry/Public/SentryEnvelope.h
+++ b/Sources/Sentry/include/HybridPublic/SentryEnvelope.h
@@ -1,7 +1,6 @@
+#import "PrivatesHeader.h"
#import
-#import "SentryDefines.h"
-
@class SentryEvent, SentrySession, SentrySdkInfo, SentryId, SentryUserFeedback, SentryAttachment,
SentryTransaction, SentryTraceContext, SentryClientReport;
diff --git a/Sources/Sentry/Public/SentryEnvelopeItemType.h b/Sources/Sentry/include/HybridPublic/SentryEnvelopeItemType.h
similarity index 100%
rename from Sources/Sentry/Public/SentryEnvelopeItemType.h
rename to Sources/Sentry/include/HybridPublic/SentryEnvelopeItemType.h
diff --git a/Sources/Sentry/Public/SentryScreenFrames.h b/Sources/Sentry/include/HybridPublic/SentryScreenFrames.h
similarity index 96%
rename from Sources/Sentry/Public/SentryScreenFrames.h
rename to Sources/Sentry/include/HybridPublic/SentryScreenFrames.h
index ec182d69cd..9c64e51dad 100644
--- a/Sources/Sentry/Public/SentryScreenFrames.h
+++ b/Sources/Sentry/include/HybridPublic/SentryScreenFrames.h
@@ -1,5 +1,4 @@
-#import "SentryDefines.h"
-#import "SentryProfilingConditionals.h"
+#import "PrivatesHeader.h"
NS_ASSUME_NONNULL_BEGIN
diff --git a/Sources/Sentry/include/SentryAppState.h b/Sources/Sentry/include/SentryAppState.h
index d5e4a2bb32..1d099734fb 100644
--- a/Sources/Sentry/include/SentryAppState.h
+++ b/Sources/Sentry/include/SentryAppState.h
@@ -42,6 +42,8 @@ SENTRY_NO_INIT
@property (nonatomic, assign) BOOL isANROngoing;
+@property (nonatomic, assign) BOOL isSDKRunning;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/Sources/Sentry/include/SentryAppStateManager.h b/Sources/Sentry/include/SentryAppStateManager.h
index d50ab4ff1a..c1cb0017d1 100644
--- a/Sources/Sentry/include/SentryAppStateManager.h
+++ b/Sources/Sentry/include/SentryAppStateManager.h
@@ -2,24 +2,28 @@
#import "SentryDefines.h"
@class SentryOptions, SentryCrashWrapper, SentryAppState, SentryFileManager, SentrySysctl,
- SentryDispatchQueueWrapper;
+ SentryDispatchQueueWrapper, SentryNSNotificationCenterWrapper;
NS_ASSUME_NONNULL_BEGIN
@interface SentryAppStateManager : NSObject
SENTRY_NO_INIT
+@property (nonatomic, readonly) NSInteger startCount;
+
- (instancetype)initWithOptions:(SentryOptions *)options
crashWrapper:(SentryCrashWrapper *)crashWrapper
fileManager:(SentryFileManager *)fileManager
currentDateProvider:(id)currentDateProvider
sysctl:(SentrySysctl *)sysctl
- dispatchQueueWrapper:(SentryDispatchQueueWrapper *)dispatchQueueWrapper;
+ dispatchQueueWrapper:(SentryDispatchQueueWrapper *)dispatchQueueWrapper
+ notificationCenterWrapper:(SentryNSNotificationCenterWrapper *)notificationCenterWrapper;
#if SENTRY_HAS_UIKIT
- (void)start;
- (void)stop;
+- (void)stopWithForce:(BOOL)forceStop;
/**
* Builds the current app state.
diff --git a/Sources/SentryCrash/Recording/Tools/SentryCrashJSONCodec.h b/Sources/SentryCrash/Recording/Tools/SentryCrashJSONCodec.h
index fedb3bf96a..11212e335d 100644
--- a/Sources/SentryCrash/Recording/Tools/SentryCrashJSONCodec.h
+++ b/Sources/SentryCrash/Recording/Tools/SentryCrashJSONCodec.h
@@ -42,7 +42,7 @@ extern "C" {
*/
#define SentryCrashJSON_SIZE_AUTOMATIC -1
-#define SentryCrashMAX_STRINGBUFFERSIZE 100000
+#define SentryCrashMAX_STRINGBUFFERSIZE 150000
enum {
/** Encoding or decoding: Everything completed without error */
diff --git a/Tests/SentryTests/Helper/SentryAppStateManagerTests.swift b/Tests/SentryTests/Helper/SentryAppStateManagerTests.swift
index ac98454fa9..62bec16744 100644
--- a/Tests/SentryTests/Helper/SentryAppStateManagerTests.swift
+++ b/Tests/SentryTests/Helper/SentryAppStateManagerTests.swift
@@ -11,6 +11,7 @@ class SentryAppStateManagerTests: XCTestCase {
let fileManager: SentryFileManager
let currentDate = TestCurrentDateProvider()
let dispatchQueue = TestSentryDispatchQueueWrapper()
+ let notificationCenterWrapper = TestNSNotificationCenterWrapper()
init() {
options = Options()
@@ -27,7 +28,8 @@ class SentryAppStateManagerTests: XCTestCase {
fileManager: fileManager,
currentDateProvider: currentDate,
sysctl: TestSysctl(),
- dispatchQueueWrapper: TestSentryDispatchQueueWrapper()
+ dispatchQueueWrapper: TestSentryDispatchQueueWrapper(),
+ notificationCenterWrapper: notificationCenterWrapper
)
}
}
@@ -76,6 +78,34 @@ class SentryAppStateManagerTests: XCTestCase {
XCTAssertNotNil(fixture.fileManager.readAppState())
}
+ func testStopUpdatesAppState() {
+ sut.start()
+
+ let stateBeforeStop = fixture.fileManager.readAppState()
+ XCTAssertTrue(stateBeforeStop!.isSDKRunning)
+
+ sut.stop(withForce: true)
+
+ let stateAfterStop = fixture.fileManager.readAppState()
+ XCTAssertFalse(stateAfterStop!.isSDKRunning)
+ }
+
+ func testForcedStop() {
+ XCTAssertNil(fixture.fileManager.readAppState())
+
+ sut.start()
+ sut.start()
+ sut.start()
+
+ sut.stop()
+ XCTAssertEqual(sut.startCount, 2)
+
+ sut.stop(withForce: true)
+ XCTAssertEqual(sut.startCount, 0)
+
+ XCTAssertEqual(fixture.notificationCenterWrapper.removeObserverWithNameInvocations.count, 4)
+ }
+
func testUpdateAppState() {
sut.storeCurrentAppState()
diff --git a/Tests/SentryTests/Helper/SentryAppStateTests.swift b/Tests/SentryTests/Helper/SentryAppStateTests.swift
index 9bb07cb3ad..2d54d0b568 100644
--- a/Tests/SentryTests/Helper/SentryAppStateTests.swift
+++ b/Tests/SentryTests/Helper/SentryAppStateTests.swift
@@ -14,6 +14,7 @@ class SentryAppStateTests: XCTestCase {
XCTAssertEqual(appState.isActive, actual["is_active"] as? Bool)
XCTAssertEqual(appState.wasTerminated, actual["was_terminated"] as? Bool)
XCTAssertEqual(appState.isANROngoing, actual["is_anr_ongoing"] as? Bool)
+ XCTAssertEqual(appState.isSDKRunning, actual["is_sdk_running"] as? Bool)
}
func testInitWithJSON_AllFields() {
@@ -26,7 +27,8 @@ class SentryAppStateTests: XCTestCase {
"system_boot_timestamp": (appState.systemBootTimestamp as NSDate).sentry_toIso8601String(),
"is_active": appState.isActive,
"was_terminated": appState.wasTerminated,
- "is_anr_ongoing": appState.isANROngoing
+ "is_anr_ongoing": appState.isANROngoing,
+ "is_sdk_running": appState.isSDKRunning
] as [String: Any]
let actual = SentryAppState(jsonObject: dict)
diff --git a/Tests/SentryTests/Helper/TestNSNotificationCenterWrapper.swift b/Tests/SentryTests/Helper/TestNSNotificationCenterWrapper.swift
index 81289540ce..1d9fc0e2f6 100644
--- a/Tests/SentryTests/Helper/TestNSNotificationCenterWrapper.swift
+++ b/Tests/SentryTests/Helper/TestNSNotificationCenterWrapper.swift
@@ -1,25 +1,20 @@
import Foundation
@objc public class TestNSNotificationCenterWrapper: SentryNSNotificationCenterWrapper {
-
var addObserverInvocations = Invocations<(observer: Any, selector: Selector, name: NSNotification.Name)>()
@objc public var addObserverInvocationsCount: Int {
return addObserverInvocations.count
}
-
+
public override func addObserver(_ observer: Any, selector aSelector: Selector, name aName: NSNotification.Name) {
addObserverInvocations.record((observer, aSelector, aName))
}
-
- var addObserverWithNotificationInvocations = Invocations<(observer: Any, name: NSNotification.Name)>()
- @objc public var removeWithNotificationInvocationsCount: Int {
- return addObserverWithNotificationInvocations.count
- }
-
+
+ var removeObserverWithNameInvocations = Invocations<(observer: Any, name: NSNotification.Name)>()
public override func removeObserver(_ observer: Any, name aName: NSNotification.Name) {
- addObserverWithNotificationInvocations.record((observer, aName))
+ removeObserverWithNameInvocations.record((observer, aName))
}
-
+
var removeObserverInvocations = Invocations()
public override func removeObserver(_ observer: Any) {
removeObserverInvocations.record(observer)
diff --git a/Tests/SentryTests/Integrations/OutOfMemory/SentryOutOfMemoryTrackerTests.swift b/Tests/SentryTests/Integrations/OutOfMemory/SentryOutOfMemoryTrackerTests.swift
index 05ea929fdf..a6c9d56ee6 100644
--- a/Tests/SentryTests/Integrations/OutOfMemory/SentryOutOfMemoryTrackerTests.swift
+++ b/Tests/SentryTests/Integrations/OutOfMemory/SentryOutOfMemoryTrackerTests.swift
@@ -36,9 +36,27 @@ class SentryOutOfMemoryTrackerTests: NotificationCenterTestCase {
}
func getSut(fileManager: SentryFileManager) -> SentryOutOfMemoryTracker {
- let appStateManager = SentryAppStateManager(options: options, crashWrapper: crashWrapper, fileManager: fileManager, currentDateProvider: currentDate, sysctl: sysctl, dispatchQueueWrapper: self.dispatchQueue)
- let logic = SentryOutOfMemoryLogic(options: options, crashAdapter: crashWrapper, appStateManager: appStateManager)
- return SentryOutOfMemoryTracker(options: options, outOfMemoryLogic: logic, appStateManager: appStateManager, dispatchQueueWrapper: dispatchQueue, fileManager: fileManager)
+ let appStateManager = SentryAppStateManager(
+ options: options,
+ crashWrapper: crashWrapper,
+ fileManager: fileManager,
+ currentDateProvider: currentDate,
+ sysctl: sysctl,
+ dispatchQueueWrapper: self.dispatchQueue,
+ notificationCenterWrapper: SentryNSNotificationCenterWrapper()
+ )
+ let logic = SentryOutOfMemoryLogic(
+ options: options,
+ crashAdapter: crashWrapper,
+ appStateManager: appStateManager
+ )
+ return SentryOutOfMemoryTracker(
+ options: options,
+ outOfMemoryLogic: logic,
+ appStateManager: appStateManager,
+ dispatchQueueWrapper: dispatchQueue,
+ fileManager: fileManager
+ )
}
}
@@ -169,7 +187,16 @@ class SentryOutOfMemoryTrackerTests: NotificationCenterTestCase {
assertNoOOMSent()
}
-
+
+ func testSDKWasClosed_NoOOM() {
+ let appState = SentryAppState(releaseName: TestData.appState.releaseName, osVersion: UIDevice.current.systemVersion, vendorId: TestData.someUUID, isDebugging: false, systemBootTimestamp: fixture.currentDate.date())
+ appState.isSDKRunning = false
+
+ givenPreviousAppState(appState: appState)
+ sut.start()
+ assertNoOOMSent()
+ }
+
func testAppWasInBackground_NoOOM() {
sut.start()
goToForeground()
diff --git a/Tests/SentryTests/Integrations/Performance/AppStartTracking/SentryAppStartTrackerTests.swift b/Tests/SentryTests/Integrations/Performance/AppStartTracking/SentryAppStartTrackerTests.swift
index 25cdf277a6..21557232de 100644
--- a/Tests/SentryTests/Integrations/Performance/AppStartTracking/SentryAppStartTrackerTests.swift
+++ b/Tests/SentryTests/Integrations/Performance/AppStartTracking/SentryAppStartTrackerTests.swift
@@ -29,7 +29,15 @@ class SentryAppStartTrackerTests: NotificationCenterTestCase {
fileManager = try! SentryFileManager(options: options, andCurrentDateProvider: currentDate, dispatchQueueWrapper: dispatchQueue)
- appStateManager = SentryAppStateManager(options: options, crashWrapper: crashWrapper, fileManager: fileManager, currentDateProvider: currentDate, sysctl: sysctl, dispatchQueueWrapper: dispatchQueue)
+ appStateManager = SentryAppStateManager(
+ options: options,
+ crashWrapper: crashWrapper,
+ fileManager: fileManager,
+ currentDateProvider: currentDate,
+ sysctl: sysctl,
+ dispatchQueueWrapper: dispatchQueue,
+ notificationCenterWrapper: SentryNSNotificationCenterWrapper()
+ )
runtimeInitTimestamp = currentDate.date().addingTimeInterval(0.2)
moduleInitializationTimestamp = currentDate.date().addingTimeInterval(0.1)
@@ -37,7 +45,13 @@ class SentryAppStartTrackerTests: NotificationCenterTestCase {
}
var sut: SentryAppStartTracker {
- let sut = SentryAppStartTracker(currentDateProvider: currentDate, dispatchQueueWrapper: TestSentryDispatchQueueWrapper(), appStateManager: appStateManager, sysctl: sysctl, enablePreWarmedAppStartTracing: enablePreWarmedAppStartTracing)
+ let sut = SentryAppStartTracker(
+ currentDateProvider: currentDate,
+ dispatchQueueWrapper: TestSentryDispatchQueueWrapper(),
+ appStateManager: appStateManager,
+ sysctl: sysctl,
+ enablePreWarmedAppStartTracing: enablePreWarmedAppStartTracing
+ )
return sut
}
}
diff --git a/Tests/SentryTests/Integrations/Session/SentrySessionTrackerTests.swift b/Tests/SentryTests/Integrations/Session/SentrySessionTrackerTests.swift
index ad4060b447..c9b42f0777 100644
--- a/Tests/SentryTests/Integrations/Session/SentrySessionTrackerTests.swift
+++ b/Tests/SentryTests/Integrations/Session/SentrySessionTrackerTests.swift
@@ -353,7 +353,7 @@ class SentrySessionTrackerTests: XCTestCase {
func testStop_RemovesObservers() {
sut.stop()
- let invocations = fixture.notificationCenter.addObserverWithNotificationInvocations
+ let invocations = fixture.notificationCenter.removeObserverWithNameInvocations
let notificationNames = invocations.invocations.map { $0.name }
assertNotificationNames(notificationNames)
diff --git a/Tests/SentryTests/SentryClientTests.swift b/Tests/SentryTests/SentryClientTests.swift
index a8565d305f..86236d71db 100644
--- a/Tests/SentryTests/SentryClientTests.swift
+++ b/Tests/SentryTests/SentryClientTests.swift
@@ -134,6 +134,10 @@ class SentryClientTest: XCTestCase {
clearTestState()
}
+ func testClientIsEnabled() {
+ XCTAssertTrue(fixture.getSut().isEnabled)
+ }
+
func testCaptureMessage() {
let eventId = fixture.getSut().capture(message: fixture.messageAsString)
diff --git a/Tests/SentryTests/SentryCrash/SentryCrashInstallationTests.m b/Tests/SentryTests/SentryCrash/SentryCrashInstallationTests.m
index 31916f58df..df94165d16 100644
--- a/Tests/SentryTests/SentryCrash/SentryCrashInstallationTests.m
+++ b/Tests/SentryTests/SentryCrash/SentryCrashInstallationTests.m
@@ -62,7 +62,7 @@ - (void)testUninstall_CallsRemoveObservers
[installation uninstall];
#if SentryCrashCRASH_HAS_UIAPPLICATION
- XCTAssertEqual(5, self.notificationCenter.removeWithNotificationInvocationsCount);
+ XCTAssertEqual(5, self.notificationCenter.removeObserverWithNameInvocations.count);
#endif
}
@@ -95,7 +95,7 @@ - (void)testUninstall_Install
crashHandlerDataAfterInstall:crashHandlerDataAfterInstall];
#if SentryCrashCRASH_HAS_UIAPPLICATION
- XCTAssertEqual(55, self.notificationCenter.removeWithNotificationInvocationsCount);
+ XCTAssertEqual(55, self.notificationCenter.removeObserverWithNameInvocations.count);
#endif
}
diff --git a/Tests/SentryTests/SentryOptionsTest.m b/Tests/SentryTests/SentryOptionsTest.m
index a24e5fba9f..380c80063e 100644
--- a/Tests/SentryTests/SentryOptionsTest.m
+++ b/Tests/SentryTests/SentryOptionsTest.m
@@ -78,6 +78,7 @@ - (void)testEmptyConstructorSetsDefaultValues
- (void)assertDefaultValues:(SentryOptions *)options
{
XCTAssertEqual(YES, options.enabled);
+ XCTAssertEqual(2.0, options.shutdownTimeInterval);
XCTAssertEqual(NO, options.debug);
XCTAssertEqual(kSentryLevelDebug, options.diagnosticLevel);
XCTAssertEqual(options.environment, kSentryDefaultEnvironment);
diff --git a/Tests/SentryTests/SentrySDKTests.swift b/Tests/SentryTests/SentrySDKTests.swift
index 2012647357..e745b40ab6 100644
--- a/Tests/SentryTests/SentrySDKTests.swift
+++ b/Tests/SentryTests/SentrySDKTests.swift
@@ -492,6 +492,67 @@ class SentrySDKTests: XCTestCase {
XCTAssertEqual(0, hub.installedIntegrations.count)
assertIntegrationsInstalled(integrations: [])
}
+
+#if SENTRY_HAS_UIKIT
+ func testClose_StopsAppStateManager() {
+ SentrySDK.start { options in
+ options.dsn = SentrySDKTests.dsnAsString
+ options.tracesSampleRate = 1
+ }
+
+ let appStateManager = SentryDependencyContainer.sharedInstance().appStateManager
+ XCTAssertEqual(appStateManager.startCount, 1)
+
+ SentrySDK.start { options in
+ options.dsn = SentrySDKTests.dsnAsString
+ options.tracesSampleRate = 1
+ }
+
+ XCTAssertEqual(appStateManager.startCount, 2)
+
+ SentrySDK.close()
+
+ XCTAssertEqual(appStateManager.startCount, 0)
+
+ let stateAfterStop = fixture.fileManager.readAppState()
+ XCTAssertFalse(stateAfterStop!.isSDKRunning)
+ }
+#endif
+
+ func testClose_SetsClientToNil() {
+ SentrySDK.start { options in
+ options.dsn = SentrySDKTests.dsnAsString
+ }
+
+ SentrySDK.close()
+
+ XCTAssertNil(SentrySDK.currentHub().client())
+ }
+
+ func testClose_ClosesClient() {
+ SentrySDK.start { options in
+ options.dsn = SentrySDKTests.dsnAsString
+ }
+
+ let client = SentrySDK.currentHub().client()
+ SentrySDK.close()
+
+ XCTAssertFalse(client?.isEnabled ?? true)
+ }
+
+ func testClose_CallsFlushCorrectlyOnTransport() {
+ SentrySDK.start { options in
+ options.dsn = SentrySDKTests.dsnAsString
+ }
+
+ let transport = TestTransport()
+ let client = SentryClient(options: fixture.options)
+ Dynamic(client).transportAdapter = TestTransportAdapter(transport: transport, options: fixture.options)
+ SentrySDK.currentHub().bindClient(client)
+ SentrySDK.close()
+
+ XCTAssertEqual(Options().shutdownTimeInterval, transport.flushInvocations.first)
+ }
func testFlush_CallsFlushCorrectlyOnTransport() {
SentrySDK.start { options in
diff --git a/scripts/xcode-test.sh b/scripts/xcode-test.sh
index 08ed9f176b..5f4a35a09f 100755
--- a/scripts/xcode-test.sh
+++ b/scripts/xcode-test.sh
@@ -65,10 +65,10 @@ if [ $PLATFORM == "iOS" -a $OS == "12.4" ]; then
GCC_GENERATE_TEST_COVERAGE_FILES=YES GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES -destination "$DESTINATION" \
-skip-testing:"SentryTests/SentrySDKTests/testMemoryFootprintOfAddingBreadcrumbs" \
-skip-testing:"SentryTests/SentrySDKTests/testMemoryFootprintOfTransactions" \
- test | tee raw-test-output.log | $RUBY_ENV_ARGS xcpretty -t && exit ${PIPESTATUS[0]}
+ test | tee raw-test-output.log | $RUBY_ENV_ARGS xcpretty -t -r junit && exit ${PIPESTATUS[0]}
else
env NSUnbufferedIO=YES xcodebuild -workspace Sentry.xcworkspace \
-scheme Sentry -configuration $CONFIGURATION \
GCC_GENERATE_TEST_COVERAGE_FILES=YES GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES -destination "$DESTINATION" \
- test | tee raw-test-output.log | $RUBY_ENV_ARGS xcpretty -t && exit ${PIPESTATUS[0]}
+ test | tee raw-test-output.log | $RUBY_ENV_ARGS xcpretty -t -r junit && exit ${PIPESTATUS[0]}
fi