Core data គឺជា database ដែលមានមកជាមួយ xcode។ ពេលយើងបង្កើត project ដំបូងសូមធីកយក Core Data ដើម្បីប្រើវា


លេខ១ គឺជា databass ដែលយើងបានបង្កើតវា។ លេខ២ គឺជាកន្លែងបង្កើត table ប៉ុន្តែនៅក្នុង xcode គេហៅថា Entity

លេខ ១ គឺជាឈ្មោះ Entity របស់យើង ។ លេខ២ គឺជា attributes ហើយនៅក្នុង attribute វាមាន attribute និង Type ។ attribute គឺជាកន្លែងដាក់ឈ្មោះ cell ចំណែកឯ Type គឺជាកន្លែងជ្រើសរើសប្រភេទattribute របស់យើង។ សញ្ញាបូកខាងក្រោមគឺសម្រាប់ឲ្យយើង add cell ។
image យើងយក Binary Data ពីព្រោះ រូបភាព វីដេអូ សម្លេងគឺជាភេទ Data យើងមិនអាចយកវា String ទេ ។ ប្រសិនជាយើងយកជា String វាមិនអាចផ្ទុកបានទេ គឺវាផ្ទុកបានតែឈ្មោះ
យើងមកមើលនៅ Class AppDelegate ដែលមាន method មួយគឺ saveContext() វាសម្រាប់ save data auto នៅពេល user បិទកម្មវិធីដោយមិនបានចុច save
យើងចង់មើល data របស់យើង ជាមួយកម្មវិធីផ្សេង ដោយយើងទៅរកទីតាំងរបស់វា ដោយយើងចូលទៅក្នុង Class AppDelegate ហើយយើង print នៅក្នុង method មួយឈ្មោះ didFinishLaunchingWithOptions
print((persistentContainer.persistentStoreCoordinator.persistentStores.first?.url)!)

យើង copy ដែលយើងបាន print វាទៅ past finder។ ដោយយើងចុចលើ Finder មួយ
រួចមកយើងទៅចុច Go => Go to folder...

បន្ទាបមកវាមានផ្ទាំងមួយសំរាប់ឲ្យ past address ដែលយើងបាន copy ពី xcode មក

នៅកន្លែង %20 នេះយើងលុបវា រួចប្តូរទៅដកឃ្លាទៅ។

សូម install កម្មវិធី DB Browser for SQLite សំរាប់បើកវា
ខាងក្រោមនេះខ្ញុំសុំបង្កើត class និង ViewController ថ្មីមួយជា form សម្រាប់បញ្ចូលទិន្ន័យ ដែលយើងដាក់ឈ្មោះវាថា AddViewController។ នៅបង្កើត form ខ្ញុំដាក់ឈ្មោះ Storyboard ID ឈ្មោះថា addScreen សំរាប់ប្រើជាមួយ Navigation ។

យើងចូលទៅ AddViewController ដើម្បីសរសេរកូដ។ យើងបង្កើត property ពីរចេញពី appDelegate ដើម្បីទំនាក់ទំនងជាមួយ coreData ។
let appDelegate = UIApplication.shared.delegate as! AppDelegate let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
យើង comform delegate protocal របស់ textField។ ដើម្បីទុកសិក្សាលក្ខណរបស់ TextField។
import UIKit class AddViewController: UIViewController { @IBOutlet weak var imageView: UIImageView! @IBOutlet weak var nameTextField: UITextField! @IBOutlet weak var phoneTextField: UITextField! @IBOutlet weak var btnLabel: UIButton! //comform ចេញពី appDelegate ប្រើជាមួយ coreData let appDelegate = UIApplication.shared.delegate as! AppDelegate let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext override func viewDidLoad() { super.viewDidLoad() nameTextField.delegate = self phoneTextField.delegate = self } @IBAction func btn(_ sender: UIButton) { } } extension AddViewController: UITextFieldDelegate{ func textFieldShouldReturn(_ textField: UITextField) -> Bool { if textField.tag == 2 { textField.resignFirstResponder() }else{ let nextKey = view.viewWithTag(textField.tag + 1) as! UITextField nextKey.becomeFirstResponder() } return true } }
ដើម្បី save ទិន្ន័យតាមរយៈ user ចុចលើ Button save ។ ដូចនេះយើងសរសេរកូននៅក្នុង btn Button ។ ដោយយើងបង្កើត property optional មួយ
@IBAction func btn(_ sender: UIButton) { let contact = Contact(context: context) }
បន្ទាបមកយើងបោះ data ពី textField coreData

@IBAction func btn(_ sender: UIButton) { let contact = Contact(context: context) contact.name = nameTextField.text contact.phone = phoneTextField.text //Covert Image to data contact.image = UIImage.pngData(imageView.image!)() //Saving to coreData appDelegate.saveContext() }
រូបភាពដើម្បីបោះចូលទៅក្នុង coreData បានទាលតែយើងបំលែងទៅ data សិនទើបយើងបោះបាន ។ នៅចំណុចនេះខ្ញុំសុំដាក់រូបភាពចេញពី Assets សិន ចំពេលចំណុចក្រោយងយើងសិក្សាអំពីទាញរូបចេញពីទូរស័ព្ទ


ទិន្ន័យរបស់យើងបានបញ្ចូលមួយហើយ
ដើម្បីទាញរូបភាពពីទូរស័ព្ទទៅ coreData បានយើងប្រើ UITapGestureRecognizer ។ មុនដំបូងយើងបង្កើត property optional មួយ។
var pickImage: UIImagePickerController!
នៅក្នុង viewDidLoad យើង implement
pickImage = UIImagePickerController() pickImage.sourceType = .photoLibrary
បន្ទាបមកយើង conform delegate នៃ UIImagePickerControllerDelegate និង UINavigationControllerDelegate ។
extension AddViewController: UIImagePickerControllerDelegate,UINavigationControllerDelegate{ func seletImage(){ let tapGuester = UITapGestureRecognizer(target: self, action: #selector(broweImage)) imageView.addGestureRecognizer(tapGuester) imageView.isUserInteractionEnabled = true } @objc func broweImage(){ present(pickImage, animated: true, completion: nil) } }

នេះយើងអាច browe រូបភាពទូរស័ព្ទបានហើយ ប៉ុន្តែមិនទាន select បាន ។ យើងហៅ method មួយទៀតគឺ didFinishPickingMediaWithInfo ដើម្បីចាប់យករូបភាព និងបិទផ្ទាំងនឹងឲ្យវាទៅវិញ
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { if let image = info[.originalImage] as? UIImage{ imageView.image = image } pickImage.dismiss(animated: true, completion: nil) }

import UIKit class AddViewController: UIViewController { @IBOutlet weak var imageView: UIImageView! @IBOutlet weak var nameTextField: UITextField! @IBOutlet weak var phoneTextField: UITextField! @IBOutlet weak var btnLabel: UIButton! //comform ចេញពី appDelegate ប្រើជាមួយ coreData let appDelegate = UIApplication.shared.delegate as! AppDelegate let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext var pickImage: UIImagePickerController! override func viewDidLoad() { super.viewDidLoad() nameTextField.delegate = self phoneTextField.delegate = self imageView.image = UIImage(named: "empty") pickImage = UIImagePickerController() pickImage.sourceType = .photoLibrary pickImage.delegate = self seletImage() } @IBAction func btn(_ sender: UIButton) { let contact = Contact(context: context) contact.name = nameTextField.text contact.phone = phoneTextField.text //Covert Image to data contact.image = UIImage.pngData(imageView.image!)() //Saving to coreData appDelegate.saveContext() } } extension AddViewController: UIImagePickerControllerDelegate,UINavigationControllerDelegate{ func seletImage(){ let tapGuester = UITapGestureRecognizer(target: self, action: #selector(broweImage)) imageView.addGestureRecognizer(tapGuester) imageView.isUserInteractionEnabled = true } @objc func broweImage(){ present(pickImage, animated: true, completion: nil) } func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { if let image = info[.originalImage] as? UIImage{ imageView.image = image } pickImage.dismiss(animated: true, completion: nil) } } extension AddViewController: UITextFieldDelegate{ func textFieldShouldReturn(_ textField: UITextField) -> Bool { if textField.tag == 2 { textField.resignFirstResponder() }else{ let nextKey = view.viewWithTag(textField.tag + 1) as! UITextField nextKey.becomeFirstResponder() } return true } }
យើងទាញទិន្ន័យពី coreData ទៅដាក់ tableView។ មុននឹងយើងទាញទិន្ន័យយើង design នៅ ViewController មួយសិន។

យើងមកសិក្សានៅ ViewController របស់យើងម្តង។ យើងបង្កើត outlet ឲ្យ table view ។ មេរៀន TableView យើងបានសិក្សាមករួចហើយ
នៅក្នុង ViewController យើងត្រូវបង្កើត property ពីរចេញពី appDelegate ដើម្បីទំនាក់ទំនងជាមួយ coreData ដូចទៅនឹង AddViewController ដែរ។ ដូចនេះយើង copy មកដាក់នៅ ViewController
let appDelegate = UIApplication.shared.delegate as! AppDelegate let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

យើងបង្កើត preperty array មួយសំរាប់ផ្ទុកទិន្ន័យចេញពី coreData
var contacts = [Contact]()
វាងាយស្រួលក្នុងការទាញទិន្ន័យ តាមរយៈ contacts នេះ
import UIKit class ViewController: UIViewController{ @IBOutlet weak var tableView: UITableView! let appDelegate = UIApplication.shared.delegate as! AppDelegate let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext // បង្កើត properties ដែលវាផ្ទុក data ពី coreData var contacts = [Contact]() override func viewDidLoad() { super.viewDidLoad() tableView.delegate = self tableView.dataSource = self } override func viewDidAppear(_ animated: Bool) { getAllData() } } extension ViewController: UITableViewDelegate,UITableViewDataSource{ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return contacts.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) cell.textLabel?.text = contacts[indexPath.row].name cell.detailTextLabel?.text = contacts[indexPath.row].phone // បំលែង image data ទៅជា UIImage cell.imageView?.image = UIImage(data: contacts[indexPath.row].image!) return cell } // fecth Data to tableView func getAllData(){ contacts = try! context.fetch(Contact.fetchRequest()) tableView.reloadData() } }

យើងចង់ update data តាមរយៈ tableview ហើយទៅ edit នៅ form insert។ ដោយយើងប្រើ method មួយឈ្មោះថា trailingSwipeActionsConfigurationForRowAt ដោយយើងសរសេរកូននេះក្នុង extension ViewController: UITableViewDelegate,UITableViewDataSource ។
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { return UISwipeActionsConfiguration(actions: [UIContextualAction]) }
នេះយើង return ទៅជា UISwipeActionsConfiguration បន្ទាបមកយើង implement កូដចេញពី UIContextualAction
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { let edit = UIContextualAction(style: .destructive, title: "Edit") { _, _, _ in let editAddVC = self.storyboard?.instantiateViewController(withIdentifier: "addScreen") as! AddViewController self.navigationController?.pushViewController(editAddVC, animated: true) } return UISwipeActionsConfiguration(actions: [edit]) }

នេះយើងអាចចុច button edit បានហើយ ក៏ប៉ុន្តែវាមិនទាន់បោះទិន្ន័យទៅឲ្យ field នៃ form របស់យើងទេ។ ដូចនេះយើងត្រូវតែសិក្សាលក្ខណឲ្យវា
យើងទៅសរសេរកូននៅក្នុង AddViewController ។ យើងបង្កើត variable មួយជា boolen ប្រសិនបើវាពិតគឺឲ្យវា update ប៉ុន្តែបើវាមិនពិតឲ្យ insert ។ ហើយទន្ទឹមនឹងនេះយើងបង្កើត variable មួយទៀតសំរាបទទួយលទិន្ន័យ ViewController ដែលបានបោះតាមរយៈ method edit របស់យើង។
var isUpdate: Bool = false // ចំទទួលទំលៃពី method edit var contact: Contact? //----ខាងក្រោមនេះកូដផ្សេង--- override func viewDidLoad() { super.viewDidLoad()
យើងសរសេរកូដដើម្បីបោះទិន្ន័យទៅឲ្យ TextField នៅក្នុង viewDidLoad ក៏ប៉ុន្តែកុំឲ្យរញ៉េរញ៉ៃនៅក្នុង viewDidLoad() របស់យើង ខ្ញុំសុំបង្កើត function មួយសំរាប់សរសេរវា
func upDate(){ if isUpdate{ //optional variable if let contact = contact { nameTextField.text = contact.name phoneTextField.text = contact.phone imageView.image = UIImage(data: contact.image!) } } }

យើងទៅ ViewController វិញ ដោយយើងបោះទិន្ន័យទៅឲ្យ variable ដែលយើងបង្កើតនៅក្នុង AddviewController
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { let edit = UIContextualAction(style: .destructive, title: "Edit") { _, _, _ in let editAddVC = self.storyboard?.instantiateViewController(withIdentifier: "addScreen") as! AddViewController self.navigationController?.pushViewController(editAddVC, animated: true) //បោះទិន្ន័យទៅ form field ប្រសិនវា true editAddVC.isUpdate = true editAddVC.contact = self.contacts[indexPath.row] } return UISwipeActionsConfiguration(actions: [edit]) }

នេះប្រសិនបើយើងចុច button save នោះវានឹង save ថ្មី ។ ដូចនេះយើងសិក្សាលក្ខណនៅក្នុង btn Button នៅក្នុង AddViewController។ ប៉ុន្តែនៅក្នុង btn Button វាកូដស្រាប ដោយយើងសិក្សាថាប្រសិនថាវាពិតលុបតែ let contact = Contact(context: context) តែបើវាមិនពិតយើងទុកកូដទាំងអស់
@IBAction func btn(_ sender: UIButton) { if isUpdate{ contact?.name = nameTextField.text contact?.phone = phoneTextField.text //Covert Image to data contact?.image = UIImage.pngData(imageView.image!)() //Saving to coreData appDelegate.saveContext() }else{ let contact = Contact(context: context) contact.name = nameTextField.text contact.phone = phoneTextField.text //Covert Image to data contact.image = UIImage.pngData(imageView.image!)() //Saving to coreData appDelegate.saveContext() } //Back to ViewController Screen self.navigationController?.popViewController(animated: true) }

ប្តូរ title នៃ Navigation Bar
title = "Contacts"
កូដនេះដាក់នៅក្នុង viewDidLoad

ប្តូរ title នៃ button save and update
យើងមាន funtion ស្រាប់គឺនៅ function upDate() យើងសរសេរកូដនៅទីនេះ
func upDate(){ if isUpdate{ btnLabel.setTitle("Update", for: .normal) title = "Update Contact" //optional variable if let contact = contact { nameTextField.text = contact.name phoneTextField.text = contact.phone imageView.image = UIImage(data: contact.image!) } }else{ btnLabel.setTitle("Save", for: .normal) title = "Add Contact" } }
ការលុបទិន្ន័យគឺធ្វើស្រដៀងទៅនឹង update ដែរ ។ ប៉ុន្តែខ្ញុំសុំយក method leadingSwipeActionsConfigurationForRowAt ម្តង
func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { let delet = UIContextualAction.init(style: .normal, title: "Delete") { _, _, _ in let alert = UIAlertController(title: "Comfirm", message: "Are you sure?", preferredStyle: .alert) self.present(alert, animated: true, completion: nil) let ok = UIAlertAction(title: "OK", style: .destructive) { _ in let contact = self.contacts[indexPath.row] self.context.delete(contact) self.appDelegate.saveContext() self.getAllData() } let cancel = UIAlertAction(title: "Cancel", style: .cancel) { _ in self.getAllData() } alert.addAction(ok) alert.addAction(cancel) } return UISwipeActionsConfiguration(actions: [delet]) }

កូដទាំងអស់
ViewController
import UIKit class ViewController: UIViewController{ @IBOutlet weak var tableView: UITableView! let appDelegate = UIApplication.shared.delegate as! AppDelegate let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext // បង្កើត properties ដែលវាផ្ទុក data ពី coreData var contacts = [Contact]() override func viewDidLoad() { super.viewDidLoad() tableView.delegate = self tableView.dataSource = self title = "Contacts" } override func viewDidAppear(_ animated: Bool) { getAllData() } } extension ViewController: UITableViewDelegate,UITableViewDataSource{ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return contacts.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) cell.textLabel?.text = contacts[indexPath.row].name cell.detailTextLabel?.text = contacts[indexPath.row].phone // បំលែង image data ទៅជា UIImage cell.imageView?.image = UIImage(data: contacts[indexPath.row].image!) return cell } // fecth Data to tableView func getAllData(){ contacts = try! context.fetch(Contact.fetchRequest()) tableView.reloadData() } func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { let edit = UIContextualAction(style: .destructive, title: "Edit") { _, _, _ in let editAddVC = self.storyboard?.instantiateViewController(withIdentifier: "addScreen") as! AddViewController self.navigationController?.pushViewController(editAddVC, animated: true) //បោះទិន្ន័យទៅ form field ប្រសិនវា true editAddVC.isUpdate = true editAddVC.contact = self.contacts[indexPath.row] } return UISwipeActionsConfiguration(actions: [edit]) } func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { let delet = UIContextualAction.init(style: .normal, title: "Delete") { _, _, _ in let alert = UIAlertController(title: "Comfirm", message: "Are you sure?", preferredStyle: .alert) self.present(alert, animated: true, completion: nil) let ok = UIAlertAction(title: "OK", style: .destructive) { _ in let contact = self.contacts[indexPath.row] self.context.delete(contact) self.appDelegate.saveContext() self.getAllData() } let cancel = UIAlertAction(title: "Cancel", style: .cancel) { _ in self.getAllData() } alert.addAction(ok) alert.addAction(cancel) } return UISwipeActionsConfiguration(actions: [delet]) } }
AddViewController
import UIKit class AddViewController: UIViewController { @IBOutlet weak var imageView: UIImageView! @IBOutlet weak var nameTextField: UITextField! @IBOutlet weak var phoneTextField: UITextField! @IBOutlet weak var btnLabel: UIButton! //comform ចេញពី appDelegate ប្រើជាមួយ coreData let appDelegate = UIApplication.shared.delegate as! AppDelegate let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext var pickImage: UIImagePickerController! var isUpdate: Bool = false var contact: Contact? override func viewDidLoad() { super.viewDidLoad() nameTextField.delegate = self phoneTextField.delegate = self imageView.image = UIImage(named: "empty") pickImage = UIImagePickerController() pickImage.sourceType = .photoLibrary pickImage.delegate = self seletImage() upDate() } @IBAction func btn(_ sender: UIButton) { if isUpdate{ contact?.name = nameTextField.text contact?.phone = phoneTextField.text //Covert Image to data contact?.image = UIImage.pngData(imageView.image!)() //Saving to coreData appDelegate.saveContext() }else{ let contact = Contact(context: context) contact.name = nameTextField.text contact.phone = phoneTextField.text //Covert Image to data contact.image = UIImage.pngData(imageView.image!)() //Saving to coreData appDelegate.saveContext() } //Back to ViewController Screen self.navigationController?.popViewController(animated: true) } func upDate(){ if isUpdate{ btnLabel.setTitle("Update", for: .normal) title = "Update Contact" //optional variable if let contact = contact { nameTextField.text = contact.name phoneTextField.text = contact.phone imageView.image = UIImage(data: contact.image!) } }else{ btnLabel.setTitle("Save", for: .normal) title = "Add Contact" } } } extension AddViewController: UIImagePickerControllerDelegate,UINavigationControllerDelegate{ func seletImage(){ let tapGuester = UITapGestureRecognizer(target: self, action: #selector(broweImage)) imageView.addGestureRecognizer(tapGuester) imageView.isUserInteractionEnabled = true } @objc func broweImage(){ present(pickImage, animated: true, completion: nil) } func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { if let image = info[.originalImage] as? UIImage{ imageView.image = image } pickImage.dismiss(animated: true, completion: nil) } } extension AddViewController: UITextFieldDelegate{ func textFieldShouldReturn(_ textField: UITextField) -> Bool { if textField.tag == 2 { textField.resignFirstResponder() }else{ let nextKey = view.viewWithTag(textField.tag + 1) as! UITextField nextKey.becomeFirstResponder() } return true } }
0 Comments