suisied
suisied

Reputation: 426

querying an object with a pointer - parse, swift2

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:

enter image description here

Upvotes: 0

Views: 133

Answers (1)

3lil636wm
3lil636wm

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

Related Questions