PFSubclassing with array pointer and swift 1.2 - fatal error: NSArray element failed to match the Swift Array Element type
Asked Answered
O

4

6

With swift 1.2, I can no longer retrieve an array of poiter with parse subclass and downcasting it with another parse subclass.

I always found the error:

fatal error: NSArray element failed to match the Swift Array Element type

Do you have an idea or it may come?

The code:

import Foundation

class ShotModel : PFObject, PFSubclassing {

    /**
    * MARK: Properties
    */
    @NSManaged var name: String

    @NSManaged var pics: [PicModel]


    override class func initialize() {
        var onceToken : dispatch_once_t = 0;
        dispatch_once(&onceToken) {
            self.registerSubclass()
        }
    }

    class func parseClassName() -> String! {
        return "Shot"
    }

}

import Foundation

class PicModel : PFObject, PFSubclassing {

    /**
    * MARK: Properties
    */
    @NSManaged var name: String


    override class func initialize() {
        var onceToken : dispatch_once_t = 0;
        dispatch_once(&onceToken) {
            self.registerSubclass()
        }
    }

    class func parseClassName() -> String! {
        return "Pic"
    }

}

// this cause error

var shot: ShotModel = // a shot model get with fetchInBackgroundWithBlock

shot.pics // fatal error: NSArray element failed to match the Swift Array Element type

Thanks for your time

Overexert answered 13/3, 2015 at 9:48 Comment(5)
Cast shot to PFObject instead of ShotModel then you can get shot.valueForKey("pics"). Try once it worked for me.Bowler
Yes i have access to shot.valueForKey("pics") with cast ShotModel but i can't downcast shot.valueForKey("pics") to [PicModel]Overexert
Try to change @NSManaged var pics: [PicModel] to ` @NSManaged var pics: [PFObject]` I had same issue solved it by casting to PFObjectBowler
ok, but how can get an array of PicModel objects ? I tried but i have en other error when i make this : pis as! PicModel => Could not cast value of type 'PFObject' to 'PicModel' ...Overexert
Found similar post on Github - github.com/burczyk/ParseCollectionsSwiftBug. May be that could help you.Bowler
O
15

The problem come from this part of code :

override class func initialize() {
    var onceToken : dispatch_once_t = 0;
    dispatch_once(&onceToken) {
        self.registerSubclass()
    }
}

registerSubclass() for ShotModel is called before registerSubclass() for PicModel.

I've resolved with this in AppDelegate :

PicModel.registerSubclass()
ShotModel.registerSubclass()
Overexert answered 13/3, 2015 at 12:46 Comment(3)
This wasn't working for me until I put the .registerSubclass() calls before Parse Initialization. Now it works great. Frustrating bug though. Thanks!Lamella
I solved it by adding PicModel.initialize() on the first line of the initialisation of ShotModelToomey
I actually filed a bug (developers.facebook.com/bugs/1452388645073907) against parse for this very same reason and they ended up updating their documentation with the following: Please note that the initialize method is not called until the class receives its first message, meaning that you need to call any instance or class method on your subclass before it will be registered with Parse SDK.`Gallery
T
4

The problem lies to the fact that ShotModel is registered as a subclass before PicModel. To invert that we can call PicModel initialisation the initialisation of ShotModel.

This way we keep the suggested solution by parse and make sure that classes are registered in the correct order.

class ShotModel : PFObject, PFSubclassing {

    /**
    * MARK: Properties
    */
    @NSManaged var name: String

    @NSManaged var pics: [PicModel]


    override class func initialize() {
        var onceToken : dispatch_once_t = 0;
        dispatch_once(&onceToken) {
            PicModel.initialize()
            self.registerSubclass()
        }
    }
Toomey answered 6/5, 2015 at 17:8 Comment(0)
A
1

Somehow I had to also init the object after registering in AppDelegate:

PicModel.registerSubclass()
PicModel()
ShotModel.registerSubclass()
ShotModel()
Alcyone answered 9/4, 2015 at 15:15 Comment(0)
G
0

I actually filed a bug against parse for this very same reason and they ended up updating their subclassing documentation with the following:

Please note that the initialize method is not called until the class receives its first message, meaning that you need to call any instance or class method on your subclass before it will be registered with Parse SDK.

So you NEED to call the registerSubclass() method, or any other method for the class to be registered properly with Parse.

Gallery answered 28/5, 2015 at 14:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.