Skip to content
Merged
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
3 changes: 2 additions & 1 deletion packages/ios-client/ios/app/NativeVoltra.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#import <VoltraSpec/VoltraSpec.h>
#import <React/RCTInvalidating.h>

@interface NativeVoltra : NativeVoltraSpecBase <NativeVoltraSpec>
@interface NativeVoltra : NativeVoltraSpecBase <NativeVoltraSpec, RCTInvalidating>

@end
29 changes: 23 additions & 6 deletions packages/ios-client/ios/app/NativeVoltra.mm
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ + (void)load

@interface NativeVoltra () {
VoltraModule *_module;
BOOL _invalidated;
}
@end

Expand All @@ -51,15 +52,25 @@ - (void)setEventEmitterCallback:(EventEmitterCallbackWrapper *_Nonnull)eventEmit
{
[super setEventEmitterCallback:eventEmitterCallbackWrapper];

if (_invalidated) {
return;
}

__weak NativeVoltra *weakSelf = self;
[self.module startMonitoringWithEventHandler:^(NSString *eventName, NSDictionary *eventData) {
__strong NativeVoltra *strongSelf = weakSelf;
if (strongSelf == nil || strongSelf->_invalidated) {
return;
}

if ([eventName isEqualToString:@"interaction"]) {
[self emitOnInteraction:eventData];
[strongSelf emitOnInteraction:eventData];
} else if ([eventName isEqualToString:@"stateChange"]) {
[self emitOnStateChanged:eventData];
[strongSelf emitOnStateChanged:eventData];
} else if ([eventName isEqualToString:@"activityTokenReceived"]) {
[self emitOnActivityTokenReceived:eventData];
[strongSelf emitOnActivityTokenReceived:eventData];
} else if ([eventName isEqualToString:@"activityPushToStartTokenReceived"]) {
[self emitOnActivityPushToStartTokenReceived:eventData];
[strongSelf emitOnActivityPushToStartTokenReceived:eventData];
}
}];
}
Expand Down Expand Up @@ -324,10 +335,16 @@ - (void)clearWidgetServerCredentials:(RCTPromiseResolveBlock)resolve reject:(RCT
resolve(nil);
}

- (void)dealloc
- (void)invalidate
{
if (_invalidated) {
return;
}

_invalidated = YES;
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self.module stopMonitoring];
[_module stopMonitoring];
_module = nil;
}

@end
2 changes: 2 additions & 0 deletions packages/ios-client/ios/app/VoltraLiveActivityService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,8 @@ public class VoltraLiveActivityService {

/// Start monitoring all Live Activities, push tokens, and lifecycle state changes.
public func startMonitoring(enablePush: Bool) {
stopMonitoring()

let onTokenUpdated: (@Sendable (String, String) -> Void)?
let onPushToStartUpdated: (@Sendable (String) -> Void)?

Expand Down
5 changes: 5 additions & 0 deletions packages/ios-client/ios/shared/VoltraEventBus.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ public class VoltraEventBus {
lock.lock()
defer { lock.unlock() }

if let observer {
NotificationCenter.default.removeObserver(observer)
self.observer = nil
}

// 1. Replay persisted events from UserDefaults (interactions from widget)
let persistedEvents = VoltraPersistentEventQueue.popAll()
for event in persistedEvents {
Expand Down
Loading