Swift -TableViewとstoryboard.instantiateViewController()で値渡しの内容をDBで参照してみた③-
はじめに
前回の記事:Swift -TableViewとstoryboard.instantiateViewController()で値渡しの内容をDBで参照してみた②-
今回はコード実装になります。
使用環境
● OS:macOS Big Sur 11.3.1
● Xcode:12.5
● Swift:5.4
● DB Browser for SQLite:3.12.1
コードの実装
// AppDelegate.swift
import UIKit
import FMDB
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
dbMethod()
return true
}
func dbMethod() {
let database = FMDatabase(url: fileURL)
guard database.open() else {
print("Unable to open database")
return
}
do {
try database.executeUpdate("CREATE TABLE IF NOT EXISTS student(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, email TEXT, college TEXT, faculty TEXT, branch TEXT, timestamp TEXT)", values: nil)
}
catch {
print("\(error.localizedDescription)")
}
database.close()
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
}
// ViewController.swift
import UIKit
import FMDB
protocol StudentDataDelegate {
func getStudentData()
}
class ViewController: UIViewController, StudentDataDelegate {
func getStudentData() {
getAllData()
}
var studentArr = [StudentModel]()
@IBOutlet weak var tblStudent: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
getAllData()
tblStudent.tableFooterView = UIView(frame: .zero)
}
func getAllData() {
let myUrl = fileURL
print(myUrl)
studentArr.removeAll()
let database = FMDatabase(url: fileURL)
if database.open() {
do {
let rs = try database.executeQuery("select * from student", values: [0])
while rs.next() {
let items : StudentModel = StudentModel()
items.id = rs.string(forColumn: "id")
items.name = rs.string(forColumn: "name")
items.email = rs.string(forColumn: "email")
items.college = rs.string(forColumn: "college")
items.faculty = rs.string(forColumn: "faculty")
items.branch = rs.string(forColumn: "branch")
studentArr.append(items)
//try database.executeUpdate("select * from student", values: [0])
}
tblStudent.delegate = self
tblStudent.dataSource = self
tblStudent.reloadData()
}
catch {
print("error:\(error.localizedDescription)")
}
}
else {
print("Unable to open database")
return
}
database.close()
}
//値の受け渡し
@IBAction func addStudentTapped(_ sender: Any) {
let storyboards = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboards.instantiateViewController(identifier: "AddStudentVC") as! AddStudentVC
vc.studentDelegate = self
self.navigationController?.pushViewController(vc, animated: true)
}
@IBAction func deleteStudentTapped(_ sender: Any) {
let database = FMDatabase(url: fileURL)
guard database.open() else {
print("Database is no fetch")
return
}
do {
_ = try database.executeUpdate("delete from student", values: nil)
}
catch let error {
print(error.localizedDescription)
}
database.close()
getStudentData()
}
}
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 180
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return studentArr.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tblStudent.dequeueReusableCell(withIdentifier: "StudentTVCell", for: indexPath) as! StudentTVCell
let obj = studentArr[indexPath.row]
cell.configureStudent(dict: obj)
return cell
}
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let student = self.studentArr[indexPath.row]
let called = student.id
let delete = UIContextualAction(style: .destructive, title: "Delete") { (action,
scrollview, completionHandler) in
let database = FMDatabase(url: fileURL)
guard database.open() else{
print("no fetch database")
return
}
do {
_ = try database.executeUpdate("delete from student where id =? ", values : [called!])
}
catch let err{
print(err.localizedDescription)
}
database.close()
self.getStudentData()
completionHandler(true)
}
let edit = UIContextualAction(style: .destructive, title: "Edit") { (action,
scrollview, completionHandler) in
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(identifier: "AddStudentVC") as! AddStudentVC
vc.name = student.name
vc.email = student.email
vc.college = student.college
vc.faculty = student.faculty
vc.branch = student.branch
vc.id = student.id
vc.isEdit = true
vc.studentDelegate = self
self.navigationController?.pushViewController(vc, animated: true)
completionHandler(true)
}
edit.backgroundColor = UIColor.black
let swipeConfigire = UISwipeActionsConfiguration(actions: [delete, edit])
swipeConfigire.performsFirstActionWithFullSwipe = false
return swipeConfigire
}
}
class StudentTVCell: UITableViewCell {
@IBOutlet weak var lblName: UILabel!
@IBOutlet weak var lblEmail: UILabel!
@IBOutlet weak var lblCollege: UILabel!
@IBOutlet weak var lblFaculty: UILabel!
@IBOutlet weak var lblBranch: UILabel!
func configureStudent(dict: StudentModel) {
lblName.text = dict.name
lblEmail.text = dict.email
lblBranch.text = dict.branch
lblCollege.text = dict.college
lblFaculty.text = dict.faculty
}
}
// AddStudentVC.swift
import UIKit
import FMDB
class AddStudentVC: UIViewController {
@IBOutlet weak var btnSubmit: UIButton!
@IBOutlet weak var branchNameTextFields: UITextField!
@IBOutlet weak var facultyNameTextFields: UITextField!
@IBOutlet weak var collegeTextFields: UITextField!
@IBOutlet weak var emailTextFields: UITextField!
@IBOutlet weak var nameTextFields: UITextField!
var isEdit = false
var name: String?
var email: String?
var college: String?
var faculty: String?
var branch: String?
var id: String?
@IBAction func bynSubmitTapped(_ sender: Any) {
if isEdit == true {
updateStudentData()
}
else if !(nameTextFields.text!.isEmpty) &&
!(emailTextFields.text!.isEmpty) &&
!(facultyNameTextFields.text!.isEmpty) &&
!(collegeTextFields.text!.isEmpty) &&
!(branchNameTextFields.text!.isEmpty) {
insertChatToDB(name: nameTextFields.text!,
email: emailTextFields.text!,
college: collegeTextFields.text!,
faculty: facultyNameTextFields.text!,
branch: branchNameTextFields.text!)
//print(fileURL)
}
}
var studentDelegate: StudentDataDelegate?
override func viewDidLoad() {
super.viewDidLoad()
if isEdit == true {
nameTextFields.text = name
emailTextFields.text = email
facultyNameTextFields.text = faculty
collegeTextFields.text = college
branchNameTextFields.text = branch
}
}
func updateStudentData() {
let database = FMDatabase(url: fileURL)
let timestamp1 = NSDate().timeIntervalSince1970
guard database.open() else {
print("Not fetch database")
return
}
do {
//name TEXT, email TEXT, college TEXT, faculty TEXT, branch TEXT, timestamp TEXT
try database.executeUpdate("UPDATE student SET name =?, email =?,college =?, faculty =?, branch =?, timestamp =? where id ='\(id!)'", values: [nameTextFields.text!,emailTextFields.text!,collegeTextFields.text!,facultyNameTextFields.text!,branchNameTextFields.text!,timestamp1])
}
catch let error {
print(error.localizedDescription)
}
database.close()
studentDelegate?.getStudentData()
self.navigationController?.popViewController(animated: true)
}
func insertChatToDB(name: String, email: String, college: String, faculty: String, branch: String) {
let database = FMDatabase(url: fileURL)
let timestamp1 = NSDate().timeIntervalSince1970
guard database.open() else {
print("Unable to open database")
return
}
do {
try database.executeUpdate("INSERT INTO student(name, email, college, faculty, branch, timestamp) values (?, ?, ?, ?, ?, ?)", values: [name, email, college, faculty, branch, "\(timestamp1)"])
}
catch {
print("\(error.localizedDescription)")
}
database.close()
studentDelegate?.getStudentData()
self.navigationController?.popViewController(animated: true)
}
}
// DBManagerData.swift
import Foundation
let fileURL = try! FileManager.default
.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
.appendingPathComponent("studentDB.sqlite3")
class StudentModel: NSObject {
var id: String?
var name: String?
var email: String?
var college: String?
var faculty: String?
var branch: String?
}
おわりに
次回はDBを使用してTextFieldで入力した内容を参照する方法について解説して行きます。
次回も宜しくお願いします。
参考文献
EasytoSwiftさんの投稿動画を参考にさせて頂きました。
大変勉強になりました。