Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Push State Machine: main thread sometimes gets stuck when accessing Local Device #826

Merged
merged 2 commits into from
Jan 21, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
26 changes: 22 additions & 4 deletions Source/ARTPush.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
#import "ARTJsonLikeEncoder.h"
#import "ARTEventEmitter.h"
#if TARGET_OS_IOS
#import "ARTPushActivationStateMachine.h"
#import <UIKit/UIKit.h>
#import "ARTPushActivationStateMachine+Private.h"
#endif
#import "ARTPushAdmin.h"
#import "ARTPushActivationEvent.h"
Expand Down Expand Up @@ -55,7 +56,6 @@ - (ARTPushActivationStateMachine *)activationMachine {
return activationMachineInstance;
}


+ (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceTokenData rest:(ARTRest *)rest {
// HEX string, i.e.: <12ce7dda 8032c423 8f8bd40f 3484e5bb f4698da5 8b7fdf8d 5c55e0a2 XXXXXXXX>
// Normalizing token by removing symbols and spaces, i.e.: 12ce7dda8032c4238f8bd40f3484e5bbf4698da58b7fdf8d5c55e0a2XXXXXXXX
Expand Down Expand Up @@ -87,11 +87,29 @@ + (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error realti
}

- (void)activate {
[[self activationMachine] sendEvent:[ARTPushActivationEventCalledActivate new]];
if (!self.activationMachine.delegate) {
dispatch_async(dispatch_get_main_queue(), ^{
// -[UIApplication delegate] is an UI API call
self.activationMachine.delegate = UIApplication.sharedApplication.delegate;
[self.activationMachine sendEvent:[ARTPushActivationEventCalledActivate new]];
});
}
else {
[self.activationMachine sendEvent:[ARTPushActivationEventCalledActivate new]];
}
}

- (void)deactivate {
[[self activationMachine] sendEvent:[ARTPushActivationEventCalledDeactivate new]];
if (!self.activationMachine.delegate) {
dispatch_async(dispatch_get_main_queue(), ^{
// -[UIApplication delegate] is an UI API call
self.activationMachine.delegate = UIApplication.sharedApplication.delegate;
[self.activationMachine sendEvent:[ARTPushActivationEventCalledDeactivate new]];
});
}
else {
[self.activationMachine sendEvent:[ARTPushActivationEventCalledDeactivate new]];
}
}

#endif
Expand Down
103 changes: 27 additions & 76 deletions Source/ARTPushActivationStateMachine.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#import "ARTNSMutableRequest+ARTPush.h"

#if TARGET_OS_IOS
#import <UIKit/UIKit.h>

NSString *const ARTPushActivationCurrentStateKey = @"ARTPushActivationCurrentState";
NSString *const ARTPushActivationPendingEventsKey = @"ARTPushActivationPendingEvents";
Expand Down Expand Up @@ -133,16 +132,7 @@ - (void)deviceRegistration:(ARTErrorInfo *)error {
#if TARGET_OS_IOS
ARTLocalDevice *local = _rest.device_nosync;

__block id delegate;
if (self.delegate) {
delegate = self.delegate;
}
else {
dispatch_sync(_userQueue, ^{
// -[UIApplication delegate] is an UI API call
delegate = UIApplication.sharedApplication.delegate;
});
}
__block id delegate = self.delegate;

if (![delegate conformsToProtocol:@protocol(ARTPushRegistererDelegate)]) {
[NSException raise:@"ARTPushRegistererDelegate must be implemented on AppDelegate" format:@""];
Expand Down Expand Up @@ -202,16 +192,7 @@ - (void)deviceUpdateRegistration:(ARTErrorInfo *)error {
#if TARGET_OS_IOS
ARTLocalDevice *local = _rest.device_nosync;

__block id delegate;
if (self.delegate) {
delegate = self.delegate;
}
else {
dispatch_sync(_userQueue, ^{
// -[UIApplication delegate] is an UI API call
delegate = UIApplication.sharedApplication.delegate;
});
}
__block id delegate = self.delegate;

if (![delegate conformsToProtocol:@protocol(ARTPushRegistererDelegate)]) {
[NSException raise:@"ARTPushRegistererDelegate must be implemented on AppDelegate" format:@""];
Expand Down Expand Up @@ -278,16 +259,7 @@ - (void)deviceUnregistration:(ARTErrorInfo *)error {
#if TARGET_OS_IOS
ARTLocalDevice *local = _rest.device_nosync;

__block id delegate;
if (self.delegate) {
delegate = self.delegate;
}
else {
dispatch_sync(_userQueue, ^{
// -[UIApplication delegate] is an UI API call
delegate = UIApplication.sharedApplication.delegate;
});
}
__block id delegate = self.delegate;

// Custom register
SEL customDeregisterMethodSelector = @selector(ablyPushCustomDeregister:deviceId:callback:);
Expand Down Expand Up @@ -334,64 +306,43 @@ - (void)deviceUnregistration:(ARTErrorInfo *)error {

- (void)callActivatedCallback:(ARTErrorInfo *)error {
#if TARGET_OS_IOS
dispatch_async(_userQueue, ^{
id delegate;
if (self.delegate) {
delegate = self.delegate;
}
else {
delegate = UIApplication.sharedApplication.delegate;
}

if ([delegate conformsToProtocol:@protocol(ARTPushRegistererDelegate)]) {
SEL activateCallbackMethodSelector = @selector(didActivateAblyPush:);
if ([delegate respondsToSelector:activateCallbackMethodSelector]) {
[delegate didActivateAblyPush:error];
dispatch_async(_userQueue, ^{
id delegate = self.delegate;
if ([delegate conformsToProtocol:@protocol(ARTPushRegistererDelegate)]) {
SEL activateCallbackMethodSelector = @selector(didActivateAblyPush:);
if ([delegate respondsToSelector:activateCallbackMethodSelector]) {
[delegate didActivateAblyPush:error];
}
}
}
});
});
#endif
}

- (void)callDeactivatedCallback:(ARTErrorInfo *)error {
#if TARGET_OS_IOS
dispatch_async(_userQueue, ^{
id delegate;
if (self.delegate) {
delegate = self.delegate;
}
else {
delegate = UIApplication.sharedApplication.delegate;
}

if ([delegate conformsToProtocol:@protocol(ARTPushRegistererDelegate)]) {
SEL deactivateCallbackMethodSelector = @selector(didDeactivateAblyPush:);
if ([delegate respondsToSelector:deactivateCallbackMethodSelector]) {
[delegate didDeactivateAblyPush:error];
dispatch_async(_userQueue, ^{
id delegate = self.delegate;
if ([delegate conformsToProtocol:@protocol(ARTPushRegistererDelegate)]) {
SEL deactivateCallbackMethodSelector = @selector(didDeactivateAblyPush:);
if ([delegate respondsToSelector:deactivateCallbackMethodSelector]) {
[delegate didDeactivateAblyPush:error];
}
}
}
});
});
#endif
}

- (void)callUpdateFailedCallback:(nullable ARTErrorInfo *)error {
#if TARGET_OS_IOS
dispatch_async(_userQueue, ^{
id delegate;
if (self.delegate) {
delegate = self.delegate;
}
else {
delegate = UIApplication.sharedApplication.delegate;
}

if ([delegate conformsToProtocol:@protocol(ARTPushRegistererDelegate)]) {
SEL updateFailedCallbackMethodSelector = @selector(didAblyPushRegistrationFail:);
if ([delegate respondsToSelector:updateFailedCallbackMethodSelector]) {
[delegate didAblyPushRegistrationFail:error];
dispatch_async(_userQueue, ^{
id delegate = self.delegate;
if ([delegate conformsToProtocol:@protocol(ARTPushRegistererDelegate)]) {
SEL updateFailedCallbackMethodSelector = @selector(didAblyPushRegistrationFail:);
if ([delegate respondsToSelector:updateFailedCallbackMethodSelector]) {
[delegate didAblyPushRegistrationFail:error];
}
}
}
});
});
#endif
}

Expand Down
2 changes: 1 addition & 1 deletion Source/ARTRest.m
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,7 @@ - (ARTLocalDevice *)device {
// Store address of once_token to access it in debug function.
static dispatch_once_t *device_once_token;

- (NSString *)device_nosync {
- (ARTLocalDevice *)device_nosync {
static dispatch_once_t once;
device_once_token = &once;
static id device;
Expand Down