mirror of https://github.com/oxen-io/session-ios
				
				
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			57 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Swift
		
	
			
		
		
	
	
			57 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Swift
		
	
| import PromiseKit
 | |
| import SessionSnodeKit
 | |
| 
 | |
| @objc(LKBackgroundPoller)
 | |
| public final class BackgroundPoller : NSObject {
 | |
|     private static var closedGroupPoller: ClosedGroupPoller!
 | |
|     private static var promises: [Promise<Void>] = []
 | |
| 
 | |
|     private override init() { }
 | |
| 
 | |
|     @objc(pollWithCompletionHandler:)
 | |
|     public static func poll(completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
 | |
|         promises = []
 | |
|         promises.append(pollForMessages())
 | |
|         promises.append(contentsOf: pollForClosedGroupMessages())
 | |
|         let openGroups: [String:OpenGroup] = Storage.shared.getAllUserOpenGroups()
 | |
|         openGroups.values.forEach { openGroup in
 | |
|             let poller = OpenGroupPoller(for: openGroup)
 | |
|             poller.stop()
 | |
|             promises.append(poller.pollForNewMessages(isBackgroundPoll: true))
 | |
|         }
 | |
|         when(resolved: promises).done { _ in
 | |
|             completionHandler(.newData)
 | |
|         }.catch { _ in
 | |
|             completionHandler(.failed)
 | |
|         }
 | |
|     }
 | |
|     
 | |
|     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).then2 { swarm -> Promise<Void> in
 | |
|             guard let snode = swarm.randomElement() else { throw SnodeAPI.Error.generic }
 | |
|             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
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 |