You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

170 lines
4.6 KiB

/**
* NotificationContent.swift
*
* Data structure for notification content
*
* @author Matthew Raymer
* @version 1.0.0
*/
import Foundation
/**
* Data structure representing notification content
*
* This class encapsulates all the information needed for a notification
* including scheduling, content, and metadata.
*/
class NotificationContent {
// MARK: - Properties
let id: String
let title: String?
let body: String?
let scheduledTime: TimeInterval // milliseconds since epoch
let fetchedAt: TimeInterval // milliseconds since epoch
let url: String?
let payload: [String: Any]?
let etag: String?
// MARK: - Initialization
/**
* Initialize notification content
*
* @param id Unique notification identifier
* @param title Notification title
* @param body Notification body text
* @param scheduledTime When notification should fire (milliseconds since epoch)
* @param fetchedAt When content was fetched (milliseconds since epoch)
* @param url URL for content fetching
* @param payload Additional payload data
* @param etag ETag for HTTP caching
*/
init(id: String,
title: String?,
body: String?,
scheduledTime: TimeInterval,
fetchedAt: TimeInterval,
url: String?,
payload: [String: Any]?,
etag: String?) {
self.id = id
self.title = title
self.body = body
self.scheduledTime = scheduledTime
self.fetchedAt = fetchedAt
self.url = url
self.payload = payload
self.etag = etag
}
// MARK: - Convenience Methods
/**
* Get scheduled time as Date
*
* @return Scheduled time as Date object
*/
func getScheduledTimeAsDate() -> Date {
return Date(timeIntervalSince1970: scheduledTime / 1000)
}
/**
* Get fetched time as Date
*
* @return Fetched time as Date object
*/
func getFetchedTimeAsDate() -> Date {
return Date(timeIntervalSince1970: fetchedAt / 1000)
}
/**
* Check if notification is scheduled for today
*
* @return true if scheduled for today
*/
func isScheduledForToday() -> Bool {
let scheduledDate = getScheduledTimeAsDate()
let today = Date()
let calendar = Calendar.current
return calendar.isDate(scheduledDate, inSameDayAs: today)
}
/**
* Check if notification is scheduled for tomorrow
*
* @return true if scheduled for tomorrow
*/
func isScheduledForTomorrow() -> Bool {
let scheduledDate = getScheduledTimeAsDate()
let tomorrow = Calendar.current.date(byAdding: .day, value: 1, to: Date()) ?? Date()
let calendar = Calendar.current
return calendar.isDate(scheduledDate, inSameDayAs: tomorrow)
}
/**
* Check if notification is in the future
*
* @return true if scheduled time is in the future
*/
func isInTheFuture() -> Bool {
return scheduledTime > Date().timeIntervalSince1970 * 1000
}
/**
* Get age of content at scheduled time
*
* @return Age in seconds at scheduled time
*/
func getAgeAtScheduledTime() -> TimeInterval {
return (scheduledTime - fetchedAt) / 1000
}
/**
* Convert to dictionary representation
*
* @return Dictionary representation of notification content
*/
func toDictionary() -> [String: Any] {
return [
"id": id,
"title": title ?? "",
"body": body ?? "",
"scheduledTime": scheduledTime,
"fetchedAt": fetchedAt,
"url": url ?? "",
"payload": payload ?? [:],
"etag": etag ?? ""
]
}
/**
* Create from dictionary representation
*
* @param dict Dictionary representation
* @return NotificationContent instance
*/
static func fromDictionary(_ dict: [String: Any]) -> NotificationContent? {
guard let id = dict["id"] as? String,
let scheduledTime = dict["scheduledTime"] as? TimeInterval,
let fetchedAt = dict["fetchedAt"] as? TimeInterval else {
return nil
}
return NotificationContent(
id: id,
title: dict["title"] as? String,
body: dict["body"] as? String,
scheduledTime: scheduledTime,
fetchedAt: fetchedAt,
url: dict["url"] as? String,
payload: dict["payload"] as? [String: Any],
etag: dict["etag"] as? String
)
}
}