Landon Tetreault Landon Tetreault - 5 months ago 46
Swift Question

How Save UILocalNotifications in CoreData

Answer is below, image is here:

enter image description here

Answer

I was searching how to do this for a couple of days and was only able to find people who stored UILocalNotificaations in NSUserDefaults. Saving these in NSUserDefaults seemed wrong to me because it is supposed to be used for small flags. I just now finally figured out how to store notifications in CoreData. This is Using Xcode 7.3.1 and Swift 2.2

First off you need to create a new entity in your CoreDataModel and then add a single attribute to it. the attribute should be of type Binary Data I named my table/entity "ManagedFiredNotifications" and my attribute "notification". it should look like this:

Image linked in Question above.

Next you need to add an extension to UILocalNotification it should go like this:

extension UILocalNotification { 
   func save() -> Bool {
      let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate
      let firedNotificationEntity = NSEntityDescription.insertNewObjectForEntityForName("ManagedFiredNotifications", inManagedObjectContext: appDelegate!.managedObjectContext)

      guard appDelegate != nil else {
         return false
      }

      let data = NSKeyedArchiver.archivedDataWithRootObject(self)

      firedNotificationEntity.setValue(data, forKey: "notification")

      do {
         try appDelegate!.managedObjectContext.save()
         return true
      } catch {
         return false
      }
   }
}

Now for saving a notification all you need to do is call

UILocalNotification.save()

On the notification you would like to save. my notifications were named 'notification' so I would call notification.save()

To retrieve a notification you need a method like this

func getLocalFiredNotifications() -> [UILocalNotification]? {
    let managedObjectContext = (UIApplication.sharedApplication().delegate as? AppDelegate)!.managedObjectContext
    let firedNotificationFetchRequest = NSFetchRequest(entityName: "ManagedFiredNotifications")
    firedNotificationFetchRequest.includesPendingChanges = false

    do {
        let fetchedFiredNotifications = try managedObjectContext.executeFetchRequest(firedNotificationFetchRequest)
        guard fetchedFiredNotifications.count > 0 else {
            return nil
        }


        var firedNotificationsToReturn = [UILocalNotification]()
        for managedFiredNotification in fetchedFiredNotifications {

            let notificationData = managedFiredNotification.valueForKey("notification") as! NSData
            let notificationToAdd = NSKeyedUnarchiver.unarchiveObjectWithData(notificationData) as! UILocalNotification

            firedNotificationsToReturn.append(notificationToAdd)
        }
        return firedNotificationsToReturn
    } catch {
        return nil
    }

}

Note that this returns an array of UILocalNotifications.

When retrieving these if you plan on removing a few of them and then storing the list again you should remove them when you get them something like this works:

func loadFiredNotifications() {
    let notifications = StudyHelper().getLocalFiredNotifications()
    if notifications != nil {
        firedNotifications = notifications!
    } else {
        // throw an error or log it
    }
    classThatRemoveMethodIsIn().removeFiredLocalNotifications()
}

I hope this helps someone who had the same problems that I did trying to implement this.