2

I've created a Custom class for both PFQuery and PFObject, where I just Inherit/extend with those classes to not having to worry about importing Parse everywhere I use a Query or an Object.

However, I've encountered a problem when trying to mix PFQuery and PFObject together with their custom class.

Heres my Custom Classes which should in theory now have the same properties and effects as PFObject and PFQuery, which they do in most cases.

class CustomQuery: PFQuery {
    override init(className:String) {
        super.init(className: className)
    }
}

class CustomObject: PFQbject {
    override init(className:String) {
        super.init(className: className)
    }
}

But I've encountered a problem when trying to use a "..InBackgroundWithBlock" function from the Query. Here's the code:

func GetAsyncObjects(query:CustomQuery, closure: (dataObjects:[CustomObject]) -> ()) {
    query.findObjectsInBackgroundWithBlock {(returnedObjects:[CustomObject]!, error:NSError?) -> Void in
        closure(dataObjects: returnedObjects!)
    }
}

The error occures at the second line of the block above, at "returnedObjects:[CustomObject]!" with the following error:

Cannot convert value of type '([CustomObject]!, NSError?) -> Void' to expected argument type 'PFQueryArrayResultBlock?'

I literally can't find to see the solution for this. Obviously changing CustomObject there to PFObject would work, but that makes the whole point of my CustomObject and CustomQuery obsolete.

Thanks!

Nikunj
  • 655
  • 3
  • 13
  • 25
Kevin Jensen Petersen
  • 423
  • 2
  • 22
  • 43

1 Answers1

2

Probably not the core issue here but your CustomObject subclasses from PFQbject (Notice there is a 'Q' instead of an 'O'). Also you will need to use PFObject in the closure inside of the GetAsyncObjects function because the signature of the block expects the returned objects to be of type [PFObject]?. You can circumvent the issue by doing something like this:

// in CustomQuery class
func GetAsyncObjects(closure: (dataObjects:[CustomObject]) -> ()) {
    self.findObjectsInBackgroundWithBlock {(returnedObjects:[PFObject]?, error:NSError?) -> Void in
        // explicitly cast to your custom object
        closure(dataObjects: returnedObjects as! [CustomObject])
    }
}

So in order for the closure to get an array of CustomObjects back, you can just cast the [PFObject]? data you get back from Parse to your desired array type, in this case [CustomObject].

the_critic
  • 12,720
  • 19
  • 67
  • 115
  • It indeeds does the trick, but again the point of what I wanted was to avoid having the Import Parse statement anywhere else but my CustomQuery and CustomClass. Is this not possible due to the pre-defined signature that the block has? And If that Is the case, why wouldn't it? It's a PFObject just as much as the actually PFObject. – Kevin Jensen Petersen Dec 17 '15 at 13:58
  • 1
    @KevinJensenPetersen If you put the `GetAsyncObjects` function into your custom query you wouldn't have to import it anywhere... – the_critic Dec 17 '15 at 14:01
  • Excellent point. I can't believe I didn't think about that. You good sir, definitely deserve the accepted answer! Thanks! – Kevin Jensen Petersen Dec 17 '15 at 14:03
  • @KevinJensenPetersen Glad to have helped! Good luck with your project! – the_critic Dec 17 '15 at 14:03
  • You can use `CustomObject` in the completion block of the query just fine since it's a subclass of `PFObject`. The error before was because it was a forced unwrapping instead of an optional `CustomObject`. This is totally fine: `findObjectsInBackgroundWithBlock {(returnedObjects:[CustomObject]?, error:NSError?) -> Void in` – Russell Dec 17 '15 at 20:14
  • 1
    @Russell I don't think that is correct. The `findObjectsInBackgroundWithBlock` expects a `PFResultBlock` which is strongly typed to use `[PFObject]?` as the first parameter of its closure. Just because there is a `is-a` relationship between `PFObject` and `CustomObject` doesn't necessarily mean the signature will respect that. – the_critic Dec 17 '15 at 22:18
  • @the_critic great catch! For some reason I could have sworn that I had used subclassed objects in a query result block, but after a quick check I'm totally wrong. Thanks for the correction. – Russell Dec 17 '15 at 22:25
  • @Russell It's always good to have somebody question others' statements, I could have been wrong too. Appreciate your input! – the_critic Dec 17 '15 at 22:29