11

I get the fatal error: "Could not cast value of type 'NSTaggedPointerString' to 'NSData'" on the line "if (NSKeyedUnarchiver.unarchiveObject(with: loadedData as! Data) as? CKRecord) != nil".

There is another fatal error:"Attempt to set a non-property-list object as an NSUserDefaults/CFPreferences value for key locationData" when I try to save locationRecord as a default.

var locationRecord = CKRecord(recordType: "location")

func getRecordToUpdate(_ locations:CLLocation)
{
    if defaults1.object(forKey: "locationData") == nil{
        locationRecord.setObject(locations, forKey: "location")
        defaults1.set(locationRecord, forKey: "locationData")
        self.updateLocationRecord(locations: locations)
    }else{
        if let loadedData = defaults1.object(forKey: "locationData") {
            print("continue")
            if (NSKeyedUnarchiver.unarchiveObject(with: loadedData as! Data)) != nil
            {
                let publicDB = CKContainer.default().publicCloudDatabase
                publicDB.fetch(withRecordID: locationRecord.recordID,completionHandler: {
                    (record, error) in
                    if error == nil
                    {
                        publicDB.delete(withRecordID: (record?.recordID)!, completionHandler: {
                            (record, error) in
                            if(error == nil){
                                print("old record delete")
                                self.locationRecord.setObject(locations, forKey: "location")
                                self.defaults1.set(self.locationRecord, forKey: "locationData")
                                self.updateLocationRecord(locations: locations)
                            }
                            else{
                            }
                        })
                    }else{
                        print("Error fetching previous record")
                        }
                })
            }
        }
    }
}
    func updateLocationRecord(locations: CLLocation)
    {
        locationRecord.setObject(locations, forKey: "location")
        let publicData = CKContainer.default().publicCloudDatabase
        publicData.save(locationRecord, completionHandler: { record, error in
        })
        if error == nil
        {
            print("Location saved")
        }
    }
Peter Hornsby
  • 4,208
  • 1
  • 25
  • 44
Steve
  • 1,121
  • 1
  • 12
  • 32
  • You have to query the existing record and update it. You are creating a new `CKRecord` each time. – rmaddy Oct 27 '16 at 02:40
  • how can i make sure that it is that users record that is being fetched? @rmaddy – Steve Oct 27 '16 at 03:49
  • Your `location` record type needs appropriate fields. Right now it looks like you just have the one `location` field. So all you have is a bunch of "location" records with just a single `CLLocation` field. You have no way to know what a given record is for. – rmaddy Oct 27 '16 at 03:55
  • Could you provide an example of just how to initialize the record with the correct arguments. @rmaddy – Steve Oct 27 '16 at 05:16
  • That's up to you and your needs. – rmaddy Oct 27 '16 at 05:18
  • I just need the location that is passed to these methods to replace the old location record – Steve Oct 27 '16 at 05:30

1 Answers1

4

Here is the code that ended up working for me:

if let loadedData = defaults1.object(forKey: "locationData") as? Data {
                let litt = NSKeyedUnarchiver.unarchiveObject(with: loadedData) as! CKRecord
                let publicDB = CKContainer.default().publicCloudDatabase
                    publicDB.fetch(withRecordID: litt.recordID ,completionHandler: {
                        (record, error) in
                        if error == nil
                        {
                            publicDB.delete(withRecordID: (record?.recordID)!, completionHandler: {
                                (record, error) in
                                if(error == nil){
                                    print("old record delete")
                                    let id = self.locationRecord.recordID.recordName
                                    self.locationRecord.setObject(locations, forKey: "location")
                                    self.defaults1.set(id, forKey: "locationData")
                                    self.updateLocationRecord(locations: locations)
                                }
                                else{
                                }
                            })
                        }else{
                            print("Error fetching previous record")
                            }
                    })
                }
        }
    }
Steve
  • 1,121
  • 1
  • 12
  • 32