From 730983748f4ca83b4785c1c5ac2e8671cfa005ad Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Sat, 30 Jul 2022 11:52:36 -0700 Subject: [PATCH 01/25] Move Android to Platforms folder --- .../{ => Platforms}/Android/AndroidEventProcessor.cs | 0 src/Sentry/{ => Platforms}/Android/AndroidScopeObserver.cs | 0 .../Android/Callbacks/BeforeBreadcrumbCallback.cs | 0 .../Android/Callbacks/BeforeSendCallback.cs | 0 .../Android/Callbacks/OptionsConfigurationCallback.cs | 0 .../Android/Callbacks/TracesSamplerCallback.cs | 0 .../Android/Extensions/BreadcrumbExtensions.cs | 0 .../{ => Platforms}/Android/Extensions/DeviceExtensions.cs | 0 .../{ => Platforms}/Android/Extensions/EnumExtensions.cs | 0 .../{ => Platforms}/Android/Extensions/JavaExtensions.cs | 0 .../{ => Platforms}/Android/Extensions/MiscExtensions.cs | 0 .../Android/Extensions/OperatingSystemExtensions.cs | 0 .../Android/Extensions/SamplingContextExtensions.cs | 0 .../Android/Extensions/SentryEventExtensions.cs | 0 .../{ => Platforms}/Android/Extensions/UserExtensions.cs | 0 .../Android/Facades/TransactionContextFacade.cs | 0 src/Sentry/{ => Platforms}/Android/JavaLogger.cs | 0 src/Sentry/{ => Platforms}/Android/Sentry.Android.props | 6 +++--- src/Sentry/{ => Platforms}/Android/SentryOptions.cs | 0 src/Sentry/{ => Platforms}/Android/SentrySdk.cs | 0 src/Sentry/{ => Platforms}/Android/Transforms/Metadata.xml | 0 src/Sentry/Sentry.csproj | 7 ++++--- src/Sentry/Sentry.csproj.DotSettings | 2 ++ 23 files changed, 9 insertions(+), 6 deletions(-) rename src/Sentry/{ => Platforms}/Android/AndroidEventProcessor.cs (100%) rename src/Sentry/{ => Platforms}/Android/AndroidScopeObserver.cs (100%) rename src/Sentry/{ => Platforms}/Android/Callbacks/BeforeBreadcrumbCallback.cs (100%) rename src/Sentry/{ => Platforms}/Android/Callbacks/BeforeSendCallback.cs (100%) rename src/Sentry/{ => Platforms}/Android/Callbacks/OptionsConfigurationCallback.cs (100%) rename src/Sentry/{ => Platforms}/Android/Callbacks/TracesSamplerCallback.cs (100%) rename src/Sentry/{ => Platforms}/Android/Extensions/BreadcrumbExtensions.cs (100%) rename src/Sentry/{ => Platforms}/Android/Extensions/DeviceExtensions.cs (100%) rename src/Sentry/{ => Platforms}/Android/Extensions/EnumExtensions.cs (100%) rename src/Sentry/{ => Platforms}/Android/Extensions/JavaExtensions.cs (100%) rename src/Sentry/{ => Platforms}/Android/Extensions/MiscExtensions.cs (100%) rename src/Sentry/{ => Platforms}/Android/Extensions/OperatingSystemExtensions.cs (100%) rename src/Sentry/{ => Platforms}/Android/Extensions/SamplingContextExtensions.cs (100%) rename src/Sentry/{ => Platforms}/Android/Extensions/SentryEventExtensions.cs (100%) rename src/Sentry/{ => Platforms}/Android/Extensions/UserExtensions.cs (100%) rename src/Sentry/{ => Platforms}/Android/Facades/TransactionContextFacade.cs (100%) rename src/Sentry/{ => Platforms}/Android/JavaLogger.cs (100%) rename src/Sentry/{ => Platforms}/Android/Sentry.Android.props (94%) rename src/Sentry/{ => Platforms}/Android/SentryOptions.cs (100%) rename src/Sentry/{ => Platforms}/Android/SentrySdk.cs (100%) rename src/Sentry/{ => Platforms}/Android/Transforms/Metadata.xml (100%) create mode 100644 src/Sentry/Sentry.csproj.DotSettings diff --git a/src/Sentry/Android/AndroidEventProcessor.cs b/src/Sentry/Platforms/Android/AndroidEventProcessor.cs similarity index 100% rename from src/Sentry/Android/AndroidEventProcessor.cs rename to src/Sentry/Platforms/Android/AndroidEventProcessor.cs diff --git a/src/Sentry/Android/AndroidScopeObserver.cs b/src/Sentry/Platforms/Android/AndroidScopeObserver.cs similarity index 100% rename from src/Sentry/Android/AndroidScopeObserver.cs rename to src/Sentry/Platforms/Android/AndroidScopeObserver.cs diff --git a/src/Sentry/Android/Callbacks/BeforeBreadcrumbCallback.cs b/src/Sentry/Platforms/Android/Callbacks/BeforeBreadcrumbCallback.cs similarity index 100% rename from src/Sentry/Android/Callbacks/BeforeBreadcrumbCallback.cs rename to src/Sentry/Platforms/Android/Callbacks/BeforeBreadcrumbCallback.cs diff --git a/src/Sentry/Android/Callbacks/BeforeSendCallback.cs b/src/Sentry/Platforms/Android/Callbacks/BeforeSendCallback.cs similarity index 100% rename from src/Sentry/Android/Callbacks/BeforeSendCallback.cs rename to src/Sentry/Platforms/Android/Callbacks/BeforeSendCallback.cs diff --git a/src/Sentry/Android/Callbacks/OptionsConfigurationCallback.cs b/src/Sentry/Platforms/Android/Callbacks/OptionsConfigurationCallback.cs similarity index 100% rename from src/Sentry/Android/Callbacks/OptionsConfigurationCallback.cs rename to src/Sentry/Platforms/Android/Callbacks/OptionsConfigurationCallback.cs diff --git a/src/Sentry/Android/Callbacks/TracesSamplerCallback.cs b/src/Sentry/Platforms/Android/Callbacks/TracesSamplerCallback.cs similarity index 100% rename from src/Sentry/Android/Callbacks/TracesSamplerCallback.cs rename to src/Sentry/Platforms/Android/Callbacks/TracesSamplerCallback.cs diff --git a/src/Sentry/Android/Extensions/BreadcrumbExtensions.cs b/src/Sentry/Platforms/Android/Extensions/BreadcrumbExtensions.cs similarity index 100% rename from src/Sentry/Android/Extensions/BreadcrumbExtensions.cs rename to src/Sentry/Platforms/Android/Extensions/BreadcrumbExtensions.cs diff --git a/src/Sentry/Android/Extensions/DeviceExtensions.cs b/src/Sentry/Platforms/Android/Extensions/DeviceExtensions.cs similarity index 100% rename from src/Sentry/Android/Extensions/DeviceExtensions.cs rename to src/Sentry/Platforms/Android/Extensions/DeviceExtensions.cs diff --git a/src/Sentry/Android/Extensions/EnumExtensions.cs b/src/Sentry/Platforms/Android/Extensions/EnumExtensions.cs similarity index 100% rename from src/Sentry/Android/Extensions/EnumExtensions.cs rename to src/Sentry/Platforms/Android/Extensions/EnumExtensions.cs diff --git a/src/Sentry/Android/Extensions/JavaExtensions.cs b/src/Sentry/Platforms/Android/Extensions/JavaExtensions.cs similarity index 100% rename from src/Sentry/Android/Extensions/JavaExtensions.cs rename to src/Sentry/Platforms/Android/Extensions/JavaExtensions.cs diff --git a/src/Sentry/Android/Extensions/MiscExtensions.cs b/src/Sentry/Platforms/Android/Extensions/MiscExtensions.cs similarity index 100% rename from src/Sentry/Android/Extensions/MiscExtensions.cs rename to src/Sentry/Platforms/Android/Extensions/MiscExtensions.cs diff --git a/src/Sentry/Android/Extensions/OperatingSystemExtensions.cs b/src/Sentry/Platforms/Android/Extensions/OperatingSystemExtensions.cs similarity index 100% rename from src/Sentry/Android/Extensions/OperatingSystemExtensions.cs rename to src/Sentry/Platforms/Android/Extensions/OperatingSystemExtensions.cs diff --git a/src/Sentry/Android/Extensions/SamplingContextExtensions.cs b/src/Sentry/Platforms/Android/Extensions/SamplingContextExtensions.cs similarity index 100% rename from src/Sentry/Android/Extensions/SamplingContextExtensions.cs rename to src/Sentry/Platforms/Android/Extensions/SamplingContextExtensions.cs diff --git a/src/Sentry/Android/Extensions/SentryEventExtensions.cs b/src/Sentry/Platforms/Android/Extensions/SentryEventExtensions.cs similarity index 100% rename from src/Sentry/Android/Extensions/SentryEventExtensions.cs rename to src/Sentry/Platforms/Android/Extensions/SentryEventExtensions.cs diff --git a/src/Sentry/Android/Extensions/UserExtensions.cs b/src/Sentry/Platforms/Android/Extensions/UserExtensions.cs similarity index 100% rename from src/Sentry/Android/Extensions/UserExtensions.cs rename to src/Sentry/Platforms/Android/Extensions/UserExtensions.cs diff --git a/src/Sentry/Android/Facades/TransactionContextFacade.cs b/src/Sentry/Platforms/Android/Facades/TransactionContextFacade.cs similarity index 100% rename from src/Sentry/Android/Facades/TransactionContextFacade.cs rename to src/Sentry/Platforms/Android/Facades/TransactionContextFacade.cs diff --git a/src/Sentry/Android/JavaLogger.cs b/src/Sentry/Platforms/Android/JavaLogger.cs similarity index 100% rename from src/Sentry/Android/JavaLogger.cs rename to src/Sentry/Platforms/Android/JavaLogger.cs diff --git a/src/Sentry/Android/Sentry.Android.props b/src/Sentry/Platforms/Android/Sentry.Android.props similarity index 94% rename from src/Sentry/Android/Sentry.Android.props rename to src/Sentry/Platforms/Android/Sentry.Android.props index 61ffb3c8f5..d139087d3f 100644 --- a/src/Sentry/Android/Sentry.Android.props +++ b/src/Sentry/Platforms/Android/Sentry.Android.props @@ -11,8 +11,8 @@ - - + + @@ -20,7 +20,7 @@ - + diff --git a/src/Sentry/Android/SentryOptions.cs b/src/Sentry/Platforms/Android/SentryOptions.cs similarity index 100% rename from src/Sentry/Android/SentryOptions.cs rename to src/Sentry/Platforms/Android/SentryOptions.cs diff --git a/src/Sentry/Android/SentrySdk.cs b/src/Sentry/Platforms/Android/SentrySdk.cs similarity index 100% rename from src/Sentry/Android/SentrySdk.cs rename to src/Sentry/Platforms/Android/SentrySdk.cs diff --git a/src/Sentry/Android/Transforms/Metadata.xml b/src/Sentry/Platforms/Android/Transforms/Metadata.xml similarity index 100% rename from src/Sentry/Android/Transforms/Metadata.xml rename to src/Sentry/Platforms/Android/Transforms/Metadata.xml diff --git a/src/Sentry/Sentry.csproj b/src/Sentry/Sentry.csproj index 835a24758e..055af6a1e7 100644 --- a/src/Sentry/Sentry.csproj +++ b/src/Sentry/Sentry.csproj @@ -7,8 +7,8 @@ Official SDK for Sentry - Open-source error tracking that helps developers monitor and fix crashes in real time. $(NoWarn);RS0017 $(AdditionalConstants) - - $(DefaultItemExcludes);$(MSBuildProjectDirectory)\Android\** + + $(DefaultItemExcludes);$(MSBuildProjectDirectory)\Platforms\** @@ -19,7 +19,8 @@ netstandard2.0 - + + diff --git a/src/Sentry/Sentry.csproj.DotSettings b/src/Sentry/Sentry.csproj.DotSettings new file mode 100644 index 0000000000..66cee506d2 --- /dev/null +++ b/src/Sentry/Sentry.csproj.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file From a2d7fd05b63b36c60c604c6d3fefc3896c29c511 Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Sat, 30 Jul 2022 11:55:42 -0700 Subject: [PATCH 02/25] Add iOS platform --- .../Platforms/iOS/Bindings/ApiDefinitions.cs | 2037 +++++++++++++++++ .../Platforms/iOS/Bindings/StructsAndEnums.cs | 98 + src/Sentry/Platforms/iOS/Sentry.iOS.props | 57 + src/Sentry/Platforms/iOS/SentryOptions.cs | 19 + src/Sentry/Platforms/iOS/SentrySdk.cs | 6 + src/Sentry/Properties/AssemblyInfo.cs | 7 +- src/Sentry/Sentry.csproj | 3 + 7 files changed, 2224 insertions(+), 3 deletions(-) create mode 100644 src/Sentry/Platforms/iOS/Bindings/ApiDefinitions.cs create mode 100644 src/Sentry/Platforms/iOS/Bindings/StructsAndEnums.cs create mode 100644 src/Sentry/Platforms/iOS/Sentry.iOS.props create mode 100644 src/Sentry/Platforms/iOS/SentryOptions.cs create mode 100644 src/Sentry/Platforms/iOS/SentrySdk.cs diff --git a/src/Sentry/Platforms/iOS/Bindings/ApiDefinitions.cs b/src/Sentry/Platforms/iOS/Bindings/ApiDefinitions.cs new file mode 100644 index 0000000000..e120275f69 --- /dev/null +++ b/src/Sentry/Platforms/iOS/Bindings/ApiDefinitions.cs @@ -0,0 +1,2037 @@ +using System; +using Foundation; +using ObjCRuntime; +using Sentry; + +namespace Sentry.Cocoa; + +[Static] +[Internal] +interface Constants +{ + // extern double SentryVersionNumber; + [Field ("SentryVersionNumber", "__Internal")] + double SentryVersionNumber { get; } + + // extern const unsigned char[] SentryVersionString; + [Field ("SentryVersionString", "__Internal")] + [return: PlainString] + NSString SentryVersionString { get; } + + // extern NSString *const _Nonnull SentryErrorDomain __attribute__((visibility("default"))); + [Field ("SentryErrorDomain", "__Internal")] + NSString SentryErrorDomain { get; } +} + +// Xamarin bug: Delegate types don't honor the [Internal] attribute. +// Workaround by using Func or Action instead. +// See: https://github.com/xamarin/xamarin-macios/issues/15299 +// Leaving code commented here so we can more easily go back when the issue is fixed. + +// // typedef void (^SentryRequestFinished)(NSError * _Nullable); +// [Internal] +// delegate void SentryRequestFinished ([NullAllowed] NSError arg0); + +// // typedef void (^SentryRequestOperationFinished)(NSHTTPURLResponse * _Nullable, NSError * _Nullable); +// [Internal] +// delegate void SentryRequestOperationFinished ([NullAllowed] NSHttpUrlResponse arg0, [NullAllowed] NSError arg1); + +// // typedef SentryBreadcrumb * _Nullable (^SentryBeforeBreadcrumbCallback)(SentryBreadcrumb * _Nonnull); +// [Internal] +// delegate SentryBreadcrumb SentryBeforeBreadcrumbCallback (SentryBreadcrumb arg0); + +// // typedef SentryEvent * _Nullable (^SentryBeforeSendEventCallback)(SentryEvent * _Nonnull); +// [Internal] +// delegate SentryEvent SentryBeforeSendEventCallback (SentryEvent arg0); + +// // typedef void (^SentryOnCrashedLastRunCallback)(SentryEvent * _Nonnull); +// [Internal] +// delegate void SentryOnCrashedLastRunCallback (SentryEvent arg0); + +// // typedef BOOL (^SentryShouldQueueEvent)(NSHTTPURLResponse * _Nullable, NSError * _Nullable); +// [Internal] +// delegate bool SentryShouldQueueEvent ([NullAllowed] NSHttpUrlResponse arg0, [NullAllowed] NSError arg1); + +// // typedef NSNumber * _Nullable (^SentryTracesSamplerCallback)(SentrySamplingContext * _Nonnull); +// [Internal] +// delegate NSNumber SentryTracesSamplerCallback (SentrySamplingContext arg0); + +// typedef void (^SentrySpanCallback)(id _Nullable); +// [Internal] +// delegate void SentrySpanCallback ([NullAllowed] SentrySpan arg0); + +// // typedef void (^SentryOnAppStartMeasurementAvailable)(SentryAppStartMeasurement * _Nullable); +// [Internal] +// delegate void SentryOnAppStartMeasurementAvailable ([NullAllowed] SentryAppStartMeasurement arg0); + +// @interface PrivateSentrySDKOnly : NSObject +[BaseType (typeof(NSObject))] +[Internal] +interface PrivateSentrySDKOnly +{ + // +(void)storeEnvelope:(SentryEnvelope * _Nonnull)envelope; + [Static] + [Export ("storeEnvelope:")] + void StoreEnvelope (SentryEnvelope envelope); + + // +(void)captureEnvelope:(SentryEnvelope * _Nonnull)envelope; + [Static] + [Export ("captureEnvelope:")] + void CaptureEnvelope (SentryEnvelope envelope); + + // +(SentryEnvelope * _Nullable)envelopeWithData:(NSData * _Nonnull)data; + [Static] + [Export ("envelopeWithData:")] + [return: NullAllowed] + SentryEnvelope EnvelopeWithData (NSData data); + + // +(NSArray * _Nonnull)getDebugImages; + [Static] + [Export ("getDebugImages")] + SentryDebugMeta[] DebugImages { get; } + + // +(void)setSdkName:(NSString * _Nonnull)sdkName andVersionString:(NSString * _Nonnull)versionString; + [Static] + [Export ("setSdkName:andVersionString:")] + void SetSdkName (string sdkName, string versionString); + + // @property (copy, nonatomic, class) SentryOnAppStartMeasurementAvailable _Nullable onAppStartMeasurementAvailable; + [Static] + [NullAllowed, Export ("onAppStartMeasurementAvailable", ArgumentSemantic.Copy)] + Action OnAppStartMeasurementAvailable { get; set; } + + // @property (readonly, nonatomic, class) SentryAppStartMeasurement * _Nullable appStartMeasurement; + [Static] + [NullAllowed, Export ("appStartMeasurement")] + SentryAppStartMeasurement AppStartMeasurement { get; } + + // @property (readonly, copy, nonatomic, class) NSString * _Nonnull installationID; + [Static] + [Export ("installationID")] + string InstallationID { get; } + + // @property (readonly, copy, nonatomic, class) SentryOptions * _Nonnull options; + [Static] + [Export ("options", ArgumentSemantic.Copy)] + SentryOptions Options { get; } + + // @property (assign, nonatomic, class) BOOL appStartMeasurementHybridSDKMode; + [Static] + [Export ("appStartMeasurementHybridSDKMode")] + bool AppStartMeasurementHybridSDKMode { get; set; } + + // @property (assign, nonatomic, class) BOOL framesTrackingMeasurementHybridSDKMode; + [Static] + [Export ("framesTrackingMeasurementHybridSDKMode")] + bool FramesTrackingMeasurementHybridSDKMode { get; set; } + + // @property (readonly, assign, nonatomic, class) BOOL isFramesTrackingRunning; + [Static] + [Export ("isFramesTrackingRunning")] + bool IsFramesTrackingRunning { get; } + + // @property (readonly, assign, nonatomic, class) SentryScreenFrames * _Nonnull currentScreenFrames; + [Static] + [Export ("currentScreenFrames", ArgumentSemantic.Assign)] + SentryScreenFrames CurrentScreenFrames { get; } +} + +// @interface SentryAppStartMeasurement : NSObject +[BaseType (typeof(NSObject))] +[DisableDefaultCtor] +[Internal] +interface SentryAppStartMeasurement +{ + // -(instancetype _Nonnull)initWithType:(SentryAppStartType)type appStartTimestamp:(NSDate * _Nonnull)appStartTimestamp duration:(NSTimeInterval)duration runtimeInitTimestamp:(NSDate * _Nonnull)runtimeInitTimestamp didFinishLaunchingTimestamp:(NSDate * _Nonnull)didFinishLaunchingTimestamp __attribute__((deprecated("Use initWithType:appStartTimestamp:duration:mainTimestamp:runtimeInitTimestamp:didFinishLaunchingTimestamp instead."))); + [Export ("initWithType:appStartTimestamp:duration:runtimeInitTimestamp:didFinishLaunchingTimestamp:")] + NativeHandle Constructor (SentryAppStartType type, NSDate appStartTimestamp, double duration, NSDate runtimeInitTimestamp, NSDate didFinishLaunchingTimestamp); + + // -(instancetype _Nonnull)initWithType:(SentryAppStartType)type appStartTimestamp:(NSDate * _Nonnull)appStartTimestamp duration:(NSTimeInterval)duration runtimeInitTimestamp:(NSDate * _Nonnull)runtimeInitTimestamp moduleInitializationTimestamp:(NSDate * _Nonnull)moduleInitializationTimestamp didFinishLaunchingTimestamp:(NSDate * _Nonnull)didFinishLaunchingTimestamp; + [Export ("initWithType:appStartTimestamp:duration:runtimeInitTimestamp:moduleInitializationTimestamp:didFinishLaunchingTimestamp:")] + NativeHandle Constructor (SentryAppStartType type, NSDate appStartTimestamp, double duration, NSDate runtimeInitTimestamp, NSDate moduleInitializationTimestamp, NSDate didFinishLaunchingTimestamp); + + // @property (readonly, assign, nonatomic) SentryAppStartType type; + [Export ("type", ArgumentSemantic.Assign)] + SentryAppStartType Type { get; } + + // @property (readonly, assign, nonatomic) NSTimeInterval duration; + [Export ("duration")] + double Duration { get; } + + // @property (readonly, nonatomic, strong) NSDate * _Nonnull appStartTimestamp; + [Export ("appStartTimestamp", ArgumentSemantic.Strong)] + NSDate AppStartTimestamp { get; } + + // @property (readonly, nonatomic, strong) NSDate * _Nonnull runtimeInitTimestamp; + [Export ("runtimeInitTimestamp", ArgumentSemantic.Strong)] + NSDate RuntimeInitTimestamp { get; } + + // @property (readonly, nonatomic, strong) NSDate * _Nonnull moduleInitializationTimestamp; + [Export ("moduleInitializationTimestamp", ArgumentSemantic.Strong)] + NSDate ModuleInitializationTimestamp { get; } + + // @property (readonly, nonatomic, strong) NSDate * _Nonnull didFinishLaunchingTimestamp; + [Export ("didFinishLaunchingTimestamp", ArgumentSemantic.Strong)] + NSDate DidFinishLaunchingTimestamp { get; } +} + +// @protocol SentrySerializable +[Protocol] [Model] +[BaseType (typeof(NSObject))] +[DisableDefaultCtor] +[Internal] +interface SentrySerializable +{ + // @required -(NSDictionary * _Nonnull)serialize; + [Abstract] + [Export ("serialize")] + NSDictionary Serialize(); +} + +// @interface SentryAttachment : NSObject +[BaseType (typeof(NSObject))] +[DisableDefaultCtor] +[Internal] +interface SentryAttachment +{ + // -(instancetype _Nonnull)initWithData:(NSData * _Nonnull)data filename:(NSString * _Nonnull)filename; + [Export ("initWithData:filename:")] + NativeHandle Constructor (NSData data, string filename); + + // -(instancetype _Nonnull)initWithData:(NSData * _Nonnull)data filename:(NSString * _Nonnull)filename contentType:(NSString * _Nonnull)contentType; + [Export ("initWithData:filename:contentType:")] + NativeHandle Constructor (NSData data, string filename, string contentType); + + // -(instancetype _Nonnull)initWithPath:(NSString * _Nonnull)path; + [Export ("initWithPath:")] + NativeHandle Constructor (string path); + + // -(instancetype _Nonnull)initWithPath:(NSString * _Nonnull)path filename:(NSString * _Nonnull)filename; + [Export ("initWithPath:filename:")] + NativeHandle Constructor (string path, string filename); + + // -(instancetype _Nonnull)initWithPath:(NSString * _Nonnull)path filename:(NSString * _Nonnull)filename contentType:(NSString * _Nonnull)contentType; + [Export ("initWithPath:filename:contentType:")] + NativeHandle Constructor (string path, string filename, string contentType); + + // @property (readonly, nonatomic, strong) NSData * _Nullable data; + [NullAllowed, Export ("data", ArgumentSemantic.Strong)] + NSData Data { get; } + + // @property (readonly, copy, nonatomic) NSString * _Nullable path; + [NullAllowed, Export ("path")] + string Path { get; } + + // @property (readonly, copy, nonatomic) NSString * _Nonnull filename; + [Export ("filename")] + string Filename { get; } + + // @property (readonly, copy, nonatomic) NSString * _Nonnull contentType; + [Export ("contentType")] + string ContentType { get; } +} + +// @interface SentryBreadcrumb : NSObject +[BaseType (typeof(NSObject))] +[Internal] +interface SentryBreadcrumb : SentrySerializable +{ + // @property (nonatomic) SentryLevel level; + [Export ("level", ArgumentSemantic.Assign)] + SentryLevel Level { get; set; } + + // @property (copy, nonatomic) NSString * _Nonnull category; + [Export ("category")] + string Category { get; set; } + + // @property (nonatomic, strong) NSDate * _Nullable timestamp; + [NullAllowed, Export ("timestamp", ArgumentSemantic.Strong)] + NSDate Timestamp { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable type; + [NullAllowed, Export ("type")] + string Type { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable message; + [NullAllowed, Export ("message")] + string Message { get; set; } + + // @property (nonatomic, strong) NSDictionary * _Nullable data; + [NullAllowed, Export ("data", ArgumentSemantic.Strong)] + NSDictionary Data { get; set; } + + // -(instancetype _Nonnull)initWithLevel:(SentryLevel)level category:(NSString * _Nonnull)category; + [Export ("initWithLevel:category:")] + NativeHandle Constructor (SentryLevel level, string category); + + // -(NSDictionary * _Nonnull)serialize; + [Export ("serialize")] + NSDictionary Serialize(); + + // // -(BOOL)isEqual:(id _Nullable)other; + // [Export ("isEqual:")] + // bool IsEqual ([NullAllowed] NSObject other); + + // -(BOOL)isEqualToBreadcrumb:(SentryBreadcrumb * _Nonnull)breadcrumb; + [Export ("isEqualToBreadcrumb:")] + bool IsEqualToBreadcrumb (SentryBreadcrumb breadcrumb); + + // -(NSUInteger)hash; + [Export ("hash")] + nuint Hash { get; } +} + +// @interface SentryClient : NSObject +[BaseType (typeof(NSObject))] +[DisableDefaultCtor] +[Internal] +interface SentryClient +{ + // @property (nonatomic, strong) SentryOptions * _Nonnull options; + [Export ("options", ArgumentSemantic.Strong)] + SentryOptions Options { get; set; } + + // -(instancetype _Nullable)initWithOptions:(SentryOptions * _Nonnull)options; + [Export ("initWithOptions:")] + NativeHandle Constructor (SentryOptions options); + + // -(SentryId * _Nonnull)captureEvent:(SentryEvent * _Nonnull)event __attribute__((swift_name("capture(event:)"))); + [Export ("captureEvent:")] + SentryId CaptureEvent (SentryEvent @event); + + // -(SentryId * _Nonnull)captureEvent:(SentryEvent * _Nonnull)event withScope:(SentryScope * _Nonnull)scope __attribute__((swift_name("capture(event:scope:)"))); + [Export ("captureEvent:withScope:")] + SentryId CaptureEvent (SentryEvent @event, SentryScope scope); + + // -(SentryId * _Nonnull)captureError:(NSError * _Nonnull)error __attribute__((swift_name("capture(error:)"))); + [Export ("captureError:")] + SentryId CaptureError (NSError error); + + // -(SentryId * _Nonnull)captureError:(NSError * _Nonnull)error withScope:(SentryScope * _Nonnull)scope __attribute__((swift_name("capture(error:scope:)"))); + [Export ("captureError:withScope:")] + SentryId CaptureError (NSError error, SentryScope scope); + + // -(SentryId * _Nonnull)captureException:(NSException * _Nonnull)exception __attribute__((swift_name("capture(exception:)"))); + [Export ("captureException:")] + SentryId CaptureException (NSException exception); + + // -(SentryId * _Nonnull)captureException:(NSException * _Nonnull)exception withScope:(SentryScope * _Nonnull)scope __attribute__((swift_name("capture(exception:scope:)"))); + [Export ("captureException:withScope:")] + SentryId CaptureException (NSException exception, SentryScope scope); + + // -(SentryId * _Nonnull)captureMessage:(NSString * _Nonnull)message __attribute__((swift_name("capture(message:)"))); + [Export ("captureMessage:")] + SentryId CaptureMessage (string message); + + // -(SentryId * _Nonnull)captureMessage:(NSString * _Nonnull)message withScope:(SentryScope * _Nonnull)scope __attribute__((swift_name("capture(message:scope:)"))); + [Export ("captureMessage:withScope:")] + SentryId CaptureMessage (string message, SentryScope scope); + + // -(void)captureUserFeedback:(SentryUserFeedback * _Nonnull)userFeedback __attribute__((swift_name("capture(userFeedback:)"))); + [Export ("captureUserFeedback:")] + void CaptureUserFeedback (SentryUserFeedback userFeedback); + + // -(void)captureSession:(SentrySession * _Nonnull)session __attribute__((swift_name("capture(session:)"))); + [Export ("captureSession:")] + void CaptureSession (SentrySession session); + + // -(void)captureEnvelope:(SentryEnvelope * _Nonnull)envelope __attribute__((swift_name("capture(envelope:)"))); + [Export ("captureEnvelope:")] + void CaptureEnvelope (SentryEnvelope envelope); +} + +// @interface SentryCrashExceptionApplication : NSObject +[BaseType (typeof(NSObject))] +[Internal] +interface SentryCrashExceptionApplication +{ +} + +// @interface SentryDebugImageProvider : NSObject +[BaseType (typeof(NSObject))] +[Internal] +interface SentryDebugImageProvider +{ + // -(NSArray * _Nonnull)getDebugImagesForThreads:(NSArray * _Nonnull)threads; + [Export ("getDebugImagesForThreads:")] + SentryDebugMeta[] GetDebugImagesForThreads (SentryThread[] threads); + + // -(NSArray * _Nonnull)getDebugImages; + [Export ("getDebugImages")] + SentryDebugMeta[] DebugImages { get; } +} + +// @interface SentryDebugMeta : NSObject +[BaseType (typeof(NSObject))] +[Internal] +interface SentryDebugMeta : SentrySerializable +{ + // @property (copy, nonatomic) NSString * _Nullable uuid; + [NullAllowed, Export ("uuid")] + string Uuid { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable type; + [NullAllowed, Export ("type")] + string Type { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable name; + [NullAllowed, Export ("name")] + string Name { get; set; } + + // @property (copy, nonatomic) NSNumber * _Nullable imageSize; + [NullAllowed, Export ("imageSize", ArgumentSemantic.Copy)] + NSNumber ImageSize { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable imageAddress; + [NullAllowed, Export ("imageAddress")] + string ImageAddress { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable imageVmAddress; + [NullAllowed, Export ("imageVmAddress")] + string ImageVmAddress { get; set; } +} + +// @interface SentryDsn : NSObject +[BaseType (typeof(NSObject))] +[Internal] +interface SentryDsn +{ + // @property (readonly, nonatomic, strong) NSURL * _Nonnull url; + [Export ("url", ArgumentSemantic.Strong)] + NSUrl Url { get; } + + // -(instancetype _Nullable)initWithString:(NSString * _Nonnull)dsnString didFailWithError:(NSError * _Nullable * _Nullable)error; + [Export ("initWithString:didFailWithError:")] + NativeHandle Constructor (string dsnString, [NullAllowed] out NSError error); + + // -(NSString * _Nonnull)getHash; + [Export ("getHash")] + string Hash { get; } + + // -(NSURL * _Nonnull)getStoreEndpoint; + [Export ("getStoreEndpoint")] + NSUrl StoreEndpoint { get; } + + // -(NSURL * _Nonnull)getEnvelopeEndpoint; + [Export ("getEnvelopeEndpoint")] + NSUrl EnvelopeEndpoint { get; } +} + +// @interface SentryEnvelopeHeader : NSObject +[BaseType (typeof(NSObject))] +[DisableDefaultCtor] +[Internal] +interface SentryEnvelopeHeader +{ + // -(instancetype _Nonnull)initWithId:(SentryId * _Nullable)eventId; + [Export ("initWithId:")] + NativeHandle Constructor ([NullAllowed] SentryId eventId); + + // // -(instancetype _Nonnull)initWithId:(SentryId * _Nullable)eventId traceContext:(SentryTraceContext * _Nullable)traceContext; + // [Export ("initWithId:traceContext:")] + // NativeHandle Constructor ([NullAllowed] SentryId eventId, [NullAllowed] SentryTraceContext traceContext); + + // // -(instancetype _Nonnull)initWithId:(SentryId * _Nullable)eventId sdkInfo:(SentrySdkInfo * _Nullable)sdkInfo traceContext:(SentryTraceContext * _Nullable)traceContext __attribute__((objc_designated_initializer)); + // [Export ("initWithId:sdkInfo:traceContext:")] + // [DesignatedInitializer] + // NativeHandle Constructor ([NullAllowed] SentryId eventId, [NullAllowed] SentrySdkInfo sdkInfo, [NullAllowed] SentryTraceContext traceContext); + + // @property (readonly, copy, nonatomic) SentryId * _Nullable eventId; + [NullAllowed, Export ("eventId", ArgumentSemantic.Copy)] + SentryId EventId { get; } + + // @property (readonly, copy, nonatomic) SentrySdkInfo * _Nullable sdkInfo; + [NullAllowed, Export ("sdkInfo", ArgumentSemantic.Copy)] + SentrySdkInfo SdkInfo { get; } + + // // @property (readonly, copy, nonatomic) SentryTraceContext * _Nullable traceContext; + // [NullAllowed, Export ("traceContext", ArgumentSemantic.Copy)] + // SentryTraceContext TraceContext { get; } +} + +// @interface SentryEnvelopeItemHeader : NSObject +[BaseType (typeof(NSObject))] +[DisableDefaultCtor] +[Internal] +interface SentryEnvelopeItemHeader +{ + // -(instancetype _Nonnull)initWithType:(NSString * _Nonnull)type length:(NSUInteger)length __attribute__((objc_designated_initializer)); + [Export ("initWithType:length:")] + [DesignatedInitializer] + NativeHandle Constructor (string type, nuint length); + + // -(instancetype _Nonnull)initWithType:(NSString * _Nonnull)type length:(NSUInteger)length filenname:(NSString * _Nonnull)filename contentType:(NSString * _Nonnull)contentType; + [Export ("initWithType:length:filenname:contentType:")] + NativeHandle Constructor (string type, nuint length, string filename, string contentType); + + // @property (readonly, copy, nonatomic) NSString * _Nonnull type; + [Export ("type")] + string Type { get; } + + // @property (readonly, nonatomic) NSUInteger length; + [Export ("length")] + nuint Length { get; } + + // @property (readonly, copy, nonatomic) NSString * _Nullable filename; + [NullAllowed, Export ("filename")] + string Filename { get; } + + // @property (readonly, copy, nonatomic) NSString * _Nullable contentType; + [NullAllowed, Export ("contentType")] + string ContentType { get; } +} + +// @interface SentryEnvelopeItem : NSObject +[BaseType (typeof(NSObject))] +[DisableDefaultCtor] +[Internal] +interface SentryEnvelopeItem +{ + // -(instancetype _Nonnull)initWithEvent:(SentryEvent * _Nonnull)event; + [Export ("initWithEvent:")] + NativeHandle Constructor (SentryEvent @event); + + // -(instancetype _Nonnull)initWithSession:(SentrySession * _Nonnull)session; + [Export ("initWithSession:")] + NativeHandle Constructor (SentrySession session); + + // -(instancetype _Nonnull)initWithUserFeedback:(SentryUserFeedback * _Nonnull)userFeedback; + [Export ("initWithUserFeedback:")] + NativeHandle Constructor (SentryUserFeedback userFeedback); + + // -(instancetype _Nullable)initWithAttachment:(SentryAttachment * _Nonnull)attachment maxAttachmentSize:(NSUInteger)maxAttachmentSize; + [Export ("initWithAttachment:maxAttachmentSize:")] + NativeHandle Constructor (SentryAttachment attachment, nuint maxAttachmentSize); + + // -(instancetype _Nonnull)initWithHeader:(SentryEnvelopeItemHeader * _Nonnull)header data:(NSData * _Nonnull)data __attribute__((objc_designated_initializer)); + [Export ("initWithHeader:data:")] + [DesignatedInitializer] + NativeHandle Constructor (SentryEnvelopeItemHeader header, NSData data); + + // @property (readonly, nonatomic, strong) SentryEnvelopeItemHeader * _Nonnull header; + [Export ("header", ArgumentSemantic.Strong)] + SentryEnvelopeItemHeader Header { get; } + + // @property (readonly, nonatomic, strong) NSData * _Nonnull data; + [Export ("data", ArgumentSemantic.Strong)] + NSData Data { get; } +} + +// @interface SentryEnvelope : NSObject +[BaseType (typeof(NSObject))] +[DisableDefaultCtor] +[Internal] +interface SentryEnvelope +{ + // -(instancetype _Nonnull)initWithId:(SentryId * _Nullable)id singleItem:(SentryEnvelopeItem * _Nonnull)item; + [Export ("initWithId:singleItem:")] + NativeHandle Constructor ([NullAllowed] SentryId id, SentryEnvelopeItem item); + + // -(instancetype _Nonnull)initWithHeader:(SentryEnvelopeHeader * _Nonnull)header singleItem:(SentryEnvelopeItem * _Nonnull)item; + [Export ("initWithHeader:singleItem:")] + NativeHandle Constructor (SentryEnvelopeHeader header, SentryEnvelopeItem item); + + // -(instancetype _Nonnull)initWithId:(SentryId * _Nullable)id items:(NSArray * _Nonnull)items; + [Export ("initWithId:items:")] + NativeHandle Constructor ([NullAllowed] SentryId id, SentryEnvelopeItem[] items); + + // -(instancetype _Nonnull)initWithSession:(SentrySession * _Nonnull)session; + [Export ("initWithSession:")] + NativeHandle Constructor (SentrySession session); + + // -(instancetype _Nonnull)initWithSessions:(NSArray * _Nonnull)sessions; + [Export ("initWithSessions:")] + NativeHandle Constructor (SentrySession[] sessions); + + // -(instancetype _Nonnull)initWithHeader:(SentryEnvelopeHeader * _Nonnull)header items:(NSArray * _Nonnull)items __attribute__((objc_designated_initializer)); + [Export ("initWithHeader:items:")] + [DesignatedInitializer] + NativeHandle Constructor (SentryEnvelopeHeader header, SentryEnvelopeItem[] items); + + // -(instancetype _Nonnull)initWithEvent:(SentryEvent * _Nonnull)event; + [Export ("initWithEvent:")] + NativeHandle Constructor (SentryEvent @event); + + // -(instancetype _Nonnull)initWithUserFeedback:(SentryUserFeedback * _Nonnull)userFeedback; + [Export ("initWithUserFeedback:")] + NativeHandle Constructor (SentryUserFeedback userFeedback); + + // @property (readonly, nonatomic, strong) SentryEnvelopeHeader * _Nonnull header; + [Export ("header", ArgumentSemantic.Strong)] + SentryEnvelopeHeader Header { get; } + + // @property (readonly, nonatomic, strong) NSArray * _Nonnull items; + [Export ("items", ArgumentSemantic.Strong)] + SentryEnvelopeItem[] Items { get; } +} + +// @interface SentryEvent : NSObject +[BaseType (typeof(NSObject))] +[Internal] +interface SentryEvent : SentrySerializable +{ + // @property (nonatomic, strong) SentryId * _Nonnull eventId; + [Export ("eventId", ArgumentSemantic.Strong)] + SentryId EventId { get; set; } + + // @property (nonatomic, strong) SentryMessage * _Nullable message; + [NullAllowed, Export ("message", ArgumentSemantic.Strong)] + SentryMessage Message { get; set; } + + // @property (copy, nonatomic) NSError * _Nullable error; + [NullAllowed, Export ("error", ArgumentSemantic.Copy)] + NSError Error { get; set; } + + // @property (nonatomic, strong) NSDate * _Nullable timestamp; + [NullAllowed, Export ("timestamp", ArgumentSemantic.Strong)] + NSDate Timestamp { get; set; } + + // @property (nonatomic, strong) NSDate * _Nullable startTimestamp; + [NullAllowed, Export ("startTimestamp", ArgumentSemantic.Strong)] + NSDate StartTimestamp { get; set; } + + // @property (nonatomic) enum SentryLevel level; + [Export ("level", ArgumentSemantic.Assign)] + SentryLevel Level { get; set; } + + // @property (copy, nonatomic) NSString * _Nonnull platform; + [Export ("platform")] + string Platform { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable logger; + [NullAllowed, Export ("logger")] + string Logger { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable serverName; + [NullAllowed, Export ("serverName")] + string ServerName { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable releaseName; + [NullAllowed, Export ("releaseName")] + string ReleaseName { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable dist; + [NullAllowed, Export ("dist")] + string Dist { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable environment; + [NullAllowed, Export ("environment")] + string Environment { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable transaction; + [NullAllowed, Export ("transaction")] + string Transaction { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable type; + [NullAllowed, Export ("type")] + string Type { get; set; } + + // @property (nonatomic, strong) NSDictionary * _Nullable tags; + [NullAllowed, Export ("tags", ArgumentSemantic.Strong)] + NSDictionary Tags { get; set; } + + // @property (nonatomic, strong) NSDictionary * _Nullable extra; + [NullAllowed, Export ("extra", ArgumentSemantic.Strong)] + NSDictionary Extra { get; set; } + + // @property (nonatomic, strong) NSDictionary * _Nullable sdk; + [NullAllowed, Export ("sdk", ArgumentSemantic.Strong)] + NSDictionary Sdk { get; set; } + + // @property (nonatomic, strong) NSDictionary * _Nullable modules; + [NullAllowed, Export ("modules", ArgumentSemantic.Strong)] + NSDictionary Modules { get; set; } + + // @property (nonatomic, strong) NSArray * _Nullable fingerprint; + [NullAllowed, Export ("fingerprint", ArgumentSemantic.Strong)] + string[] Fingerprint { get; set; } + + // @property (nonatomic, strong) SentryUser * _Nullable user; + [NullAllowed, Export ("user", ArgumentSemantic.Strong)] + SentryUser User { get; set; } + + // @property (nonatomic, strong) NSDictionary *> * _Nullable context; + [NullAllowed, Export ("context", ArgumentSemantic.Strong)] + NSDictionary> Context { get; set; } + + // @property (nonatomic, strong) NSArray * _Nullable threads; + [NullAllowed, Export ("threads", ArgumentSemantic.Strong)] + SentryThread[] Threads { get; set; } + + // @property (nonatomic, strong) NSArray * _Nullable exceptions; + [NullAllowed, Export ("exceptions", ArgumentSemantic.Strong)] + SentryException[] Exceptions { get; set; } + + // @property (nonatomic, strong) SentryStacktrace * _Nullable stacktrace; + [NullAllowed, Export ("stacktrace", ArgumentSemantic.Strong)] + SentryStacktrace Stacktrace { get; set; } + + // @property (nonatomic, strong) NSArray * _Nullable debugMeta; + [NullAllowed, Export ("debugMeta", ArgumentSemantic.Strong)] + SentryDebugMeta[] DebugMeta { get; set; } + + // @property (nonatomic, strong) NSArray * _Nullable breadcrumbs; + [NullAllowed, Export ("breadcrumbs", ArgumentSemantic.Strong)] + SentryBreadcrumb[] Breadcrumbs { get; set; } + + // -(instancetype _Nonnull)initWithLevel:(enum SentryLevel)level __attribute__((objc_designated_initializer)); + [Export ("initWithLevel:")] + [DesignatedInitializer] + NativeHandle Constructor (SentryLevel level); + + // -(instancetype _Nonnull)initWithError:(NSError * _Nonnull)error; + [Export ("initWithError:")] + NativeHandle Constructor (NSError error); +} + +// @interface SentryException : NSObject +[BaseType (typeof(NSObject))] +[DisableDefaultCtor] +[Internal] +interface SentryException : SentrySerializable +{ + // @property (copy, nonatomic) NSString * _Nonnull value; + [Export ("value")] + string Value { get; set; } + + // @property (copy, nonatomic) NSString * _Nonnull type; + [Export ("type")] + string Type { get; set; } + + // @property (nonatomic, strong) SentryMechanism * _Nullable mechanism; + [NullAllowed, Export ("mechanism", ArgumentSemantic.Strong)] + SentryMechanism Mechanism { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable module; + [NullAllowed, Export ("module")] + string Module { get; set; } + + // @property (copy, nonatomic) NSNumber * _Nullable threadId; + [NullAllowed, Export ("threadId", ArgumentSemantic.Copy)] + NSNumber ThreadId { get; set; } + + // @property (nonatomic, strong) SentryStacktrace * _Nullable stacktrace; + [NullAllowed, Export ("stacktrace", ArgumentSemantic.Strong)] + SentryStacktrace Stacktrace { get; set; } + + // -(instancetype _Nonnull)initWithValue:(NSString * _Nonnull)value type:(NSString * _Nonnull)type; + [Export ("initWithValue:type:")] + NativeHandle Constructor (string value, string type); +} + +// @interface SentryFrame : NSObject +[BaseType (typeof(NSObject))] +[Internal] +interface SentryFrame : SentrySerializable +{ + // @property (copy, nonatomic) NSString * _Nullable symbolAddress; + [NullAllowed, Export ("symbolAddress")] + string SymbolAddress { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable fileName; + [NullAllowed, Export ("fileName")] + string FileName { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable function; + [NullAllowed, Export ("function")] + string Function { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable module; + [NullAllowed, Export ("module")] + string Module { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable package; + [NullAllowed, Export ("package")] + string Package { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable imageAddress; + [NullAllowed, Export ("imageAddress")] + string ImageAddress { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable platform; + [NullAllowed, Export ("platform")] + string Platform { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable instructionAddress; + [NullAllowed, Export ("instructionAddress")] + string InstructionAddress { get; set; } + + // @property (copy, nonatomic) NSNumber * _Nullable lineNumber; + [NullAllowed, Export ("lineNumber", ArgumentSemantic.Copy)] + NSNumber LineNumber { get; set; } + + // @property (copy, nonatomic) NSNumber * _Nullable columnNumber; + [NullAllowed, Export ("columnNumber", ArgumentSemantic.Copy)] + NSNumber ColumnNumber { get; set; } + + // @property (copy, nonatomic) NSNumber * _Nullable inApp; + [NullAllowed, Export ("inApp", ArgumentSemantic.Copy)] + NSNumber InApp { get; set; } + + // @property (copy, nonatomic) NSNumber * _Nullable stackStart; + [NullAllowed, Export ("stackStart", ArgumentSemantic.Copy)] + NSNumber StackStart { get; set; } +} + +// @interface SentryOptions : NSObject +[BaseType (typeof(NSObject))] +[Internal] +interface SentryOptions +{ + // -(instancetype _Nullable)initWithDict:(NSDictionary * _Nonnull)options didFailWithError:(NSError * _Nullable * _Nullable)error; + [Export ("initWithDict:didFailWithError:")] + NativeHandle Constructor (NSDictionary options, [NullAllowed] out NSError error); + + // @property (nonatomic, strong) NSString * _Nullable dsn; + [NullAllowed, Export ("dsn", ArgumentSemantic.Strong)] + string Dsn { get; set; } + + // @property (nonatomic, strong) SentryDsn * _Nullable parsedDsn; + [NullAllowed, Export ("parsedDsn", ArgumentSemantic.Strong)] + SentryDsn ParsedDsn { get; set; } + + // @property (assign, nonatomic) BOOL debug; + [Export ("debug")] + bool Debug { get; set; } + + // @property (assign, nonatomic) SentryLevel diagnosticLevel; + [Export ("diagnosticLevel", ArgumentSemantic.Assign)] + SentryLevel DiagnosticLevel { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable releaseName; + [NullAllowed, Export ("releaseName")] + string ReleaseName { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable dist; + [NullAllowed, Export ("dist")] + string Dist { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable environment; + [NullAllowed, Export ("environment")] + string Environment { get; set; } + + // @property (assign, nonatomic) BOOL enabled; + [Export ("enabled")] + bool Enabled { get; set; } + + // @property (assign, nonatomic) NSUInteger maxBreadcrumbs; + [Export ("maxBreadcrumbs")] + nuint MaxBreadcrumbs { get; set; } + + // @property (assign, nonatomic) BOOL enableNetworkBreadcrumbs; + [Export ("enableNetworkBreadcrumbs")] + bool EnableNetworkBreadcrumbs { get; set; } + + // @property (assign, nonatomic) NSUInteger maxCacheItems; + [Export ("maxCacheItems")] + nuint MaxCacheItems { get; set; } + + // @property (copy, nonatomic) SentryBeforeSendEventCallback _Nullable beforeSend; + [NullAllowed, Export ("beforeSend", ArgumentSemantic.Copy)] + Func BeforeSend { get; set; } + + // @property (copy, nonatomic) SentryBeforeBreadcrumbCallback _Nullable beforeBreadcrumb; + [NullAllowed, Export ("beforeBreadcrumb", ArgumentSemantic.Copy)] + Func BeforeBreadcrumb { get; set; } + + // @property (copy, nonatomic) SentryOnCrashedLastRunCallback _Nullable onCrashedLastRun; + [NullAllowed, Export ("onCrashedLastRun", ArgumentSemantic.Copy)] + Action OnCrashedLastRun { get; set; } + + // @property (copy, nonatomic) NSArray * _Nullable integrations; + [NullAllowed, Export ("integrations", ArgumentSemantic.Copy)] + string[] Integrations { get; set; } + + // +(NSArray * _Nonnull)defaultIntegrations; + [Static] + [Export ("defaultIntegrations")] + string[] DefaultIntegrations { get; } + + // @property (copy, nonatomic) NSNumber * _Nullable sampleRate; + [NullAllowed, Export ("sampleRate", ArgumentSemantic.Copy)] + NSNumber SampleRate { get; set; } + + // @property (assign, nonatomic) BOOL enableAutoSessionTracking; + [Export ("enableAutoSessionTracking")] + bool EnableAutoSessionTracking { get; set; } + + // @property (assign, nonatomic) BOOL enableOutOfMemoryTracking; + [Export ("enableOutOfMemoryTracking")] + bool EnableOutOfMemoryTracking { get; set; } + + // @property (assign, nonatomic) NSUInteger sessionTrackingIntervalMillis; + [Export ("sessionTrackingIntervalMillis")] + nuint SessionTrackingIntervalMillis { get; set; } + + // @property (assign, nonatomic) BOOL attachStacktrace; + [Export ("attachStacktrace")] + bool AttachStacktrace { get; set; } + + // @property (assign, nonatomic) BOOL stitchAsyncCode; + [Export ("stitchAsyncCode")] + bool StitchAsyncCode { get; set; } + + // @property (readonly, nonatomic, strong) DEPRECATED_MSG_ATTRIBUTE("This property will be removed in a future version of the SDK") SentrySdkInfo * sdkInfo __attribute__((deprecated("This property will be removed in a future version of the SDK"))); + [Export ("sdkInfo", ArgumentSemantic.Strong)] + SentrySdkInfo SdkInfo { get; } + + // @property (assign, nonatomic) NSUInteger maxAttachmentSize; + [Export ("maxAttachmentSize")] + nuint MaxAttachmentSize { get; set; } + + // @property (assign, nonatomic) BOOL sendDefaultPii; + [Export ("sendDefaultPii")] + bool SendDefaultPii { get; set; } + + // @property (assign, nonatomic) BOOL enableAutoPerformanceTracking; + [Export ("enableAutoPerformanceTracking")] + bool EnableAutoPerformanceTracking { get; set; } + + // @property (assign, nonatomic) BOOL enableUIViewControllerTracking; + [Export ("enableUIViewControllerTracking")] + bool EnableUIViewControllerTracking { get; set; } + + // @property (assign, nonatomic) BOOL attachScreenshot; + [Export ("attachScreenshot")] + bool AttachScreenshot { get; set; } + + // @property (assign, nonatomic) BOOL enableUserInteractionTracing; + [Export ("enableUserInteractionTracing")] + bool EnableUserInteractionTracing { get; set; } + + // @property (assign, nonatomic) NSTimeInterval idleTimeout; + [Export ("idleTimeout")] + double IdleTimeout { get; set; } + + // @property (assign, nonatomic) BOOL enableNetworkTracking; + [Export ("enableNetworkTracking")] + bool EnableNetworkTracking { get; set; } + + // @property (assign, nonatomic) BOOL enableFileIOTracking; + [Export ("enableFileIOTracking")] + bool EnableFileIOTracking { get; set; } + + // @property (nonatomic, strong) NSNumber * _Nullable tracesSampleRate; + [NullAllowed, Export ("tracesSampleRate", ArgumentSemantic.Strong)] + NSNumber TracesSampleRate { get; set; } + + // @property (nonatomic) SentryTracesSamplerCallback _Nullable tracesSampler; + [NullAllowed, Export ("tracesSampler", ArgumentSemantic.Assign)] + Func TracesSampler { get; set; } + + // @property (readonly, assign, nonatomic) BOOL isTracingEnabled; + [Export ("isTracingEnabled")] + bool IsTracingEnabled { get; } + + // @property (readonly, copy, nonatomic) NSArray * _Nonnull inAppIncludes; + [Export ("inAppIncludes", ArgumentSemantic.Copy)] + string[] InAppIncludes { get; } + + // -(void)addInAppInclude:(NSString * _Nonnull)inAppInclude; + [Export ("addInAppInclude:")] + void AddInAppInclude (string inAppInclude); + + // @property (readonly, copy, nonatomic) NSArray * _Nonnull inAppExcludes; + [Export ("inAppExcludes", ArgumentSemantic.Copy)] + string[] InAppExcludes { get; } + + // -(void)addInAppExclude:(NSString * _Nonnull)inAppExclude; + [Export ("addInAppExclude:")] + void AddInAppExclude (string inAppExclude); + + [Wrap ("WeakUrlSessionDelegate")] + [NullAllowed] + NSUrlSessionDelegate UrlSessionDelegate { get; set; } + + // @property (nonatomic, weak) id _Nullable urlSessionDelegate; + [NullAllowed, Export ("urlSessionDelegate", ArgumentSemantic.Weak)] + NSObject WeakUrlSessionDelegate { get; set; } + + // @property (assign, nonatomic) BOOL enableSwizzling; + [Export ("enableSwizzling")] + bool EnableSwizzling { get; set; } + + // @property (assign, nonatomic) BOOL enableCoreDataTracking; + [Export ("enableCoreDataTracking")] + bool EnableCoreDataTracking { get; set; } + + // @property (assign, nonatomic) BOOL enableProfiling; + [Export ("enableProfiling")] + bool EnableProfiling { get; set; } + + // @property (assign, nonatomic) BOOL sendClientReports; + [Export ("sendClientReports")] + bool SendClientReports { get; set; } + + // @property (assign, nonatomic) BOOL enableAppHangTracking; + [Export ("enableAppHangTracking")] + bool EnableAppHangTracking { get; set; } + + // @property (assign, nonatomic) NSTimeInterval appHangTimeoutInterval; + [Export ("appHangTimeoutInterval")] + double AppHangTimeoutInterval { get; set; } + + // @property (assign, nonatomic) BOOL enableAutoBreadcrumbTracking; + [Export ("enableAutoBreadcrumbTracking")] + bool EnableAutoBreadcrumbTracking { get; set; } +} + +// @protocol SentryIntegrationProtocol +[Protocol] +[BaseType (typeof(NSObject))] +[Internal] +interface SentryIntegrationProtocol +{ + // @required -(void)installWithOptions:(SentryOptions * _Nonnull)options; + [Abstract] + [Export ("installWithOptions:")] + void InstallWithOptions (SentryOptions options); + + // @optional -(void)uninstall; + [Export ("uninstall")] + void Uninstall (); +} + +// @interface SentrySpanContext : NSObject +[BaseType (typeof(NSObject))] +[DisableDefaultCtor] +[Internal] +interface SentrySpanContext : SentrySerializable +{ + // @property (readonly, nonatomic) SentryId * _Nonnull traceId; + [Export ("traceId")] + SentryId TraceId { get; } + + // @property (readonly, nonatomic) SentrySpanId * _Nonnull spanId; + [Export ("spanId")] + SentrySpanId SpanId { get; } + + // @property (readonly, nonatomic) SentrySpanId * _Nullable parentSpanId; + [NullAllowed, Export ("parentSpanId")] + SentrySpanId ParentSpanId { get; } + + // @property (nonatomic) SentrySampleDecision sampled; + [Export ("sampled", ArgumentSemantic.Assign)] + SentrySampleDecision Sampled { get; set; } + + // @property (copy, nonatomic) NSString * _Nonnull operation; + [Export ("operation")] + string Operation { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable spanDescription; + [NullAllowed, Export ("spanDescription")] + string SpanDescription { get; set; } + + // @property (nonatomic) SentrySpanStatus status; + [Export ("status", ArgumentSemantic.Assign)] + SentrySpanStatus Status { get; set; } + + // @property (readonly, nonatomic) NSDictionary * _Nonnull tags; + [Export ("tags")] + NSDictionary Tags { get; } + + // -(instancetype _Nonnull)initWithOperation:(NSString * _Nonnull)operation; + [Export ("initWithOperation:")] + NativeHandle Constructor (string operation); + + // -(instancetype _Nonnull)initWithOperation:(NSString * _Nonnull)operation sampled:(SentrySampleDecision)sampled; + [Export ("initWithOperation:sampled:")] + NativeHandle Constructor (string operation, SentrySampleDecision sampled); + + // -(instancetype _Nonnull)initWithTraceId:(SentryId * _Nonnull)traceId spanId:(SentrySpanId * _Nonnull)spanId parentId:(SentrySpanId * _Nullable)parentId operation:(NSString * _Nonnull)operation sampled:(SentrySampleDecision)sampled; + [Export ("initWithTraceId:spanId:parentId:operation:sampled:")] + NativeHandle Constructor (SentryId traceId, SentrySpanId spanId, [NullAllowed] SentrySpanId parentId, string operation, SentrySampleDecision sampled); + + // -(void)setTagValue:(NSString * _Nonnull)value forKey:(NSString * _Nonnull)key __attribute__((swift_name("setTag(value:key:)"))); + [Export ("setTagValue:forKey:")] + void SetTagValue (string value, string key); + + // -(void)removeTagForKey:(NSString * _Nonnull)key __attribute__((swift_name("removeTag(key:)"))); + [Export ("removeTagForKey:")] + void RemoveTagForKey (string key); + + // @property (readonly, copy, nonatomic, class) NSString * _Nonnull type; + [Static] + [Export ("type")] + string Type { get; } +} + +// @protocol SentrySpan +[Protocol, Model] +[BaseType (typeof(NSObject))] +[Internal] +interface SentrySpan : SentrySerializable +{ + // @required @property (readonly, nonatomic) SentrySpanContext * _Nonnull context; + [Abstract] + [Export ("context")] + SentrySpanContext Context { get; } + + // @required @property (nonatomic, strong) NSDate * _Nullable timestamp; + [Abstract] + [NullAllowed, Export ("timestamp", ArgumentSemantic.Strong)] + NSDate Timestamp { get; set; } + + // @required @property (nonatomic, strong) NSDate * _Nullable startTimestamp; + [Abstract] + [NullAllowed, Export ("startTimestamp", ArgumentSemantic.Strong)] + NSDate StartTimestamp { get; set; } + + // @required @property (readonly) NSDictionary * _Nullable data; + [Abstract] + [NullAllowed, Export ("data")] + NSDictionary Data { get; } + + // @required @property (readonly) NSDictionary * _Nonnull tags; + [Abstract] + [Export ("tags")] + NSDictionary Tags { get; } + + // @required @property (readonly) BOOL isFinished; + [Abstract] + [Export ("isFinished")] + bool IsFinished { get; } + + // @required -(id _Nonnull)startChildWithOperation:(NSString * _Nonnull)operation __attribute__((swift_name("startChild(operation:)"))); + [Abstract] + [Export ("startChildWithOperation:")] + SentrySpan StartChildWithOperation (string operation); + + // @required -(id _Nonnull)startChildWithOperation:(NSString * _Nonnull)operation description:(NSString * _Nullable)description __attribute__((swift_name("startChild(operation:description:)"))); + [Abstract] + [Export ("startChildWithOperation:description:")] + SentrySpan StartChildWithOperation (string operation, [NullAllowed] string description); + + // @required -(void)setDataValue:(id _Nullable)value forKey:(NSString * _Nonnull)key __attribute__((swift_name("setData(value:key:)"))); + [Abstract] + [Export ("setDataValue:forKey:")] + void SetDataValue ([NullAllowed] NSObject value, string key); + + // @required -(void)setExtraValue:(id _Nullable)value forKey:(NSString * _Nonnull)key __attribute__((swift_name("setExtra(value:key:)"))); + [Abstract] + [Export ("setExtraValue:forKey:")] + void SetExtraValue ([NullAllowed] NSObject value, string key); + + // @required -(void)removeDataForKey:(NSString * _Nonnull)key __attribute__((swift_name("removeData(key:)"))); + [Abstract] + [Export ("removeDataForKey:")] + void RemoveDataForKey (string key); + + // @required -(void)setTagValue:(NSString * _Nonnull)value forKey:(NSString * _Nonnull)key __attribute__((swift_name("setTag(value:key:)"))); + [Abstract] + [Export ("setTagValue:forKey:")] + void SetTagValue (string value, string key); + + // @required -(void)removeTagForKey:(NSString * _Nonnull)key __attribute__((swift_name("removeTag(key:)"))); + [Abstract] + [Export ("removeTagForKey:")] + void RemoveTagForKey (string key); + + // @required -(void)finish; + [Abstract] + [Export ("finish")] + void Finish (); + + // @required -(void)finishWithStatus:(SentrySpanStatus)status __attribute__((swift_name("finish(status:)"))); + [Abstract] + [Export ("finishWithStatus:")] + void FinishWithStatus (SentrySpanStatus status); + + // @required -(SentryTraceHeader * _Nonnull)toTraceHeader; + [Abstract] + [Export ("toTraceHeader")] + SentryTraceHeader ToTraceHeader(); +} + +// @interface SentryHub : NSObject +[BaseType (typeof(NSObject))] +[DisableDefaultCtor] +[Internal] +interface SentryHub +{ + // -(instancetype _Nonnull)initWithClient:(SentryClient * _Nullable)client andScope:(SentryScope * _Nullable)scope; + [Export ("initWithClient:andScope:")] + NativeHandle Constructor ([NullAllowed] SentryClient client, [NullAllowed] SentryScope scope); + + // @property (readonly, nonatomic, strong) SentrySession * _Nullable session; + [NullAllowed, Export ("session", ArgumentSemantic.Strong)] + SentrySession Session { get; } + + // -(void)startSession; + [Export ("startSession")] + void StartSession (); + + // -(void)endSession; + [Export ("endSession")] + void EndSession (); + + // -(void)endSessionWithTimestamp:(NSDate * _Nonnull)timestamp; + [Export ("endSessionWithTimestamp:")] + void EndSessionWithTimestamp (NSDate timestamp); + + // // @property (nonatomic, strong) NSMutableArray *> * _Nonnull installedIntegrations; + // [Export ("installedIntegrations", ArgumentSemantic.Strong)] + // NSMutableArray InstalledIntegrations { get; set; } + + // -(SentryId * _Nonnull)captureEvent:(SentryEvent * _Nonnull)event __attribute__((swift_name("capture(event:)"))); + [Export ("captureEvent:")] + SentryId CaptureEvent (SentryEvent @event); + + // -(SentryId * _Nonnull)captureEvent:(SentryEvent * _Nonnull)event withScope:(SentryScope * _Nonnull)scope __attribute__((swift_name("capture(event:scope:)"))); + [Export ("captureEvent:withScope:")] + SentryId CaptureEvent (SentryEvent @event, SentryScope scope); + + // -(id _Nonnull)startTransactionWithName:(NSString * _Nonnull)name operation:(NSString * _Nonnull)operation __attribute__((swift_name("startTransaction(name:operation:)"))); + [Export ("startTransactionWithName:operation:")] + SentrySpan StartTransactionWithName (string name, string operation); + + // -(id _Nonnull)startTransactionWithName:(NSString * _Nonnull)name operation:(NSString * _Nonnull)operation bindToScope:(BOOL)bindToScope __attribute__((swift_name("startTransaction(name:operation:bindToScope:)"))); + [Export ("startTransactionWithName:operation:bindToScope:")] + SentrySpan StartTransactionWithName (string name, string operation, bool bindToScope); + + // -(id _Nonnull)startTransactionWithContext:(SentryTransactionContext * _Nonnull)transactionContext __attribute__((swift_name("startTransaction(transactionContext:)"))); + [Export ("startTransactionWithContext:")] + SentrySpan StartTransactionWithContext (SentryTransactionContext transactionContext); + + // -(id _Nonnull)startTransactionWithContext:(SentryTransactionContext * _Nonnull)transactionContext bindToScope:(BOOL)bindToScope __attribute__((swift_name("startTransaction(transactionContext:bindToScope:)"))); + [Export ("startTransactionWithContext:bindToScope:")] + SentrySpan StartTransactionWithContext (SentryTransactionContext transactionContext, bool bindToScope); + + // -(id _Nonnull)startTransactionWithContext:(SentryTransactionContext * _Nonnull)transactionContext bindToScope:(BOOL)bindToScope customSamplingContext:(NSDictionary * _Nonnull)customSamplingContext __attribute__((swift_name("startTransaction(transactionContext:bindToScope:customSamplingContext:)"))); + [Export ("startTransactionWithContext:bindToScope:customSamplingContext:")] + SentrySpan StartTransactionWithContext (SentryTransactionContext transactionContext, bool bindToScope, NSDictionary customSamplingContext); + + // -(id _Nonnull)startTransactionWithContext:(SentryTransactionContext * _Nonnull)transactionContext customSamplingContext:(NSDictionary * _Nonnull)customSamplingContext __attribute__((swift_name("startTransaction(transactionContext:customSamplingContext:)"))); + [Export ("startTransactionWithContext:customSamplingContext:")] + SentrySpan StartTransactionWithContext (SentryTransactionContext transactionContext, NSDictionary customSamplingContext); + + // -(SentryId * _Nonnull)captureError:(NSError * _Nonnull)error __attribute__((swift_name("capture(error:)"))); + [Export ("captureError:")] + SentryId CaptureError (NSError error); + + // -(SentryId * _Nonnull)captureError:(NSError * _Nonnull)error withScope:(SentryScope * _Nonnull)scope __attribute__((swift_name("capture(error:scope:)"))); + [Export ("captureError:withScope:")] + SentryId CaptureError (NSError error, SentryScope scope); + + // -(SentryId * _Nonnull)captureException:(NSException * _Nonnull)exception __attribute__((swift_name("capture(exception:)"))); + [Export ("captureException:")] + SentryId CaptureException (NSException exception); + + // -(SentryId * _Nonnull)captureException:(NSException * _Nonnull)exception withScope:(SentryScope * _Nonnull)scope __attribute__((swift_name("capture(exception:scope:)"))); + [Export ("captureException:withScope:")] + SentryId CaptureException (NSException exception, SentryScope scope); + + // -(SentryId * _Nonnull)captureMessage:(NSString * _Nonnull)message __attribute__((swift_name("capture(message:)"))); + [Export ("captureMessage:")] + SentryId CaptureMessage (string message); + + // -(SentryId * _Nonnull)captureMessage:(NSString * _Nonnull)message withScope:(SentryScope * _Nonnull)scope __attribute__((swift_name("capture(message:scope:)"))); + [Export ("captureMessage:withScope:")] + SentryId CaptureMessage (string message, SentryScope scope); + + // -(void)captureUserFeedback:(SentryUserFeedback * _Nonnull)userFeedback __attribute__((swift_name("capture(userFeedback:)"))); + [Export ("captureUserFeedback:")] + void CaptureUserFeedback (SentryUserFeedback userFeedback); + + // -(void)configureScope:(void (^ _Nonnull)(SentryScope * _Nonnull))callback; + [Export ("configureScope:")] + void ConfigureScope (Action callback); + + // -(void)addBreadcrumb:(SentryBreadcrumb * _Nonnull)crumb; + [Export ("addBreadcrumb:")] + void AddBreadcrumb (SentryBreadcrumb crumb); + + // -(SentryClient * _Nullable)getClient; + [NullAllowed, Export ("getClient")] + SentryClient Client { get; } + + // @property (readonly, nonatomic, strong) SentryScope * _Nonnull scope; + [Export ("scope", ArgumentSemantic.Strong)] + SentryScope Scope { get; } + + // -(void)bindClient:(SentryClient * _Nullable)client; + [Export ("bindClient:")] + void BindClient ([NullAllowed] SentryClient client); + + // -(id _Nullable)getIntegration:(NSString * _Nonnull)integrationName; + [Export ("getIntegration:")] + [return: NullAllowed] + NSObject GetIntegration (string integrationName); + + // -(BOOL)isIntegrationInstalled:(Class _Nonnull)integrationClass; + [Export ("isIntegrationInstalled:")] + bool IsIntegrationInstalled (Class integrationClass); + + // -(void)setUser:(SentryUser * _Nullable)user; + [Export ("setUser:")] + void SetUser ([NullAllowed] SentryUser user); + + // -(void)captureEnvelope:(SentryEnvelope * _Nonnull)envelope __attribute__((swift_name("capture(envelope:)"))); + [Export ("captureEnvelope:")] + void CaptureEnvelope (SentryEnvelope envelope); +} + +// @interface SentryId : NSObject +[BaseType (typeof(NSObject))] +[Internal] +interface SentryId +{ + // -(instancetype _Nonnull)initWithUUID:(NSUUID * _Nonnull)uuid; + [Export ("initWithUUID:")] + NativeHandle Constructor (NSUuid uuid); + + // -(instancetype _Nonnull)initWithUUIDString:(NSString * _Nonnull)string; + [Export ("initWithUUIDString:")] + NativeHandle Constructor (string @string); + + // @property (readonly, copy) NSString * _Nonnull sentryIdString; + [Export ("sentryIdString")] + string SentryIdString { get; } + + // @property (readonly, nonatomic, strong, class) SentryId * _Nonnull empty; + [Static] + [Export ("empty", ArgumentSemantic.Strong)] + SentryId Empty { get; } +} + +// @interface SentryMechanism : NSObject +[BaseType (typeof(NSObject))] +[DisableDefaultCtor] +[Internal] +interface SentryMechanism : SentrySerializable +{ + // @property (copy, nonatomic) NSString * _Nonnull type; + [Export ("type")] + string Type { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable desc; + [NullAllowed, Export ("desc")] + string Desc { get; set; } + + // @property (nonatomic, strong) NSDictionary * _Nullable data; + [NullAllowed, Export ("data", ArgumentSemantic.Strong)] + NSDictionary Data { get; set; } + + // @property (copy, nonatomic) NSNumber * _Nullable handled; + [NullAllowed, Export ("handled", ArgumentSemantic.Copy)] + NSNumber Handled { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable helpLink; + [NullAllowed, Export ("helpLink")] + string HelpLink { get; set; } + + // @property (nonatomic, strong) SentryMechanismMeta * _Nullable meta; + [NullAllowed, Export ("meta", ArgumentSemantic.Strong)] + SentryMechanismMeta Meta { get; set; } + + // -(instancetype _Nonnull)initWithType:(NSString * _Nonnull)type; + [Export ("initWithType:")] + NativeHandle Constructor (string type); +} + +// @interface SentryMechanismMeta : NSObject +[BaseType (typeof(NSObject))] +[Internal] +interface SentryMechanismMeta : SentrySerializable +{ + // @property (nonatomic, strong) NSDictionary * _Nullable signal; + [NullAllowed, Export ("signal", ArgumentSemantic.Strong)] + NSDictionary Signal { get; set; } + + // @property (nonatomic, strong) NSDictionary * _Nullable machException; + [NullAllowed, Export ("machException", ArgumentSemantic.Strong)] + NSDictionary MachException { get; set; } + + // @property (nonatomic, strong) SentryNSError * _Nullable error; + [NullAllowed, Export ("error", ArgumentSemantic.Strong)] + SentryNSError Error { get; set; } +} + +// @interface SentryMessage : NSObject +[BaseType (typeof(NSObject))] +[DisableDefaultCtor] +[Internal] +interface SentryMessage : SentrySerializable +{ + // -(instancetype _Nonnull)initWithFormatted:(NSString * _Nonnull)formatted; + [Export ("initWithFormatted:")] + NativeHandle Constructor (string formatted); + + // @property (readonly, copy, nonatomic) NSString * _Nonnull formatted; + [Export ("formatted")] + string Formatted { get; } + + // @property (copy, nonatomic) NSString * _Nullable message; + [NullAllowed, Export ("message")] + string Message { get; set; } + + // @property (nonatomic, strong) NSArray * _Nullable params; + [NullAllowed, Export ("params", ArgumentSemantic.Strong)] + string[] Params { get; set; } +} + +// @interface SentryNSError : NSObject +[BaseType (typeof(NSObject))] +[DisableDefaultCtor] +[Internal] +interface SentryNSError : SentrySerializable +{ + // @property (copy, nonatomic) NSString * _Nonnull domain; + [Export ("domain")] + string Domain { get; set; } + + // @property (assign, nonatomic) NSInteger code; + [Export ("code")] + nint Code { get; set; } + + // -(instancetype _Nonnull)initWithDomain:(NSString * _Nonnull)domain code:(NSInteger)code; + [Export ("initWithDomain:code:")] + NativeHandle Constructor (string domain, nint code); +} + +// @interface SentrySDK : NSObject +[BaseType (typeof(NSObject))] +[DisableDefaultCtor] +[Internal] +interface SentrySDK +{ + // @property (readonly, nonatomic, class) id _Nullable span; + [Static] + [NullAllowed, Export ("span")] + SentrySpan Span { get; } + + // @property (readonly, nonatomic, class) BOOL isEnabled; + [Static] + [Export ("isEnabled")] + bool IsEnabled { get; } + + // +(void)startWithOptions:(NSDictionary * _Nonnull)optionsDict __attribute__((swift_name("start(options:)"))); + [Static] + [Export ("startWithOptions:")] + void StartWithOptions (NSDictionary optionsDict); + + // +(void)startWithOptionsObject:(SentryOptions * _Nonnull)options __attribute__((swift_name("start(options:)"))); + [Static] + [Export ("startWithOptionsObject:")] + void StartWithOptionsObject (SentryOptions options); + + // +(void)startWithConfigureOptions:(void (^ _Nonnull)(SentryOptions * _Nonnull))configureOptions __attribute__((swift_name("start(configureOptions:)"))); + [Static] + [Export ("startWithConfigureOptions:")] + void StartWithConfigureOptions (Action configureOptions); + + // +(SentryId * _Nonnull)captureEvent:(SentryEvent * _Nonnull)event __attribute__((swift_name("capture(event:)"))); + [Static] + [Export ("captureEvent:")] + SentryId CaptureEvent (SentryEvent @event); + + // +(SentryId * _Nonnull)captureEvent:(SentryEvent * _Nonnull)event withScope:(SentryScope * _Nonnull)scope __attribute__((swift_name("capture(event:scope:)"))); + [Static] + [Export ("captureEvent:withScope:")] + SentryId CaptureEvent (SentryEvent @event, SentryScope scope); + + // +(SentryId * _Nonnull)captureEvent:(SentryEvent * _Nonnull)event withScopeBlock:(void (^ _Nonnull)(SentryScope * _Nonnull))block __attribute__((swift_name("capture(event:block:)"))); + [Static] + [Export ("captureEvent:withScopeBlock:")] + SentryId CaptureEvent (SentryEvent @event, Action block); + + // +(id _Nonnull)startTransactionWithName:(NSString * _Nonnull)name operation:(NSString * _Nonnull)operation __attribute__((swift_name("startTransaction(name:operation:)"))); + [Static] + [Export ("startTransactionWithName:operation:")] + SentrySpan StartTransactionWithName (string name, string operation); + + // +(id _Nonnull)startTransactionWithName:(NSString * _Nonnull)name operation:(NSString * _Nonnull)operation bindToScope:(BOOL)bindToScope __attribute__((swift_name("startTransaction(name:operation:bindToScope:)"))); + [Static] + [Export ("startTransactionWithName:operation:bindToScope:")] + SentrySpan StartTransactionWithName (string name, string operation, bool bindToScope); + + // +(id _Nonnull)startTransactionWithContext:(SentryTransactionContext * _Nonnull)transactionContext __attribute__((swift_name("startTransaction(transactionContext:)"))); + [Static] + [Export ("startTransactionWithContext:")] + SentrySpan StartTransactionWithContext (SentryTransactionContext transactionContext); + + // +(id _Nonnull)startTransactionWithContext:(SentryTransactionContext * _Nonnull)transactionContext bindToScope:(BOOL)bindToScope __attribute__((swift_name("startTransaction(transactionContext:bindToScope:)"))); + [Static] + [Export ("startTransactionWithContext:bindToScope:")] + SentrySpan StartTransactionWithContext (SentryTransactionContext transactionContext, bool bindToScope); + + // +(id _Nonnull)startTransactionWithContext:(SentryTransactionContext * _Nonnull)transactionContext bindToScope:(BOOL)bindToScope customSamplingContext:(NSDictionary * _Nonnull)customSamplingContext __attribute__((swift_name("startTransaction(transactionContext:bindToScope:customSamplingContext:)"))); + [Static] + [Export ("startTransactionWithContext:bindToScope:customSamplingContext:")] + SentrySpan StartTransactionWithContext (SentryTransactionContext transactionContext, bool bindToScope, NSDictionary customSamplingContext); + + // +(id _Nonnull)startTransactionWithContext:(SentryTransactionContext * _Nonnull)transactionContext customSamplingContext:(NSDictionary * _Nonnull)customSamplingContext __attribute__((swift_name("startTransaction(transactionContext:customSamplingContext:)"))); + [Static] + [Export ("startTransactionWithContext:customSamplingContext:")] + SentrySpan StartTransactionWithContext (SentryTransactionContext transactionContext, NSDictionary customSamplingContext); + + // +(SentryId * _Nonnull)captureError:(NSError * _Nonnull)error __attribute__((swift_name("capture(error:)"))); + [Static] + [Export ("captureError:")] + SentryId CaptureError (NSError error); + + // +(SentryId * _Nonnull)captureError:(NSError * _Nonnull)error withScope:(SentryScope * _Nonnull)scope __attribute__((swift_name("capture(error:scope:)"))); + [Static] + [Export ("captureError:withScope:")] + SentryId CaptureError (NSError error, SentryScope scope); + + // +(SentryId * _Nonnull)captureError:(NSError * _Nonnull)error withScopeBlock:(void (^ _Nonnull)(SentryScope * _Nonnull))block __attribute__((swift_name("capture(error:block:)"))); + [Static] + [Export ("captureError:withScopeBlock:")] + SentryId CaptureError (NSError error, Action block); + + // +(SentryId * _Nonnull)captureException:(NSException * _Nonnull)exception __attribute__((swift_name("capture(exception:)"))); + [Static] + [Export ("captureException:")] + SentryId CaptureException (NSException exception); + + // +(SentryId * _Nonnull)captureException:(NSException * _Nonnull)exception withScope:(SentryScope * _Nonnull)scope __attribute__((swift_name("capture(exception:scope:)"))); + [Static] + [Export ("captureException:withScope:")] + SentryId CaptureException (NSException exception, SentryScope scope); + + // +(SentryId * _Nonnull)captureException:(NSException * _Nonnull)exception withScopeBlock:(void (^ _Nonnull)(SentryScope * _Nonnull))block __attribute__((swift_name("capture(exception:block:)"))); + [Static] + [Export ("captureException:withScopeBlock:")] + SentryId CaptureException (NSException exception, Action block); + + // +(SentryId * _Nonnull)captureMessage:(NSString * _Nonnull)message __attribute__((swift_name("capture(message:)"))); + [Static] + [Export ("captureMessage:")] + SentryId CaptureMessage (string message); + + // +(SentryId * _Nonnull)captureMessage:(NSString * _Nonnull)message withScope:(SentryScope * _Nonnull)scope __attribute__((swift_name("capture(message:scope:)"))); + [Static] + [Export ("captureMessage:withScope:")] + SentryId CaptureMessage (string message, SentryScope scope); + + // +(SentryId * _Nonnull)captureMessage:(NSString * _Nonnull)message withScopeBlock:(void (^ _Nonnull)(SentryScope * _Nonnull))block __attribute__((swift_name("capture(message:block:)"))); + [Static] + [Export ("captureMessage:withScopeBlock:")] + SentryId CaptureMessage (string message, Action block); + + // +(void)captureUserFeedback:(SentryUserFeedback * _Nonnull)userFeedback __attribute__((swift_name("capture(userFeedback:)"))); + [Static] + [Export ("captureUserFeedback:")] + void CaptureUserFeedback (SentryUserFeedback userFeedback); + + // +(void)addBreadcrumb:(SentryBreadcrumb * _Nonnull)crumb __attribute__((swift_name("addBreadcrumb(crumb:)"))); + [Static] + [Export ("addBreadcrumb:")] + void AddBreadcrumb (SentryBreadcrumb crumb); + + // +(void)configureScope:(void (^ _Nonnull)(SentryScope * _Nonnull))callback; + [Static] + [Export ("configureScope:")] + void ConfigureScope (Action callback); + + // @property (readonly, nonatomic, class) BOOL crashedLastRun; + [Static] + [Export ("crashedLastRun")] + bool CrashedLastRun { get; } + + // +(void)setUser:(SentryUser * _Nullable)user; + [Static] + [Export ("setUser:")] + void SetUser ([NullAllowed] SentryUser user); + + // +(void)startSession; + [Static] + [Export ("startSession")] + void StartSession (); + + // +(void)endSession; + [Static] + [Export ("endSession")] + void EndSession (); + + // +(void)crash; + [Static] + [Export ("crash")] + void Crash (); + + // +(void)close; + [Static] + [Export ("close")] + void Close (); +} + +// @interface SentrySamplingContext : NSObject +[BaseType (typeof(NSObject))] +[Internal] +interface SentrySamplingContext +{ + // @property (readonly, nonatomic) SentryTransactionContext * _Nonnull transactionContext; + [Export ("transactionContext")] + SentryTransactionContext TransactionContext { get; } + + // @property (readonly, nonatomic) NSDictionary * _Nullable customSamplingContext; + [NullAllowed, Export ("customSamplingContext")] + NSDictionary CustomSamplingContext { get; } + + // -(instancetype _Nonnull)initWithTransactionContext:(SentryTransactionContext * _Nonnull)transactionContext; + [Export ("initWithTransactionContext:")] + NativeHandle Constructor (SentryTransactionContext transactionContext); + + // -(instancetype _Nonnull)initWithTransactionContext:(SentryTransactionContext * _Nonnull)transactionContext customSamplingContext:(NSDictionary * _Nonnull)customSamplingContext; + [Export ("initWithTransactionContext:customSamplingContext:")] + NativeHandle Constructor (SentryTransactionContext transactionContext, NSDictionary customSamplingContext); +} + +// @interface SentryScope : NSObject +[BaseType (typeof(NSObject))] +[Internal] +interface SentryScope : SentrySerializable +{ + // @property (nonatomic, strong) id _Nullable span; + [NullAllowed, Export ("span", ArgumentSemantic.Strong)] + SentrySpan Span { get; set; } + + // -(instancetype _Nonnull)initWithMaxBreadcrumbs:(NSInteger)maxBreadcrumbs __attribute__((objc_designated_initializer)); + [Export ("initWithMaxBreadcrumbs:")] + [DesignatedInitializer] + NativeHandle Constructor (nint maxBreadcrumbs); + + // -(instancetype _Nonnull)initWithScope:(SentryScope * _Nonnull)scope; + [Export ("initWithScope:")] + NativeHandle Constructor (SentryScope scope); + + // -(void)setUser:(SentryUser * _Nullable)user; + [Export ("setUser:")] + void SetUser ([NullAllowed] SentryUser user); + + // -(void)setTagValue:(NSString * _Nonnull)value forKey:(NSString * _Nonnull)key __attribute__((swift_name("setTag(value:key:)"))); + [Export ("setTagValue:forKey:")] + void SetTagValue (string value, string key); + + // -(void)removeTagForKey:(NSString * _Nonnull)key __attribute__((swift_name("removeTag(key:)"))); + [Export ("removeTagForKey:")] + void RemoveTagForKey (string key); + + // -(void)setTags:(NSDictionary * _Nullable)tags; + [Export ("setTags:")] + void SetTags ([NullAllowed] NSDictionary tags); + + // -(void)setExtras:(NSDictionary * _Nullable)extras; + [Export ("setExtras:")] + void SetExtras ([NullAllowed] NSDictionary extras); + + // -(void)setExtraValue:(id _Nullable)value forKey:(NSString * _Nonnull)key __attribute__((swift_name("setExtra(value:key:)"))); + [Export ("setExtraValue:forKey:")] + void SetExtraValue ([NullAllowed] NSObject value, string key); + + // -(void)removeExtraForKey:(NSString * _Nonnull)key __attribute__((swift_name("removeExtra(key:)"))); + [Export ("removeExtraForKey:")] + void RemoveExtraForKey (string key); + + // -(void)setDist:(NSString * _Nullable)dist; + [Export ("setDist:")] + void SetDist ([NullAllowed] string dist); + + // -(void)setEnvironment:(NSString * _Nullable)environment; + [Export ("setEnvironment:")] + void SetEnvironment ([NullAllowed] string environment); + + // -(void)setFingerprint:(NSArray * _Nullable)fingerprint; + [Export ("setFingerprint:")] + void SetFingerprint ([NullAllowed] string[] fingerprint); + + // -(void)setLevel:(enum SentryLevel)level; + [Export ("setLevel:")] + void SetLevel (SentryLevel level); + + // -(void)addBreadcrumb:(SentryBreadcrumb * _Nonnull)crumb; + [Export ("addBreadcrumb:")] + void AddBreadcrumb (SentryBreadcrumb crumb); + + // -(void)clearBreadcrumbs; + [Export ("clearBreadcrumbs")] + void ClearBreadcrumbs (); + + // -(NSDictionary * _Nonnull)serialize; + [Export ("serialize")] + NSDictionary Serialize(); + + // -(SentryEvent * _Nullable)applyToEvent:(SentryEvent * _Nonnull)event maxBreadcrumb:(NSUInteger)maxBreadcrumbs; + [Export ("applyToEvent:maxBreadcrumb:")] + [return: NullAllowed] + SentryEvent ApplyToEvent (SentryEvent @event, nuint maxBreadcrumbs); + + // -(void)applyToSession:(SentrySession * _Nonnull)session; + [Export ("applyToSession:")] + void ApplyToSession (SentrySession session); + + // -(void)setContextValue:(NSDictionary * _Nonnull)value forKey:(NSString * _Nonnull)key __attribute__((swift_name("setContext(value:key:)"))); + [Export ("setContextValue:forKey:")] + void SetContextValue (NSDictionary value, string key); + + // -(void)removeContextForKey:(NSString * _Nonnull)key __attribute__((swift_name("removeContext(key:)"))); + [Export ("removeContextForKey:")] + void RemoveContextForKey (string key); + + // -(void)addAttachment:(SentryAttachment * _Nonnull)attachment; + [Export ("addAttachment:")] + void AddAttachment (SentryAttachment attachment); + + // -(void)clearAttachments; + [Export ("clearAttachments")] + void ClearAttachments (); + + // -(void)clear; + [Export ("clear")] + void Clear (); + + // -(void)useSpan:(SentrySpanCallback _Nonnull)callback; + [Export ("useSpan:")] + void UseSpan (Action callback); +} + +// @interface SentryScreenFrames : NSObject +[BaseType (typeof(NSObject))] +[DisableDefaultCtor] +[Internal] +interface SentryScreenFrames +{ + // -(instancetype _Nonnull)initWithTotal:(NSUInteger)total frozen:(NSUInteger)frozen slow:(NSUInteger)slow; + [Export ("initWithTotal:frozen:slow:")] + NativeHandle Constructor (nuint total, nuint frozen, nuint slow); + + // -(instancetype _Nonnull)initWithTotal:(NSUInteger)total frozen:(NSUInteger)frozen slow:(NSUInteger)slow frameTimestamps:(SentryFrameInfoTimeSeries * _Nonnull)frameTimestamps frameRateTimestamps:(SentryFrameInfoTimeSeries * _Nonnull)frameRateTimestamps; + [Export ("initWithTotal:frozen:slow:frameTimestamps:frameRateTimestamps:")] + NativeHandle Constructor (nuint total, nuint frozen, nuint slow, NSDictionary[] frameTimestamps, NSDictionary[] frameRateTimestamps); + + // @property (readonly, assign, nonatomic) NSUInteger total; + [Export ("total")] + nuint Total { get; } + + // @property (readonly, assign, nonatomic) NSUInteger frozen; + [Export ("frozen")] + nuint Frozen { get; } + + // @property (readonly, assign, nonatomic) NSUInteger slow; + [Export ("slow")] + nuint Slow { get; } + + // @property (readonly, copy, nonatomic) SentryFrameInfoTimeSeries * _Nonnull frameTimestamps; + [Export ("frameTimestamps", ArgumentSemantic.Copy)] + NSDictionary[] FrameTimestamps { get; } + + // @property (readonly, copy, nonatomic) SentryFrameInfoTimeSeries * _Nonnull frameRateTimestamps; + [Export ("frameRateTimestamps", ArgumentSemantic.Copy)] + NSDictionary[] FrameRateTimestamps { get; } +} + +// @interface SentrySdkInfo : NSObject +[BaseType (typeof(NSObject))] +[DisableDefaultCtor] +[Internal] +interface SentrySdkInfo : SentrySerializable +{ + // @property (readonly, copy, nonatomic) NSString * _Nonnull name; + [Export ("name")] + string Name { get; } + + // @property (readonly, copy, nonatomic) NSString * _Nonnull version; + [Export ("version")] + string Version { get; } + + // -(instancetype _Nonnull)initWithName:(NSString * _Nonnull)name andVersion:(NSString * _Nonnull)version __attribute__((objc_designated_initializer)); + [Export ("initWithName:andVersion:")] + [DesignatedInitializer] + NativeHandle Constructor (string name, string version); + + // -(instancetype _Nonnull)initWithDict:(NSDictionary * _Nonnull)dict; + [Export ("initWithDict:")] + NativeHandle Constructor (NSDictionary dict); + + // -(instancetype _Nonnull)initWithDict:(NSDictionary * _Nonnull)dict orDefaults:(SentrySdkInfo * _Nonnull)info; + [Export ("initWithDict:orDefaults:")] + NativeHandle Constructor (NSDictionary dict, SentrySdkInfo info); +} + +// @interface SentrySession : NSObject +[BaseType (typeof(NSObject))] +[DisableDefaultCtor] +[Internal] +interface SentrySession : SentrySerializable //, INSCopying +{ + // -(instancetype _Nonnull)initWithReleaseName:(NSString * _Nonnull)releaseName; + [Export ("initWithReleaseName:")] + NativeHandle Constructor (string releaseName); + + // -(instancetype _Nullable)initWithJSONObject:(NSDictionary * _Nonnull)jsonObject; + [Export ("initWithJSONObject:")] + NativeHandle Constructor (NSDictionary jsonObject); + + // -(void)endSessionExitedWithTimestamp:(NSDate * _Nonnull)timestamp; + [Export ("endSessionExitedWithTimestamp:")] + void EndSessionExitedWithTimestamp (NSDate timestamp); + + // -(void)endSessionCrashedWithTimestamp:(NSDate * _Nonnull)timestamp; + [Export ("endSessionCrashedWithTimestamp:")] + void EndSessionCrashedWithTimestamp (NSDate timestamp); + + // -(void)endSessionAbnormalWithTimestamp:(NSDate * _Nonnull)timestamp; + [Export ("endSessionAbnormalWithTimestamp:")] + void EndSessionAbnormalWithTimestamp (NSDate timestamp); + + // -(void)incrementErrors; + [Export ("incrementErrors")] + void IncrementErrors (); + + // @property (readonly, nonatomic, strong) NSUUID * _Nonnull sessionId; + [Export ("sessionId", ArgumentSemantic.Strong)] + NSUuid SessionId { get; } + + // @property (readonly, nonatomic, strong) NSDate * _Nonnull started; + [Export ("started", ArgumentSemantic.Strong)] + NSDate Started { get; } + + // @property (readonly, nonatomic) enum SentrySessionStatus status; + [Export ("status")] + SentrySessionStatus Status { get; } + + // @property (readonly, nonatomic) NSUInteger errors; + [Export ("errors")] + nuint Errors { get; } + + // @property (readonly, nonatomic) NSUInteger sequence; + [Export ("sequence")] + nuint Sequence { get; } + + // @property (readonly, nonatomic, strong) NSString * _Nonnull distinctId; + [Export ("distinctId", ArgumentSemantic.Strong)] + string DistinctId { get; } + + // @property (readonly, copy, nonatomic) NSNumber * _Nullable flagInit; + [NullAllowed, Export ("flagInit", ArgumentSemantic.Copy)] + NSNumber FlagInit { get; } + + // @property (readonly, nonatomic, strong) NSDate * _Nullable timestamp; + [NullAllowed, Export ("timestamp", ArgumentSemantic.Strong)] + NSDate Timestamp { get; } + + // @property (readonly, nonatomic, strong) NSNumber * _Nullable duration; + [NullAllowed, Export ("duration", ArgumentSemantic.Strong)] + NSNumber Duration { get; } + + // @property (readonly, copy, nonatomic) NSString * _Nullable releaseName; + [NullAllowed, Export ("releaseName")] + string ReleaseName { get; } + + // @property (copy, nonatomic) NSString * _Nullable environment; + [NullAllowed, Export ("environment")] + string Environment { get; set; } + + // @property (copy, nonatomic) SentryUser * _Nullable user; + [NullAllowed, Export ("user", ArgumentSemantic.Copy)] + SentryUser User { get; set; } + + // -(NSDictionary * _Nonnull)serialize; + [Export ("serialize")] + NSDictionary Serialize(); +} + +// @interface SentrySpanId : NSObject +[BaseType (typeof(NSObject))] +[Internal] +interface SentrySpanId // : INSCopying +{ + // -(instancetype _Nonnull)initWithUUID:(NSUUID * _Nonnull)uuid; + [Export ("initWithUUID:")] + NativeHandle Constructor (NSUuid uuid); + + // -(instancetype _Nonnull)initWithValue:(NSString * _Nonnull)value; + [Export ("initWithValue:")] + NativeHandle Constructor (string value); + + // @property (readonly, copy) NSString * _Nonnull sentrySpanIdString; + [Export ("sentrySpanIdString")] + string SentrySpanIdString { get; } + + // @property (readonly, nonatomic, strong, class) SentrySpanId * _Nonnull empty; + [Static] + [Export ("empty", ArgumentSemantic.Strong)] + SentrySpanId Empty { get; } +} + +// @interface SentryStacktrace : NSObject +[BaseType (typeof(NSObject))] +[DisableDefaultCtor] +[Internal] +interface SentryStacktrace : SentrySerializable +{ + // @property (nonatomic, strong) NSArray * _Nonnull frames; + [Export ("frames", ArgumentSemantic.Strong)] + SentryFrame[] Frames { get; set; } + + // @property (nonatomic, strong) NSDictionary * _Nonnull registers; + [Export ("registers", ArgumentSemantic.Strong)] + NSDictionary Registers { get; set; } + + // -(instancetype _Nonnull)initWithFrames:(NSArray * _Nonnull)frames registers:(NSDictionary * _Nonnull)registers; + [Export ("initWithFrames:registers:")] + NativeHandle Constructor (SentryFrame[] frames, NSDictionary registers); + + // -(void)fixDuplicateFrames; + [Export ("fixDuplicateFrames")] + void FixDuplicateFrames (); +} + +// @interface SentryThread : NSObject +[BaseType (typeof(NSObject))] +[DisableDefaultCtor] +[Internal] +interface SentryThread : SentrySerializable +{ + // @property (copy, nonatomic) NSNumber * _Nonnull threadId; + [Export ("threadId", ArgumentSemantic.Copy)] + NSNumber ThreadId { get; set; } + + // @property (copy, nonatomic) NSString * _Nullable name; + [NullAllowed, Export ("name")] + string Name { get; set; } + + // @property (nonatomic, strong) SentryStacktrace * _Nullable stacktrace; + [NullAllowed, Export ("stacktrace", ArgumentSemantic.Strong)] + SentryStacktrace Stacktrace { get; set; } + + // @property (copy, nonatomic) NSNumber * _Nullable crashed; + [NullAllowed, Export ("crashed", ArgumentSemantic.Copy)] + NSNumber Crashed { get; set; } + + // @property (copy, nonatomic) NSNumber * _Nullable current; + [NullAllowed, Export ("current", ArgumentSemantic.Copy)] + NSNumber Current { get; set; } + + // -(instancetype _Nonnull)initWithThreadId:(NSNumber * _Nonnull)threadId; + [Export ("initWithThreadId:")] + NativeHandle Constructor (NSNumber threadId); +} + +// @interface SentryTraceHeader : NSObject +[BaseType (typeof(NSObject))] +[DisableDefaultCtor] +[Internal] +interface SentryTraceHeader +{ + // @property (readonly, nonatomic) SentryId * _Nonnull traceId; + [Export ("traceId")] + SentryId TraceId { get; } + + // @property (readonly, nonatomic) SentrySpanId * _Nonnull spanId; + [Export ("spanId")] + SentrySpanId SpanId { get; } + + // @property (readonly, nonatomic) SentrySampleDecision sampled; + [Export ("sampled")] + SentrySampleDecision Sampled { get; } + + // -(instancetype _Nonnull)initWithTraceId:(SentryId * _Nonnull)traceId spanId:(SentrySpanId * _Nonnull)spanId sampled:(SentrySampleDecision)sampled; + [Export ("initWithTraceId:spanId:sampled:")] + NativeHandle Constructor (SentryId traceId, SentrySpanId spanId, SentrySampleDecision sampled); + + // -(NSString * _Nonnull)value; + [Export ("value")] + string Value { get; } +} + +// @interface SentryTransactionContext : SentrySpanContext +[BaseType (typeof(SentrySpanContext))] +[DisableDefaultCtor] +[Internal] +interface SentryTransactionContext +{ + // @property (readonly, nonatomic) NSString * _Nonnull name; + [Export ("name")] + string Name { get; } + + // @property (nonatomic) SentrySampleDecision parentSampled; + [Export ("parentSampled", ArgumentSemantic.Assign)] + SentrySampleDecision ParentSampled { get; set; } + + // @property (nonatomic, strong) NSNumber * _Nullable sampleRate; + [NullAllowed, Export ("sampleRate", ArgumentSemantic.Strong)] + NSNumber SampleRate { get; set; } + + // -(instancetype _Nonnull)initWithName:(NSString * _Nonnull)name operation:(NSString * _Nonnull)operation; + [Export ("initWithName:operation:")] + NativeHandle Constructor (string name, string operation); + + // -(instancetype _Nonnull)initWithName:(NSString * _Nonnull)name operation:(NSString * _Nonnull)operation sampled:(SentrySampleDecision)sampled; + [Export ("initWithName:operation:sampled:")] + NativeHandle Constructor (string name, string operation, SentrySampleDecision sampled); + + // -(instancetype _Nonnull)initWithName:(NSString * _Nonnull)name operation:(NSString * _Nonnull)operation traceId:(SentryId * _Nonnull)traceId spanId:(SentrySpanId * _Nonnull)spanId parentSpanId:(SentrySpanId * _Nullable)parentSpanId parentSampled:(SentrySampleDecision)parentSampled; + [Export ("initWithName:operation:traceId:spanId:parentSpanId:parentSampled:")] + NativeHandle Constructor (string name, string operation, SentryId traceId, SentrySpanId spanId, [NullAllowed] SentrySpanId parentSpanId, SentrySampleDecision parentSampled); +} + +// @interface SentryUser : NSObject +[BaseType (typeof(NSObject))] +[Internal] +interface SentryUser : SentrySerializable //, INSCopying +{ + // @property (copy, atomic) NSString * _Nonnull userId; + [Export ("userId")] + string UserId { get; set; } + + // @property (copy, atomic) NSString * _Nullable email; + [NullAllowed, Export ("email")] + string Email { get; set; } + + // @property (copy, atomic) NSString * _Nullable username; + [NullAllowed, Export ("username")] + string Username { get; set; } + + // @property (copy, atomic) NSString * _Nullable ipAddress; + [NullAllowed, Export ("ipAddress")] + string IpAddress { get; set; } + + // @property (atomic, strong) NSDictionary * _Nullable data; + [NullAllowed, Export ("data", ArgumentSemantic.Strong)] + NSDictionary Data { get; set; } + + // -(instancetype _Nonnull)initWithUserId:(NSString * _Nonnull)userId; + [Export ("initWithUserId:")] + NativeHandle Constructor (string userId); + + // // -(BOOL)isEqual:(id _Nullable)other; + // [Export ("isEqual:")] + // bool IsEqual ([NullAllowed] NSObject other); + + // -(BOOL)isEqualToUser:(SentryUser * _Nonnull)user; + [Export ("isEqualToUser:")] + bool IsEqualToUser (SentryUser user); + + // -(NSUInteger)hash; + [Export ("hash")] + nuint Hash { get; } +} + +// @interface SentryUserFeedback : NSObject +[BaseType (typeof(NSObject))] +[DisableDefaultCtor] +[Internal] +interface SentryUserFeedback : SentrySerializable +{ + // -(instancetype _Nonnull)initWithEventId:(SentryId * _Nonnull)eventId; + [Export ("initWithEventId:")] + NativeHandle Constructor (SentryId eventId); + + // @property (readonly, nonatomic, strong) SentryId * _Nonnull eventId; + [Export ("eventId", ArgumentSemantic.Strong)] + SentryId EventId { get; } + + // @property (copy, nonatomic) NSString * _Nonnull name; + [Export ("name")] + string Name { get; set; } + + // @property (copy, nonatomic) NSString * _Nonnull email; + [Export ("email")] + string Email { get; set; } + + // @property (copy, nonatomic) NSString * _Nonnull comments; + [Export ("comments")] + string Comments { get; set; } +} diff --git a/src/Sentry/Platforms/iOS/Bindings/StructsAndEnums.cs b/src/Sentry/Platforms/iOS/Bindings/StructsAndEnums.cs new file mode 100644 index 0000000000..9169c61738 --- /dev/null +++ b/src/Sentry/Platforms/iOS/Bindings/StructsAndEnums.cs @@ -0,0 +1,98 @@ +using System.Runtime.InteropServices; +using Foundation; +using ObjCRuntime; +using Sentry; + +namespace Sentry.Cocoa; + +[Native] +internal enum SentryLogLevel : long +{ + None = 1, + Error, + Debug, + Verbose +} + +[Native] +internal enum SentryLevel : ulong +{ + None = 0, + Debug = 1, + Info = 2, + Warning = 3, + Error = 4, + Fatal = 5 +} + +[Native] +internal enum SentryAppStartType : ulong +{ + Warm, + Cold, + Unknown +} + +[Native] +internal enum SentryError : long +{ + UnknownError = -1, + InvalidDsnError = 100, + SentryCrashNotInstalledError = 101, + InvalidCrashReportError = 102, + CompressionError = 103, + JsonConversionError = 104, + CouldNotFindDirectory = 105, + RequestError = 106, + EventNotSent = 107 +} + +// internal static class CFunctions +// { +// // extern NSError * _Nullable NSErrorFromSentryError (SentryError error, NSString * _Nonnull description) __attribute__((visibility("default"))); +// [DllImport ("__Internal")] +// [Verify (PlatformInvoke)] +// [Internal] +// [return: NullAllowed] +// static extern NSError NSErrorFromSentryError (SentryError error, NSString description); +// } + +[Native] +internal enum SentrySampleDecision : ulong +{ + Undecided, + Yes, + No +} + +[Native] +internal enum SentrySpanStatus : ulong +{ + Undefined, + Ok, + DeadlineExceeded, + Unauthenticated, + PermissionDenied, + NotFound, + ResourceExhausted, + InvalidArgument, + Unimplemented, + Unavailable, + InternalError, + UnknownError, + Cancelled, + AlreadyExists, + FailedPrecondition, + Aborted, + OutOfRange, + DataLoss +} + +[Native] +internal enum SentrySessionStatus : ulong +{ + Ok = 0, + Exited = 1, + Crashed = 2, + Abnormal = 3 +} diff --git a/src/Sentry/Platforms/iOS/Sentry.iOS.props b/src/Sentry/Platforms/iOS/Sentry.iOS.props new file mode 100644 index 0000000000..50061bb7b4 --- /dev/null +++ b/src/Sentry/Platforms/iOS/Sentry.iOS.props @@ -0,0 +1,57 @@ + + + + 10 + true + 9.0 + 13.1 + true + true + + + + + + + + + + + + 7.22.0 + $(BaseIntermediateOutputPath)sdks\Sentry\Cocoa\$(SentryCocoaSdkVersion)\ + $(SentryCocoaSdkDirectory)Carthage\Build\Sentry.xcframework + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Sentry/Platforms/iOS/SentryOptions.cs b/src/Sentry/Platforms/iOS/SentryOptions.cs new file mode 100644 index 0000000000..a1a081d0ad --- /dev/null +++ b/src/Sentry/Platforms/iOS/SentryOptions.cs @@ -0,0 +1,19 @@ +namespace Sentry; + +public partial class SentryOptions +{ + /// + /// Exposes additional options for the iOS platform. + /// + public IOSOptions IOS { get; } = new(); + + /// + /// Provides additional options for the iOS platform. + /// + public class IOSOptions + { + internal IOSOptions() { } + + // TODO + } +} diff --git a/src/Sentry/Platforms/iOS/SentrySdk.cs b/src/Sentry/Platforms/iOS/SentrySdk.cs new file mode 100644 index 0000000000..6e059c0056 --- /dev/null +++ b/src/Sentry/Platforms/iOS/SentrySdk.cs @@ -0,0 +1,6 @@ +namespace Sentry; + +public static partial class SentrySdk +{ + // TODO +} diff --git a/src/Sentry/Properties/AssemblyInfo.cs b/src/Sentry/Properties/AssemblyInfo.cs index d81260cead..d8912e7113 100644 --- a/src/Sentry/Properties/AssemblyInfo.cs +++ b/src/Sentry/Properties/AssemblyInfo.cs @@ -31,9 +31,10 @@ // This attribute automatically adds the metadata to the final AndroidManifest.xml [assembly: Android.App.MetaData("io.sentry.auto-init", Value = "false")] -#else +#endif -// The Android target is not CLS Compliant -[assembly: CLSCompliant(true)] +// The targets for these platforms are not CLS Compliant +#if !(ANDROID || IOS || MACCATALYST) +[assembly: CLSCompliant(true)] #endif diff --git a/src/Sentry/Sentry.csproj b/src/Sentry/Sentry.csproj index 055af6a1e7..65f90c2f1f 100644 --- a/src/Sentry/Sentry.csproj +++ b/src/Sentry/Sentry.csproj @@ -13,6 +13,7 @@ net6.0;net5.0;netcoreapp3.0;netstandard2.1;netstandard2.0;net461;net6.0-android + $(TargetFrameworks);net6.0-ios;net6.0-maccatalyst @@ -21,6 +22,8 @@ + + From a145ceaddbe6362bbf8ccb76f91d7f12e0cf0988 Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Sat, 30 Jul 2022 11:56:10 -0700 Subject: [PATCH 03/25] Add iOS Sample --- samples/Sentry.Samples.Ios/AppDelegate.cs | 30 +++++ .../AppIcon.appiconset/Contents.json | 117 ++++++++++++++++++ .../AppIcon.appiconset/Icon1024.png | Bin 0 -> 70429 bytes .../AppIcon.appiconset/Icon120.png | Bin 0 -> 3773 bytes .../AppIcon.appiconset/Icon152.png | Bin 0 -> 4750 bytes .../AppIcon.appiconset/Icon167.png | Bin 0 -> 4692 bytes .../AppIcon.appiconset/Icon180.png | Bin 0 -> 5192 bytes .../AppIcon.appiconset/Icon20.png | Bin 0 -> 1313 bytes .../AppIcon.appiconset/Icon29.png | Bin 0 -> 845 bytes .../AppIcon.appiconset/Icon40.png | Bin 0 -> 1101 bytes .../AppIcon.appiconset/Icon58.png | Bin 0 -> 1761 bytes .../AppIcon.appiconset/Icon60.png | Bin 0 -> 2537 bytes .../AppIcon.appiconset/Icon76.png | Bin 0 -> 2332 bytes .../AppIcon.appiconset/Icon80.png | Bin 0 -> 2454 bytes .../AppIcon.appiconset/Icon87.png | Bin 0 -> 2758 bytes samples/Sentry.Samples.Ios/Entitlements.plist | 6 + samples/Sentry.Samples.Ios/Info.plist | 42 +++++++ .../LaunchScreen.storyboard | 26 ++++ samples/Sentry.Samples.Ios/Main.cs | 6 + .../Resources/LaunchScreen.xib | 43 +++++++ samples/Sentry.Samples.Ios/SceneDelegate.cs | 54 ++++++++ .../Sentry.Samples.Ios.csproj | 25 ++++ 22 files changed, 349 insertions(+) create mode 100644 samples/Sentry.Samples.Ios/AppDelegate.cs create mode 100644 samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon1024.png create mode 100644 samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon120.png create mode 100644 samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon152.png create mode 100644 samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon167.png create mode 100644 samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon180.png create mode 100644 samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon20.png create mode 100644 samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon29.png create mode 100644 samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon40.png create mode 100644 samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon58.png create mode 100644 samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon60.png create mode 100644 samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon76.png create mode 100644 samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon80.png create mode 100644 samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon87.png create mode 100644 samples/Sentry.Samples.Ios/Entitlements.plist create mode 100644 samples/Sentry.Samples.Ios/Info.plist create mode 100644 samples/Sentry.Samples.Ios/LaunchScreen.storyboard create mode 100644 samples/Sentry.Samples.Ios/Main.cs create mode 100644 samples/Sentry.Samples.Ios/Resources/LaunchScreen.xib create mode 100644 samples/Sentry.Samples.Ios/SceneDelegate.cs create mode 100644 samples/Sentry.Samples.Ios/Sentry.Samples.Ios.csproj diff --git a/samples/Sentry.Samples.Ios/AppDelegate.cs b/samples/Sentry.Samples.Ios/AppDelegate.cs new file mode 100644 index 0000000000..8e6064adef --- /dev/null +++ b/samples/Sentry.Samples.Ios/AppDelegate.cs @@ -0,0 +1,30 @@ +namespace Sentry.Samples.Ios; + +[Register ("AppDelegate")] +public class AppDelegate : UIApplicationDelegate { + public override UIWindow? Window { + get; + set; + } + + public override bool FinishedLaunching (UIApplication application, NSDictionary launchOptions) + { + // create a new window instance based on the screen size + Window = new UIWindow (UIScreen.MainScreen.Bounds); + + // create a UIViewController with a single UILabel + var vc = new UIViewController (); + vc.View!.AddSubview (new UILabel (Window!.Frame) { + BackgroundColor = UIColor.SystemBackground, + TextAlignment = UITextAlignment.Center, + Text = "Hello, iOS!", + AutoresizingMask = UIViewAutoresizing.All, + }); + Window.RootViewController = vc; + + // make the window visible + Window.MakeKeyAndVisible (); + + return true; + } +} diff --git a/samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Contents.json b/samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000..98f4d035c8 --- /dev/null +++ b/samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,117 @@ +{ + "images": [ + { + "scale": "2x", + "size": "20x20", + "idiom": "iphone", + "filename": "Icon40.png" + }, + { + "scale": "3x", + "size": "20x20", + "idiom": "iphone", + "filename": "Icon60.png" + }, + { + "scale": "2x", + "size": "29x29", + "idiom": "iphone", + "filename": "Icon58.png" + }, + { + "scale": "3x", + "size": "29x29", + "idiom": "iphone", + "filename": "Icon87.png" + }, + { + "scale": "2x", + "size": "40x40", + "idiom": "iphone", + "filename": "Icon80.png" + }, + { + "scale": "3x", + "size": "40x40", + "idiom": "iphone", + "filename": "Icon120.png" + }, + { + "scale": "2x", + "size": "60x60", + "idiom": "iphone", + "filename": "Icon120.png" + }, + { + "scale": "3x", + "size": "60x60", + "idiom": "iphone", + "filename": "Icon180.png" + }, + { + "scale": "1x", + "size": "20x20", + "idiom": "ipad", + "filename": "Icon20.png" + }, + { + "scale": "2x", + "size": "20x20", + "idiom": "ipad", + "filename": "Icon40.png" + }, + { + "scale": "1x", + "size": "29x29", + "idiom": "ipad", + "filename": "Icon29.png" + }, + { + "scale": "2x", + "size": "29x29", + "idiom": "ipad", + "filename": "Icon58.png" + }, + { + "scale": "1x", + "size": "40x40", + "idiom": "ipad", + "filename": "Icon40.png" + }, + { + "scale": "2x", + "size": "40x40", + "idiom": "ipad", + "filename": "Icon80.png" + }, + { + "scale": "1x", + "size": "76x76", + "idiom": "ipad", + "filename": "Icon76.png" + }, + { + "scale": "2x", + "size": "76x76", + "idiom": "ipad", + "filename": "Icon152.png" + }, + { + "scale": "2x", + "size": "83.5x83.5", + "idiom": "ipad", + "filename": "Icon167.png" + }, + { + "scale": "1x", + "size": "1024x1024", + "idiom": "ios-marketing", + "filename": "Icon1024.png" + } + ], + "properties": {}, + "info": { + "version": 1, + "author": "xcode" + } +} \ No newline at end of file diff --git a/samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon1024.png b/samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon1024.png new file mode 100644 index 0000000000000000000000000000000000000000..9174c989a9c8b8a5ca133228f4ed7c173fffd2ee GIT binary patch literal 70429 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 z zCn)b8&=oMu6ygwwJfdasJX|@L6?m1Dv0X9t>JAWO^UIj0#&(3UrHx;vP^3g= zL{(XT!?`D*pP8)WoGHYEZZc$!odTzb8n)q0|88*>6P z`?6&CSv_W7r2yF0beQ2*?V^_%pKktVAo`)T^26X@NpK_*-ni{D7{Sp{C0A<|16l(; zOL*xGW|*sKsiwHvE!h3QXe@^a#6W3}8!DQu-h?A_4gkeRYkt4NC~GR5P8eyp;9kVQ8$QG$5ad7Fo23Z~ak1jY~RXG{v?3G$RarFe`XePu3X{R+=mBOw&X zks)|Sc$RcG-jhn!`~-x|vg!&DA&@}QH^RNdyy9nq56yrU$^qAaS+F_NOaeFb)CVaH z?!UvPajgrK&zqdAs>&Def#wkcG_UhmYOVw^M`VZz@+4IWAVzK%`+za9rm2SD9={u@ zlx5D6UDL;lc7#9`+%vnlP3PescU=N`DHQPt_N55GNBMkVCRMR4?fvp zAFsvcHN4c9rb>J@{*IH>RTr9de%9i4Gd(cbFa9SP4anhoP;TA0!oZyB8?lNMDHPHK zCaOaFU9?x2A!o>p>mCF9r+hKs9Czu_P1l$LWU%}q#)=T3p`ZnYyeHmsewqw`}L^4LuHqfo+CG6<2n7#l^3;H^^!1 zsaieYFnN)Kc7Mv}^xE)4kXUw8<9I+jMB@QV9T9I8haLDt1Ne#exWUfGYG$4uMoEu& zo81#2up18Y40h%tIsOZglp(ltVsE*j1~$lVd|;rN)&${~o~-%KZnJp&3|OFR{^8E9 zJ;fCu53Ysw%}@VYWE*z7r)&4P=^B-SF%a@>*9g84<4aFUZT7x)qdsS+#2tu5NbpU@ zg;EwV)l-#sK>#r9>(0Figx{9lKm>KvRj;y<8 zc8SxMW4<11(s@QMV_}n9MRzA*62->vzxmHh1)GVASEJY7LVtRw`Rv{v`(Fuc00(&o z%m>gS2aJekmdNQ4p<{pD3HqZ-%4hdU1__xYhLi9mTJXD|E zE`t6SX)}l_DY5vO0Xrs#O6_DKtPKn0f+e~SprDYmJL_`<053iA5P`zn z4<5etc%aF58sHFr#M;U-9|=;l)J#Q2vS!Q9(d(EX6fubL%uA_lqa2%!cpNIv78QZ}Ayo(>C(ZpsRtKhzD--fpuoCch87cX-Bna9_{z%$b*dHM0?+T&Hk!+^UM`r|vq z2Id$??bX^|tfYaE+h#Nik(ZcN+wt)28q^gWe!y8jDCXrD<2qV#49x@5$8&Zrd5NTs zNYcix;9fe#PQQ;T?!6hG>9K{K+RCPqiGc9z%t{=`QaX>7O{l(+#7mJ1>Rae^J?82e z6cLqLypskTCyu>uc~$0-XZ^1Qvhwr+pKQ#CKImhGu*MGM*ZrROuAHWuT*yM$ieEy8*KLFMMdLZL|D+yDmy@3_PELTEVMI6nwfcYA3ZQ9wwKdtkT z;`;z7fU{U6>CS7kr3=A-()_G*G(Mjf2wXKe

Fpy)y!S(AQHSG#udd_8#b4sQu!R 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 PgFh2POM|ilu9yD@)d*=D literal 0 HcmV?d00001 diff --git a/samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon120.png b/samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon120.png new file mode 100644 index 0000000000000000000000000000000000000000..9c60a1761dbf62cc2a45ff98b9fdb63ade16e4d9 GIT binary patch literal 3773 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 Dh-f%Y literal 0 HcmV?d00001 diff --git a/samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon152.png b/samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon152.png new file mode 100644 index 0000000000000000000000000000000000000000..448d6efb577d07e227a5c62545173ddf6bd86b55 GIT binary patch literal 4750 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 literal 0 HcmV?d00001 diff --git a/samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon167.png b/samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon167.png new file mode 100644 index 0000000000000000000000000000000000000000..8524768f8d764da7e9c452a444208708f2d18ff1 GIT binary patch literal 4692 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 literal 0 HcmV?d00001 diff --git a/samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon180.png b/samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon180.png new file mode 100644 index 0000000000000000000000000000000000000000..60a64703c0f11d08705cd607f7751338707f5919 GIT binary patch literal 5192 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 nB>N_)Q7iwV%v7MwAoJ}E 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 T3-0p800000NkvXXu0mjfSlal| literal 0 HcmV?d00001 diff --git a/samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon58.png b/samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon58.png new file mode 100644 index 0000000000000000000000000000000000000000..1ad04f004b638bf781012290d78e4138f97bbe5e GIT binary patch literal 1761 zcmV<71|Io|P)4P%ubY|S^%$zf~ zmwTOa@12BA$oV-Y9!V&U%c=j==#_}M2ylE}1m>yyDoGsZ#Yy zNX}RO*f(MzmKS&u`qiajIyW{Y_LC%m2NqT@Ic|QpvYqwNgBK7n5X%c(3k^?2>EOA` zqGaXjE7H9BiJ55fh0iJRW}@=&(@R^E1hLB>kE%PS6eP@VZVdtn(fh;5DPKg!j;fJZ%)wH{Wn#~V&#n(o1URS zsyS`0Tu2m;-H}z9O^h`!UZAFr@?0a7Z;pYOi0uZhgzh=rOEDi`FIkKtVu*gEcSM!h zmb#_XR$akjlg$JI75MXgWkG7IUnYJ+X=1J!qJ%jXVj{L1I2QU%?=?DgV^U?)92DZm zV?>``xT1#kZdgUt!2n?|0>*6ae4tikA9FAlJ}kjmMQm_z3LB5sZYHBKdbex9_Hv@K z%Y?q@9-)b7vJ6X$3h0B4tH__=#*`9^efY@IQfghn*=E2Nb8sR8lrQlu`Ca_Rmm6>Z z7bkEe^w8M>x;hoNUvWu_GZJPVpI;bMTsBpf(@U$Ch(-gk0T#WpsaB1{7ISQ~Y48mW z;Nk?@LjM_?q{BV-D=veoOmJoncVDC1GwGGz(O5@o7ZkGCIJMPO(7K9b6M_wF?Xqd< zo4J6KF0_U2<1=T3x0qc6G6#g+^=N{QTpChC!GZuCY*|eU{Rw)LMN7a2wwbaCdn_dE zzy+Lip(XU4-+SoTFyEcnH3?HRV^%-;Ylx;|>8v&^Dy459ZJ_1zio`68!6s8SO(6sq zaN75WUKiF9+8MruR3=w5)hzA^Z1clVBuXc)+8@e);xX7bfygR&FsIIt-gQ+==(c;S z#J*CO1qZBF&M&6TRmskZXaMOU6&?jn_(BqY5 z>Y|^?uOh;yp6w0QR1`>tiEz_-{Zu!N#(nhRndJV$7;LOgPyZQ*J2yCin+~*u!qKj# zItsG2IDi{ZH+E6j=D|ht=qWxKNxaA6E>3Wna>=z1gy?*#>|g_1^BGspGro&OWRc(k zPP)(*y0WZ7Z-kICr3#g7($P*LCjE>7S`Xh~s!b~bPTo0XSkRm2T(M`QZbv-`Imx*Ulqk*aI* zaqa*=>61?nFb8w3wuiA&zyVyGz>!cm-pY3xEsMEiY)Th4FVrtqWp%V~gxW82)>4^N z*H{>GR?m$^s6BN^M=4^iEjT7(gM(8z7K#9Sn(M_`)oSH2zHDCla&cmK)bb|4nAMIO ze4S3gI9L8AD+T9c#C8K8JF)I68NBWK`5pE`q^OR#h~-u!e7P2i$UDq7^*uZr< zbp8sR<$nYxb8EKH|BltapZ^j3+PZt_u^PR*lT6;TCNxu^yFH$j(!JXvbmHfQ>a0>O z+2k{tOWD%ln$M`tD&>+*KBKvmEgi1;jOwgXF4_DG_&r&PcxYTT00000NkvXXu0mjf DptxI> literal 0 HcmV?d00001 diff --git a/samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon60.png b/samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon60.png new file mode 100644 index 0000000000000000000000000000000000000000..2dd52620a8f15577e56ec7fe8e671988dd17ab0f GIT binary patch literal 2537 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 literal 0 HcmV?d00001 diff --git a/samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon76.png b/samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon76.png new file mode 100644 index 0000000000000000000000000000000000000000..b058cae2f440e5a5875e45c036c99f1fb6356046 GIT binary patch literal 2332 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 Kc&(xHv;P1B$EH01 literal 0 HcmV?d00001 diff --git a/samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon87.png b/samples/Sentry.Samples.Ios/Assets.xcassets/AppIcon.appiconset/Icon87.png new file mode 100644 index 0000000000000000000000000000000000000000..4954a4bd33f613d45f74dc0b12beb516e3b38661 GIT binary patch literal 2758 zcmbW3`9Bkm1IFjp%zcKjbSPx1iJT2#jw$8XupGH_6Pa_%ghXz$B+5DFthu6mLe4ot z&P8+P_HpF;_W2jSKRnO#)BDHg^?JwMMH+Ae#eo0-fE!_`Xa0As{tGAj-}dYL@%Zns zy24H206Tby@Oa7NhkA}!dczK$r?iEZ$Vhk-~@_+0zcnhHN1L<7SAz`^F^nt`pwmv zI;#7fNKRBqbi6#R=nWp3-t74^oio)O;EmZe%xSE-ft@G$^pS1_xV#<%J(m%H+rQ!* zeO`jU&03LnPLHln2g*P?)v6~sZQ-n}D1!`%X!+++kd;pV^S*5Se2>5=Z`KM3Gmd<| zJF!(*?{;#~qk4WSj+3+crGgdT6Ejft?G(>s%rr;yx#obfA_zOw!F@HHO!JVZp zf$<-eL=R(cgna67o3&QbQ_Rv*Q3p@(;J(R=%OVA1GC$(xNcNjoL@EYV2i{_r-2)EH zuPBIa^h!{Vodg4CW|9W&yI7UkliwR^OOdj33md-r{pnaxx#u8hxDfrw)Zji{*2~q+ z7s#&eS`I3`P&rvQ&9R3K4UCVN@WZ4U?cRjaKLs$vHD_)tQkkvXQFSJ39(>pGT5kO? z4$r!Ckk=G-IQ&Y{=&Q&r%QB(f*eAJKW1+G4^)wQ;;Is5kVTDO(4*m4+^SUL0;l*&a zR*i&l3aH4_<=^bf)VUI&RnPTvXd#uOHx}H?N&(>;FqeU(mz_40%hZ07s+ns=(XfmN zfa6EuMsqpK`5mhsIfMX9rY_}S%S_p1G%+J(e4oCGhW1~|wa{pMX9%*zz(O{Cb)i?- zzHB+y_c>Z32re>o|HXeNxpkmC8#Q(j@b31u^6f428bei>AXBC;6ayPmOOwHH-KPWQ_;$cG1QWdMZmpVBz4>j2M>~_Jmn`f3U{Sc`+6wF7O^SA9Txq7z6%gi&%=Xw% z#e7x|hba_?Yu}$U_?@kA>3mc4bY9&a%lK|Pg0XGE5unnOc`#(_w%fVdHcXxLp8j0Q z*qWsYKz4{YZ?Nup!t@>mgADqL=qOE$H(>+Rz9-WF895)?l$n}Md~Wrhwf_{7p&9f} z-E%@I-SYD>cz3nQa3Awe-dO*5|5<<0i?hRFdus8$thon(4#!b*Ue&2wgwMe~=|~EcV-FCW^eVMd?2* z!RTvDWs{aXYqR9@PPod9mI^vYmjn6mlS%GBU6bur7&I~?Yl_w*PSxfX3tci=)sD!$ zbid|y14KETnjx36kq`iA>^~T-LTf;u?U+5r6j%+=_Ah8+<>(MR3$I@Pe=v|Lw}Xo^ z0g)a$zHcy)U8+X{^6#M>Qix)zCRhgZT?$!DaqiXl7F!WlOIT5C1v2NBQ=-?n%|+<1 z5828!%oV_92uT1|EKEN!*fTYVUy)my7PkJZxfWesufbp7qe8Ttz=q>^ zUZ3ThC&FHZ(L=ty~-bcQytnTxM6SsuPt zx4MsrKD)N6{UoC@_s>>cuJ?Q*b9Iw%A96%N))!B}U}C6bvM4@aquDr+TfQ0T$;YA{ z(P6a9(KYIQyLk8CiP9aH;qagxLZi-H42&%!25R#bg`~6dG!I_>rRBH+ZUshGwt;%7 zClZx|gp^-oY!vVGl(p%Z+R>#2&ZSFyBiE&s?L+a9JwTRjO=d$tH!)j)osWL~$c9dn zXNhEEPYc}*l;(E)IvN-K_y^j+4{%r#@7T~%s6#0X=AaBDh!RLs8Ta_}>1axha^o6` z16K*+URzT!L-mK&b9FJ1_c62QH^D*j#Y+`vAK{xanlRIv`)KZAoaJY!N(D(`U2PBt z_MRtLeDZYH0ei;Ssrqg5EK_de^6vuUf;nPV&Bw-dv_Y_ae572`i410XSh0qh`bdh~eju;=kTI2--?I;!N6U8+kDt!vDkUU2suB3% z8v)2l$ZyA1J2W%uQv&a5h-^_veL7R*_rokWR%MhuY~rz$xUI|f_lERZ{(==GA~mR0 zK!H(Xad9WxqLbhrxH~QeZk@-8nqk~Rgte8gBVv)W+4>VJrNt5M(O{I4AunWN_spXO z|F@)8#>+kLlHPBjVB_fP2-f?L>o6XnWvTiO??9z8QB5s#%yzG{W_qjY))A?T_ty8R ze$H2PtgwU6!nCZ#Okr_}3!k{8DRKo+$F!+m@#~@k$?1NaExb2d0knV{`Vf}Z&5922cL0(H%cf|9Zp zF^~f7>{S|WGrQx-QQbI=mjgWF#Hyh3uN>dh*Q}ivx84}*?r01~V1n&ov&@riGnMMt z?JbJ}kJ0(M2e==tN8y6(^>1sVq^6@lq>I(;-o-Q!@ECB$=h)Z>nRU9cs!05~E~ToL z6~KWBw*XJ-2iRoZv%{pl^O;`bz3^cSRo1JybN$)v&*Idczu#*&S77BE^Vz9s^*fvlW%}$lz5B2&e7W$MS z%%bwZZ9W~Dr{Pn_*{lkcF?6I?_rP^;z%@-rd^wI1&q6 zYu38JL*FT;Mp>Tbrr0;;GGpJ$50brQ)6@u1r~N2D_HQDWrcotJ%XovVOGuX&PH50? zd|9`iE|d~B62LXh)5H*Mgbs1pg$IT$s&Siiotm8!j`3@dkWLBn(!Dr^PmK>VpZ?ri z + + + + + diff --git a/samples/Sentry.Samples.Ios/Info.plist b/samples/Sentry.Samples.Ios/Info.plist new file mode 100644 index 0000000000..c082b7cce5 --- /dev/null +++ b/samples/Sentry.Samples.Ios/Info.plist @@ -0,0 +1,42 @@ + + + + + CFBundleDisplayName + Sentry.Samples.Ios + CFBundleIdentifier + com.companyname.Sentry.Samples.Ios + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + UIDeviceFamily + + 1 + 2 + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + XSAppIconAssets + Assets.xcassets/AppIcon.appiconset + + diff --git a/samples/Sentry.Samples.Ios/LaunchScreen.storyboard b/samples/Sentry.Samples.Ios/LaunchScreen.storyboard new file mode 100644 index 0000000000..2296c6b7fd --- /dev/null +++ b/samples/Sentry.Samples.Ios/LaunchScreen.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/Sentry.Samples.Ios/Main.cs b/samples/Sentry.Samples.Ios/Main.cs new file mode 100644 index 0000000000..8124756014 --- /dev/null +++ b/samples/Sentry.Samples.Ios/Main.cs @@ -0,0 +1,6 @@ +using Sentry.Samples.Ios; + +// This is the main entry point of the application. +// If you want to use a different Application Delegate class from "AppDelegate" +// you can specify it here. +UIApplication.Main (args, null, typeof (AppDelegate)); diff --git a/samples/Sentry.Samples.Ios/Resources/LaunchScreen.xib b/samples/Sentry.Samples.Ios/Resources/LaunchScreen.xib new file mode 100644 index 0000000000..8190201742 --- /dev/null +++ b/samples/Sentry.Samples.Ios/Resources/LaunchScreen.xib @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/Sentry.Samples.Ios/SceneDelegate.cs b/samples/Sentry.Samples.Ios/SceneDelegate.cs new file mode 100644 index 0000000000..0912ade054 --- /dev/null +++ b/samples/Sentry.Samples.Ios/SceneDelegate.cs @@ -0,0 +1,54 @@ +namespace Sentry.Samples.Ios; + +[Register ("SceneDelegate")] +public class SceneDelegate : UIResponder, IUIWindowSceneDelegate { + + [Export ("window")] + public UIWindow? Window { get; set; } + + [Export ("scene:willConnectToSession:options:")] + public void WillConnect (UIScene scene, UISceneSession session, UISceneConnectionOptions connectionOptions) + { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see UIApplicationDelegate `GetConfiguration` instead). + } + + [Export ("sceneDidDisconnect:")] + public void DidDisconnect (UIScene scene) + { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see UIApplicationDelegate `DidDiscardSceneSessions` instead). + } + + [Export ("sceneDidBecomeActive:")] + public void DidBecomeActive (UIScene scene) + { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + [Export ("sceneWillResignActive:")] + public void WillResignActive (UIScene scene) + { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + [Export ("sceneWillEnterForeground:")] + public void WillEnterForeground (UIScene scene) + { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + [Export ("sceneDidEnterBackground:")] + public void DidEnterBackground (UIScene scene) + { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } +} diff --git a/samples/Sentry.Samples.Ios/Sentry.Samples.Ios.csproj b/samples/Sentry.Samples.Ios/Sentry.Samples.Ios.csproj new file mode 100644 index 0000000000..bd073cde15 --- /dev/null +++ b/samples/Sentry.Samples.Ios/Sentry.Samples.Ios.csproj @@ -0,0 +1,25 @@ + + + + net6.0-ios + Exe + enable + true + 13.0 + + + + + + + + + + + + + + From 4c5847d5ce33b59715c8399815b510d93564cf9f Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Sat, 30 Jul 2022 12:25:45 -0700 Subject: [PATCH 04/25] Change initialization order --- src/Sentry/Platforms/Android/SentrySdk.cs | 38 ++++++++++++++++------- src/Sentry/SentrySdk.cs | 5 +++ 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/Sentry/Platforms/Android/SentrySdk.cs b/src/Sentry/Platforms/Android/SentrySdk.cs index fdee437dfb..15f342e908 100644 --- a/src/Sentry/Platforms/Android/SentrySdk.cs +++ b/src/Sentry/Platforms/Android/SentrySdk.cs @@ -1,13 +1,15 @@ using Sentry.Android; using Sentry.Android.Callbacks; using Sentry.Android.Extensions; -using Sentry.Internal; +using Sentry.Extensibility; using Sentry.Protocol; namespace Sentry; public static partial class SentrySdk { + private static AndroidContext? AndroidContext; + ///

/// Initializes the SDK for Android, with an optional configuration options callback. /// @@ -29,7 +31,29 @@ public static IDisposable Init(AndroidContext context, Action? co /// An object that should be disposed when the application terminates. public static IDisposable Init(AndroidContext context, SentryOptions options) { - // Init the Java Android SDK first + AndroidContext = context; + return Init(options); + } + + private static void InitSentryAndroidSdk(SentryOptions options) + { + // Set options for the managed SDK that don't depend on the Android SDK + options.AutoSessionTracking = true; + options.IsGlobalModeEnabled = true; + + // "Best" mode throws permission exception on Android + options.DetectStartupTime = StartupTimeDetectionMode.Fast; + + // Now initialize the Android SDK if we have been given an AndroidContext + var context = AndroidContext; + if (context == null) + { + options.LogWarning("Running on Android, but did not initialize Sentry with an AndroidContext. " + + "Call SentrySdk.Init(AndroidContext, SentryOptions) instead. " + + "The Sentry Android SDK is disabled."); + return; + } + SentryAndroidOptions? androidOptions = null; SentryAndroid.Init(context, new JavaLogger(options), new OptionsConfigurationCallback(o => @@ -155,21 +179,13 @@ public static IDisposable Init(AndroidContext context, SentryOptions options) // Make sure we capture managed exceptions from the Android environment AndroidEnvironment.UnhandledExceptionRaiser += AndroidEnvironment_UnhandledExceptionRaiser; - // Set options for the managed SDK - options.AutoSessionTracking = true; - options.IsGlobalModeEnabled = true; + // Set options for the managed SDK that depend on the Android SDK options.AddEventProcessor(new AndroidEventProcessor(androidOptions!)); options.CrashedLastRun = () => Java.Sentry.IsCrashedLastRun()?.BooleanValue() is true; options.EnableScopeSync = true; options.ScopeObserver = new AndroidScopeObserver(options); - // "Best" mode throws permission exception on Android - options.DetectStartupTime = StartupTimeDetectionMode.Fast; - // TODO: Pause/Resume - - // Init the managed SDK - return Init(options); } private static void AndroidEnvironment_UnhandledExceptionRaiser(object? _, RaiseThrowableEventArgs e) diff --git a/src/Sentry/SentrySdk.cs b/src/Sentry/SentrySdk.cs index 15644825c1..d63895af9f 100644 --- a/src/Sentry/SentrySdk.cs +++ b/src/Sentry/SentrySdk.cs @@ -52,6 +52,11 @@ internal static IHub InitHub(SentryOptions options) options.LogWarning("The provided DSN that contains a secret key. This is not required and will be ignored."); } + // Initialize bundled platform SDKs here +#if ANDROID + InitSentryAndroidSdk(options); +#endif + return new Hub(options); } From eab4eaef0b0d410fee2fe06de1bdf3dc34c24cd7 Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Sat, 30 Jul 2022 12:27:02 -0700 Subject: [PATCH 05/25] Add init for iOS SDK --- src/Sentry/Platforms/iOS/SentrySdk.cs | 6 +++++- src/Sentry/SentrySdk.cs | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Sentry/Platforms/iOS/SentrySdk.cs b/src/Sentry/Platforms/iOS/SentrySdk.cs index 6e059c0056..9f751503ef 100644 --- a/src/Sentry/Platforms/iOS/SentrySdk.cs +++ b/src/Sentry/Platforms/iOS/SentrySdk.cs @@ -2,5 +2,9 @@ namespace Sentry; public static partial class SentrySdk { - // TODO + private static void InitSentryCocoaSdk(SentryOptions options) + { + //TODO + + } } diff --git a/src/Sentry/SentrySdk.cs b/src/Sentry/SentrySdk.cs index d63895af9f..95411f9dab 100644 --- a/src/Sentry/SentrySdk.cs +++ b/src/Sentry/SentrySdk.cs @@ -55,6 +55,8 @@ internal static IHub InitHub(SentryOptions options) // Initialize bundled platform SDKs here #if ANDROID InitSentryAndroidSdk(options); +#elif IOS || MACCATALYST + InitSentryCocoaSdk(options); #endif return new Hub(options); From 32703fcbb20f227b311d6c6669e3cf871345478e Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Sat, 30 Jul 2022 12:55:12 -0700 Subject: [PATCH 06/25] Don't intermingle namespaces --- src/Sentry/Platforms/iOS/Bindings/ApiDefinitions.cs | 3 +-- src/Sentry/Platforms/iOS/Bindings/StructsAndEnums.cs | 5 +---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/Sentry/Platforms/iOS/Bindings/ApiDefinitions.cs b/src/Sentry/Platforms/iOS/Bindings/ApiDefinitions.cs index e120275f69..ecdb2c874e 100644 --- a/src/Sentry/Platforms/iOS/Bindings/ApiDefinitions.cs +++ b/src/Sentry/Platforms/iOS/Bindings/ApiDefinitions.cs @@ -1,9 +1,8 @@ using System; using Foundation; using ObjCRuntime; -using Sentry; -namespace Sentry.Cocoa; +namespace SentryCocoa; [Static] [Internal] diff --git a/src/Sentry/Platforms/iOS/Bindings/StructsAndEnums.cs b/src/Sentry/Platforms/iOS/Bindings/StructsAndEnums.cs index 9169c61738..37933deb0d 100644 --- a/src/Sentry/Platforms/iOS/Bindings/StructsAndEnums.cs +++ b/src/Sentry/Platforms/iOS/Bindings/StructsAndEnums.cs @@ -1,9 +1,6 @@ -using System.Runtime.InteropServices; -using Foundation; using ObjCRuntime; -using Sentry; -namespace Sentry.Cocoa; +namespace SentryCocoa; [Native] internal enum SentryLogLevel : long From 5271a2970b2e6fef5e7c9b61ebc9f3cc9cf5a0c6 Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Sat, 30 Jul 2022 13:26:43 -0700 Subject: [PATCH 07/25] Missed one for Android init --- src/Sentry/Platforms/Android/SentrySdk.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Sentry/Platforms/Android/SentrySdk.cs b/src/Sentry/Platforms/Android/SentrySdk.cs index 15f342e908..af56401036 100644 --- a/src/Sentry/Platforms/Android/SentrySdk.cs +++ b/src/Sentry/Platforms/Android/SentrySdk.cs @@ -44,6 +44,9 @@ private static void InitSentryAndroidSdk(SentryOptions options) // "Best" mode throws permission exception on Android options.DetectStartupTime = StartupTimeDetectionMode.Fast; + // Make sure we capture managed exceptions from the Android environment + AndroidEnvironment.UnhandledExceptionRaiser += AndroidEnvironment_UnhandledExceptionRaiser; + // Now initialize the Android SDK if we have been given an AndroidContext var context = AndroidContext; if (context == null) @@ -176,9 +179,6 @@ private static void InitSentryAndroidSdk(SentryOptions options) o.AddIgnoredExceptionForType(JavaClass.ForName("android.runtime.JavaProxyThrowable")); })); - // Make sure we capture managed exceptions from the Android environment - AndroidEnvironment.UnhandledExceptionRaiser += AndroidEnvironment_UnhandledExceptionRaiser; - // Set options for the managed SDK that depend on the Android SDK options.AddEventProcessor(new AndroidEventProcessor(androidOptions!)); options.CrashedLastRun = () => Java.Sentry.IsCrashedLastRun()?.BooleanValue() is true; From 561c998467d55b19a5f5678d7d4946ed3ddd6b03 Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Sat, 30 Jul 2022 13:27:31 -0700 Subject: [PATCH 08/25] Add nullability to binding --- src/Sentry/Platforms/iOS/Bindings/ApiDefinitions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Sentry/Platforms/iOS/Bindings/ApiDefinitions.cs b/src/Sentry/Platforms/iOS/Bindings/ApiDefinitions.cs index ecdb2c874e..c4ac2e9df1 100644 --- a/src/Sentry/Platforms/iOS/Bindings/ApiDefinitions.cs +++ b/src/Sentry/Platforms/iOS/Bindings/ApiDefinitions.cs @@ -831,7 +831,7 @@ interface SentryOptions // @property (copy, nonatomic) SentryBeforeBreadcrumbCallback _Nullable beforeBreadcrumb; [NullAllowed, Export ("beforeBreadcrumb", ArgumentSemantic.Copy)] - Func BeforeBreadcrumb { get; set; } + Func BeforeBreadcrumb { get; set; } // @property (copy, nonatomic) SentryOnCrashedLastRunCallback _Nullable onCrashedLastRun; [NullAllowed, Export ("onCrashedLastRun", ArgumentSemantic.Copy)] From fc55831842789357b5717ce644d33b37cf822ade Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Sat, 30 Jul 2022 14:25:05 -0700 Subject: [PATCH 09/25] Android namespace --- src/Sentry/Platforms/Android/SentryOptions.cs | 1 + src/Sentry/Platforms/Android/SentrySdk.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/Sentry/Platforms/Android/SentryOptions.cs b/src/Sentry/Platforms/Android/SentryOptions.cs index 1677ef85cb..c484493e9c 100644 --- a/src/Sentry/Platforms/Android/SentryOptions.cs +++ b/src/Sentry/Platforms/Android/SentryOptions.cs @@ -1,3 +1,4 @@ +// ReSharper disable once CheckNamespace namespace Sentry; public partial class SentryOptions diff --git a/src/Sentry/Platforms/Android/SentrySdk.cs b/src/Sentry/Platforms/Android/SentrySdk.cs index af56401036..3443943b17 100644 --- a/src/Sentry/Platforms/Android/SentrySdk.cs +++ b/src/Sentry/Platforms/Android/SentrySdk.cs @@ -4,6 +4,7 @@ using Sentry.Extensibility; using Sentry.Protocol; +// ReSharper disable once CheckNamespace namespace Sentry; public static partial class SentrySdk From 5dd57101743e6b52cf70f12fd005a42458894247 Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Sat, 30 Jul 2022 14:25:35 -0700 Subject: [PATCH 10/25] Bump min iOS to 10.0 --- src/Sentry/Platforms/iOS/Sentry.iOS.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Sentry/Platforms/iOS/Sentry.iOS.props b/src/Sentry/Platforms/iOS/Sentry.iOS.props index 50061bb7b4..b98aadb5ef 100644 --- a/src/Sentry/Platforms/iOS/Sentry.iOS.props +++ b/src/Sentry/Platforms/iOS/Sentry.iOS.props @@ -3,7 +3,7 @@ 10 true - 9.0 + 10.0 13.1 true true From 1dd01a69c67f569385099c00ba3c17ef1824834b Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Sat, 30 Jul 2022 14:26:03 -0700 Subject: [PATCH 11/25] Initialize iOS SDK --- .../iOS/Extensions/BreadcrumbExtensions.cs | 43 ++++++ .../iOS/Extensions/CocoaExtensions.cs | 8 ++ .../iOS/Extensions/EnumExtensions.cs | 30 +++++ src/Sentry/Platforms/iOS/SentryOptions.cs | 1 + src/Sentry/Platforms/iOS/SentrySdk.cs | 122 +++++++++++++++++- 5 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 src/Sentry/Platforms/iOS/Extensions/BreadcrumbExtensions.cs create mode 100644 src/Sentry/Platforms/iOS/Extensions/CocoaExtensions.cs create mode 100644 src/Sentry/Platforms/iOS/Extensions/EnumExtensions.cs diff --git a/src/Sentry/Platforms/iOS/Extensions/BreadcrumbExtensions.cs b/src/Sentry/Platforms/iOS/Extensions/BreadcrumbExtensions.cs new file mode 100644 index 0000000000..421a4ef648 --- /dev/null +++ b/src/Sentry/Platforms/iOS/Extensions/BreadcrumbExtensions.cs @@ -0,0 +1,43 @@ +namespace Sentry.iOS.Extensions; + +internal static class BreadcrumbExtensions +{ + public static Breadcrumb ToBreadcrumb(this SentryCocoa.SentryBreadcrumb breadcrumb) + { + var items = breadcrumb.Data as IEnumerable>; + var data = items?.ToDictionary( + x => (string)x.Key, + x => x.Value?.ToString() ?? ""); + + return new Breadcrumb( + breadcrumb.Timestamp?.ToDateTimeOffset(), + breadcrumb.Message, + breadcrumb.Type, + data, + breadcrumb.Category, + breadcrumb.Level.ToBreadcrumbLevel()); + } + + public static SentryCocoa.SentryBreadcrumb ToCocoaBreadcrumb(this Breadcrumb breadcrumb) + { + NSDictionary? data = null; + if (breadcrumb.Data is { } breadcrumbData) + { + data = new NSDictionary(); + foreach (var item in breadcrumbData) + { + data[item.Key] = NSObject.FromObject(item.Value); + } + } + + return new SentryCocoa.SentryBreadcrumb + { + Timestamp = breadcrumb.Timestamp.ToNSDate(), + Message = breadcrumb.Message, + Type = breadcrumb.Type, + Data = data, + Category = breadcrumb.Category ?? "", + Level = breadcrumb.Level.ToCocoaSentryLevel() + }; + } +} diff --git a/src/Sentry/Platforms/iOS/Extensions/CocoaExtensions.cs b/src/Sentry/Platforms/iOS/Extensions/CocoaExtensions.cs new file mode 100644 index 0000000000..8fda459a4e --- /dev/null +++ b/src/Sentry/Platforms/iOS/Extensions/CocoaExtensions.cs @@ -0,0 +1,8 @@ +namespace Sentry.iOS.Extensions; + +internal static class CocoaExtensions +{ + public static DateTimeOffset ToDateTimeOffset(this NSDate timestamp) => new((DateTime)timestamp); + + public static NSDate ToNSDate(this DateTimeOffset timestamp) => (NSDate)timestamp.DateTime; +} diff --git a/src/Sentry/Platforms/iOS/Extensions/EnumExtensions.cs b/src/Sentry/Platforms/iOS/Extensions/EnumExtensions.cs new file mode 100644 index 0000000000..ca2d7c2601 --- /dev/null +++ b/src/Sentry/Platforms/iOS/Extensions/EnumExtensions.cs @@ -0,0 +1,30 @@ +namespace Sentry.iOS.Extensions; + +internal static class EnumExtensions +{ + // These align, so we can just cast + public static SentryLevel ToSentryLevel(this SentryCocoa.SentryLevel level) => (SentryLevel)level; + public static SentryCocoa.SentryLevel ToCocoaSentryLevel(this SentryLevel level) => (SentryCocoa.SentryLevel)level; + + public static BreadcrumbLevel ToBreadcrumbLevel(this SentryCocoa.SentryLevel level) => + level switch + { + SentryCocoa.SentryLevel.Debug => BreadcrumbLevel.Debug, + SentryCocoa.SentryLevel.Info => BreadcrumbLevel.Info, + SentryCocoa.SentryLevel.Warning => BreadcrumbLevel.Warning, + SentryCocoa.SentryLevel.Error => BreadcrumbLevel.Error, + SentryCocoa.SentryLevel.Fatal => BreadcrumbLevel.Critical, + _ => throw new ArgumentOutOfRangeException(nameof(level), level, null) + }; + + public static SentryCocoa.SentryLevel ToCocoaSentryLevel(this BreadcrumbLevel level) => + level switch + { + BreadcrumbLevel.Debug => SentryCocoa.SentryLevel.Debug, + BreadcrumbLevel.Info => SentryCocoa.SentryLevel.Info, + BreadcrumbLevel.Warning => SentryCocoa.SentryLevel.Warning, + BreadcrumbLevel.Error => SentryCocoa.SentryLevel.Error, + BreadcrumbLevel.Critical => SentryCocoa.SentryLevel.Fatal, + _ => throw new ArgumentOutOfRangeException(nameof(level), level, message: default) + }; +} diff --git a/src/Sentry/Platforms/iOS/SentryOptions.cs b/src/Sentry/Platforms/iOS/SentryOptions.cs index a1a081d0ad..0e4f10bd6d 100644 --- a/src/Sentry/Platforms/iOS/SentryOptions.cs +++ b/src/Sentry/Platforms/iOS/SentryOptions.cs @@ -1,3 +1,4 @@ +// ReSharper disable once CheckNamespace namespace Sentry; public partial class SentryOptions diff --git a/src/Sentry/Platforms/iOS/SentrySdk.cs b/src/Sentry/Platforms/iOS/SentrySdk.cs index 9f751503ef..664105822b 100644 --- a/src/Sentry/Platforms/iOS/SentrySdk.cs +++ b/src/Sentry/Platforms/iOS/SentrySdk.cs @@ -1,10 +1,130 @@ +using Sentry.iOS.Extensions; + +// ReSharper disable once CheckNamespace namespace Sentry; public static partial class SentrySdk { private static void InitSentryCocoaSdk(SentryOptions options) { - //TODO + // Set options for the managed SDK that don't depend on the Cocoa SDK + options.AutoSessionTracking = true; + options.IsGlobalModeEnabled = true; + + // // "Best" mode throws permission exception on Android -- TODO: does it on iOS? + // options.DetectStartupTime = StartupTimeDetectionMode.Fast; + + // Now initialize the Cocoa SDK + SentryCocoa.SentryOptions? cocoaOptions = null; + SentryCocoa.SentrySDK.StartWithConfigureOptions(o => + { + // Capture the Cocoa options reference on the outer scope + cocoaOptions = o; + + // TODO: Equivalent of Android options? + // o.DistinctId + // o.EnableScopeSync + + // These options are copied over from our SentryOptions + o.AttachStacktrace = options.AttachStacktrace; + o.Debug = options.Debug; + o.DiagnosticLevel = options.DiagnosticLevel.ToCocoaSentryLevel(); + o.Dsn = options.Dsn; + o.EnableAutoSessionTracking = options.AutoSessionTracking; + o.Environment = options.Environment; + //o.FlushTimeoutMillis = (long)options.InitCacheFlushTimeout.TotalMilliseconds; + o.MaxAttachmentSize = (nuint) options.MaxAttachmentSize; + o.MaxBreadcrumbs = (nuint) options.MaxBreadcrumbs; + o.MaxCacheItems = (nuint) options.MaxCacheItems; + // o.MaxQueueSize = options.MaxQueueItems; + o.ReleaseName = options.Release; + o.SampleRate = options.SampleRate; + o.SendClientReports = options.SendClientReports; + o.SendDefaultPii = options.SendDefaultPii; + o.SessionTrackingIntervalMillis = (nuint) options.AutoSessionTrackingInterval.TotalMilliseconds; + // o.ShutdownTimeoutMillis = (long)options.ShutdownTimeout.TotalMilliseconds; + + // NOTE: options.CacheDirectoryPath - No option for this in Sentry Cocoa, but caching is still enabled + // https://github.com/getsentry/sentry-cocoa/issues/1051 + + // o.??? = options.DefaultTags + + if (options.BeforeBreadcrumb is { } beforeBreadcrumb) + { + // Note: Nullable return is allowed but delegate is generated incorrectly + o.BeforeBreadcrumb = b => beforeBreadcrumb(b.ToBreadcrumb())?.ToCocoaBreadcrumb()!; + } + + // TOOD: Work on below (copied from Android) + + // + // // These options we have behind feature flags + // if (options.Android.EnableAndroidSdkTracing) + // { + // o.TracesSampleRate = (JavaDouble?)options.TracesSampleRate; + // + // if (options.TracesSampler is { } tracesSampler) + // { + // o.TracesSampler = new TracesSamplerCallback(tracesSampler); + // } + // } + // + // if (options.Android.EnableAndroidSdkBeforeSend && options.BeforeSend is { } beforeSend) + // { + // o.BeforeSend = new BeforeSendCallback(beforeSend, options, o); + // } + // + // // These options are from SentrycocoaOptions + // o.AttachScreenshot = options.Android.AttachScreenshot; + // o.AnrEnabled = options.Android.AnrEnabled; + // o.AnrReportInDebug = options.Android.AnrReportInDebug; + // o.AnrTimeoutIntervalMillis = (long)options.Android.AnrTimeoutInterval.TotalMilliseconds; + // o.EnableActivityLifecycleBreadcrumbs = options.Android.EnableActivityLifecycleBreadcrumbs; + // o.EnableAutoActivityLifecycleTracing = options.Android.EnableAutoActivityLifecycleTracing; + // o.EnableActivityLifecycleTracingAutoFinish = options.Android.EnableActivityLifecycleTracingAutoFinish; + // o.EnableAppComponentBreadcrumbs = options.Android.EnableAppComponentBreadcrumbs; + // o.EnableAppLifecycleBreadcrumbs = options.Android.EnableAppLifecycleBreadcrumbs; + // o.EnableSystemEventBreadcrumbs = options.Android.EnableSystemEventBreadcrumbs; + // o.EnableUserInteractionBreadcrumbs = options.Android.EnableUserInteractionBreadcrumbs; + // o.EnableUserInteractionTracing = options.Android.EnableUserInteractionTracing; + // o.ProfilingTracesIntervalMillis = (int)options.Android.ProfilingTracesInterval.TotalMilliseconds; + // + // // These options are in Java.SentryOptions but not ours + // o.AttachThreads = options.Android.AttachThreads; + // o.ConnectionTimeoutMillis = (int)options.Android.ConnectionTimeout.TotalMilliseconds; + // o.Dist = options.Android.Distribution; + // o.EnableNdk = options.Android.EnableNdk; + // o.EnableShutdownHook = options.Android.EnableShutdownHook; + // o.EnableUncaughtExceptionHandler = options.Android.EnableUncaughtExceptionHandler; + // o.ProfilingEnabled = options.Android.ProfilingEnabled; + // o.PrintUncaughtStackTrace = options.Android.PrintUncaughtStackTrace; + // o.ReadTimeoutMillis = (int)options.Android.ReadTimeout.TotalMilliseconds; + // + // // In-App Excludes and Includes to be passed to the Android SDK + // options.Android.InAppExclude?.ToList().ForEach(x => o.AddInAppExclude(x)); + // options.Android.InAppInclude?.ToList().ForEach(x => o.AddInAppInclude(x)); + // + // // These options are intentionally set and not exposed for modification + // o.EnableExternalConfiguration = false; + // o.EnableDeduplication = false; + // o.AttachServerName = false; + // + // // These options are intentionally not expose or modified + // //o.MaxRequestBodySize // N/A for Android apps + // //o.MaxSpans // See https://github.com/getsentry/sentry-dotnet/discussions/1698 + // + // // Don't capture managed exceptions in the native SDK, since we already capture them in the managed SDK + // o.AddIgnoredExceptionForType(JavaClass.ForName("android.runtime.JavaProxyThrowable")); + + }); + + // Set options for the managed SDK that depend on the Cocoa SDK + // options.AddEventProcessor(new CocoaEventProcessor(cocoaOptions!)); + options.CrashedLastRun = () => SentryCocoa.SentrySDK.CrashedLastRun; + // options.EnableScopeSync = true; + // options.ScopeObserver = new CocoaScopeObserver(options); + + // TODO: Pause/Resume } } From 090ffeb10004af87284d5ae683f29112063bcfa9 Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Sat, 30 Jul 2022 14:33:53 -0700 Subject: [PATCH 12/25] Add iOS Sample to solution --- Sentry.sln | 9 +++++++++ SentryMaui.slnf | 1 + 2 files changed, 10 insertions(+) diff --git a/Sentry.sln b/Sentry.sln index 79391f90ee..489e9f97a9 100644 --- a/Sentry.sln +++ b/Sentry.sln @@ -147,6 +147,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sentry.Maui", "src\Sentry.M EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sentry.Maui.Tests", "test\Sentry.Maui.Tests\Sentry.Maui.Tests.csproj", "{143076C0-8D6B-4054-9F45-06B21655F417}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sentry.Samples.Ios", "samples\Sentry.Samples.Ios\Sentry.Samples.Ios.csproj", "{C2876321-A612-4E66-AF33-D3928FA6366F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -341,6 +343,12 @@ Global {143076C0-8D6B-4054-9F45-06B21655F417}.Debug|Any CPU.Build.0 = Debug|Any CPU {143076C0-8D6B-4054-9F45-06B21655F417}.Release|Any CPU.ActiveCfg = Release|Any CPU {143076C0-8D6B-4054-9F45-06B21655F417}.Release|Any CPU.Build.0 = Release|Any CPU + {C2876321-A612-4E66-AF33-D3928FA6366F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C2876321-A612-4E66-AF33-D3928FA6366F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C2876321-A612-4E66-AF33-D3928FA6366F}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {C2876321-A612-4E66-AF33-D3928FA6366F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C2876321-A612-4E66-AF33-D3928FA6366F}.Release|Any CPU.Build.0 = Release|Any CPU + {C2876321-A612-4E66-AF33-D3928FA6366F}.Release|Any CPU.Deploy.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -395,6 +403,7 @@ Global {EBCCABF9-F670-4C8D-AABC-4EB132961929} = {77454495-55EE-4B40-A089-71B9E8F82E89} {FFFC74C5-680B-43E3-9C42-A7A23B589CB6} = {AF6AF4C7-8AA2-4D59-8064-2D79560904EB} {143076C0-8D6B-4054-9F45-06B21655F417} = {83263231-1A2A-4733-B759-EEFF14E8C5D5} + {C2876321-A612-4E66-AF33-D3928FA6366F} = {77454495-55EE-4B40-A089-71B9E8F82E89} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {0C652B1A-DF72-4EE5-A98B-194FE2C054F6} diff --git a/SentryMaui.slnf b/SentryMaui.slnf index a6982031af..3bc79e2bb7 100644 --- a/SentryMaui.slnf +++ b/SentryMaui.slnf @@ -3,6 +3,7 @@ "path": "Sentry.sln", "projects": [ "samples\\Sentry.Samples.Android\\Sentry.Samples.Android.csproj", + "samples\\Sentry.Samples.Ios\\Sentry.Samples.Ios.csproj", "samples\\Sentry.Samples.Maui\\Sentry.Samples.Maui.csproj", "src\\Sentry.Extensions.Logging\\Sentry.Extensions.Logging.csproj", "src\\Sentry.Maui\\Sentry.Maui.csproj", From a17184184b6c1d7aa86bc4ccf1022c5e5ed0fb33 Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Sat, 30 Jul 2022 14:36:48 -0700 Subject: [PATCH 13/25] Init and test from the sample --- samples/Sentry.Samples.Ios/AppDelegate.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/samples/Sentry.Samples.Ios/AppDelegate.cs b/samples/Sentry.Samples.Ios/AppDelegate.cs index 8e6064adef..03e16deb35 100644 --- a/samples/Sentry.Samples.Ios/AppDelegate.cs +++ b/samples/Sentry.Samples.Ios/AppDelegate.cs @@ -9,7 +9,14 @@ public override UIWindow? Window { public override bool FinishedLaunching (UIApplication application, NSDictionary launchOptions) { - // create a new window instance based on the screen size + // Init the Sentry SDK + SentrySdk.Init(o => + { + o.Debug = true; + o.Dsn = "https://eb18e953812b41c3aeb042e666fd3b5c@o447951.ingest.sentry.io/5428537"; + }); + + // create a new window instance based on the screen size Window = new UIWindow (UIScreen.MainScreen.Bounds); // create a UIViewController with a single UILabel @@ -25,6 +32,11 @@ public override bool FinishedLaunching (UIApplication application, NSDictionary // make the window visible Window.MakeKeyAndVisible (); + + // Try out the Sentry SDK + SentrySdk.CaptureMessage("From iOS"); + + return true; } } From 4d342caa000b6995eb2361c62999c234e716aaa9 Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Sat, 30 Jul 2022 14:43:37 -0700 Subject: [PATCH 14/25] Add developer codesign key for iOS --- samples/Sentry.Samples.Ios/Sentry.Samples.Ios.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/Sentry.Samples.Ios/Sentry.Samples.Ios.csproj b/samples/Sentry.Samples.Ios/Sentry.Samples.Ios.csproj index bd073cde15..78e63cf453 100644 --- a/samples/Sentry.Samples.Ios/Sentry.Samples.Ios.csproj +++ b/samples/Sentry.Samples.Ios/Sentry.Samples.Ios.csproj @@ -6,6 +6,7 @@ enable true 13.0 + iPhone Developer From 171567064fe2fbfbac85da982d2cb2451b3e9e77 Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Sat, 30 Jul 2022 15:00:29 -0700 Subject: [PATCH 15/25] Fix date conversion --- src/Sentry/Platforms/iOS/Extensions/CocoaExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Sentry/Platforms/iOS/Extensions/CocoaExtensions.cs b/src/Sentry/Platforms/iOS/Extensions/CocoaExtensions.cs index 8fda459a4e..515aa9fb9b 100644 --- a/src/Sentry/Platforms/iOS/Extensions/CocoaExtensions.cs +++ b/src/Sentry/Platforms/iOS/Extensions/CocoaExtensions.cs @@ -4,5 +4,5 @@ internal static class CocoaExtensions { public static DateTimeOffset ToDateTimeOffset(this NSDate timestamp) => new((DateTime)timestamp); - public static NSDate ToNSDate(this DateTimeOffset timestamp) => (NSDate)timestamp.DateTime; + public static NSDate ToNSDate(this DateTimeOffset timestamp) => (NSDate)timestamp.UtcDateTime; } From f1022ee82ed02a4cc6a6c992c2d17b3e25a8bf56 Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Sat, 30 Jul 2022 15:00:48 -0700 Subject: [PATCH 16/25] Add native crash method --- src/Sentry/Platforms/iOS/SentrySdk.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Sentry/Platforms/iOS/SentrySdk.cs b/src/Sentry/Platforms/iOS/SentrySdk.cs index 664105822b..972e2b831a 100644 --- a/src/Sentry/Platforms/iOS/SentrySdk.cs +++ b/src/Sentry/Platforms/iOS/SentrySdk.cs @@ -5,6 +5,11 @@ namespace Sentry; public static partial class SentrySdk { + /// + /// Causes a native crash. Use for testing purposes only. + /// + public static void CauseNativeCrash() => SentryCocoa.SentrySDK.Crash(); + private static void InitSentryCocoaSdk(SentryOptions options) { // Set options for the managed SDK that don't depend on the Cocoa SDK From de45f311861ab17533aa18bb91f93a73e41758c8 Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Sat, 30 Jul 2022 15:01:01 -0700 Subject: [PATCH 17/25] testing --- samples/Sentry.Samples.Ios/AppDelegate.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/samples/Sentry.Samples.Ios/AppDelegate.cs b/samples/Sentry.Samples.Ios/AppDelegate.cs index 03e16deb35..9353e4b8bb 100644 --- a/samples/Sentry.Samples.Ios/AppDelegate.cs +++ b/samples/Sentry.Samples.Ios/AppDelegate.cs @@ -36,6 +36,9 @@ public override bool FinishedLaunching (UIApplication application, NSDictionary // Try out the Sentry SDK SentrySdk.CaptureMessage("From iOS"); + // Uncomment to try these + // throw new Exception("Test Unhandled Managed Exception"); + // SentrySdk.CauseNativeCrash(); return true; } From 96b39bb955a6b056f01deece5f3a9ec05cb33747 Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Sat, 30 Jul 2022 15:02:13 -0700 Subject: [PATCH 18/25] Formatting --- samples/Sentry.Samples.Ios/AppDelegate.cs | 49 +++++----- samples/Sentry.Samples.Ios/SceneDelegate.cs | 102 ++++++++++---------- 2 files changed, 77 insertions(+), 74 deletions(-) diff --git a/samples/Sentry.Samples.Ios/AppDelegate.cs b/samples/Sentry.Samples.Ios/AppDelegate.cs index 9353e4b8bb..9e663c4779 100644 --- a/samples/Sentry.Samples.Ios/AppDelegate.cs +++ b/samples/Sentry.Samples.Ios/AppDelegate.cs @@ -1,14 +1,16 @@ namespace Sentry.Samples.Ios; -[Register ("AppDelegate")] -public class AppDelegate : UIApplicationDelegate { - public override UIWindow? Window { - get; - set; - } - - public override bool FinishedLaunching (UIApplication application, NSDictionary launchOptions) - { +[Register("AppDelegate")] +public class AppDelegate : UIApplicationDelegate +{ + public override UIWindow? Window + { + get; + set; + } + + public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions) + { // Init the Sentry SDK SentrySdk.Init(o => { @@ -17,20 +19,21 @@ public override bool FinishedLaunching (UIApplication application, NSDictionary }); // create a new window instance based on the screen size - Window = new UIWindow (UIScreen.MainScreen.Bounds); + Window = new UIWindow(UIScreen.MainScreen.Bounds); - // create a UIViewController with a single UILabel - var vc = new UIViewController (); - vc.View!.AddSubview (new UILabel (Window!.Frame) { - BackgroundColor = UIColor.SystemBackground, - TextAlignment = UITextAlignment.Center, - Text = "Hello, iOS!", - AutoresizingMask = UIViewAutoresizing.All, - }); - Window.RootViewController = vc; + // create a UIViewController with a single UILabel + var vc = new UIViewController(); + vc.View!.AddSubview(new UILabel(Window!.Frame) + { + BackgroundColor = UIColor.SystemBackground, + TextAlignment = UITextAlignment.Center, + Text = "Hello, iOS!", + AutoresizingMask = UIViewAutoresizing.All, + }); + Window.RootViewController = vc; - // make the window visible - Window.MakeKeyAndVisible (); + // make the window visible + Window.MakeKeyAndVisible(); // Try out the Sentry SDK @@ -40,6 +43,6 @@ public override bool FinishedLaunching (UIApplication application, NSDictionary // throw new Exception("Test Unhandled Managed Exception"); // SentrySdk.CauseNativeCrash(); - return true; - } + return true; + } } diff --git a/samples/Sentry.Samples.Ios/SceneDelegate.cs b/samples/Sentry.Samples.Ios/SceneDelegate.cs index 0912ade054..c37dd574de 100644 --- a/samples/Sentry.Samples.Ios/SceneDelegate.cs +++ b/samples/Sentry.Samples.Ios/SceneDelegate.cs @@ -1,54 +1,54 @@ namespace Sentry.Samples.Ios; -[Register ("SceneDelegate")] -public class SceneDelegate : UIResponder, IUIWindowSceneDelegate { - - [Export ("window")] - public UIWindow? Window { get; set; } - - [Export ("scene:willConnectToSession:options:")] - public void WillConnect (UIScene scene, UISceneSession session, UISceneConnectionOptions connectionOptions) - { - // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. - // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. - // This delegate does not imply the connecting scene or session are new (see UIApplicationDelegate `GetConfiguration` instead). - } - - [Export ("sceneDidDisconnect:")] - public void DidDisconnect (UIScene scene) - { - // Called as the scene is being released by the system. - // This occurs shortly after the scene enters the background, or when its session is discarded. - // Release any resources associated with this scene that can be re-created the next time the scene connects. - // The scene may re-connect later, as its session was not neccessarily discarded (see UIApplicationDelegate `DidDiscardSceneSessions` instead). - } - - [Export ("sceneDidBecomeActive:")] - public void DidBecomeActive (UIScene scene) - { - // Called when the scene has moved from an inactive state to an active state. - // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. - } - - [Export ("sceneWillResignActive:")] - public void WillResignActive (UIScene scene) - { - // Called when the scene will move from an active state to an inactive state. - // This may occur due to temporary interruptions (ex. an incoming phone call). - } - - [Export ("sceneWillEnterForeground:")] - public void WillEnterForeground (UIScene scene) - { - // Called as the scene transitions from the background to the foreground. - // Use this method to undo the changes made on entering the background. - } - - [Export ("sceneDidEnterBackground:")] - public void DidEnterBackground (UIScene scene) - { - // Called as the scene transitions from the foreground to the background. - // Use this method to save data, release shared resources, and store enough scene-specific state information - // to restore the scene back to its current state. - } +[Register("SceneDelegate")] +public class SceneDelegate : UIResponder, IUIWindowSceneDelegate +{ + + [Export("window")] public UIWindow? Window { get; set; } + + [Export("scene:willConnectToSession:options:")] + public void WillConnect(UIScene scene, UISceneSession session, UISceneConnectionOptions connectionOptions) + { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see UIApplicationDelegate `GetConfiguration` instead). + } + + [Export("sceneDidDisconnect:")] + public void DidDisconnect(UIScene scene) + { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see UIApplicationDelegate `DidDiscardSceneSessions` instead). + } + + [Export("sceneDidBecomeActive:")] + public void DidBecomeActive(UIScene scene) + { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + [Export("sceneWillResignActive:")] + public void WillResignActive(UIScene scene) + { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + [Export("sceneWillEnterForeground:")] + public void WillEnterForeground(UIScene scene) + { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + [Export("sceneDidEnterBackground:")] + public void DidEnterBackground(UIScene scene) + { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } } From dcd148e2fbafd88fd7e7ed0cfdf87114758872c1 Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Sat, 30 Jul 2022 15:06:12 -0700 Subject: [PATCH 19/25] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85ae2c2af3..6090dea05c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Added 'integrations' to SdkVersion ([#1820](https://github.com/getsentry/sentry-dotnet/pull/1820)) - Updated Sentry Android SDK to version 6.3.0 ([#1826](https://github.com/getsentry/sentry-dotnet/pull/1826)) +- Add the Sentry iOS SDK ([#1829](https://github.com/getsentry/sentry-dotnet/pull/1829)) ### Fixes From f358ab101f578cb1e3d64132060b9fac2a54a302 Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Mon, 1 Aug 2022 08:18:01 -0700 Subject: [PATCH 20/25] Only build real iOS sample on a Mac --- .../Sentry.Samples.Ios.csproj | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/samples/Sentry.Samples.Ios/Sentry.Samples.Ios.csproj b/samples/Sentry.Samples.Ios/Sentry.Samples.Ios.csproj index 78e63cf453..28189fe416 100644 --- a/samples/Sentry.Samples.Ios/Sentry.Samples.Ios.csproj +++ b/samples/Sentry.Samples.Ios/Sentry.Samples.Ios.csproj @@ -9,11 +9,31 @@ iPhone Developer
+ + + - + + + net6.0 + Library + **\* + + + Date: Mon, 1 Aug 2022 11:53:06 -0700 Subject: [PATCH 21/25] Bump Sentry Cocoa to 7.23.0 --- src/Sentry/Platforms/iOS/Sentry.iOS.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Sentry/Platforms/iOS/Sentry.iOS.props b/src/Sentry/Platforms/iOS/Sentry.iOS.props index b98aadb5ef..94f953b7e9 100644 --- a/src/Sentry/Platforms/iOS/Sentry.iOS.props +++ b/src/Sentry/Platforms/iOS/Sentry.iOS.props @@ -18,7 +18,7 @@ - 7.22.0 + 7.23.0 $(BaseIntermediateOutputPath)sdks\Sentry\Cocoa\$(SentryCocoaSdkVersion)\ $(SentryCocoaSdkDirectory)Carthage\Build\Sentry.xcframework From a3d94fd87e79b119d6b61457818c41d810e93e49 Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Mon, 1 Aug 2022 13:30:27 -0700 Subject: [PATCH 22/25] Disable maccatalyst target --- src/Sentry/Sentry.csproj | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Sentry/Sentry.csproj b/src/Sentry/Sentry.csproj index 65f90c2f1f..9366df0540 100644 --- a/src/Sentry/Sentry.csproj +++ b/src/Sentry/Sentry.csproj @@ -13,7 +13,12 @@ net6.0;net5.0;netcoreapp3.0;netstandard2.1;netstandard2.0;net461;net6.0-android - $(TargetFrameworks);net6.0-ios;net6.0-maccatalyst + + + $(TargetFrameworks);net6.0-ios From ec0681b3121a42c38f612516d9502d21d42c8272 Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Mon, 1 Aug 2022 13:30:44 -0700 Subject: [PATCH 23/25] Add native crash button to MAUI sample for iOS --- samples/Sentry.Samples.Maui/MainPage.xaml | 7 +++++++ samples/Sentry.Samples.Maui/MainPage.xaml.cs | 10 ++++++++++ 2 files changed, 17 insertions(+) diff --git a/samples/Sentry.Samples.Maui/MainPage.xaml b/samples/Sentry.Samples.Maui/MainPage.xaml index cd2d3b8b6e..2c17a10651 100644 --- a/samples/Sentry.Samples.Maui/MainPage.xaml +++ b/samples/Sentry.Samples.Maui/MainPage.xaml @@ -49,6 +49,13 @@ Clicked="OnCapturedExceptionClicked" HorizontalOptions="Center" /> +