SubscriptionManager.swift 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. import Foundation
  2. import FirebaseMessaging
  3. /// Manager to combine persisting a subscription to the data store and subscribing to Firebase.
  4. /// This is to centralize the logic in one place.
  5. struct SubscriptionManager {
  6. private let tag = "Store"
  7. var store: Store
  8. func subscribe(baseUrl: String, topic: String) {
  9. Log.d(tag, "Subscribing to \(topicUrl(baseUrl: baseUrl, topic: topic))")
  10. if baseUrl == Config.appBaseUrl {
  11. Messaging.messaging().subscribe(toTopic: topic)
  12. } else {
  13. Messaging.messaging().subscribe(toTopic: topicHash(baseUrl: baseUrl, topic: topic))
  14. }
  15. let subscription = store.saveSubscription(baseUrl: baseUrl, topic: topic)
  16. poll(subscription)
  17. }
  18. func unsubscribe(_ subscription: Subscription) {
  19. Log.d(tag, "Unsubscribing from \(subscription.urlString())")
  20. DispatchQueue.main.async {
  21. if let baseUrl = subscription.baseUrl, let topic = subscription.topic {
  22. if baseUrl == Config.appBaseUrl {
  23. Messaging.messaging().unsubscribe(fromTopic: topic)
  24. } else {
  25. Messaging.messaging().unsubscribe(fromTopic: topicHash(baseUrl: baseUrl, topic: topic))
  26. }
  27. }
  28. store.delete(subscription: subscription)
  29. }
  30. }
  31. func poll(_ subscription: Subscription) {
  32. poll(subscription) { _ in }
  33. }
  34. func poll(_ subscription: Subscription, completionHandler: @escaping ([Message]) -> Void) {
  35. let user = store.getUser(baseUrl: subscription.baseUrl!)?.toBasicUser()
  36. Log.d(tag, "Polling from \(subscription.urlString()) with user \(user?.username ?? "anonymous")")
  37. ApiService.shared.poll(subscription: subscription, user: user) { messages, error in
  38. guard let messages = messages else {
  39. Log.e(tag, "Polling failed", error)
  40. completionHandler([])
  41. return
  42. }
  43. Log.d(tag, "Polling success, \(messages.count) new message(s)", messages)
  44. if !messages.isEmpty {
  45. DispatchQueue.main.sync {
  46. for message in messages {
  47. store.saveNotification(fromMessage: message, withSubscription: subscription)
  48. }
  49. }
  50. }
  51. completionHandler(messages)
  52. }
  53. }
  54. }