Develop a simple iOS mobile app (toDoList) using Swift – Part 2

In the first part of the simple iOS mobile app (toDoList) tutorial series, you covered the basics of setting environment and user interface/autolayout.

In this second and final part of the tutorial series, we’ll cover Parse integration.

We’ll start where we left off last tutorial, so open your project from last time, or go through the previous tutorial first. http://blog.revivalx.com/2015/05/13/develop-a-simple-ios-mobile-app-todolist-using-swift-part-1/

Select UITableViewController in Main.Storyboard and edit Attribute Inspector according to this setting:

Style: Basic
Identifier: TaskCell
Accessory: Disclosure Indicator

Attribute Inspector.

Attribute Inspector.

UiTableViewController

UiTableViewController

Go to UIViewController and make sure the user interface is similar like this one. Don’t forget to set constraints for each elements. If you don’t know how to do it, feel free to refer it here, https://developer.apple.com/library/ios/referencelibrary/GettingStarted/RoadMapiOS/DesigningaUserInterface.html.

UIViewController.

UIViewController.

Sign up for your new account here, https://www.parse.com/.

Parse

Parse

Click Create a New App.

Create a New App

Create a New App

Go to Keys and save your Application ID and Client Key. Open AppDelegate.swift file and update the Application ID and Client Key.

import UIKit
import ParseFacebookUtils
 
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
 
  func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // [Optional] Power your app with Local Datastore. For more info, go to
    // https://parse.com/docs/ios_guide#localdatastore/iOS
    Parse.enableLocalDatastore()
 
    // Initialize Parse.
    Parse.setApplicationId("xxxxx",
      clientKey: "xxxxx")
 
    // [Optional] Track statistics around application opens.
    PFAnalytics.trackAppOpenedWithLaunchOptions(launchOptions)
 
    // ...
}
 
// ...

Create two Cocoa Touch Class. One is TableViewController.swift (UITableViewController) and the other one is ViewController.swift (UIViewController).

Xcode 6.4 - New File.

Xcode 6.4 – New File.

Cocoa Touch Class

Cocoa Touch Class

UITableViewController

UITableViewController

UIViewController

UIViewController

Project navigator

Project navigator

Then make sure you attach both files into each controllers in Identity inspector.

Identity inspector - UITableViewController

Identity inspector – UITableViewController

Identity inspector -UIViewController

Identity inspector -UIViewController

Select Table View Cell, go to Identity Inspector and select PFTableViewCell.

PFTableViewCell

PFTableViewCell

Create Task model.

Swift File.

Swift File.

Project navigator

Project navigator

Go to the Task.swift file and replace with this code.

import Foundation
import UIKit

class Task: NSObject {
    var taskId: Int
    var name: String
    
    init(taskId: Int, name: String) {
        self.taskId = taskId
        self.name = name
        super.init()
    }
}

Open TableViewController.swift and update the with this code.

import UIKit
import Parse
import ParseUI

class TableViewController: PFQueryTableViewController {
    
    var id: String!
    var name: String!
    var descriptions: String!
    
    override init(style: UITableViewStyle, className: String?) {
        super.init(style: style, className: className)
    }
    
    @IBAction func addNewTask(sender: AnyObject) {
        self.id = nil
        self.performSegueWithIdentifier("MySegue", sender: self)
    }
    
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        
        self.parseClassName = "Task"
        self.textKey = "name"
        self.pullToRefreshEnabled = true
        self.paginationEnabled = false
        
    }
    
    override func queryForTable() -> PFQuery {
        var query = PFQuery(className: "Task")
        query.orderByAscending("name")
        
        
        return query
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.tableView.estimatedRowHeight = 44
        self.tableView.rowHeight = UITableViewAutomaticDimension
        self.tableView.reloadData()
    }
    
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell? {
        var cell = tableView.dequeueReusableCellWithIdentifier("TaskCell") as! PFTableViewCell!
        if cell == nil {
            cell = PFTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
        }
        
        cell.textLabel?.text = object!["name"] as? String
        
        return cell
    }

    override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if editingStyle == .Delete {
            let objectToDelete = objects?[indexPath.row] as! PFObject
            objectToDelete.deleteInBackgroundWithBlock {
                (success: Bool, error: NSError?) -> Void in
                if (success) {
                    self.tableView.reloadData()
                }
            }
        }
    }
    
    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        let object = objects?[indexPath.row] as! PFObject
        var query = PFQuery(className:"Task")
        query.getObjectInBackgroundWithId(object.objectId!) {
            (task: PFObject?, error: NSError?) -> Void in
            if error == nil && task != nil {
                self.id = task!.objectId!
                self.name = task!["name"] as! String
                self.descriptions = task!["description"] as! String
                self.performSegueWithIdentifier("MySegue", sender: self)
            } else {
                print(error)
            }
        }
    }
    
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "MySegue" {
            let viewController: ViewController = segue.destinationViewController as! ViewController
            viewController.id = id
            viewController.name = name
            viewController.descriptions = descriptions
        }
    }
}

Open ViewController.swift and replace the with this code.

import UIKit
import Parse

class ViewController: UIViewController {

    @IBOutlet weak var txtName: UITextField!
    @IBOutlet weak var txtDescription: UITextField!
    var id: String!
    var name: String!
    var descriptions: String!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        if id != nil {
            txtName.text = name
            txtDescription.text = descriptions
        }
    }

    @IBAction func btnSubmit(sender: AnyObject) {
        if id != nil {
            var query = PFQuery(className:"Task")
            query.getObjectInBackgroundWithId(id) {
                (task: PFObject?, error: NSError?) -> Void in
                if error != nil {
                    print(error)
                } else if let task = task {
                    task["name"] = self.txtName.text
                    task["description"] = self.txtDescription.text
                    task.saveInBackground()
                    self.navigationController!.popViewControllerAnimated(true)
                }
            }
        } else {
            var task = PFObject(className:"Task")
            task["name"] = txtName.text
            task["description"] = txtDescription.text
            task.saveEventually()
            navigationController!.popViewControllerAnimated(true)
        }
    }
}

Result

ToDoList Screenshot 1

ToDoList Screenshot 1

 

ToDoList Screenshot 2

ToDoList Screenshot 2

One thought on “Develop a simple iOS mobile app (toDoList) using Swift – Part 2

Leave a Reply

Your email address will not be published. Required fields are marked *