Получение столбца из SQLite в метку в ячейке табличного представления Swift iOS

Я получаю все значения столбца formname в titleLabel в ячейке таблицы, но, к сожалению, я сталкиваюсь с этими двумя ошибками

Вызов может бросить, но он не помечен как «попытка», и ошибка не обрабатывается

и это

Вызов может бросить, но он не помечен как «попытка», и ошибка не обрабатывается

на этих линиях ниже указанного класса.

Вот другие классы моделей данных

введите описание изображения здесь

import UIKit
import SQLite
import SQLite3

@available(iOS 11.0, *)
class ViewViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

var fileURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
    .appendingPathComponent("Stephencelis.sqlite")


let forms = Table("FormTable")

var cities : [String]?
var dbd: Connection?

var heroList = [FormDatabase]()
var db : OpaquePointer?
var stmt:OpaquePointer?

var formidV = Int64()
var formnameV = String()
var formdescriptionV = String()
var formdateV = String()

@IBOutlet weak var menu: UIBarButtonItem!
@IBOutlet weak var viewTableView: UITableView!
@IBOutlet weak var dateStringLabelView: UILabel!



private init() {
    let path = NSSearchPathForDirectoriesInDomains(
        .documentDirectory, .userDomainMask, true
        ).first!

    do {
        dbd = try Connection("\(path)/Stephencelis.sqlite3")
    } catch {
        dbd = nil
        print ("Unable to open database")
    }
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}



func readValues(){

    heroList.removeAll()

    //this is our select query
    let queryString = "SELECT * FROM AuditorTable"

    //statement pointer
    var stmt:OpaquePointer?

    //preparing the query
    if sqlite3_prepare(db, queryString, -1, &stmt, nil) != SQLITE_OK{
        let errmsg = String(cString: sqlite3_errmsg(db)!)
        print("error preparing insert: \(errmsg)")
        return
    }

    //traversing through all the records
    while(sqlite3_step(stmt) == SQLITE_ROW){
        let formidC = sqlite3_column_int(stmt, 0)
        let formnameC = String(cString: sqlite3_column_text(stmt, 1))
        let formdescriptionC = String(cString: sqlite3_column_text(stmt, 2))
        let formcategoryC = String(cString: sqlite3_column_text(stmt, 3))
         let formdateC = String(cString: sqlite3_column_text(stmt, 4))

        //adding values to list
        heroList.append(FormDatabase(formid: Int64(formidC), formname: String(describing: formnameC), formdescription: String(describing: formdescriptionC), formcategory: String(describing: formcategoryC), formdate: String(describing: formdateC)))
    }
}

var numberofrowsinColumn = String()
func countValues(){

    //first empty the list of heroes
    //heroList.removeAll()

    //this is our select query
    let queryString = "SELECT COUNT(*) FROM AuditorTable"

    //statement pointer
    var stmt:OpaquePointer?

    //preparing the query
    if sqlite3_prepare(db, queryString, -1, &stmt, nil) != SQLITE_OK{
        let errmsg = String(cString: sqlite3_errmsg(db)!)
        print("error preparing insert: \(errmsg)")
        return
    }

    //traversing through all the records
    while(sqlite3_step(stmt) == SQLITE_ROW){
        let formidC = sqlite3_column_int(stmt, 0)
        let formnameC = String(cString: sqlite3_column_text(stmt, 1))
        let formdescriptionC = String(cString: sqlite3_column_text(stmt, 2))
        let formcategoryC = String(cString: sqlite3_column_text(stmt, 3))
        let formdateC = String(cString: sqlite3_column_text(stmt, 4))
        //adding values to list
        heroList.append(FormDatabase(formid: Int64(formidC), formname: String(describing: formnameC), formdescription: String(describing: formdescriptionC), formcategory: String(describing: formcategoryC), formdate: String(describing: formdateC)))
        numberofrowsinColumn = queryString
    }
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
   // return heroList.count
    if cities == nil {
        return 0
    }
    return cities!.count

}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = viewTableView.dequeueReusableCell(withIdentifier: "ViewTableViewCell") as! ViewTableViewCell

    cell.titleLabel?.text = self.cities?[indexPath.row]



    cities = [String]()

    for row in (try dbd?.prepare(forms))! {

       try? cities!.append(row[0] as! String)





override func viewDidLoad() {
    super.viewDidLoad()


    if sqlite3_open(fileURL.path, &db) != SQLITE_OK {
        print("error opening database")
    }


    viewTableView.delegate = self
    viewTableView.dataSource = self
    viewTableView.reloadData()


}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


}

person iOS Developer    schedule 16.02.2018    source источник


Ответы (2)


Вам нужно изменить свой код на что-то вроде:

let statement = try! dbd?.prepare(forms) 
for row in statement {
    if let city = row[0] as? String {
        cities?.append(city)
    }
}
person HereTrix    schedule 16.02.2018
comment
это показывает ошибку при попытке? строка Не может подписать значение типа «Row» индексом типа «Int» - person iOS Developer; 16.02.2018
comment
@Moritz Я получаю сообщение об ошибке: невозможно индексировать значение типа «Row» с индексом типа «Int». - person iOS Developer; 16.02.2018

Вы используете метод:

func prepare(_ query: QueryType) throws -> AnySequence<Row>

С этим методом вы не можете использовать row[0], вам нужно использовать метод row.get(Expression<V>), который кажется именем столбца.

Метод, который вы пытаетесь использовать:

public func prepare(_ statement: String, _ bindings: Binding?...) throws -> Statement

С помощью этой функции вы можете использовать row[0]

Чтобы быть немного более ясным, у вас есть две возможности.

1

let forms = Table("FormTable")
...

cities = [String]()
if let connection = dbd {
    for row in try connection.prepare(forms) {
        // I'm not entirely sure about the way to use Expression
        let columnName = Expression<String>("COLUMN_NAME")
        try cities!.append(row.get(columnName))
    }
}

2

cities = [String]()
if let connection = dbd {
    for row in connection.prepare("SELECT * FROM FormTable") {
        try? cities!.append(row[0] as! String)
    }
}

Я пришел к этому решению, прочитав исходный код.

Я надеюсь, что это поможет вам.

person Xavier Bauquet    schedule 19.02.2018
comment
спасибо, Ксавье, но я получаю сообщение об ошибке из решения варианта 1, что в строке try я нашел эту ошибку - person iOS Developer; 19.02.2018
comment
Вы всегда должны обрабатывать ошибки. Вам нужно добавить способ обработки ошибок для каждого try и для if let connection = dbd. - person Xavier Bauquet; 19.02.2018
comment
та же ошибка во втором решении, не могли бы вы сделать что-нибудь, пожалуйста - person iOS Developer; 19.02.2018
comment
Ваш код с открытым исходным кодом, поэтому я могу посмотреть на него, чтобы увидеть, что не так? Убедитесь, что база данных существует и не пуста. - person Xavier Bauquet; 19.02.2018
comment
Давайте продолжим обсуждение в чате. - person Xavier Bauquet; 19.02.2018
comment
база данных существует и таблица существует, но код находится здесь по указанной ссылке в описании вопроса см. ссылку - person iOS Developer; 19.02.2018