Erstellen, Lesen, Aktualisieren und Löschen von SQLite – Swift & Swift UI

[ad_1]

SQLite wird verwendet, um die Daten lokal in der App in der SQL-Struktur zu speichern. Es ist eine relationale lokale Datenbank. Sie können diese Datenbank verwenden, um Daten in der App mithilfe von Swift und Swift UI zu speichern.

Wir werden eine einfache iOS-App in der Swift-Benutzeroberfläche erstellen, um Benutzer aus der SQLite-Datenbank zu erstellen, zu lesen, zu aktualisieren und zu löschen.

Wir werden eine Bibliothek namens SQLite von verwenden Stephen Celis. Um diese Bibliothek zu installieren, müssen Cocoapods in Ihrem System installiert sein.

Installation

Sie können Cocoapods in Ihrem System installieren, indem Sie einfach den folgenden Befehl in Ihrem Terminal ausführen:

sudo gem install cocoapods

Zunächst müssen Sie eine Eingabeaufforderung (Terminal) im Stammverzeichnis Ihres XCode-Projekts öffnen und den folgenden Befehl ausführen:

pod init

Jetzt sehen Sie eine neue Datei, die im Stammverzeichnis Ihres Projekts mit dem Namen erstellt wurde Podfile. Öffnen Sie diese Datei in Ihrem Texteditor und fügen Sie die Zeile hinzu, um die Bibliothek zu installieren. Folgendes wird der Inhalt Ihres Podfiles sein:

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'SQLite_Database' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for SQLite_Database
  pod 'SQLite.swift', '~> 0.12.0'

end

Führen Sie danach den folgenden Befehl in Ihrem Terminal aus, um diese Bibliothek zu installieren:

pod update

Schließen Sie nach der Installation Ihren XCode und öffnen Sie ihn erneut. Doppelklicken Sie diesmal jedoch auf die Datei mit der Erweiterung „.xcworkspace“. Diese Datei wird erst erstellt, nachdem der Pod installiert / aktualisiert wurde.

1. Benutzer hinzufügen

Zunächst erstellen wir eine Modellklasse, die die Datenstruktur für jeden Benutzer enthält. Erstellen Sie eine Datei mit dem Namen „UserModel.swift”Und fügen Sie den folgenden Code ein:

//
//  UserModel.swift
//  SQLite_Database
//
//  Created by Adnan Afzal on 24/11/2020.
//  Copyright © 2020 Adnan Afzal. All rights reserved.
//

import Foundation

class UserModel: Identifiable {
    public var id: Int64 = 0
    public var name: String = ""
    public var email: String = ""
    public var age: Int64 = 0
}

Ihre Modellklasse muss übereinstimmen Identifizierbar Protokoll, um die Benutzer in der Listenansicht anzuzeigen.

Um die Datenbankfunktionen zu handhaben, erstellen wir eine separate Datei mit dem Namen „DB_Manager.swift“. In dieser Klasse erstellen wir die Datenbank, die Tabellen und ihre Spalten im Konstruktor.

//
//  DB_Manager.swift
//  SQLite_Database
//
//  Created by Adnan Afzal on 24/11/2020.
//  Copyright © 2020 Adnan Afzal. All rights reserved.
//

import Foundation

// import library
import SQLite

class DB_Manager {
    
    // sqlite instance
    private var db: Connection!
    
    // table instance
    private var users: Table!

    // columns instances of table
    private var id: Expression<Int64>!
    private var name: Expression<String>!
    private var email: Expression<String>!
    private var age: Expression<Int64>!
    
    // constructor of this class
    init () {
        
        // exception handling
        do {
            
            // path of document directory
            let path: String = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first ?? ""

            // creating database connection
            db = try Connection("(path)/my_users.sqlite3")
            
            // creating table object
            users = Table("users")
            
            // create instances of each column
            id = Expression<Int64>("id")
            name = Expression<String>("name")
            email = Expression<String>("email")
            age = Expression<Int64>("age")
            
            // check if the user's table is already created
            if (!UserDefaults.standard.bool(forKey: "is_db_created")) {

                // if not, then create the table
                try db.run(users.create { 
                    t.column(id, primaryKey: true)
                    t.column(name)
                    t.column(email, unique: true)
                    t.column(age)
                })
                
                // set the value to true, so it will not attempt to create the table again
                UserDefaults.standard.set(true, forKey: "is_db_created")
            }
            
        } catch {
            // show error message if any
            print(error.localizedDescription)
        }
        
    }
}

Zur Verdeutlichung wurde jeder Zeile ein Kommentar hinzugefügt. In Ihrer Inhaltsansicht erstellen wir nun einen Navigationslink, der zum AddUserView Datei.

Öffnen Sie Ihre Datei mit der Inhaltsansichtsdatei und platzieren Sie diesen Code im Hauptteil:

// create navigation view
NavigationView {

    VStack {

        // create link to add user
        HStack {
            Spacer()
            NavigationLink (destination: AddUserView(), label: {
                Text("Add user")
            })
        }

        // list view goes here

    }.padding()
    .navigationBarTitle("SQLite")
}

Erstellen Sie jetzt eine neue Ansichtsdatei mit dem Namen „AddUserView.swift”Und fügen Sie den folgenden Code ein:

//
//  AddUserView.swift
//  SQLite_Database
//
//  Created by Adnan Afzal on 24/11/2020.
//  Copyright © 2020 Adnan Afzal. All rights reserved.
//

import SwiftUI

struct AddUserView: View {
    
    // create variables to store user input values
    @State var name: String = ""
    @State var email: String = ""
    @State var age: String = ""
    
    // to go back on the home screen when the user is added
    @Environment(.presentationMode) var mode: Binding<PresentationMode>
    
    var body: some View {
        
        VStack {
            // create name field
            TextField("Enter name", text: $name)
                .padding(10)
                .background(Color(.systemGray6))
                .cornerRadius(5)
                .disableAutocorrection(true)
            
            // create email field
            TextField("Enter email", text: $email)
                .padding(10)
                .background(Color(.systemGray6))
                .cornerRadius(5)
                .keyboardType(.emailAddress)
                .autocapitalization(.none)
                .disableAutocorrection(true)
            
            // create age field, number pad
            TextField("Enter age", text: $age)
                .padding(10)
                .background(Color(.systemGray6))
                .cornerRadius(5)
                .keyboardType(.numberPad)
                .disableAutocorrection(true)
            
            // button to add a user
            Button(action: {
                // call function to add row in sqlite database
                DB_Manager().addUser(nameValue: self.name, emailValue: self.email, ageValue: Int64(self.age) ?? 0)
                
                // go back to home page
                self.mode.wrappedValue.dismiss()
            }, label: {
                Text("Add User")
            })
                .frame(maxWidth: .infinity, alignment: .trailing)
                .padding(.top, 10)
                .padding(.bottom, 10)
        }.padding()
        
    }
}

Dies ist etwas langwierig, aber zur Erläuterung wurden zu jeder Zeile Kommentare hinzugefügt.

An dieser Stelle wird in der hervorgehobenen Zeile ein Fehler angezeigt. Weil wir diese Funktion in unserer DB-Manager-Klasse erstellen müssen. Erstellen Sie also die folgende Funktion in Ihrem DB_Manager.swift Datei:

public func addUser(nameValue: String, emailValue: String, ageValue: Int64) {
    do {
        try db.run(users.insert(name <- nameValue, email <- emailValue, age <- ageValue))
    } catch {
        print(error.localizedDescription)
    }
}

Wenn Sie die App jetzt ausführen, wird ein Link zum Hinzufügen einer Benutzeransicht angezeigt. In dieser Ansicht werden 3 Felder angezeigt. Nachdem Sie die Felder ausgefüllt und auf die Schaltfläche “Senden” geklickt haben, werden die Daten in der SQLite-Datenbank gespeichert und Sie werden in die Startansicht verschoben.

Die in der Datenbank gespeicherten Daten werden jedoch nicht angezeigt. Jetzt zeigen wir die Daten in der Listenansicht.

2. Alle Benutzer anzeigen

Erstellen Sie in Ihrer Inhaltsansicht, in der Sie alle Daten aus der Datenbank anzeigen möchten, einen Wrapper für Statuseigenschaften:

// array of user models
@State var userModels: [UserModel] = []

Erstellen Sie nun nach dem Navigationslink eine Listenansicht im Inhaltsansichtstext, um eine Benutzeransicht hinzuzufügen:

// create list view to show all users
List (self.userModels) { (model) in

    // show name, email and age horizontally
    HStack {
        Text(model.name)
        Spacer()
        Text(model.email)
        Spacer()
        Text("(model.age)")
        Spacer()

        // edit and delete button goes here
    }
}

Wenn die Inhaltsansicht geladen wird, müssen wir die Daten aus der Datenbank hinzufügen userModels Array. Befestigen Sie eine onAppear Funktion am Ende Ihres VStacks wie folgt:

VStack {
    ...
}
// load data in user models array
.onAppear(perform: {
    self.userModels = DB_Manager().getUsers()
})

Jetzt müssen wir eine Funktion mit dem Namen erstellen getUsers () in unserer DB Manager Klasse:

// return array of user models
public func getUsers() -> [UserModel] {
    
    // create empty array
    var userModels: [UserModel] = []

    // get all users in descending order
    users = users.order(id.desc)

    // exception handling
    do {

        // loop through all users
        for user in try db.prepare(users) {

            // create new model in each loop iteration
            let userModel: UserModel = UserModel()

            // set values in model from database
            userModel.id = user[id]
            userModel.name = user[name]
            userModel.email = user[email]
            userModel.age = user[age]

            // append in new array
            userModels.append(userModel)
        }
    } catch {
        print(error.localizedDescription)
    }

    // return array
    return userModels
}

Dadurch werden die Benutzer in absteigender Reihenfolge (zuerst die neuesten Benutzer) aus der SQLite-Datenbank abgerufen und als Array von Benutzermodellklassen zurückgegeben.

Führen Sie die App aus und Sie sehen nun die Benutzer, die in einem Tabellenformat hinzugefügt wurden. Sie können versuchen, indem Sie die App aus dem Hintergrund entfernen und erneut öffnen. Die Daten bleiben weiterhin erhalten. Daten werden nur entfernt, wenn die App deinstalliert ist.

3. Benutzer bearbeiten

Das Bearbeiten des Benutzers erfordert mehrere Schritte:

  1. Benutzer anhand der ID abrufen.
  2. Benutzerdetails in Eingabefeldern anzeigen.
  3. Aktualisieren Sie den Benutzer in der Datenbank mit seiner ID.

Zuerst müssen wir 2 Statusvariablen oben in der Inhaltsansicht erstellen, die es zeigen WANN Der Benutzer wird zum Bearbeiten ausgewählt und WELCHE Benutzer ist ausgewählt.

// check if user is selected for edit
@State var userSelected: Bool = false

// id of selected user to edit or delete
@State var selectedUserId: Int64 = 0

Erstellen Sie nun in Ihrem HStack in der Listenansicht eine Schaltfläche zum Bearbeiten des Benutzers:

// button to edit user
Button(action: {
    self.selectedUserId = model.id
    self.userSelected = true
}, label: {
    Text("Edit")
        .foregroundColor(Color.blue)
    })
    // by default, buttons are full width.
    // to prevent this, use the following
    .buttonStyle(PlainButtonStyle())

Dadurch wird die Variable userSelected auf true und selectedUserId auf die ID des von Ihnen ausgewählten Benutzers gesetzt. Jetzt müssen wir zur neuen Ansicht wechseln, um den Benutzer zu bearbeiten.

Erstellen Sie einen Navigationslink mit einer leeren Ansicht im Hauptteil der Inhaltsansicht und vor der Listenansicht:

// navigation link to go to edit user view
NavigationLink (destination: EditUserView(id: self.$selectedUserId), isActive: self.$userSelected) {
    EmptyView()
}

Erstellen Sie eine neue Ansichtsdatei mit dem Namen EditUserView.swift und fügen Sie den folgenden Code ein. Achten Sie genau auf die hervorgehobenen Linien:

//
//  EditUserView.swift
//  SQLite_Database
//
//  Created by Adnan Afzal on 24/11/2020.
//  Copyright © 2020 Adnan Afzal. All rights reserved.
//

import SwiftUI

struct EditUserView: View {
    
    // id receiving of user from previous view
    @Binding var id: Int64
    
    // variables to store value from input fields
    @State var name: String = ""
    @State var email: String = ""
    @State var age: String = ""
    
    // to go back to previous view
    @Environment(.presentationMode) var mode: Binding<PresentationMode>
    
    var body: some View {
        VStack {
            // create name field
            TextField("Enter name", text: $name)
                .padding(10)
                .background(Color(.systemGray6))
                .cornerRadius(5)
                .disableAutocorrection(true)
            
            // create email field
            TextField("Enter email", text: $email)
                .padding(10)
                .background(Color(.systemGray6))
                .cornerRadius(5)
                .keyboardType(.emailAddress)
                .autocapitalization(.none)
                .disableAutocorrection(true)
            
            // create age field, number pad
            TextField("Enter age", text: $age)
                .padding(10)
                .background(Color(.systemGray6))
                .cornerRadius(5)
                .keyboardType(.numberPad)
                .disableAutocorrection(true)
            
            // button to update user
            Button(action: {
                // call function to update row in sqlite database
                DB_Manager().updateUser(idValue: self.id, nameValue: self.name, emailValue: self.email, ageValue: Int64(self.age) ?? 0)

                // go back to home page
                self.mode.wrappedValue.dismiss()
            }, label: {
                Text("Edit User")
            })
                .frame(maxWidth: .infinity, alignment: .trailing)
                .padding(.top, 10)
                .padding(.bottom, 10)
        }.padding()

        // populate user's data in fields when view loaded
        .onAppear(perform: {
            
            // get data from database
            let userModel: UserModel = DB_Manager().getUser(idValue: self.id)
            
            // populate in text fields
            self.name = userModel.name
            self.email = userModel.email
            self.age = String(userModel.age)
        })
    }
}

struct EditUserView_Previews: PreviewProvider {
    
    // when using @Binding, do this in preview provider
    @State static var id: Int64 = 0
    
    static var previews: some View {
        EditUserView(id: $id)
    }
}

@Binding wird verwendet, wenn Sie den Wert von einer Ansicht an eine andere übergeben möchten. Wenn Sie in diesem Fall den Vorschau-Anbieter verwenden, müssen Sie die Variable @State darin erstellen.

Zu diesem Zeitpunkt erhalten Sie eine Fehlermeldung DB_Manager (). UpdateUser und DB_Manager (). GetUser da diese Funktionen noch nicht in der DB-Manager-Klasse erstellt wurden.

Zuerst erstellen wir die Funktion, um den einzelnen Benutzer mithilfe seiner ID aus der SQLite-Datenbank abzurufen. In deiner DB_Manager.swift::

// get single user data
public func getUser(idValue: Int64) -> UserModel {

    // create an empty object
    let userModel: UserModel = UserModel()
    
    // exception handling
    do {

        // get user using ID
        let user: AnySequence<Row> = try db.prepare(users.filter(id == idValue))

        // get row
        try user.forEach({ (rowValue) in

            // set values in model
            userModel.id = try rowValue.get(id)
            userModel.name = try rowValue.get(name)
            userModel.email = try rowValue.get(email)
            userModel.age = try rowValue.get(age)
        })
    } catch {
        print(error.localizedDescription)
    }

    // return model
    return userModel
}

Die Filterfunktion in der hervorgehobenen Zeile hilft beim Ausführen der WHERE-Klausel (zum Filtern der Daten).

Jetzt müssen wir eine Funktion in der DB Manager-Klasse erstellen, um den Benutzer in der SQLite-Datenbank zu aktualisieren.

// function to update user
public func updateUser(idValue: Int64, nameValue: String, emailValue: String, ageValue: Int64) {
    do {
        // get user using ID
        let user: Table = users.filter(id == idValue)
        
        // run the update query
        try db.run(user.update(name <- nameValue, email <- emailValue, age <- ageValue))
    } catch {
        print(error.localizedDescription)
    }
}

Hier erhalten wir zuerst das Benutzerobjekt mit dem Filter() Funktion. Dann führen wir die Aktualisierungsabfrage für das Objekt dieses Benutzers aus.

Führen Sie die App aus, und am Ende des Datensatzes jedes Benutzers wird die Schaltfläche “Bearbeiten” angezeigt. Wenn Sie darauf klicken, gelangen Sie zu einer anderen Ansicht, von der aus Sie die Benutzerdaten in Eingabefeldern sehen. Durch Klicken auf die Schaltfläche „Aktualisieren“ werden die Daten aktualisiert und zur Startansicht zurückgekehrt.

4. Benutzer löschen

Um einen Benutzer aus der SQLite-Datenbank zu löschen, erstellen wir zunächst eine Löschschaltfläche in der Listenansicht, so wie wir die Bearbeitungsschaltfläche erstellt haben.

// create list view to show all users
List (self.userModels) { (model) in

    // show name, email, and age horizontally
    HStack {
        ... edit button
        
        // button to delete user
        Button(action: {

            // create db manager instance
            let dbManager: DB_Manager = DB_Manager()

            // call delete function
            dbManager.deleteUser(idValue: model.id)

            // refresh the user models array
            self.userModels = dbManager.getUsers()
        }, label: {
            Text("Delete")
                .foregroundColor(Color.red)
        })// by default, buttons are full width.
        // to prevent this, use the following
        .buttonStyle(PlainButtonStyle())
    }
}

Der obige Code sollte in der Inhaltsansicht nach der Schaltfläche Bearbeiten platziert werden. Sie können sehen, dass wir eine Instanz der DB_Manager-Klasse erstellt und in einer anderen Variablen gespeichert haben. Weil wir 2 Funktionen aus der DB_Manager-Klasse aufrufen müssen.

Die erste Funktion löscht den Benutzer aus der SQLite-Datenbank und die zweite Funktion aktualisiert die Listenansicht. Daher wird der Benutzer zum Löschen ebenfalls aus der Ansicht entfernt.

Erstellen Sie die folgende Funktion in Ihrem DB_Manager Klasse:

// function to delete user
public func deleteUser(idValue: Int64) {
    do {
        // get user using ID
        let user: Table = users.filter(id == idValue)
        
        // run the delete query
        try db.run(user.delete())
    } catch {
        print(error.localizedDescription)
    }
}

Wenn Sie die App jetzt ausführen, wird am Ende des Datensatzes jedes Benutzers eine Schaltfläche zum Löschen angezeigt. Durch Klicken auf diese Schaltfläche wird der Benutzer aus der Datenbank und auch aus der Listenansicht entfernt. Sie können versuchen, die App aus dem Hintergrundprozess zu entfernen und erneut zu öffnen. Die Löschdaten werden nicht erneut angezeigt.

Wo können Sie SQLite in der iOS-App verwenden?

Sie können eine Funktion erstellen, um den Suchverlauf des Benutzers lokal in der App zu speichern. So kann der Benutzer dasselbe aus dem Suchverlauf erneut suchen.

Sie können die häufigen Daten in SQLite zwischenspeichern. Anstatt die Daten vom Server anzufordern, wird über die App darauf zugegriffen. Dies erhöht die Leistung Ihrer App.

Oder Sie können einfach eine App ohne Server mit SQLite erstellen, z. B. “App zur Buchführung persönlicher Konten”. Für diese Art von Apps ist keine Internetverbindung erforderlich, und der Benutzer kann sie auch ohne Internetzugang verwenden.



[ad_2]