3

I am trying to write to the NSUserDefaults by adding an array of objects NOT just an object.

But, I get this error

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to insert non-property list object (
"MyNotificaiton",
"MyNotificaiton"
) for key pushArray'

I pretty sure this means that the array I am trying to insert is not the right type but I don't know what I need to do with it to fix it.

This is what I have so far

class PushNotificationController: UIViewController {


let arrayKey : String = "pushArray"


var defualtUrl : String = ""
var defualtMessage : String = ""
var defualtTitle : String = ""
var defualtCoupon : String = ""
var storedUrl : String = ""
var storedMessage : String = ""
var storedTitle : String = ""
var storedCoupon : String = ""

var urlVar : String = ""
var messageVar : String = ""
var titleVar : String = ""
var couponVar : String = ""


var myNote : MyNotificaiton?

let loginInformation = NSUserDefaults.standardUserDefaults()
let noteificationDefaults = NSUserDefaults.standardUserDefaults()

var recivedNotification = [MyNotificaiton]()

@IBOutlet weak var titleLable: UILabel!
@IBOutlet weak var messageLable: UILabel!
@IBOutlet weak var urlLable: UILabel!
@IBOutlet weak var couponLable: UILabel!


override func viewDidLoad() {
    super.viewDidLoad()
    //add observer for load request in webview when receive remote notification.
    NSNotificationCenter.defaultCenter().addObserver(self, selector:#selector(PushNotificationController.PushReceiver(_:)), name: "PushReceived", object: nil)

    var isThereAMessage : Bool = false

    //create an array
    //Fill it with the userdefulat data
    //Check to see if there is any writen data
    //othere wise just move along
    if noteificationDefaults.objectForKey(arrayKey) != nil
    {
        recivedNotification = loadPushArray()
        print("Loading push Array")
        print(recivedNotification.count)
    }


    //Get the Url from the push notification
    if loginInformation.objectForKey("URL") != nil
    {
        storedUrl = loginInformation.objectForKey("URL") as! String
        if storedUrl.isEmpty
        {urlLable.text = "Url is Empty"
        }else{
             urlLable.text = storedUrl
             urlVar = storedUrl
        }
    }else
    {urlLable.text  = "Url is Empty"}
    //Display the Push notification

    //Set the message variable
    if loginInformation.objectForKey("Message") != nil
    {
        storedMessage = loginInformation.objectForKey("Message") as! String

        if storedMessage.isEmpty
        {messageLable.text  = "Message is Empty"
        }
        else{
            messageLable.text = storedMessage
            messageVar = storedMessage
            isThereAMessage = true
        }
    }else{messageLable.text = "Message is Empty"}

    //Set the Title variable
    if loginInformation.objectForKey("Title") != nil
    {
        storedTitle = loginInformation.objectForKey("Title") as! String

        if storedTitle.isEmpty
        {titleLable.text = "Title is Empty"}
        else{
            titleLable.text = storedTitle
            titleVar = storedTitle
        }
    }else{titleLable.text = "Title is Empty"}

    //Set the Title variable
    if loginInformation.objectForKey("Coupon") != nil
    {
        storedCoupon = loginInformation.objectForKey("Coupon") as! String

        if storedCoupon.isEmpty
        {couponLable.text = "Coupon is Empty"
        }else{
            couponLable.text = storedCoupon
            couponVar = storedCoupon
        }
    }else
    {couponLable.text = "Title is Empty"}

    //Saved the recived data to the push notifcation items

    print("Check to see if I recived a message : ")
    print(isThereAMessage)


    //Test to see if there was a push notificaiton sent
    if(isThereAMessage)
    {
        //if there was then create a new object with the data recived
        myNote = MyNotificaiton(pUrl: urlVar,pMessage: messageVar,pTitle: titleVar,pCoupon: couponVar)
        recivedNotification.insert(myNote!, atIndex: 0)
        recivedNotification.insert(recivedNotification[0], atIndex: 1)

        print("Added item to Recived Note Array")
        printPushObject(myNote!)
        print(recivedNotification.count)
        print("Printing the Array")
        printPushObject(recivedNotification[0])
        print("Printed the Array")
        //Save the array now
        savePushArray(recivedNotification)
    }

}

func clearLoginInfo()
{
    //set everything back to empty so it can recive new notification
    loginInformation.setObject(defualtUrl, forKey: "URL")
    loginInformation.setObject(defualtMessage, forKey: "Message")
    loginInformation.setObject(defualtTitle, forKey: "Title")
    loginInformation.setObject(defualtCoupon, forKey: "Coupon")
    self.loginInformation.synchronize()
}


//Save the Modified Arrays
func savePushArray(myArray : [MyNotificaiton])
{
    noteificationDefaults.setObject(myArray, forKey: arrayKey)
    noteificationDefaults.synchronize()
}
//Load the array
func loadPushArray() -> [MyNotificaiton]
{
    let array : [MyNotificaiton] = noteificationDefaults.objectForKey(arrayKey) as! [MyNotificaiton]
    return array
}

//When post notification then below method is called.
func PushReceiver(notifi: NSNotification)
{
    print("Pushed Recieved")
    //let dicNotifi: [NSObject : AnyObject] = notifi.userInfo!
    //NSLog("notificiation Info %@ \n", dicNotifi)
}

//Printing of an object
//This is a tail of Cpt Jack Sparrow
func printPushObject(myObject : MyNotificaiton)
{
    print(myObject.title)
    print(myObject.message)
    print(myObject.url)
    print(myObject.coupon)
}

//Build the object

//MARK: MYNotification class
class MyNotificaiton
{
    var url : String?
    var message : String?
    var title : String?
    var coupon : String?

    init(pUrl : String, pMessage : String, pTitle : String, pCoupon : String)
    {
        url = pUrl
        message = pMessage
        title = pTitle
        coupon = pCoupon
    }
    //Save and load data from NSUserDefaults
    init(coder aDecoder : NSCoder!)
    {
        self.url = aDecoder.decodeObjectForKey("thisUrl") as? String
        self.message = aDecoder.decodeObjectForKey("thisMessage") as? String
        self.title = aDecoder.decodeObjectForKey("thisTitle") as? String
        self.coupon = aDecoder.decodeObjectForKey("thisCoupon") as? String
    }

    func initWithCoder(aDecoder : NSCoder) -> MyNotificaiton
    {
        self.url = aDecoder.decodeObjectForKey("thisUrl") as? String
        self.message = aDecoder.decodeObjectForKey("thisMessage") as? String
        self.title = aDecoder.decodeObjectForKey("thisTitle") as? String
        self.coupon = aDecoder.decodeObjectForKey("thisCoupon") as? String

        return self
    }

    func encodeWithCoder(aCoder : NSCoder!)
    {
        aCoder.encodeObject(url, forKey: "thisUrl")
        aCoder.encodeObject(message, forKey: "thisMessage")
        aCoder.encodeObject(title, forKey: "thisTitle")
        aCoder.encodeObject(coupon, forKey: "thisCoupon")
    }

}
MNM
  • 2,673
  • 6
  • 38
  • 73
  • 1
    https://www.google.co.uk/search?q=%22Attempt+to+insert+non-property+list+object%22 – Wain Aug 23 '16 at 08:49
  • Please edit your question to only contains the part that you wanted to ask about, including the print of the array, that would be better than just throw the whole massive view controller here – Tj3n Aug 23 '16 at 08:49
  • @Paulw11 I am trying to save an array of objects not just one object as in the question you pointed me to. I have already looked there and didn't find the answer I needed – MNM Aug 24 '16 at 00:00
  • Once your object implements NSCoding then you can encode the array and save it to NSUserDefaults – Paulw11 Aug 24 '16 at 00:39

1 Answers1

4

You cannot save an array in the way you are trying to, do it like this instead:

let arr = ["1", "2", "3"]

let dataSave = NSKeyedArchiver.archivedDataWithRootObject(arr)
NSUserDefaults.standardUserDefaults().setObject(dataSave, forKey: "array")
NSUserDefaults.standardUserDefaults().synchronize()


let data = NSUserDefaults.standardUserDefaults().objectForKey("array")
let savedArray = NSKeyedUnarchiver.unarchiveObjectWithData(data! as! NSData)

print(savedArray!)

Will print out:

(
    1,
    2,
    3
)
Rashwan L
  • 38,237
  • 7
  • 103
  • 107
  • 1
    An array like `["1", "2", "3"]` can be stored in the user defaults directly, *without* the need to archive/unarchive. – Martin R Aug 23 '16 at 09:14