CRUD Operations using Core data - Swift
I hope you are familiar with Core data fundamentals. It is not a Pure database and it is ORM blah.. blah.. blah.. Here I'm starting with Xcode.
Step 1 : Create New iOS Application with "Single View Application"
Step 2 : Name you app, and don't forget to CHECK "Use Core Data" from bottom section. By checking this xCode will add ".xcdatamodeld" file automatically in project and also write code for context in AppDelegate.swift. So you don't have to make any efforts for context handling.
Step 3 : In AppDelegate.swift file you can find some code for core data that xCode has writes for you.
Step 4 : Here you can see file structure of ".xcdatamodeld" file.
Step 5 : To create new entity in Core data you can find "Add Entity" button at bottom. Edit the default name to your required name. Like Person, Friends, History, List. This name will considered in query as a table name (In sql database query to update table we are using table name in sql query, same like here the entity name will used as a table name.)
Step 6 : After adding entity (Table) add its attribute (Field) and also specify types of attribute.
Step 7 : Let's make pretty design for app. I have taken 2 controllers.
> The first is Table View Controller which will show list of record. In TableView the prototype cell is customised and there is two labels for name and phone number. Also added one + button on top right to present second view controller.
> Second view controller has two textfield to accept text from user and there is two buttons to handle navigation and saving data.
And now the Coding is started.
Write import statement in view controllers.
----------------------------------------------------------------------------------------------
ListViewController
----------------------------------------------------------------------------------------------
In TableViewController create local constant of appdelegate object to access managedContext.
Create array of NSManagedObject
Call this function in viewDidAppear() So every time when screen is appeared the data will be refreshed.
I have created custom class for UITableViewCell.
Now code for UITableViewDataSource methods :
To delete record write below code :
To edit a record call segue and pass record index.
To add new record call segue to another view controller. This is a action of "+" button from first view controller (Top Right positioned)
Segue to Add / Edit view controller. Here i'm passing index of record. If the call is from add new record then the sender value will be -1 to identify the request.
-----------------------------------------------------------------------------------------------
ADD / EDIT View controller.
-----------------------------------------------------------------------------------------------
Don't forgot to add
Here we have two IBOutlets of UITextField.
Constant and Variable
In viewDidLoad() check if request for edit record or not. If editRecNo variable is equal to -1 then its new record request otherwise have to edit.
To close view controller "X" button from top left.
To add / edit record i have coded in IBAction of Done button.
In above code i have checked that if the request for edit record then get the managed object from the Array and update the value from the textfield. Then save the context.
If the request to add new record then create NSEntityDescription it taken entity name for identification of the entity and object of managed object context.
Then create new NSManagedObject with NSEntityDescription and object of managed object context. NSManagedObject has many types of initialisation. Here we are about to add record so we have used insertIntoManagedObjectContext.
Now set the value NSManagedObject and save the context. After completion of add or edit dismiss the view controller. List will updated automatically.
Download Demo project of CoreData : CoreDataDemo-Swift
Thanks.
Step 1 : Create New iOS Application with "Single View Application"
Step 2 : Name you app, and don't forget to CHECK "Use Core Data" from bottom section. By checking this xCode will add ".xcdatamodeld" file automatically in project and also write code for context in AppDelegate.swift. So you don't have to make any efforts for context handling.
Step 3 : In AppDelegate.swift file you can find some code for core data that xCode has writes for you.
Step 4 : Here you can see file structure of ".xcdatamodeld" file.
Step 5 : To create new entity in Core data you can find "Add Entity" button at bottom. Edit the default name to your required name. Like Person, Friends, History, List. This name will considered in query as a table name (In sql database query to update table we are using table name in sql query, same like here the entity name will used as a table name.)
Step 6 : After adding entity (Table) add its attribute (Field) and also specify types of attribute.
Step 7 : Let's make pretty design for app. I have taken 2 controllers.
> The first is Table View Controller which will show list of record. In TableView the prototype cell is customised and there is two labels for name and phone number. Also added one + button on top right to present second view controller.
> Second view controller has two textfield to accept text from user and there is two buttons to handle navigation and saving data.
And now the Coding is started.
Write import statement in view controllers.
import CoreData
Add below code in Top of AppDelegate.swift file to access globally.let kEntityStr = "Contacts"
let kNameStr = "name"
let kPhoneStr = "phonenum"
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {.....}
----------------------------------------------------------------------------------------------
ListViewController
----------------------------------------------------------------------------------------------
In TableViewController create local constant of appdelegate object to access managedContext.
let appDelegateObj : AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
Create array of NSManagedObject
var dataArray = [NSManagedObject]()
Write below function to fetch data.func fetchData() {
let entityDescription = NSEntityDescription.entityForName(kEntityStr, inManagedObjectContext: appDelegateObj.managedObjectContext)
let fetchRequest = NSFetchRequest()
fetchRequest.entity = entityDescription
do {
dataArray = try appDelegateObj.managedObjectContext.executeFetchRequest(fetchRequest) as! [NSManagedObject]
self.tableView.reloadData()
} catch {
let fetchError = error as NSError
print(fetchError)
}
}
Call this function in viewDidAppear() So every time when screen is appeared the data will be refreshed.
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
fetchData()
}
I have created custom class for UITableViewCell.
class ContactCell : UITableViewCell {
@IBOutlet weak var lblName: UILabel!
@IBOutlet weak var lblContactNo: UILabel!
}
Now code for UITableViewDataSource methods :
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.dataArray.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! ContactCell
cell.lblName.text = dataArray[indexPath.row].valueForKey(kNameStr) as? String
cell.lblContactNo.text = dataArray[indexPath.row].valueForKey(kPhoneStr) as? String
return cell
}
To delete record write below code :
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
appDelegateObj.managedObjectContext.deleteObject(dataArray[indexPath.row])
do {
try appDelegateObj.managedObjectContext.save()
dataArray.removeAtIndex(indexPath.row)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
} catch {
let saveError = error as NSError
print(saveError)
}
}
}
To edit a record call segue and pass record index.
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("SegueAdd", sender: indexPath.row)
}
To add new record call segue to another view controller. This is a action of "+" button from first view controller (Top Right positioned)
@IBAction func btnAddTapped(sender: AnyObject) {
self.performSegueWithIdentifier("SegueAdd", sender: -1)
}
Segue to Add / Edit view controller. Here i'm passing index of record. If the call is from add new record then the sender value will be -1 to identify the request.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "SegueAdd" {
let vc : AddVC = segue.destinationViewController as! AddVC
vc.dataArray = dataArray
vc.editRecNo = sender as! Int
}
}
-----------------------------------------------------------------------------------------------
ADD / EDIT View controller.
-----------------------------------------------------------------------------------------------
Don't forgot to add
import CoreData
Here we have two IBOutlets of UITextField.
@IBOutlet weak var txtName: UITextField!
@IBOutlet weak var txtPhone: UITextField!
Constant and Variable
let appDelegateObj : AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
var editRecNo = Int()
var dataArray = [NSManagedObject]()
In viewDidLoad() check if request for edit record or not. If editRecNo variable is equal to -1 then its new record request otherwise have to edit.
override func viewDidLoad() {
super.viewDidLoad()
if editRecNo != -1 {
txtName.text = self.dataArray[editRecNo].valueForKey(kNameStr) as? String
txtPhone.text = self.dataArray[editRecNo].valueForKey(kPhoneStr) as? String
}
}
To close view controller "X" button from top left.
@IBAction func btnCancelTappe(sender: AnyObject) {
self.dismissViewControllerAnimated(true, completion: nil)
}
To add / edit record i have coded in IBAction of Done button.
@IBAction func btnDoneTapped(sender: AnyObject) {
if editRecNo != -1 {
self.dataArray[editRecNo].setValue(txtName.text!, forKey: kNameStr)
self.dataArray[editRecNo].setValue(txtPhone.text!, forKey: kPhoneStr)
do {
try self.dataArray[editRecNo].managedObjectContext?.save()
} catch {
print("Error occured during updating entity")
}
} else {
let entityDescription = NSEntityDescription.entityForName(kEntityStr, inManagedObjectContext: appDelegateObj.managedObjectContext)
let newPerson = NSManagedObject(entity: entityDescription!, insertIntoManagedObjectContext: appDelegateObj.managedObjectContext)
newPerson.setValue(txtName.text!, forKey: kNameStr)
newPerson.setValue(txtPhone.text!, forKey: kPhoneStr)
do {
try newPerson.managedObjectContext?.save()
} catch {
print("Error occured during save entity")
}
}
self.dismissViewControllerAnimated(true, completion: nil)
}
In above code i have checked that if the request for edit record then get the managed object from the Array and update the value from the textfield. Then save the context.
If the request to add new record then create NSEntityDescription it taken entity name for identification of the entity and object of managed object context.
Then create new NSManagedObject with NSEntityDescription and object of managed object context. NSManagedObject has many types of initialisation. Here we are about to add record so we have used insertIntoManagedObjectContext.
Now set the value NSManagedObject and save the context. After completion of add or edit dismiss the view controller. List will updated automatically.
Download Demo project of CoreData : CoreDataDemo-Swift
Thanks.
CRUD Operations using Core data - Swift
Reviewed by KIRIT MODI
on
05:33:00
Rating:
No comments: