Compare commits

...

1 Commits

Author SHA1 Message Date
Chris Ballinger f5dd2d4811 Attempting to fix background fetch crash 2021-08-12 20:05:32 -07:00
4 changed files with 43 additions and 41 deletions

View File

@ -57,6 +57,12 @@
return self;
}
- (NSArray<id<OTRProtocol>>*) allProtocols {
@synchronized (self) {
return [self.protocolManagers allValues];
}
}
- (void)removeProtocolForAccount:(OTRAccount *)account
{
NSParameterAssert(account);
@ -159,47 +165,9 @@
}
}
- (void)disconnectAllAccountsSocketOnly:(BOOL)socketOnly timeout:(NSTimeInterval)timeout completionBlock:(nullable void (^)())completionBlock
{
@synchronized (self) {
dispatch_group_t group = dispatch_group_create();
NSMutableDictionary<NSString*, NSObject<OTRProtocol>*> *observingManagersForTokens = [NSMutableDictionary new];
for (NSObject<OTRProtocol> *manager in self.protocolManagers.allValues) {
OTRXMPPManager *xmpp = (OTRXMPPManager*)manager;
NSParameterAssert([xmpp isKindOfClass:OTRXMPPManager.class]);
if (![xmpp isKindOfClass:OTRXMPPManager.class]) {
DDLogError(@"Wrong protocol class for manager %@", manager);
continue;
}
if (xmpp.loginStatus != OTRLoginStatusDisconnected) {
dispatch_group_enter(group);
NSString *token = [xmpp addObserverForKeyPath:NSStringFromSelector(@selector(loginStatus))
options:0
block:^(NSString *keyPath, OTRXMPPManager *mgr, NSDictionary *change) {
if (mgr.loginStatus == OTRLoginStatusDisconnected) {
dispatch_group_leave(group);
}
}];
observingManagersForTokens[token] = manager;
[manager disconnectSocketOnly:socketOnly];
}
}
if (timeout > 0) {
dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, (int64_t) (timeout * NSEC_PER_SEC)));
}
for (NSString *token in observingManagersForTokens.allKeys) {
[observingManagersForTokens[token] removeObserverForToken:token];
}
if (completionBlock != nil) {
completionBlock();
}
}
}
- (void)disconnectAllAccounts
{
[self disconnectAllAccountsSocketOnly:NO timeout:0 completionBlock:nil];
[self disconnectAllAccountsSocketOnly:NO timeout:1 completionBlock:nil];
}
- (void)protocolDidChange:(NSDictionary *)change

View File

@ -21,3 +21,36 @@ extension OTRProtocolManager {
@objc public static let pushController = PushController(baseURL: OTRProtocolManager.pushApiEndpoint, sessionConfiguration: URLSessionConfiguration.ephemeral)
}
extension OTRProtocolManager {
@objc(disconnectAllAccountsSocketOnly:timeout:completionBlock:)
public func disconnectAllAccounts(socketOnly: Bool, timeout: TimeInterval, completion: (()->Void)? = nil) {
let group = DispatchGroup()
let tokens: [NSKeyValueObservation] = allProtocols
.compactMap { $0 as? XMPPManager }
.filter { $0.loginStatus != .disconnected }
.map {
group.enter()
let token = $0.observe(\.loginStatus) { xmppManager, change in
if xmppManager.loginStatus == .disconnected {
group.leave()
}
}
$0.disconnectSocketOnly(socketOnly)
return token
}
DispatchQueue.global(qos: .default).async {
let result = group.wait(timeout: .now() + timeout)
switch result {
case .success:
break
case .timedOut:
DDLogWarn("Exceeded max time for disconnect")
}
tokens.forEach { $0.invalidate() }
DispatchQueue.main.async {
completion?()
}
}
}
}

View File

@ -60,7 +60,7 @@ extension OTRAppDelegate {
OTRProtocolManager.shared.loginAccounts(OTRAccountsManager.allAutoLoginAccounts())
DispatchQueue.main.asyncAfter(deadline: .now() + 8, execute: {
let timeout = 1.0
OTRProtocolManager.shared.disconnectAllAccountsSocketOnly(true, timeout: timeout) {
OTRProtocolManager.shared.disconnectAllAccounts(socketOnly: true, timeout: timeout) {
DispatchQueue.main.async {
UIApplication.shared.removeExtraForegroundNotifications()
switch type {

View File

@ -35,6 +35,8 @@ NS_ASSUME_NONNULL_BEGIN
@property (atomic, readonly) NSUInteger numberOfConnectedProtocols;
@property (atomic, readonly) NSUInteger numberOfConnectingProtocols;
@property (atomic, readonly) NSArray<id<OTRProtocol>>* allProtocols;
- (BOOL)existsProtocolForAccount:(OTRAccount *)account;
- (nullable id <OTRProtocol>)protocolForAccount:(OTRAccount *)account;
- (nullable OTRXMPPManager*)xmppManagerForAccount:(OTRAccount *)account;
@ -48,7 +50,6 @@ NS_ASSUME_NONNULL_BEGIN
- (void)loginAccounts:(NSArray<OTRAccount*> *)accounts;
- (void)goAwayForAllAccounts;
- (void)disconnectAllAccounts;
- (void)disconnectAllAccountsSocketOnly:(BOOL)socketOnly timeout:(NSTimeInterval)timeout completionBlock:(nullable void (^)())completionBlock;
- (void)sendMessage:(OTROutgoingMessage *)message;