session-ios/Session/Utilities/BackgroundPoller.swift

60 lines
2.8 KiB
Swift
Raw Normal View History

2020-09-15 03:30:45 +02:00
import PromiseKit
2020-12-07 01:21:24 +01:00
import SessionSnodeKit
2020-09-15 03:30:45 +02:00
@objc(LKBackgroundPoller)
public final class BackgroundPoller : NSObject {
2020-09-18 08:12:19 +02:00
private static var closedGroupPoller: ClosedGroupPoller!
2020-12-07 01:21:24 +01:00
private static var promises: [Promise<Void>] = []
2020-09-15 03:30:45 +02:00
private override init() { }
@objc(pollWithCompletionHandler:)
public static func poll(completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
2020-12-07 01:21:24 +01:00
promises = []
promises.append(pollForMessages())
promises.append(contentsOf: pollForClosedGroupMessages())
2021-04-19 06:47:45 +02:00
let v2OpenGroupServers = Set(Storage.shared.getAllV2OpenGroups().values.map { $0.server })
v2OpenGroupServers.forEach { server in
let poller = OpenGroupPollerV2(for: server)
2021-03-24 04:36:26 +01:00
poller.stop()
2021-04-19 06:47:45 +02:00
promises.append(poller.poll(isBackgroundPoll: true))
2021-03-24 04:36:26 +01:00
}
2020-09-15 03:30:45 +02:00
when(resolved: promises).done { _ in
completionHandler(.newData)
2021-05-19 00:49:20 +02:00
}.catch { error in
SNLog("Background poll failed due to error: \(error)")
2020-09-15 03:30:45 +02:00
completionHandler(.failed)
}
}
2020-12-07 01:21:24 +01:00
private static func pollForMessages() -> Promise<Void> {
let userPublicKey = getUserHexEncodedPublicKey()
return getMessages(for: userPublicKey)
}
private static func pollForClosedGroupMessages() -> [Promise<Void>] {
let publicKeys = Storage.shared.getUserClosedGroupPublicKeys()
return publicKeys.map { getMessages(for: $0) }
}
private static func getMessages(for publicKey: String) -> Promise<Void> {
return SnodeAPI.getSwarm(for: publicKey).then(on: DispatchQueue.main) { swarm -> Promise<Void> in
2020-12-07 01:21:24 +01:00
guard let snode = swarm.randomElement() else { throw SnodeAPI.Error.generic }
2021-05-19 00:49:20 +02:00
return attempt(maxRetryCount: 4, recoveringOn: DispatchQueue.main) {
return SnodeAPI.getRawMessages(from: snode, associatedWith: publicKey).then(on: DispatchQueue.main) { rawResponse -> Promise<Void> in
let messages = SnodeAPI.parseRawMessagesResponse(rawResponse, from: snode, associatedWith: publicKey)
let promises = messages.compactMap { json -> Promise<Void>? in
// Use a best attempt approach here; we don't want to fail the entire process if one of the
// messages failed to parse.
guard let envelope = SNProtoEnvelope.from(json),
let data = try? envelope.serializedData() else { return nil }
let job = MessageReceiveJob(data: data, isBackgroundPoll: true)
return job.execute()
}
return when(fulfilled: promises) // The promise returned by MessageReceiveJob never rejects
2020-12-07 01:21:24 +01:00
}
}
}
}
2020-09-15 03:30:45 +02:00
}