Reputation: 426
I have 2 classes, I have an Activity Class and JobPost class, in my Activity class there is an object called "postedJob" which is a pointer(JobPost), it stores the objectID of every job posted.
What I am trying to achieve is to query the postedJob from activity, but my code below form parse is throwing an error.
let jobPostObject = PFObject(className: "JobPost")
let query = PFQuery(className: "Activity")
query.whereKey("postedJob", equalTo: jobPostObject)
let objects = query.findObjects()
print(objects)
I dont understand why it's returning this error below
'Tried to save an object with a new, unsaved child.'
*** First throw call stack:
(
0 CoreFoundation 0x0000000108213f45 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000107c8bdeb objc_exception_throw + 48
2 CoreFoundation 0x0000000108213e7d +[NSException raise:format:] + 205
3 post 0x00000001063c5e92 -[PFPointerObjectEncoder encodeParseObject:] + 108
4 post 0x00000001063c5324 -[PFEncoder encodeObject:] + 113
5 post 0x00000001063948ef __129+[PFRESTQueryCommand findCommandParametersWithOrder:conditions:selectedKeys:includedKeys:limit:skip:extraOptions:tracingEnabled:]_block_invoke97 + 1808
6 CoreFoundation 0x0000000108180cb5 __65-[__NSDictionaryI enumerateKeysAndObjectsWithOptions:usingBlock:]_block_invoke + 85
7 CoreFoundation 0x0000000108180bbd -[__NSDictionaryI enumerateKeysAndObjectsWithOptions:usingBlock:] + 237
8 post 0x00000001063940fd +[PFRESTQueryCommand findCommandParametersWithOrder:conditions:selectedKeys:includedKeys:limit:skip:extraOptions:tracingEnabled:] + 911
9 post 0x0000000106393d2c +[PFRESTQueryCommand findCommandParametersForQueryState:] + 296
10 post 0x00000001063937df +[PFRESTQueryCommand findCommandForQueryState:withSessionToken:] + 79
11 post 0x00000001063a5739 __78-[PFQueryController findObjectsAsyncForQueryState:withCancellationToken:user:]_block_invoke + 106
12 post 0x000000010634a7be __37+[BFTask taskFromExecutor:withBlock:]_block_invoke + 78
13 post 0x000000010634bf20 __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke_2 + 112
14 libdispatch.dylib 0x000000010a2f1e5d _dispatch_call_block_and_release + 12
15 libdispatch.dylib 0x000000010a31249b _dispatch_client_callout + 8
16 libdispatch.dylib 0x000000010a2fabef _dispatch_root_queue_drain + 1829
17 libdispatch.dylib 0x000000010a2fa4c5 _dispatch_worker_thread3 + 111
18 libsystem_pthread.dylib 0x000000010a65a4f2 _pthread_wqthread + 1129
19 libsystem_pthread.dylib 0x000000010a658375 start_wqthread + 13
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
Edit 1 :
Import UIKit
class ActivityEmployerVC: UITableViewController {
var num = 0
var postJob: String?
var dataSource: [PFObject] = []
//MARK: - PULL TO REFRESH FUNCTION
func refresh(sender:AnyObject) {
// Updating your data here...
self.fetchDataFromParse()
self.refreshControl?.endRefreshing()
}
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.barTintColor = UIColor(netHex: 0x003366)
self.navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.whiteColor()]
// Do any additional setup after loading the view.
self.refreshControl?.addTarget(self, action: "refresh:", forControlEvents: UIControlEvents.ValueChanged)
//self.refreshControl?.backgroundColor = UIColor(netHex: 0x003366)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewDidAppear(animated: Bool) {
fetchDataFromParse()
}
//MARK: - TABLE VIEW
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let query = PFQuery(className: "Activity")
let userPointer = PFUser.objectWithoutDataWithObjectId(PFUser.currentUser()?.objectId)
query.whereKey("fromUser", equalTo: userPointer)
let objects = query.findObjects()
self.num = (objects?.count)!
print(num)
return num
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "Cells"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier , forIndexPath: indexPath)
if dataSource.isEmpty{
fetchDataFromParse()
print("No Post")
} else {
if num == 0{
cell.textLabel?.text = "Start posting a job!"
} else {
//MARK: - TABLEVIEW TITLE CELL
let itemArr:PFObject = self.dataSource[indexPath.row]
postJob = itemArr["type"] as? String
if postJob == "jobPost"{
let jobPostObject = PFObject(className: "JobPost")
let query = PFQuery(className: "Activity")
query.whereKey("postedJob", equalTo: jobPostObject)
let objects = query.findObjects()
print(objects)
cell.textLabel?.text = "You posted a job - \(postJob!)"
}
//MARK: - TABLEVIEW DATE CELL
let createdDate = itemArr.createdAt
let form = NSDateComponentsFormatter()
form.maximumUnitCount = 2
form.unitsStyle = .Abbreviated // or .Full, whatever you prefer
let d = form.stringFromTimeInterval(NSDate.timeIntervalSinceReferenceDate() - createdDate!.timeIntervalSinceReferenceDate)
cell.detailTextLabel?.text = "\(d!) ago"
}//end of if num
}//end of datasource.isempty
return cell
}
//MARK: - DATA FETCHING FUNCTIONS
func fetchDataFromParse() {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in
//MARK: - CLEARING ARRAYS
self.dataSource.removeAll()
// MARK: - JOB POST QUERY
if PFUser.currentUser()?.objectId == nil{
PFUser.currentUser()?.saveInBackgroundWithBlock({ (success, error) -> Void in
let query = PFQuery(className: "Activity")
//creating a pointer
let userPointer = PFUser.objectWithoutDataWithObjectId(PFUser.currentUser()?.objectId)
query.whereKey("fromUser", equalTo: userPointer)
query.orderByDescending("createdAt")
let objects = query.findObjects()
for object in (objects as? [PFObject])!{
//print(object.objectId)
self.dataSource.append(object)
}//end of for loop
})//end of saveInBackground
} else {
let query = PFQuery(className: "Activity")
//creating a pointer
let userPointer = PFUser.objectWithoutDataWithObjectId(PFUser.currentUser()?.objectId)
query.whereKey("fromUser", equalTo: userPointer)
query.orderByDescending("createdAt")
query.findObjectsInBackgroundWithBlock({ (objs, error) -> Void in
if error == nil {
for obj in (objs as? [PFObject])!{
//print(object.objectId)
self.dataSource.append(obj)
self.tableView.reloadData()
}//for loop
}//end of error == nil
})// end of findobjectsinbackground
print("query executed")
}//end of PFUser objectID == nil else clause
})
}
}
EDIT 2:
Upvotes: 0
Views: 133
Reputation: 7660
This is happening because jobPostObject
is not a complete object, it's just an empty, unsaved JobPost
.
The query itself doesn't make a lot of sense:
You first create a new JobPost
let jobPostObject = PFObject(className: "JobPost")
Then you are trying to find
an Activity associated to this JobPost:
query.whereKey("postedJob", equalTo: jobPostObject)
Since jobPostObject is brand new, has no data, and more importantly, has never been saved to parse, how could this request return anything?
That's being said this error:
Tried to save an object with a new, unsaved child
means that you are trying to use an object that is dirty in a query. A dirty object is an object that is new OR is an existing object that has been modified, but that hasn't been saved in the database.
Try to add
query.includeKey("postedJob")
after all your
let query = PFQuery(className: "Activity")
then you can replace the jobPostObject
part:
let jobPostObject = PFObject(className: "JobPost")
let query = PFQuery(className: "Activity")
query.whereKey("postedJob", equalTo: jobPostObject)
let objects = query.findObjects()
print(objects)
by something like
let jobPostObject = itemArr["postedJob"] as? PFObject
Upvotes: 1