mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Update background polling for SSKs
This commit is contained in:
parent
f11f289f9d
commit
a8b53f6cf3
6 changed files with 51 additions and 38 deletions
|
@ -586,6 +586,7 @@
|
|||
C39DD28A24F3336E008590FC /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C39DD28724F3318C008590FC /* Colors.xcassets */; };
|
||||
C39DD28B24F3336F008590FC /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C39DD28724F3318C008590FC /* Colors.xcassets */; };
|
||||
C3C3CF8924D8EED300E1CCE7 /* TextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3C3CF8824D8EED300E1CCE7 /* TextView.swift */; };
|
||||
C3D0972B2510499C00F6E3E4 /* BackgroundPoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3D0972A2510499C00F6E3E4 /* BackgroundPoller.swift */; };
|
||||
C3DAB3242480CB2B00725F25 /* SRCopyableLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3DAB3232480CB2A00725F25 /* SRCopyableLabel.swift */; };
|
||||
C3DFFAC623E96F0D0058DAF8 /* Sheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3DFFAC523E96F0D0058DAF8 /* Sheet.swift */; };
|
||||
C3DFFAC823E970080058DAF8 /* OpenGroupSuggestionSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3DFFAC723E970080058DAF8 /* OpenGroupSuggestionSheet.swift */; };
|
||||
|
@ -1376,6 +1377,7 @@
|
|||
C3AA6BB824CE8F1B002358B6 /* Migrating Translations from Android.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "Migrating Translations from Android.md"; sourceTree = "<group>"; };
|
||||
C3AECBEA24EF5244005743DE /* fa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fa; path = translations/fa.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
C3C3CF8824D8EED300E1CCE7 /* TextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextView.swift; sourceTree = "<group>"; };
|
||||
C3D0972A2510499C00F6E3E4 /* BackgroundPoller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundPoller.swift; sourceTree = "<group>"; };
|
||||
C3DAB3232480CB2A00725F25 /* SRCopyableLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRCopyableLabel.swift; sourceTree = "<group>"; };
|
||||
C3DFFAC523E96F0D0058DAF8 /* Sheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sheet.swift; sourceTree = "<group>"; };
|
||||
C3DFFAC723E970080058DAF8 /* OpenGroupSuggestionSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenGroupSuggestionSheet.swift; sourceTree = "<group>"; };
|
||||
|
@ -2672,6 +2674,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
B8544E3223D50E4900299F14 /* AppearanceUtilities.swift */,
|
||||
C3D0972A2510499C00F6E3E4 /* BackgroundPoller.swift */,
|
||||
C31A6C5B247F2CF3001123EF /* CGRect+Utilities.swift */,
|
||||
C35E8AAD2485E51D00ACB629 /* IP2Country.swift */,
|
||||
B84664F4235022F30083A1CD /* MentionUtilities.swift */,
|
||||
|
@ -3802,6 +3805,7 @@
|
|||
3496955E219B605E00DCFE74 /* PhotoLibrary.swift in Sources */,
|
||||
45D231771DC7E8F10034FA89 /* SessionResetJob.swift in Sources */,
|
||||
340FC8A9204DAC8D007AEB0F /* NotificationSettingsOptionsViewController.m in Sources */,
|
||||
C3D0972B2510499C00F6E3E4 /* BackgroundPoller.swift in Sources */,
|
||||
C3548F0624456447009433A8 /* PNModeVC.swift in Sources */,
|
||||
B80A579F23DFF1F300876683 /* NewClosedGroupVC.swift in Sources */,
|
||||
452037D11EE84975004E4CDF /* DebugUISessionState.m in Sources */,
|
||||
|
|
|
@ -357,36 +357,8 @@ static NSTimeInterval launchStartedAt;
|
|||
|
||||
- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler
|
||||
{
|
||||
NSLog(@"[Loki] Performing background fetch.");
|
||||
[AppReadiness runNowOrWhenAppDidBecomeReady:^{
|
||||
NSMutableArray *promises = [NSMutableArray new];
|
||||
|
||||
__block AnyPromise *fetchMessagesPromise = [AppEnvironment.shared.messageFetcherJob run].then(^{
|
||||
fetchMessagesPromise = nil;
|
||||
}).catch(^{
|
||||
fetchMessagesPromise = nil;
|
||||
});
|
||||
[promises addObject:fetchMessagesPromise];
|
||||
[fetchMessagesPromise retainUntilComplete];
|
||||
|
||||
__block NSDictionary<NSString *, LKPublicChat *> *publicChats;
|
||||
[OWSPrimaryStorage.sharedManager.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||
publicChats = [LKDatabaseUtilities getAllPublicChats:transaction];
|
||||
}];
|
||||
for (LKPublicChat *publicChat in publicChats) {
|
||||
if (![publicChat isKindOfClass:LKPublicChat.class]) { continue; }
|
||||
LKPublicChatPoller *poller = [[LKPublicChatPoller alloc] initForPublicChat:publicChat];
|
||||
[poller stop];
|
||||
AnyPromise *fetchGroupMessagesPromise = [poller pollForNewMessages];
|
||||
[promises addObject:fetchGroupMessagesPromise];
|
||||
[fetchGroupMessagesPromise retainUntilComplete];
|
||||
}
|
||||
|
||||
PMKJoin(promises).then(^(id results) {
|
||||
completionHandler(UIBackgroundFetchResultNewData);
|
||||
}).catch(^(id error) {
|
||||
completionHandler(UIBackgroundFetchResultFailed);
|
||||
});
|
||||
[LKBackgroundPoller pollWithCompletionHandler:completionHandler];
|
||||
}];
|
||||
}
|
||||
|
||||
|
|
28
Signal/src/Loki/Utilities/BackgroundPoller.swift
Normal file
28
Signal/src/Loki/Utilities/BackgroundPoller.swift
Normal file
|
@ -0,0 +1,28 @@
|
|||
import PromiseKit
|
||||
|
||||
@objc(LKBackgroundPoller)
|
||||
public final class BackgroundPoller : NSObject {
|
||||
|
||||
private override init() { }
|
||||
|
||||
@objc(pollWithCompletionHandler:)
|
||||
public static func poll(completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
|
||||
var promises: [Promise<Void>] = []
|
||||
promises.append(AppEnvironment.shared.messageFetcherJob.run()) // FIXME: It'd be nicer to just use Poller directly
|
||||
promises.append(contentsOf: ClosedGroupPoller().pollOnce())
|
||||
var openGroups: [String:PublicChat] = [:]
|
||||
Storage.read { transaction in
|
||||
openGroups = LokiDatabaseUtilities.getAllPublicChats(in: transaction)
|
||||
}
|
||||
openGroups.values.forEach { openGroup in
|
||||
let poller = PublicChatPoller(for: openGroup)
|
||||
poller.stop()
|
||||
promises.append(poller.pollForNewMessages())
|
||||
}
|
||||
when(resolved: promises).done { _ in
|
||||
completionHandler(.newData)
|
||||
}.catch { _ in
|
||||
completionHandler(.failed)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -245,7 +245,7 @@ public final class SnodeAPI : NSObject {
|
|||
guard let json = rawResponse as? JSON, let rawMessages = json["messages"] as? [JSON] else { return [] }
|
||||
if let (lastHash, expirationDate) = updateLastMessageHashValueIfPossible(for: snode, associatedWith: publicKey, from: rawMessages),
|
||||
UserDefaults.standard[.isUsingFullAPNs] {
|
||||
LokiPushNotificationManager.acknowledgeDelivery(forMessageWithHash: lastHash, expiration: expirationDate, hexEncodedPublicKey: getUserHexEncodedPublicKey())
|
||||
LokiPushNotificationManager.acknowledgeDelivery(forMessageWithHash: lastHash, expiration: expirationDate, publicKey: getUserHexEncodedPublicKey())
|
||||
}
|
||||
let rawNewMessages = removeDuplicates(from: rawMessages, associatedWith: publicKey)
|
||||
let newMessages = parseProtoEnvelopes(from: rawNewMessages)
|
||||
|
|
|
@ -31,24 +31,31 @@ public final class ClosedGroupPoller : NSObject {
|
|||
}
|
||||
}
|
||||
|
||||
public func pollOnce() -> [Promise<Void>] {
|
||||
guard !isPolling else { return [] }
|
||||
isPolling = true
|
||||
return poll()
|
||||
}
|
||||
|
||||
@objc public func stop() {
|
||||
isPolling = false
|
||||
timer?.invalidate()
|
||||
}
|
||||
|
||||
// MARK: Private API
|
||||
private func poll() {
|
||||
guard isPolling else { return }
|
||||
private func poll() -> [Promise<Void>] {
|
||||
guard isPolling else { return [] }
|
||||
let publicKeys = Storage.getUserClosedGroupPublicKeys()
|
||||
publicKeys.forEach { publicKey in
|
||||
SnodeAPI.getSwarm(for: publicKey).then2 { [weak self] swarm -> Promise<[SSKProtoEnvelope]> in
|
||||
return publicKeys.map { publicKey in
|
||||
let promise = SnodeAPI.getSwarm(for: publicKey).then2 { [weak self] swarm -> Promise<[SSKProtoEnvelope]> in
|
||||
// randomElement() uses the system's default random generator, which is cryptographically secure
|
||||
guard let snode = swarm.randomElement() else { return Promise(error: Error.insufficientSnodes) }
|
||||
guard let self = self, self.isPolling else { return Promise(error: Error.pollingCanceled) }
|
||||
return SnodeAPI.getRawMessages(from: snode, associatedWith: publicKey).map2 {
|
||||
SnodeAPI.parseRawMessagesResponse($0, from: snode, associatedWith: publicKey)
|
||||
}
|
||||
}.done2 { [weak self] messages in
|
||||
}
|
||||
promise.done2 { [weak self] messages in
|
||||
guard let self = self, self.isPolling else { return }
|
||||
if !messages.isEmpty {
|
||||
print("[Loki] Received \(messages.count) new message(s) in closed group with public key: \(publicKey).")
|
||||
|
@ -61,9 +68,11 @@ public final class ClosedGroupPoller : NSObject {
|
|||
print("[Loki] Failed to deserialize envelope due to error: \(error).")
|
||||
}
|
||||
}
|
||||
}.catch2 { error in
|
||||
}
|
||||
promise.catch2 { error in
|
||||
print("[Loki] Polling failed for closed group with public key: \(publicKey) due to error: \(error).")
|
||||
}
|
||||
return promise.map { _ in }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import PromiseKit
|
||||
|
||||
internal extension AnyPromise {
|
||||
public extension AnyPromise {
|
||||
|
||||
internal static func from<T : Any>(_ promise: Promise<T>) -> AnyPromise {
|
||||
public static func from<T : Any>(_ promise: Promise<T>) -> AnyPromise {
|
||||
let result = AnyPromise(promise)
|
||||
result.retainUntilComplete()
|
||||
return result
|
||||
|
|
Loading…
Reference in a new issue