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
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							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
							 | 
						|
								        )
							 | 
						|
								    }
							 | 
						|
								}
							 | 
						|
								
							 |