Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Fixes

- The SDK now correctly syncs attachments to the native layer on iOS and macOS (with the Cococa backend) for non-crashing events. ([#2743](https://github.com/getsentry/sentry-unity/pull/2743))

### Dependencies

- Bump CLI from v3.5.1 to v3.6.0 ([#2741](https://github.com/getsentry/sentry-unity/pull/2741))
Expand Down
41 changes: 41 additions & 0 deletions package-dev/Plugins/iOS/SentryNativeBridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,47 @@ void SentryNativeBridgeSetTrace(const char *traceId, const char *spanId)
}
}

void SentryNativeBridgeAddFileAttachment(
const char *path, const char *filename, const char *contentType)
{
if (path == NULL) {
return;
}

NSString *pathStr = [NSString stringWithUTF8String:path];
NSString *filenameStr = _NSStringOrNil(filename);
NSString *contentTypeStr = _NSStringOrNil(contentType);

SentryAttachment *attachment = [[SentryAttachment alloc] initWithPath:pathStr
filename:filenameStr
contentType:contentTypeStr];

[SentrySDK configureScope:^(SentryScope *scope) { [scope addAttachment:attachment]; }];
}

void SentryNativeBridgeAddByteAttachment(
const uint8_t *bytes, int32_t length, const char *filename, const char *contentType)
{
if (bytes == NULL || filename == NULL) {
return;
}

NSData *data = [NSData dataWithBytes:bytes length:length];
NSString *filenameStr = [NSString stringWithUTF8String:filename];
NSString *contentTypeStr = _NSStringOrNil(contentType);

SentryAttachment *attachment = [[SentryAttachment alloc] initWithData:data
filename:filenameStr
contentType:contentTypeStr];

[SentrySDK configureScope:^(SentryScope *scope) { [scope addAttachment:attachment]; }];
}

void SentryNativeBridgeClearAttachments()
{
[SentrySDK configureScope:^(SentryScope *scope) { [scope clearAttachments]; }];
}

void SentryNativeBridgeWriteScope( // clang-format off
// // const char *AppStartTime,
// const char *AppBuildType,
Expand Down
8 changes: 8 additions & 0 deletions package-dev/Plugins/iOS/SentryNativeBridgeNoOp.m
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ void SentryNativeBridgeUnsetUser() { }

void SentryNativeBridgeSetTrace(const char *traceId, const char *spanId) { }

void SentryNativeBridgeAddFileAttachment(
const char *path, const char *filename, const char *contentType) { }

void SentryNativeBridgeAddByteAttachment(
const uint8_t *bytes, int32_t length, const char *filename, const char *contentType) { }

void SentryNativeBridgeClearAttachments() { }

void SentryNativeBridgeWriteScope( // clang-format off
// // const char *AppStartTime,
// const char *AppBuildType,
Expand Down
59 changes: 56 additions & 3 deletions package-dev/Plugins/macOS/SentryNativeBridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
static Class SentrySpanId;
static Class PrivateSentrySDKOnly;
static Class SentryHttpStatusCodeRange;
static Class SentryAttachment;

#define LOAD_CLASS_OR_BREAK(name) \
name = (__bridge Class)dlsym(dylib, "OBJC_CLASS_$_" #name); \
Expand Down Expand Up @@ -90,6 +91,7 @@ int SentryNativeBridgeLoadLibrary()
LOAD_CLASS_OR_BREAK(SentrySpanId)
LOAD_CLASS_OR_BREAK(PrivateSentrySDKOnly)
LOAD_CLASS_OR_BREAK(SentryHttpStatusCodeRange)
LOAD_CLASS_OR_BREAK(SentryAttachment)

// everything above passed - mark as successfully loaded
loadStatus = 1;
Expand Down Expand Up @@ -357,12 +359,63 @@ void SentryNativeBridgeSetTrace(const char *traceId, const char *spanId)
performSelector:@selector(initWithValue:)
withObject:[NSString stringWithUTF8String:spanId]];

[PrivateSentrySDKOnly
performSelector:@selector(setTrace:spanId:)
withObject:sentryTraceId
[PrivateSentrySDKOnly
performSelector:@selector(setTrace:spanId:)
withObject:sentryTraceId
withObject:sentrySpanId];
}

void SentryNativeBridgeAddFileAttachment(
const char *path, const char *filename, const char *contentType)
{
if (path == NULL) {
return;
}

NSString *pathStr = [NSString stringWithUTF8String:path];
NSString *filenameStr = _NSStringOrNil(filename);
NSString *contentTypeStr = _NSStringOrNil(contentType);

// initWithPath:filename:contentType: - use objc_msgSend directly for the multi-arg init
id attachment = ((id (*)(id, SEL, NSString *, NSString *, NSString *))objc_msgSend)(
[SentryAttachment alloc], @selector(initWithPath:filename:contentType:), pathStr,
filenameStr, contentTypeStr);
if (!attachment) {
return;
}

SentryConfigureScope(
^(id scope) { [scope performSelector:@selector(addAttachment:) withObject:attachment]; });
}

void SentryNativeBridgeAddByteAttachment(
const uint8_t *bytes, int32_t length, const char *filename, const char *contentType)
{
if (bytes == NULL || filename == NULL) {
return;
}

NSData *data = [NSData dataWithBytes:bytes length:length];
NSString *filenameStr = [NSString stringWithUTF8String:filename];
NSString *contentTypeStr = _NSStringOrNil(contentType);

// initWithData:filename:contentType: - use objc_msgSend directly for the multi-arg init
id attachment = ((id (*)(id, SEL, NSData *, NSString *, NSString *))objc_msgSend)(
[SentryAttachment alloc], @selector(initWithData:filename:contentType:), data, filenameStr,
contentTypeStr);
if (!attachment) {
return;
}

SentryConfigureScope(
^(id scope) { [scope performSelector:@selector(addAttachment:) withObject:attachment]; });
}

void SentryNativeBridgeClearAttachments()
{
SentryConfigureScope(^(id scope) { [scope performSelector:@selector(clearAttachments)]; });
}

void SentryNativeBridgeWriteScope( // clang-format off
// // const char *AppStartTime,
// const char *AppBuildType,
Expand Down
18 changes: 6 additions & 12 deletions src/Sentry.Unity.iOS/NativeScopeObserver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,20 +55,14 @@ public override void SetUserImpl(SentryUser user) =>
public override void SetTraceImpl(SentryId traceId, SpanId spanId) =>
SentryCocoaBridgeProxy.SetTrace(traceId.ToString(), spanId.ToString());

public override void AddFileAttachmentImpl(string filePath, string fileName, string? contentType)
{
// iOS/macOS attachment sync to sentry-cocoa is not yet supported.
}
public override void AddFileAttachmentImpl(string filePath, string fileName, string? contentType) =>
SentryCocoaBridgeProxy.AddFileAttachment(filePath, fileName, contentType);

public override void AddByteAttachmentImpl(byte[] data, string fileName, string? contentType)
{
// iOS/macOS attachment sync to sentry-cocoa is not yet supported.
}
public override void AddByteAttachmentImpl(byte[] data, string fileName, string? contentType) =>
SentryCocoaBridgeProxy.AddByteAttachment(data, data.Length, fileName, contentType);

public override void ClearAttachmentsImpl()
{
// iOS/macOS attachment sync to sentry-cocoa is not yet supported.
}
public override void ClearAttachmentsImpl() =>
SentryCocoaBridgeProxy.ClearAttachments();

internal static string GetTimestamp(DateTimeOffset timestamp) =>
// "o": Using ISO 8601 to make sure the timestamp makes it to the bridge correctly.
Expand Down
9 changes: 9 additions & 0 deletions src/Sentry.Unity.iOS/SentryCocoaBridgeProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,4 +151,13 @@ public static extern void AddBreadcrumb(string timestamp, string? message, strin

[DllImport("__Internal", EntryPoint = "SentryNativeBridgeSetTrace")]
public static extern void SetTrace(string traceId, string spanId);

[DllImport("__Internal", EntryPoint = "SentryNativeBridgeAddFileAttachment")]
public static extern void AddFileAttachment(string path, string fileName, string? contentType);

[DllImport("__Internal", EntryPoint = "SentryNativeBridgeAddByteAttachment")]
public static extern void AddByteAttachment(byte[] bytes, int length, string fileName, string? contentType);

[DllImport("__Internal", EntryPoint = "SentryNativeBridgeClearAttachments")]
public static extern void ClearAttachments();
}
Loading