feat(ios): implement getContentCacheById, getLatestContentCache, and saveContentCache methods

Implemented content cache access methods using Core Data:

getContentCacheById():
- Returns content cache by ID or latest if ID not provided
- Uses Core Data fetch with predicate for ID lookup
- Returns null if cache not found
- Matches Android getContentCacheById method

getLatestContentCache():
- Returns latest content cache entry
- Delegates to getContentCacheById with no ID
- Matches Android getLatestContentCache method

saveContentCache():
- Saves content to cache in Core Data
- Auto-generates ID if not provided (cache_timestamp)
- Converts payload string to Data for storage
- Stores fetchedAt, ttlSeconds, payload, and meta
- Returns saved cache object

iOS Adaptations:
- Uses Core Data ContentCache entity
- Payload stored as Data (from JSON string)
- Timestamp conversion (Date to milliseconds)
- Error handling for invalid payload data

Progress: 47/52 methods implemented (90% complete)
This commit is contained in:
Matthew Raymer
2025-11-11 02:18:55 -08:00
parent be6cdc98d6
commit 9d5ffcfdb5

View File

@@ -1333,6 +1333,143 @@ public class DailyNotificationPlugin: CAPPlugin {
} }
} }
/**
* Get content cache by ID
*
* Returns content cache by ID, or latest if ID not provided.
*
* Equivalent to Android's getContentCacheById method.
*/
@objc func getContentCacheById(_ call: CAPPluginCall) {
let options = call.getObject("options")
let id = options?["id"] as? String
print("DNP-PLUGIN: Getting content cache: id=\(id ?? "latest")")
Task {
do {
let context = persistenceController.container.viewContext
let request: NSFetchRequest<ContentCache> = ContentCache.fetchRequest()
if let cacheId = id {
request.predicate = NSPredicate(format: "id == %@", cacheId)
} else {
request.sortDescriptors = [NSSortDescriptor(keyPath: \ContentCache.fetchedAt, ascending: false)]
request.fetchLimit = 1
}
let results = try context.fetch(request)
if let cache = results.first {
let payload = try JSONSerialization.jsonObject(with: cache.payload!) as? [String: Any] ?? [:]
let result: [String: Any] = [
"id": cache.id ?? "",
"fetchedAt": Int64((cache.fetchedAt?.timeIntervalSince1970 ?? 0) * 1000),
"ttlSeconds": cache.ttlSeconds,
"payload": payload,
"meta": cache.meta ?? ""
]
DispatchQueue.main.async {
call.resolve(result)
}
} else {
DispatchQueue.main.async {
call.resolve(["contentCache": NSNull()])
}
}
} catch {
print("DNP-PLUGIN: Failed to get content cache: \(error)")
DispatchQueue.main.async {
call.reject("Failed to get content cache: \(error.localizedDescription)")
}
}
}
}
/**
* Get latest content cache
*
* Returns the latest content cache entry.
*
* Equivalent to Android's getLatestContentCache method.
*/
@objc func getLatestContentCache(_ call: CAPPluginCall) {
// Delegate to getContentCacheById with no ID (returns latest)
let options: [String: Any] = [:]
call.options = options
getContentCacheById(call)
}
/**
* Save content cache
*
* Saves content to cache in Core Data.
*
* Equivalent to Android's saveContentCache method.
*/
@objc func saveContentCache(_ call: CAPPluginCall) {
guard let contentJson = call.getObject("content") else {
call.reject("Content data is required")
return
}
guard let payloadString = contentJson["payload"] as? String else {
call.reject("Payload is required")
return
}
guard let ttlSeconds = contentJson["ttlSeconds"] as? Int else {
call.reject("TTL seconds is required")
return
}
let id = contentJson["id"] as? String ?? "cache_\(Int64(Date().timeIntervalSince1970 * 1000))"
let meta = contentJson["meta"] as? String
print("DNP-PLUGIN: Saving content cache: id=\(id)")
Task {
do {
let context = persistenceController.container.viewContext
// Convert payload string to Data
guard let payloadData = payloadString.data(using: .utf8) else {
throw NSError(domain: "DailyNotificationPlugin", code: 1, userInfo: [NSLocalizedDescriptionKey: "Invalid payload data"])
}
let cache = ContentCache(context: context)
cache.id = id
cache.fetchedAt = Date()
cache.ttlSeconds = Int32(ttlSeconds)
cache.payload = payloadData
cache.meta = meta
try context.save()
let result: [String: Any] = [
"id": id,
"fetchedAt": Int64(Date().timeIntervalSince1970 * 1000),
"ttlSeconds": ttlSeconds,
"payload": try JSONSerialization.jsonObject(with: payloadData) as? [String: Any] ?? [:],
"meta": meta ?? ""
]
print("DNP-PLUGIN: Content cache saved successfully")
DispatchQueue.main.async {
call.resolve(result)
}
} catch {
print("DNP-PLUGIN: Failed to save content cache: \(error)")
DispatchQueue.main.async {
call.reject("Failed to save content cache: \(error.localizedDescription)")
}
}
}
}
/** /**
* Get power state * Get power state
* *