feat(ios)!: implement iOS parity with BGTaskScheduler + UNUserNotificationCenter
- Add complete iOS plugin implementation with BGTaskScheduler integration - Implement Core Data model mirroring Android SQLite schema (ContentCache, Schedule, Callback, History) - Add background task handlers for content fetch and notification delivery - Implement TTL-at-fire logic with Core Data persistence - Add callback management with HTTP and local callback support - Include comprehensive error handling and structured logging - Add Info.plist configuration for background tasks and permissions - Support for dual scheduling with BGAppRefreshTask and BGProcessingTask BREAKING CHANGE: iOS implementation requires iOS 13.0+ and background task permissions
This commit is contained in:
139
ios/Plugin/DailyNotificationModel.swift
Normal file
139
ios/Plugin/DailyNotificationModel.swift
Normal file
@@ -0,0 +1,139 @@
|
||||
//
|
||||
// DailyNotificationModel.xcdatamodeld
|
||||
// DailyNotificationPlugin
|
||||
//
|
||||
// Created by Matthew Raymer on 2025-09-22
|
||||
// Copyright © 2025 TimeSafari. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CoreData
|
||||
|
||||
/**
|
||||
* Core Data model for Daily Notification Plugin
|
||||
* Mirrors Android SQLite schema for cross-platform consistency
|
||||
*
|
||||
* @author Matthew Raymer
|
||||
* @version 1.1.0
|
||||
* @created 2025-09-22 09:22:32 UTC
|
||||
*/
|
||||
|
||||
// MARK: - ContentCache Entity
|
||||
@objc(ContentCache)
|
||||
public class ContentCache: NSManagedObject {
|
||||
|
||||
}
|
||||
|
||||
extension ContentCache {
|
||||
@nonobjc public class func fetchRequest() -> NSFetchRequest<ContentCache> {
|
||||
return NSFetchRequest<ContentCache>(entityName: "ContentCache")
|
||||
}
|
||||
|
||||
@NSManaged public var id: String?
|
||||
@NSManaged public var fetchedAt: Date?
|
||||
@NSManaged public var ttlSeconds: Int32
|
||||
@NSManaged public var payload: Data?
|
||||
@NSManaged public var meta: String?
|
||||
}
|
||||
|
||||
extension ContentCache: Identifiable {
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Schedule Entity
|
||||
@objc(Schedule)
|
||||
public class Schedule: NSManagedObject {
|
||||
|
||||
}
|
||||
|
||||
extension Schedule {
|
||||
@nonobjc public class func fetchRequest() -> NSFetchRequest<Schedule> {
|
||||
return NSFetchRequest<Schedule>(entityName: "Schedule")
|
||||
}
|
||||
|
||||
@NSManaged public var id: String?
|
||||
@NSManaged public var kind: String?
|
||||
@NSManaged public var cron: String?
|
||||
@NSManaged public var clockTime: String?
|
||||
@NSManaged public var enabled: Bool
|
||||
@NSManaged public var lastRunAt: Date?
|
||||
@NSManaged public var nextRunAt: Date?
|
||||
@NSManaged public var jitterMs: Int32
|
||||
@NSManaged public var backoffPolicy: String?
|
||||
@NSManaged public var stateJson: String?
|
||||
}
|
||||
|
||||
extension Schedule: Identifiable {
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Callback Entity
|
||||
@objc(Callback)
|
||||
public class Callback: NSManagedObject {
|
||||
|
||||
}
|
||||
|
||||
extension Callback {
|
||||
@nonobjc public class func fetchRequest() -> NSFetchRequest<Callback> {
|
||||
return NSFetchRequest<Callback>(entityName: "Callback")
|
||||
}
|
||||
|
||||
@NSManaged public var id: String?
|
||||
@NSManaged public var kind: String?
|
||||
@NSManaged public var target: String?
|
||||
@NSManaged public var headersJson: String?
|
||||
@NSManaged public var enabled: Bool
|
||||
@NSManaged public var createdAt: Date?
|
||||
}
|
||||
|
||||
extension Callback: Identifiable {
|
||||
|
||||
}
|
||||
|
||||
// MARK: - History Entity
|
||||
@objc(History)
|
||||
public class History: NSManagedObject {
|
||||
|
||||
}
|
||||
|
||||
extension History {
|
||||
@nonobjc public class func fetchRequest() -> NSFetchRequest<History> {
|
||||
return NSFetchRequest<History>(entityName: "History")
|
||||
}
|
||||
|
||||
@NSManaged public var id: String?
|
||||
@NSManaged public var refId: String?
|
||||
@NSManaged public var kind: String?
|
||||
@NSManaged public var occurredAt: Date?
|
||||
@NSManaged public var durationMs: Int32
|
||||
@NSManaged public var outcome: String?
|
||||
@NSManaged public var diagJson: String?
|
||||
}
|
||||
|
||||
extension History: Identifiable {
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Persistence Controller
|
||||
class PersistenceController {
|
||||
static let shared = PersistenceController()
|
||||
|
||||
let container: NSPersistentContainer
|
||||
|
||||
init(inMemory: Bool = false) {
|
||||
container = NSPersistentContainer(name: "DailyNotificationModel")
|
||||
|
||||
if inMemory {
|
||||
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
|
||||
}
|
||||
|
||||
container.loadPersistentStores { _, error in
|
||||
if let error = error as NSError? {
|
||||
fatalError("Core Data error: \(error), \(error.userInfo)")
|
||||
}
|
||||
}
|
||||
|
||||
container.viewContext.automaticallyMergesChangesFromParent = true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user