diff --git a/ntfy/Persistence/Store.swift b/ntfy/Persistence/Store.swift index e216901..aa6ed42 100644 --- a/ntfy/Persistence/Store.swift +++ b/ntfy/Persistence/Store.swift @@ -52,11 +52,14 @@ class Store: ObservableObject { .store(in: &cancellables) } - func saveSubscription(baseUrl: String, topic: String) { + func saveSubscription(baseUrl: String, topic: String) -> Subscription { let subscription = Subscription(context: context) subscription.baseUrl = appBaseUrl subscription.topic = topic - try? context.save() + DispatchQueue.main.sync { + try? context.save() + } + return subscription } func getSubscription(baseUrl: String, topic: String) -> Subscription? { diff --git a/ntfy/Persistence/SubscriptionManager.swift b/ntfy/Persistence/SubscriptionManager.swift index 4ff7233..a0225ac 100644 --- a/ntfy/Persistence/SubscriptionManager.swift +++ b/ntfy/Persistence/SubscriptionManager.swift @@ -10,7 +10,23 @@ struct SubscriptionManager { func subscribe(baseUrl: String, topic: String) { Log.d(tag, "Subscribing to \(topicUrl(baseUrl: appBaseUrl, topic: topic))") Messaging.messaging().subscribe(toTopic: topic) - store.saveSubscription(baseUrl: baseUrl, topic: topic) + let subscription = store.saveSubscription(baseUrl: baseUrl, topic: topic) + + // FIXME: Duplicate code! + ApiService.shared.poll(subscription: subscription) { messages, error in + guard let messages = messages else { + Log.e(tag, "Polling failed", error) + return + } + Log.d(tag, "Polling success, \(messages.count) new message(s)", messages) + if !messages.isEmpty { + DispatchQueue.main.async { + for message in messages { + store.save(notificationFromMessage: message, withSubscription: subscription) + } + } + } + } } func unsubscribe(_ subscription: Subscription) { diff --git a/ntfy/Views/SubscriptionAddView.swift b/ntfy/Views/SubscriptionAddView.swift index 110069e..def00b9 100644 --- a/ntfy/Views/SubscriptionAddView.swift +++ b/ntfy/Views/SubscriptionAddView.swift @@ -7,7 +7,7 @@ struct SubscriptionAddView: View { @Environment(\.presentationMode) var presentationMode: Binding @EnvironmentObject private var store: Store @State private var topic: String = "" - + private var subscriptionManager: SubscriptionManager { return SubscriptionManager(store: store) } @@ -29,22 +29,24 @@ struct SubscriptionAddView: View { Button(action: subscribeAction) { Text("Subscribe") } - .disabled(!isTopicValid(topic: sanitizeTopic(topic: topic))) + .disabled(!isValid(topic: sanitize(topic: topic))) } } } } - private func sanitizeTopic(topic: String) -> String { + private func sanitize(topic: String) -> String { return topic.trimmingCharacters(in: [" "]) } - private func isTopicValid(topic: String) -> Bool { + private func isValid(topic: String) -> Bool { return !topic.isEmpty && (topic.range(of: "^[-_A-Za-z0-9]{1,64}$", options: .regularExpression, range: nil, locale: nil) != nil) } private func subscribeAction() { - subscriptionManager.subscribe(baseUrl: appBaseUrl, topic: topic) + DispatchQueue.global(qos: .background).async { + subscriptionManager.subscribe(baseUrl: appBaseUrl, topic: sanitize(topic: topic)) + } presentationMode.wrappedValue.dismiss() } }