1111#import " SentryDependencyContainer.h"
1212#import " SentryDispatchQueueWrapper.h"
1313#import " SentryDsn.h"
14- #import " SentryEnvelope.h"
14+ #import " SentryEnvelope+Private .h"
1515#import " SentryEnvelopeItemType.h"
1616#import " SentryEvent.h"
1717#import " SentryException.h"
2727#import " SentryMechanismMeta.h"
2828#import " SentryMessage.h"
2929#import " SentryMeta.h"
30+ #import " SentryMsgPackSerializer.h"
3031#import " SentryNSDictionarySanitize.h"
3132#import " SentryNSError.h"
3233#import " SentryOptions+Private.h"
3334#import " SentryPropagationContext.h"
3435#import " SentryRandom.h"
36+ #import " SentryReplayEvent.h"
3537#import " SentrySDK+Private.h"
3638#import " SentryScope+Private.h"
39+ #import " SentrySerialization.h"
3740#import " SentrySession.h"
3841#import " SentryStacktraceBuilder.h"
3942#import " SentrySwift.h"
@@ -472,13 +475,44 @@ - (void)captureSession:(SentrySession *)session
472475 }
473476
474477 SentryEnvelopeItem *item = [[SentryEnvelopeItem alloc ] initWithSession: session];
475- SentryEnvelopeHeader *envelopeHeader = [[SentryEnvelopeHeader alloc ] initWithId: nil
476- traceContext: nil ];
477- SentryEnvelope *envelope = [[SentryEnvelope alloc ] initWithHeader: envelopeHeader
478+ SentryEnvelope *envelope = [[SentryEnvelope alloc ] initWithHeader: [SentryEnvelopeHeader empty ]
478479 singleItem: item];
479480 [self captureEnvelope: envelope];
480481}
481482
483+ - (void )captureReplayEvent : (SentryReplayEvent *)replayEvent
484+ replayRecording : (SentryReplayRecording *)replayRecording
485+ video : (NSURL *)videoURL
486+ withScope : (SentryScope *)scope
487+ {
488+ replayEvent = (SentryReplayEvent *)[self prepareEvent: replayEvent
489+ withScope: scope
490+ alwaysAttachStacktrace: NO ];
491+
492+ if (![replayEvent isKindOfClass: SentryReplayEvent.class]) {
493+ SENTRY_LOG_DEBUG (@" The event preprocessor didn't update the replay event in place. The "
494+ @" replay was discarded." );
495+ return ;
496+ }
497+
498+ SentryEnvelopeItem *videoEnvelopeItem =
499+ [[SentryEnvelopeItem alloc ] initWithReplayEvent: replayEvent
500+ replayRecording: replayRecording
501+ video: videoURL];
502+
503+ if (videoEnvelopeItem == nil ) {
504+ SENTRY_LOG_DEBUG (@" The Session Replay segment will not be sent to Sentry because an "
505+ @" Envelope Item could not be created." );
506+ return ;
507+ }
508+
509+ SentryEnvelope *envelope = [[SentryEnvelope alloc ]
510+ initWithHeader: [[SentryEnvelopeHeader alloc ] initWithId: replayEvent.eventId]
511+ items: @[ videoEnvelopeItem ]];
512+
513+ [self captureEnvelope: envelope];
514+ }
515+
482516- (void )captureEnvelope : (SentryEnvelope *)envelope
483517{
484518 if ([self isDisabled ]) {
@@ -553,9 +587,11 @@ - (SentryEvent *_Nullable)prepareEvent:(SentryEvent *)event
553587
554588 BOOL eventIsNotATransaction
555589 = event.type == nil || ![event.type isEqualToString: SentryEnvelopeItemTypeTransaction];
590+ BOOL eventIsNotReplay
591+ = event.type == nil || ![event.type isEqualToString: SentryEnvelopeItemTypeReplayVideo];
556592
557- // Transactions have their own sampleRate
558- if (eventIsNotATransaction && [self isSampled: self .options.sampleRate]) {
593+ // Transactions and replays have their own sampleRate
594+ if (eventIsNotATransaction && eventIsNotReplay && [self isSampled: self .options.sampleRate]) {
559595 SENTRY_LOG_DEBUG (@" Event got sampled, will not send the event" );
560596 [self recordLostEvent: kSentryDataCategoryError reason: kSentryDiscardReasonSampleRate ];
561597 return nil ;
@@ -582,8 +618,8 @@ - (SentryEvent *_Nullable)prepareEvent:(SentryEvent *)event
582618
583619 [self setSdk: event];
584620
585- // We don't want to attach debug meta and stacktraces for transactions;
586- if (eventIsNotATransaction) {
621+ // We don't want to attach debug meta and stacktraces for transactions and replays.
622+ if (eventIsNotATransaction && eventIsNotReplay ) {
587623 BOOL shouldAttachStacktrace = alwaysAttachStacktrace || self.options .attachStacktrace
588624 || (nil != event.exceptions && [event.exceptions count ] > 0 );
589625
@@ -623,6 +659,10 @@ - (SentryEvent *_Nullable)prepareEvent:(SentryEvent *)event
623659
624660 event = [scope applyToEvent: event maxBreadcrumb: self .options.maxBreadcrumbs];
625661
662+ if (!eventIsNotReplay) {
663+ event.breadcrumbs = nil ;
664+ }
665+
626666 if ([self isWatchdogTermination: event isCrashEvent: isCrashEvent]) {
627667 // Remove some mutable properties from the device/app contexts which are no longer
628668 // applicable
0 commit comments