I have just completed an implementation a like button for an Instagram-like app, but now that I am looking at it I feel that there is something off. Maybe it is my formatting or maybe I am not quite conforming to the MVC pattern I am not sure. I am not very experienced, so I was hoping someone with more knowledge would point me in the right direction.

The main idea is that I have a table view with users posts in it. Each cell has a like button. Pressing the like button causes the method in tableViewController to execute. That method then finds the index path of the cell by accessing the superview of the cell, then gets the current logged in user ID from firebase and then finds the post in the array of FeedPost objects, that constitute my model, and runs method post.like(idToken: idToken!, completed: {}).


var feed : FeedObject = FeedObject()

    //doing this in the controller and not in the FeedTableViewCell because I need to conform to MVC protocol
    @IBAction func likeButtonPressed(_ sender: AnyObject) {
        if let button = sender as? UIButton {
            let initialButtonState = button.isSelected //save initial button state
            button.isSelected = !button.isSelected //to make interface feel more responsive, change the initial state of the button immediatly. If something goes worng, change it back later (I think thats how Instagram does it)

            if let cell = button.superview?.superview as? FeedTableViewCell { //superview twice to get the cell beacuse first superview is a content view
                let indexPath = self.tableView.indexPath(for: cell) //get index path of the cell
                let currentUser = FIRAuth.auth()?.currentUser
                currentUser?.getTokenForcingRefresh(true) {idToken, error in
                    if let error = error {
                        button.isSelected = initialButtonState //operation failed, return to the initial button state and handle the error
                        //TODO: output an error message
                    let post = self.feed.posts[(indexPath?.row)!]
                    post.like(idToken: idToken!, completed: { result in
                        if result == "Successful" {
                            button.isSelected = post.liked
                        else {
                            button.isSelected = initialButtonState //operation failed, return to the initial buttons state


func like(idToken: String , completed: @escaping (String) -> Void ) {
        let headers = ["Authorization": "Bearer " + idToken,] //pass token in the header
        let URLString = "<My server domain name>?post="+String(_id) //request string
        Alamofire.request(URLString,headers: headers).responseJSON{ response in //make a request with alamofire
            if let JSON = response.result.value { //server returns JSON with the status of the request (Successful or Failed) and any details about the error
                if let dict =  JSON as? Dictionary<String, String>{
                    if dict["status"] == "successful" { //check if sucessful
                        self._liked = self._liked ? false : true
                    else { //TODO: Handle different errors
                        completed("Unknown Error") //Did not catch error


class FeedObject {
    var posts: [FeedPost] = []

    func loadArray(array: Array<Dictionary<String, AnyObject>> ){
        for postDict in array{
            let post = FeedPost(dict: postDict)
    //Some more methods to laod the feed from the server

My questions are:

  • Is this okay from MVC perspective
  • Is this safe?
  • Does it look and feel right to you?
  • \$\begingroup\$ "//doing this in the controller and not in the FeedTableViewCell because I need to conform to MVC protocol" if you are doing this inside the cell, then how you can use tableView? Because you shouldn't be able to connect the tableview \$\endgroup\$ – Tarvo Mäesepp Oct 17 '16 at 14:29
  • \$\begingroup\$ @TarvoMäesepp well, the point was, that I am not doing this in the cell \$\endgroup\$ – Ilya Lapan Oct 17 '16 at 16:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.