Create App Table programmatically in Swift

I try to rebuild you 3. tutorial (Saving Objects with relation). But I have two errors with following code:

    // description func
    func description() -> NSString {
        return "Order #\(self.orderNumber) '\(self.orderName)'\n\(self.orderItems)"
    }

Error message: Method ‘description()’ with Objective-C selector ‘description’ conflicts with getter for ‘description’ from superclass ‘NSObject’ with the same Objective-C selector

 Types.try({ () -> Void in

Error message: Expected member name following ‘.’

By my first issue. Can I just rename description() in information()?

Yes

ok, I searched for my second problem, but I found nothing similar then my problem…

Hi Pascal,

Here is the objective-C style wrapper for try/cache[/finally] construction.

From Swift 2.0 it should be:

Types.tryblock({ () -> Void in
 
 
 
 
 
 
 
 
 }, 
 
 catchblock: { (exception) -> Void in 
 
 print("Server reported an error: \(exception as! Fault)") 
 
 }


Great, thanks. I worked around with the tutorial. I know right know, how I create a relationship between box and Card. But how would I do that between User to Box?

    Create Box class Construct an instance of Box Call setProperty on the user object and pass box in there Save user object

I try hard to understand this stuff. I did written some code but every time i started my app, it crashed. What is wrong with it?

import UIKit


class Users : BackendlessEntity {
    
    var name : String?
    var box : [Box] = []
    
    // description func
    func descriptionn() -> NSString {
        return "Order #\(self.name) \(self.box) * \'"
    }
}


class Box : BackendlessEntity {
    
    var name : String?
    var cards : [Card] = []
    
    // description func
    func descriptionn() -> NSString {
        return "Order #\(self.name)'"
    }
}


class Card : BackendlessEntity {
    
    var name : String?
    var firstLanguage : String?
    var secondLanguage : String?
    
    // description func
    func descriptionn() -> NSString {
        return "OrderItem '\(self.name)' \(self.firstLanguage) * \(self.secondLanguage)"
    }
}






class ViewController: UIViewController {
    
    var backendless = Backendless.sharedInstance()


    override func viewDidLoad() {
        super.viewDidLoad()
        
        
        let backendless = Backendless.sharedInstance()
        backendless.userService.login("name", password:"password",
            response: { ( user : BackendlessUser!) -> () in
                print("User has been logged in")
                
                // create the orders datastore
                let createBox = self.backendless.persistenceService.of(Users().ofClass())
                
                let cardItem1 = Card()
                cardItem1.name = "Printer"
                cardItem1.firstLanguage = "First1"
                cardItem1.secondLanguage = "Second1"
                
                let cardItem2 = Card()
                cardItem2.name = "Paper"
                cardItem2.firstLanguage = "First2"
                cardItem2.secondLanguage = "Second2"
                
                let boxItem = Box()
                boxItem.name = "Printer"
                boxItem.cards.append(cardItem1)
                boxItem.cards.append(cardItem2)
                
                var userItem = Users()
                userItem.box.append(boxItem)
                
                userItem = createBox.save(userItem) as! Users
                
            },
            error: { ( fault : Fault!) -> () in
                print("Server reported an error: \(fault)")
            })
    }
}

Pascal, have you tried debugging the code? I think reviewing the code for the users is okay to a certain point, but here, with 80 lines of code, that’s a bit too much, don’t you think? We’d love to help, but to make this process scale, we really need you to try solving the problem first and then come to us for help.

Users class is inside Backendless class, you may not use it in you code.

I got it!!! :slight_smile:
Mark, would it not be easier to have two tables called “Users” and “Cards”. I have a relationship (one to many) form my “Users” table to “Cards”. “Cards” does have a column called “name” and two “Array column” called" firstLanguage", “secondLanguage”. It would be easier for me to retrieve an array and handle with it then with a “Box Column” step. Or does Backendless not support arrays?

Pascal, Backendless does not support “array” columns.

Ok, but that means actually by 1 Mio. users, each user have 20 boxes with around 20 cards = 400000000 cards. Is that correct and possible? I know right now how to save data with relation how can I right now retrieve this objects? I found some code, but with it I retrieve all cards:

    func searchingDataObjectByDistance() {
        
        Types.tryblock({ () -> Void in
            
            let queryOptions = QueryOptions()
            queryOptions.relationsDepth = 1;
            
            let dataQuery = BackendlessDataQuery()
            dataQuery.queryOptions = queryOptions;
            
            let cards = self.backendless.persistenceService.find(Card.ofClass(),
                dataQuery:dataQuery) as BackendlessCollection
            for card in cards.data as! [Card] {
                let info = card.firstLanguage! as String
                print(info)
            }
            },
            catchblock: { (exception) -> Void in
                print("searchingDataObjectByDistance (FAULT): \(exception as! Fault)")
        })
    }

Pascal, if you don’t need to load all relations, you can use ‘filtring tools’ of the query, for example: queryOptions.related - allow you to load only said relation, dataQuery,whereClause - sql-style filter. These features are described in Data documentation - see the examples are there.

Pascal,

Since Slava answered the filtering question, I’ll respond to his:

Ok, but that means actually by 1 Mio. users, each user have 20 boxes with around 20 cards = 400`000`000 cards. Is that correct and possible?

I do not see anything wrong with it. With your original approach (table per user), you’d have 1 million tables with arrays of languages for every card. Either way it is a lot of data, however, the first approach provides a more normalized data view.

Mark

I tried the singleStepRetrieval code from this tutorial: https://backendless.com/documentation/data/ios/data_relations_retrieve.htm
It does retrieve data but like that:

Orders have been retrieved: [<BackendlessEntity> objectId: '0E0965CE-21E6-132B-FF71-6384136A2400' meta: '{"relationRemovalIds":{},"selectedProperties":["created","name","___class","ownerId","updated","items","objectId"],"relatedObjects":{"items":["AFD4B66F-50CB-0A53-FF73-A969F0B82400","B4274CE8-9BA9-C94D-FF96-9248DF9C7E00"]}}']

How can I right now filtering this code for the name in Manufacturer?

What is “Manufacturer” ?

I try to repeat the tutorial. Manufacurer ist just a normal class with one column (name)

Hi Pascal,

The sample in tutorial simply shows how you can retrieve the related objects.
So, if you have data model classes like these:

class Order : NSObject {    
     var objectId : String?
    var name : String?
     var items : [Item]?
}
class Item : NSObject {
    var objectId : String?
    var itemName : String?
    var unitPrice = 0.0
    var manufacturer : Manufacturer
}


class Manufacturer : NSObject {
    var objectId : String?
    var name : String?
    var phone : String?
    var address : Address?
}

you can retrieve all objects from Order table with them Item objects (1:N relation) and Item’s Manufacturer object (1:1 relation) using code from tutorial.

What data model classes did you use? Did you set ‘items’ property of your Order object?
Can you add here your whole code? - we try to reproduce this problem.

Regards,
Slava