Data from retrieved collection is nil

I seem to be successfully retrieving data of my custom class (named Friendship) via the following code:

 class func retrieveAllFriendships(completed : (friendships : [Friendship]?, fault : Fault?) -> Void) {
 let backendless = Backendless.sharedInstance()
 let query = BackendlessDataQuery()



 //retrieves related objects
 let queryOptions = QueryOptions()
 queryOptions.related = ["members"];
 query.queryOptions = queryOptions



 let dataStore = backendless.persistenceService.of(Friendship.ofClass()) as IDataStore
 dataStore.find(query, response: { (retrievedCollection) -> Void in
 print("Successfully retrieved friendships")
 completed(friendships: retrievedCollection.data as? [Friendship], fault: nil)
 }) { (fault) -> Void in
 print("Server reported an error: \(fault)")
 completed(friendships: nil, fault: fault)
 }
 }

because when I log out retrievedCollection, it shows the following:

http://support.backendless.com/public/attachments/2b096fc2367fbbe5f25dca91e500b351.png</img>
However, when I try to get the data from this collection and cast it as an array of custom Friendship objects, it returns nil:
http://support.backendless.com/public/attachments/c3ad124af94252d39aa15d0bd8bb7f81.png</img>

I am unsure why the retrieved collection becomes nil when I access its data property and cast it to an array of its custom class; I’ve done this very similarly in another app and it works just fine.

Here is my custom Friendship class

c3ad124af94252d39aa15d0bd8bb7f81.png

I made a few changes in the class definition and it worked for me. It is important to keep in mind that the Bool and Int properties must be initialized, if they are declared optional, serialization of the values does not properly work. Here are my property definitions:

    var objectId: String?
    var ownerId: String?
    var created: NSDate?
    var members: [BackendlessUser]?
    
    var suhCount: Int = 0;
    var sendPush: Bool = false;
    var lastSent: NSDate?
    var lastSender: BackendlessUser?
    var group: Bool = false;

Also, check the type of the “members” and the “lastSender” properties in Backendless console. If they were created dynamically, I suspect they will have type STRING in console - make sure they are declared as relations.

I made the changes the my properties that you recommended:

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

And have confirmed that in the console my relations are declared as relations:
http://support.backendless.com/public/attachments/9d3caad11298565d54b88c072fe6f232.png</img>

However, I still get nil when I call collection.data as? [Friendship]

Seems very odd considering my collection is not nil; it just returns nil when I try to get its data as an array of my custom Friendship class.

9189188a93a44188e7f45b8684f853cd.png

Here’s the code I run:

    class func retrieveAllFriendships() {
        let backendless = Backendless.sharedInstance()
        let query = BackendlessDataQuery()
        
        //retrieves related objects
        let queryOptions = QueryOptions()
        queryOptions.related = ["members"];
        query.queryOptions = queryOptions
        
        let dataStore = backendless.persistenceService.of(Friendship.ofClass()) as IDataStore
        dataStore.find(query, response: { (retrievedCollection) -> Void in
            print("Successfully retrieved friendships")
            //completed(friendships: retrievedCollection.data as? [Friendship], fault: nil)
            let friendships = retrievedCollection.data as? [Friendship];
            print( "friendships \(friendships)")
            for friendship in friendships! {
                print("friendship = \(friendship.objectId)")
            }
            }) { (fault) -> Void in
                print("Server reported an error: \(fault)")
              //  completed(friendships: nil, fault: fault)
        }
    }

This is the output it produces:

Successfully retrieved friendships
friendships Optional([<TestApp.Friendship: 0x7f80b4b57270>, <TestApp.Friendship: 0x7f80b4b5e4b0>, <TestApp.Friendship: 0x7f80b4b619f0>])
friendship = Optional("1F6679CD-F11A-39D7-FF2B-9435396D9A00")
friendship = Optional("13783A6A-B879-6812-FFA4-5B4F8D179A00")
friendship = Optional("D2C8A07C-97ED-DDD9-FF84-4C89CFD85200")   

And here’s what I have in the data table:
http://support.backendless.com/public/attachments/168fc72fcc1845f612e7f15375c41be7.jpg</img>

I just ran your code in my program and am still getting nil for some reason. I also updated to the most recent iOS SDK from GitHub.

I am quite stumped as to why I can’t get the data from my collection.

This is indeed rather strange. Could you please email your app id and ios key to support@backendless.com? I’d like to run my code against your backend.

No problem, I just sent the email. Thanks so much

Hey Vic,

It is still working for me. Here’s the output I am getting:

Successfully retrieved friendships
friendships Optional([<TestApp.Friendship: 0x7f8739841790>, <TestApp.Friendship: 0x7f87398474b0>])
friendship = Optional("323D296C-7DB9-DF3D-FFDE-245EEE777600")
friendship = Optional("7B851D48-CA77-BEDA-FF8A-E584630DC200")

Just to remove any other possible differences, could you please use the attached Friendship.swift file and call “Friendship.retrieveAllFriendships()” from viewDidLoad() in your ViewController?

Friendship.swift.txt (2.88kB)

I copied in your code and ran it in viewDidLoad() and it still comes out to nil. Very weird that it works for you and not me even though we’re using the same code and backend. I’m not sure what to do

I run it in iPhone 6 emulator, what about you?

I’ve run it 5s, 6s, and 6s plus in the simulator and still get nil. I tried deleting my derived data, and restarting Xcode but still the same result.

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

Above you’ll notice that it’s only when I try to get the data from the collection as an array of my custom data type; the retrieval of the collection appears to be successful though.

I am on Xcode 7.2.1 and using the latest Backendless iOS SDK from Github

I set a breakpoint and inspected the retrieved collection. I do see an important difference between the object I get and yours:

http://support.backendless.com/public/attachments/1635007c4a06705f41262a7f72dce68b.jpg</img>

This is what my project structure looks like:
http://support.backendless.com/public/attachments/245d504b38a90d7e83ff7c71a8266ee9.jpg</img>

Good catch, I bet that is the issue.

Here is my project structure:
http://support.backendless.com/public/attachments/9df43e62365ff75d997a360d84ed2d53.png</img>

Could something with the way the project structure / files are organized be affecting this? Any idea why my collection type is (null) while yours is TestApp.Friendship?

9df43e62365ff75d997a360d84ed2d53.png

Well, I tried to recreate your structure and it still works. Here’s what I have now:

http://support.backendless.com/public/attachments/c98089b57b38b4911701b76ec4172829.jpg</img>

Yes, that’s how mine looks. I just can’t figure out why your collection is retrieved with the proper type (TestApp.Friendship) while mine comes back as (null); I think this is the problem.

If you’d like, we can review your project - we need to figure it out for ourselves too. Zip it up and upload to dropbox or google drive and send a link to support@backendless.com

No problem; just emailed it over. Thanks again

Hi Vic,

This issue is fixed by setting Info → Bundle Name in ‘$(PRODUCT_NAME)’:
http://support.backendless.com/public/attachments/eefa1d8cda9a618df1695fd08a555029.png</img>
Working with Backendless SDK you shouldn’t change this option.

Regards,
Slava

Ok, so then how do you suggest I change the name that appears below my app’s icon then? If I can’t change that.

Regardless, thank you for such detailed help on this issue; I don’t think I ever would have figured that out.

edit: I believe I solved this by setting the Product Name value in my build settings. Thanks again

The answer for that question is right here: http://stackoverflow.com/questions/8723164/where-are-executable-name-and-product-name-defined