skuenstler skuenstler - 8 months ago 53
Swift Question

conformity requirements for userInfo object of UILocalNotification

Using Swift-2.2,

I would like to pass a 'struct' or a 'class object' to userInfo of a UILocalNotification. (see code-illustration below).

Can you tell me how this struct needs to be changed in order to be conform to the requirements of the UserInfo ?

I read something about

a) UserInfo can't be a struct (but I also tried with a class - it did not work either)

b) "plist type" conformity --> but how would I do so ?

c) "NSCoder" and "NSObject" conformity --> but how would I do so ?

The error message I get running the code below is:

"unable to serialize userInfo"

Thank you for any help on this.

struct MeetingData {
let title: String
let uuid: String
let startDate: NSDate
let endDate: NSDate

let notification = UILocalNotification()
notification.category = "some_category"
notification.alertLaunchImage = "Logo"
notification.fireDate = NSDate(timeIntervalSinceNow: 10)
notification.alertBody = "Data-Collection Request!"
// notification.alertAction = "I want to participate"
notification.soundName = UILocalNotificationDefaultSoundName

let myData = MeetingData(title: "myTitle",
uuid: "myUUID",
startDate: NSDate(),
endDate: NSDate(timeIntervalSinceNow: 10))

// that's where everything crashes !!!!!!!!!!!!!!
notification.userInfo = ["myKey": myData] as [String: AnyObject]


As the documentation for UILocalNotification.userInfo says:

You may add arbitrary key-value pairs to this dictionary. However, the keys and values must be valid property-list types; if any are not, an exception is raised.

You'll need to convert your data to this type yourself. You might want to do something like this:

enum Keys {
    static let title = "title"
    static let uuid = "uuid"
    static let startDate = "startDate"
    static let endDate = "endDate"
extension MeetingData {
    func dictionaryRepresentation() -> NSDictionary {
        return [Keys.title: title,
                Keys.uuid: uuid,
                Keys.startDate: startDate,
                Keys.endDate: endDate]
    init?(dictionaryRepresentation dict: NSDictionary) {
        if let title = dict[Keys.title] as? String,
            let uuid = dict[Keys.uuid] as? String,
            let startDate = dict[Keys.startDate] as? NSDate,
            let endDate = dict[Keys.endDate] as? NSDate
            self.init(title: title, uuid: uuid, startDate: startDate, endDate: endDate)
        } else {
            return nil

Then you can use myData.dictionaryRepresentation() to convert to a dictionary, and MeetingData(dictionaryRepresentation: ...) to convert from a dictionary.