ErrorCode3000
ErrorCode3000

Reputation: 28

UITableView with sections and custom Objects in Swift

I'm looking to populate a UITableView with a custom object without having to use multi-dimensional arrays to work with the sections. I think what I'm missing is a piece of logic which will sort the objects. The object, is basically a dictionary, I have the var section: Int either set to 0 or 1. These objects currently stored in an array and loaded in the table view. The other vars are various bits of info.

I have an object which looks like this:

class MenuModel {
    var displayText: String
    var displayImage: UIImage
    var location: String
    var otherData: String
    var section: Int
}

invoked like this:

let bc = MenuModel(displayText: "Basic Commands", displayImage: UIImage(named: "[email protected]")!, location: "commands", otherData: "", section: 0)
self.MenuList.append(bc)     //Right now I'm appending it to an array called MenuList

How can I access the MenuModel.section and sort the objects into those sections by getting a result of 0 or 1? Does this need to be done in tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int


This part is more specific to my current implementation. It's not perfect (or even properly working right now) the UI is updated and seems quite happy, however, the MenuList array gets presented four times even though the completion handler runs once.

This is the code I'm running. There's essentially two calls to networks, one to Firebase and one through Alamofire.

public func ConstructMenu(completion: (Bool) -> ()) {

    if let user = FIRAuth.auth()?.currentUser {
            // User is signed in.

            GlobalFirebase.UserRef.child(user.uid).observeSingleEventOfType(.Value, withBlock: { (snapshot) in
                let serverAdmin = snapshot.value!["serverAdmin"] as! String
                if serverAdmin != "none" {

                    self.log.info("User as a Server Admin signed in")

                    let bc = MenuModel(displayText: "Basic Commands", displayImage: UIImage(named: "[email protected]")!, location: "commands", otherData: "", section: 0)
                    let ca = MenuModel(displayText: "Console Access", displayImage: UIImage(named: "[email protected]")!, location: "console", otherData: "", section: 0)
                    let sm = MenuModel(displayText: "Server Management", displayImage: UIImage(named: "[email protected]")!, location: "management", otherData: "", section: 0)
                    let cs = MenuModel(displayText: "Connect and Share", displayImage: UIImage(named: "[email protected]")!, location: "connect", otherData: "", section: 0)

                    self.MenuList.append(bc, ca, sm, cs)
                    completion(true)


                } else {

                    self.log.info("User not a Server Admin signed in")

                    let ns = MenuModel(displayText: "New Server", displayImage: UIImage(named: "[email protected]")!, location: "makeServer", otherData: "", section: 0)

                    self.MenuList.append(ns)
                    completion(true)
                }
            })

        } else {
            self.log.info("No user is signed in.")

            let ns = MenuModel(displayText: "New Server", displayImage: UIImage(named: "[email protected]")!, location: "makeServer", otherData: "", section: 0)

            self.MenuList.append(ns)
            completion(true)

        }

    //Check for Other Archetype Servers

    //Query Multicraft
    let commandDictionary = [ "APIuser" : GlobalConstants.MulticraftAPIUser,
                              "APIkey" : "\(GlobalConstants.MulticraftAPIKey)",
                              "APIreq" : "listServers"]

    Alamofire.request(.POST, "\(GlobalConstants.MulticraftAPIURL)tworeq.php", parameters: commandDictionary)
        .responseJSON(){ response in
            self.log.info("Request: \(response.result.value)")
            if let _ = response.result.value {

                if (JSON(response.result.value!)["success"] == true) {

                    let json = JSON(response.result.value!)
                    //    self.log.verbose(json["data"]["Servers"].dictionaryValue)

                    for (key, value) in json["data"]["Servers"].dictionaryValue {
                        self.log.verbose("\"\(key) : \(value.string!)\"")

                        var name = "\(value.string!)"
                        var serverID = "\(key)"
                        var image = UIImage(named: "server_\(Int(arc4random_uniform(4) + 1))")!

                        var item = MenuModel(displayText: name, displayImage: image, location: "serverInfo", otherData: serverID, section: 1)

                        self.MenuList.append(item)


                    }

                    completion(true)
                } //If result succeeds
    }
} // Alamofire Request

}

and I'm invoking that code like this:

override public func viewWillAppear(animated: Bool) {

    MenuList.removeAll()
    self.ConstructMenu() {completion in completion
        if completion == true {
            self.tableView.reloadData()
            print("Menu Setup Completed")
        } else {
            self.tableView.reloadData()
            print("Menu Setup Failed")
        }
    } 

Upvotes: 0

Views: 276

Answers (1)

creeperspeak
creeperspeak

Reputation: 5521

You can quickly filter that menuList array by section with the filter method - it'd look like this: let sectionZero = menuList.filter { (model) -> Bool in return model.section == 0 } let sectionOne = menuList.filter { (model) -> Bool in return model.section == 1 }

It may be a pain if you're frequently reloading the menuList and the tableView, but it's doable if you don't want to have a multi-dimensional array.

Upvotes: 1

Related Questions