Persist and maybe sometimes but sadly not always update the UI
This commit is contained in:
parent
2520ccef65
commit
066be631ec
5 changed files with 39 additions and 87 deletions
|
|
@ -4,54 +4,6 @@
|
|||
type = "1"
|
||||
version = "2.0">
|
||||
<Breakpoints>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "75468F65-9E01-4DF5-A169-07217AF6D1B2"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "ntfyNSE/NotificationService.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "25"
|
||||
endingLineNumber = "25"
|
||||
landmarkName = "didReceive(_:withContentHandler:)"
|
||||
landmarkType = "7">
|
||||
<Locations>
|
||||
<Location
|
||||
uuid = "75468F65-9E01-4DF5-A169-07217AF6D1B2 - 427a5e501e23ebe0"
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
symbolName = "ntfyNSE.NotificationService.didReceive(_: __C.UNNotificationRequest, withContentHandler: (__C.UNNotificationContent) -> ()) -> ()"
|
||||
moduleName = "ntfyNSE"
|
||||
usesParentBreakpointCondition = "Yes"
|
||||
urlString = "file:///Users/pheckel/Code/ntfy/ntfyNSE/NotificationService.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "25"
|
||||
endingLineNumber = "25"
|
||||
offsetFromSymbolStart = "516">
|
||||
</Location>
|
||||
<Location
|
||||
uuid = "75468F65-9E01-4DF5-A169-07217AF6D1B2 - 427a5e501e23ebe0"
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
symbolName = "ntfyNSE.NotificationService.didReceive(_: __C.UNNotificationRequest, withContentHandler: (__C.UNNotificationContent) -> ()) -> ()"
|
||||
moduleName = "ntfyNSE"
|
||||
usesParentBreakpointCondition = "Yes"
|
||||
urlString = "file:///Users/pheckel/Code/ntfy/ntfyNSE/NotificationService.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "25"
|
||||
endingLineNumber = "25"
|
||||
offsetFromSymbolStart = "560">
|
||||
</Location>
|
||||
</Locations>
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
|
|
@ -62,8 +14,8 @@
|
|||
filePath = "ntfyNSE/NotificationService.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "32"
|
||||
endingLineNumber = "32"
|
||||
startingLineNumber = "25"
|
||||
endingLineNumber = "25"
|
||||
landmarkName = "didReceive(_:withContentHandler:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ import Firebase
|
|||
|
||||
@main
|
||||
struct AppMain: App {
|
||||
let tag = "main"
|
||||
|
||||
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate: AppDelegate
|
||||
@StateObject private var store = Store.shared
|
||||
|
||||
|
|
@ -21,6 +23,13 @@ struct AppMain: App {
|
|||
WindowGroup {
|
||||
ContentView()
|
||||
.environment(\.managedObjectContext, store.container.viewContext)
|
||||
.onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { _ in
|
||||
// Use this hook instead of applicationDidBecomeActive, see https://stackoverflow.com/a/68888509/1440785
|
||||
// That post also explains how to start SwiftUI from AppDelegate if that's ever needed.
|
||||
|
||||
Log.d(tag, "App became active, refreshing objects")
|
||||
store.context.refreshAllObjects()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,10 @@
|
|||
//
|
||||
// DataController.swift
|
||||
// ntfy
|
||||
//
|
||||
// Created by Philipp Heckel on 5/14/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CoreData
|
||||
|
||||
class Store: ObservableObject {
|
||||
static let shared = Store()
|
||||
static let tag = "Store"
|
||||
|
||||
let tag = "Store"
|
||||
let container: NSPersistentContainer
|
||||
var context: NSManagedObjectContext
|
||||
|
||||
|
|
@ -19,13 +12,13 @@ class Store: ObservableObject {
|
|||
let directory = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.io.heckel.ntfy")!
|
||||
let storeUrl = directory.appendingPathComponent("ntfy.sqlite")
|
||||
let description = NSPersistentStoreDescription(url: storeUrl)
|
||||
|
||||
|
||||
// Set up container and observe changes from app extension
|
||||
container = NSPersistentContainer(name: "Model")
|
||||
container.persistentStoreDescriptions = [description]
|
||||
container.loadPersistentStores { description, error in
|
||||
if let error = error {
|
||||
print("Core Data failed to load: \(error.localizedDescription)")
|
||||
Log.e(Store.tag, "Core Data failed to load: \(error.localizedDescription)", error)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -56,11 +49,11 @@ class Store: ObservableObject {
|
|||
let time = userInfo["time"] as? String,
|
||||
let timeInt = Int64(time),
|
||||
let message = userInfo["message"] as? String else {
|
||||
print("Unknown or irrelevant message", userInfo)
|
||||
Log.d(Store.tag, "Unknown or irrelevant message", userInfo)
|
||||
return
|
||||
}
|
||||
guard let subscription = getSubscription(baseUrl: appBaseUrl, topic: topic) else {
|
||||
print("Subscription for topic \(topic) unknown")
|
||||
Log.d(Store.tag, "Subscription for topic \(topic) unknown")
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -73,8 +66,8 @@ class Store: ObservableObject {
|
|||
subscription.addToNotifications(notification)
|
||||
try context.save()
|
||||
} catch let error {
|
||||
Log.w(tag, "Cannot store notification", error)
|
||||
context.rollback()
|
||||
Log.w(Store.tag, "Cannot store notification (fromUserInfo)", error)
|
||||
rollbackAndRefresh()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -88,8 +81,17 @@ class Store: ObservableObject {
|
|||
subscription.addToNotifications(notification)
|
||||
try context.save()
|
||||
} catch let error {
|
||||
print(error)
|
||||
context.rollback()
|
||||
Log.w(Store.tag, "Cannot store notification (fromMessage)", error)
|
||||
rollbackAndRefresh()
|
||||
}
|
||||
}
|
||||
|
||||
func rollbackAndRefresh() {
|
||||
// Hack: We refresh all objects, since failing to store a notification usually means
|
||||
// that the app extension stored the notification first. This is a way to update the
|
||||
// UI properly when it is in the foreground and the app extension stores a notification.
|
||||
|
||||
context.rollback()
|
||||
context.refreshAllObjects()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,3 @@
|
|||
//
|
||||
// Subscription.swift
|
||||
// ntfy
|
||||
//
|
||||
// Created by Philipp Heckel on 5/15/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension Subscription {
|
||||
|
|
@ -25,6 +18,9 @@ extension Subscription {
|
|||
}
|
||||
|
||||
func notificationsSorted() -> [Notification] {
|
||||
return notifications!.sortedArray(using: [NSSortDescriptor(key: "time", ascending: false)]) as! [Notification]
|
||||
if let notifications = notifications {
|
||||
return notifications.sortedArray(using: [NSSortDescriptor(key: "time", ascending: false)]) as! [Notification]
|
||||
}
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,11 @@
|
|||
//
|
||||
// NotificationService.swift
|
||||
// ntfyNSE
|
||||
//
|
||||
// Created by Philipp Heckel on 5/13/22.
|
||||
//
|
||||
|
||||
import UserNotifications
|
||||
import CoreData
|
||||
|
||||
// https://debashishdas3100.medium.com/save-push-notifications-to-coredata-userdefaults-ios-swift-5-ea074390b57
|
||||
|
||||
class NotificationService: UNNotificationServiceExtension {
|
||||
let tag = "NotificationService"
|
||||
|
||||
var contentHandler: ((UNNotificationContent) -> Void)?
|
||||
var bestAttemptContent: UNMutableNotificationContent?
|
||||
|
||||
|
|
@ -20,15 +15,13 @@ class NotificationService: UNNotificationServiceExtension {
|
|||
) {
|
||||
self.contentHandler = contentHandler
|
||||
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
|
||||
|
||||
print("NotificationService didReceive")
|
||||
Log.d(tag, "Notification received (in service)") // Logs from extensions are not printed in Xcode!
|
||||
|
||||
if let bestAttemptContent = bestAttemptContent {
|
||||
bestAttemptContent.title = "\(bestAttemptContent.title) [modified]"
|
||||
// bestAttemptContent.title = "\(bestAttemptContent.title) [modified]"
|
||||
|
||||
let userInfo = bestAttemptContent.userInfo
|
||||
let store = Store.shared
|
||||
|
||||
store.saveNotification(fromUserInfo: userInfo)
|
||||
Store.shared.saveNotification(fromUserInfo: userInfo)
|
||||
|
||||
contentHandler(bestAttemptContent)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue