简体   繁体   中英

I cannot get the data from the Sqlite database

I cannot get the data from the Sqlite database. It doesn't print anything for me. I checked the connection to the db is made and the database contains the data. It gives no error but does not print anything. When I start the app the tableView contains no records.

In console print this:

API call with NULL database connection pointer
misuse at line 139466 of [d24547a13b]
prepare: out of memory



// AppDelegate.swift

import UIKit
import SQLite3

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        
DataManager.dataManager.dbOpaquePointer = DataManager.dataManager.openDatabase(dbName: "DB.sqlite")
        
return true

}

}

// TableWord.swift

import Foundation

class TableWord{

    var idword: Int = 0
    var word: String = ""
    var features: String = ""
    var number: Int = 0
    
    init(idword: Int, word: String, features: String, number: Int) {
        self.idword = idword
        self.word = word
        self.features = features
        self.number = number
    }
    
}

// DataManager.swift

import UIKit
import SQLite3


class DataManager {
    
    static let dataManager = DataManager()

    var dbOpaquePointer: OpaquePointer?
    
    // OPEN
    func openDatabase(dbName: String) -> OpaquePointer? {
        

        let documentDirectory = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
        let fileUrl = documentDirectory?.appendingPathComponent(dbName).relativePath
        
        
        guard let part1DbPath = fileUrl else {
            print("part1DbPath is nil.")
            return nil
        }
        

        if sqlite3_open(part1DbPath, &dbOpaquePointer) == SQLITE_OK {
            print(“Open database in \(part1DbPath)")
            return dbOpaquePointer
        } else {
            print("\(Errors.SQLiteError.openDatabase)")
        }
        
        return dbOpaquePointer
        
    }
    
    
    
    // SELECT
    func selectTableWord() -> [TableWord] {
        
        let querySelectTableWord = "SELECT * FROM tableword;"
        
        var dbOpaquePointer2: OpaquePointer? = nil
        
        var dataTableWord: [TableWord] = []
        
        if sqlite3_prepare_v2(dbOpaquePointer, querySelectTableWord, -1, &dbOpaquePointer2, nil) == SQLITE_OK {
            
            while (sqlite3_step(dbOpaquePointer2) == SQLITE_ROW) {
                
                let idword = sqlite3_column_int(dbOpaquePointer2, 0)
                
                guard let queryResultCol1 = sqlite3_column_text(dbOpaquePointer2, 1) else {
                    print("\(Errors.SQLiteError.queryNil)")
                    return dataTableWord
                }
                
                let word = String(cString: queryResultCol1)
                
                guard let queryResultCol2 = sqlite3_column_text(dbOpaquePointer2, 2) else {
                    print("\(Errors.SQLiteError.queryNil)")
                    return dataTableWord
                }
                
                let features = String(cString: queryResultCol2)
                
                let number = sqlite3_column_int(dbOpaquePointer2, 3)
                
                dataTableWord.append(TableWord(idword: Int(idword), word: word, features: features, number: Int(number)))
                
            }
            
            
        } else {
            let errorMessage = String(cString: sqlite3_errmsg(dbOpaquePointer2))
            print("\(Errors.SQLiteError.prepare): \(errorMessage)")
        }
        
        sqlite3_finalize(dbOpaquePointer2)
        
        return dataTableWord
        
    }
    
    
}

// ViewController.swift

import UIKit
import SQLite3

class ViewController: UIViewController, UITextViewDelegate, UITableViewDataSource {
    
    @IBOutlet weak var resultTableView: UITableView!
    
    var db: DataManager = DataManager()
    
    var dataTableWord: [TableWord] = []

    override func viewDidLoad() {
        super.viewDidLoad()

        dataTableWord = db.selectTableWord()
        
        searchTextView.delegate = self
        resultTableView.dataSource = self
        
    }

    //MARK: - UITableViewDataSource

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataTableWord.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "idCell1Main1", for: indexPath) as! TableViewCell
        
       cell.cellLabelNumber.text = String(dataTableWord[indexPath.row].idword)
       cell.cellLabelTitle.text = dataTableWord[indexPath.row].word
       cell.cellLabelSubtitle.text = dataTableWord[indexPath.row].features

    return cell

    }

}

In viewDidLoad you call

var db: DataManager = DataManager()

Which means you are creating a new instance of DataManager instead of using the instance you created in your app delegate and that has an open database connection

You should always access your database using the static property you have created

let db = DataManager.databaseManager

To avoid mistakes like this you can add a private init to your class

private init() {}

this way you can only access it via DataManager.databaseManager

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM