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

SDK: v3.1.0
There are people who can be in multiple groups. With groups being autoloaded

class Person: NSObject {
var name: String?
var groups: [Group] = []
}
class Group: NSObject {
var name: String?
}

I save a group to each person using this function:


 func saveByAsync(_ person: Person, completionHandler: ((_ person: Person?) -> Void)? = nil) {
 dataStore?.save(person, response: { result -> Void in
 completionHandler?(result as! Person)
 }, error: { fault -> Void in
 print("Server reported an error (save person async): \(String(describing: fault))")
 completionHandler?(nil)
 })
 }

Then I want to find all the people that are in a certain group:


 func findPeopleByAsync(in group: Group, completionHandler: @escaping (_ people: [Person]) -> Void) {
 let whereClause = "groups.name = '\(group.name!)'"
 let dataQuery = BackendlessDataQuery()
 dataQuery.whereClause = whereClause
 
 dataStore?.find(dataQuery, response: { (result) in
 let people = result?.getCurrentPage() as! [Person]
 for obj in people {
 for group in obj.groups {
 print("Person = \(String(describing: group))") // Error here
 }
 }
 completionHandler(people)
 }, error: { fault in
 print("Server reported an error: \(String(describing: fault))")
 })
 }

But when I examine each person, a person with multiple groups has an array like this

person.groups = [Group, [Group]]

Or even

person.groups = [[String, String]]

When I save, a group into a person, I’m checking each save and I don’t create anything like this. When you check the console data table, everything is fine and nothing resembles that. My hypothesis is that this happens in the SDK and during the parsing function?
This problem doesn’t happen only if I search for specific people with a group name. This happens when I want to call all the people as well.

Hi Brian,

Are you saying you get person objects back with groups a person does not belong to?

Btw, we do not have SDK version 3.1.0. It should be something line 3.0.X - please check what that “X” is in your case and better yet, make sure to update to the latest version (3.0.46)

Mark

It should be giving me the correct groups. The problem is is that person.groups is suppose to be [Groups] but it’s not. It’s person.groups = [Group, [Group]], if the person is in two groups. Because of this I get an error fatal error: NSArray element failed to match the Swift Array Element type for relational array.

You’re right. It is the latest version though, 3.0.46

Could you attach a screenshot from the debugger showing what you get?

It just shows fatal error: NSArray element failed to match the Swift Array Element type for relational array.

You’re saying the data returned from the server is:

person.groups = [Group, [Group]]

How do you know that? Can you attach a screenshot showing us what you see?

This is [[String, String]]

http://support.backendless.com/public/attachments/cb585fd704060608b7c9c9c33fb7acf2.png</img>

This is somewhat like [Group, [Group]] but all it did was [[Group]]
http://support.backendless.com/public/attachments/3c3b27f50367743b6a4e1212a08bf486.png</img>

3c3b27f50367743b6a4e1212a08bf486.png

cb585fd704060608b7c9c9c33fb7acf2.png

It is an array of one group, which I turn contains an array of two strings.

Yes, and that causes an array because it’s expecting to be [Group]

Please post the source code for the Ryze.Group class and let us know your application ID.

It’s already in the initial post.

app id: 3562E910-193E-F469-FFA8-DF25DFDCA000

    Is the Group class defined is a separate .swift file? Such as Group.swift ? What happens to the "color" property? It is in the database, but not defined in the class.
  1. Yes

  2. color property is there in the class

The “color” property is not in the original post. Could you post the entire contents of the Group.swift file?

Also, you have custom business logic for the Person table. Please temporarily disable the event handlers and try retrieving objects again - this will make sure that the business logic does not introduce any changes.

That’s about it

class Group: NSObject {
var name: String?
var color: String?
}

Thanks for the suggestion. After disabling the event handler, it works. BUT the event handler we have does not modify groups.
afterFind event handler


Backendless.ServerCode.Persistence.afterFind('Person', (req, res) => {
    if(res.result.data && res.result.data.length > 0) {
        for(let i = 0; i < res.result.data.length; i++) {
            res.result.data = appendStatus(res.result.data);
        }
    }
});

and appendStatus


const appendStatus = (person) => {


    if (person && Array.isArray(person.reminders) && person.reminders[0]) {


        // NOTE: this uses the FIRST reminder!
        const reminder = person.reminders[0],
            notifyDate = reminder.notifyDate,
            notifyMoment = moment.utc(notifyDate)


        if (moment.utc().isBefore(notifyMoment)) {
            person.status = {"___class": "Status", "status": "early", "title": notifyMoment.fromNow()};
        } else {
            person.status = {"___class": "Status", "status": "late", "title": notifyMoment.fromNow()};
        }


    } else {
        person.status = {"___class": "Status", "status": "none", "title": null};
    }


    return person;


};

Thanks for verifying. This is a regression we found earlier today in another app. The problem is the CodeRunner may break object fidelity when the object is sent to/from the CodeRunner. We’re working on a fix and it should be available shortly.

Glad to hear you found the culprit. Thanks for the help!

Any updates?

Got any good news? :slight_smile:

Hi Brian,

An engineer is working on the problem. We will update this topic when a fix becomes available.

Regards,
Mark