通过索引明智的问题从sqlite表中检索数据

时间:2019-03-25 06:08:56

标签: ios swift uitableview sqlite

您好,我正在为我的快速应用程序实现sqlite3,并且我的要求可以使我的应用程序在线和离线运行,因此我将从实时api获取的数据存储在sqlite表上,因此首先我将向您展示我的代码步骤一步一步

在下面,我将向您显示代码,无论是否在enable中进行互联网连接,我都可以从中获取身份

检查Internet连接代码

func checkNet(){
        NotificationCenter.default.addObserver(self,selector: #selector(statusManager),name: .flagsChanged,object:nil)
        updateUserInterface()
    }
    func updateUserInterface() {
        if Network.reachability.isReachable == true{
            print("Success")
            self.clientListData.removeAll()
            let fileURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false).appendingPathComponent("EOBA.sqlite")

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

            let createTable = "CREATE TABLE IF NOT EXISTS Client_List (id INTEGER PRIMARY KEY AUTOINCREMENT, client_id INTEGER, client_type TEXT, first_name TEXT)"

            if sqlite3_exec(db, createTable, nil, nil, nil) != SQLITE_OK{
                print("Table Not Created")
                return
            }
            print("Every Thing is Fine")

            clientList()
        }else{
            print("Offline")

            self.clientLocalData.removeAll()
            let fileURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
                .appendingPathComponent("EOBA.sqlite")


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

            let queryString = "SELECT * FROM Client_List"

            var stmt:OpaquePointer?

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

            while(sqlite3_step(stmt) == SQLITE_ROW){
                let id = sqlite3_column_int(stmt, 0)
                let client_id =  sqlite3_column_int(stmt, 1)
                let client_type =  String(cString: sqlite3_column_text(stmt, 2))
                let first_name =  String(cString: sqlite3_column_text(stmt, 3))
                print(id)
                print(client_id)
                print(client_type)
                print(first_name)

                //heroList.append(Hero(id: Int(id), name: String(describing: name), powerRanking: Int(powerrank)))
                clientLocalData.append(ClientOfflineModel(id: Int(id), client_id: String(describing: client_id), client_type: String(describing: client_type)))
                do {
                    let jsonData = try JSONEncoder().encode(clientLocalData)
                    let jsonString = String(data: jsonData, encoding: .utf8)!
                    print(jsonString)
                } catch {
                    print(error)

                }

            }

            self.tblListView.reloadData()

        }
    }

当用户当时启用Internet时,您可以在我的代码中看到,我正在创建数据库表,然后在调用API之后,现在让我向我展示我的API调用方法名称clientList()

API调用方法

    func clientList(){
        let preferences = UserDefaults.standard
        let uid = "u_id"
        let acTkn = "acc_tkn"

        let u_ID = preferences.object(forKey: uid)
        let A_Token = preferences.object(forKey: acTkn)
        let params = ["user_id": u_ID!,"access_token": A_Token!]
        print(params)
        self.viewMainSpinner.isHidden = false
        self.viewSpinnerInner.startAnimating()
        Alamofire.request(clientlist, method: .post, parameters: params).responseJSON(completionHandler: {(response) in
            switch response.result{
            case.success(let value):
                let json  = JSON(value)
                print(json)
                let data = json["client_list"]
                print(data)
                if data == []{
                    //self.viewNodata.isHidden = false
                }else{
                    data.array?.forEach({ (cList) in
                        let client_List = ClientList(updated_by: cList["updated_by"].stringValue,client_id: cList["client_id"].stringValue, first_name: cList["first_name"].stringValue,address2: cList["address2"].stringValue,country: cList["country"].stringValue, status: cList["status"].stringValue, address1: cList["address1"].stringValue, created_date: cList["created_date"].stringValue, last_name: cList["last_name"].stringValue, email: cList["email"].stringValue, photo: cList["photo"].stringValue, created_by: cList["created_by"].stringValue,client_type: cList["client_type"].stringValue,phone_number: cList["phone_number"].stringValue,zipcode: cList["zipcode"].stringValue,address3: cList["address3"].stringValue,updated_date: cList["updated_date"].stringValue,city: cList["city"].stringValue,state: cList["state"].stringValue,gender: cList["gender"].stringValue,rtb_reg_number: cList["rtb_reg_number"].stringValue)



                        let client_id = cList["client_id"].stringValue
                        let client_type = cList["client_type"].stringValue
                        let first_name = cList["first_name"].stringValue

                        print(client_type)
                        var stmt: OpaquePointer?

                        let insertQuery = "INSERT INTO Client_List (client_id, client_type, first_name) VALUES (?,?,?)"

                        if sqlite3_prepare(self.db, insertQuery, -1, &stmt, nil) != SQLITE_OK{
                            print("Error Binding Query")
                        }

                        if sqlite3_bind_int(stmt, 1, (client_id as NSString).intValue) != SQLITE_OK{
                                let errmsg = String(cString: sqlite3_errmsg(self.db)!)
                                print("failure binding name: \(errmsg)")
                                return
                        }
                        if sqlite3_bind_text(stmt, 2, client_type, -2, nil) != SQLITE_OK{
                            let errmsg = String(cString: sqlite3_errmsg(self.db)!)
                            print("failure binding name: \(errmsg)")
                            return
                        }

                        if sqlite3_bind_text(stmt, 3, first_name, -3, nil) != SQLITE_OK{
                            let errmsg = String(cString: sqlite3_errmsg(self.db)!)
                            print("failure binding name: \(errmsg)")
                            return
                        }

                        if sqlite3_step(stmt) == SQLITE_DONE{
                            print("table Saved Successfully")
                        }

                        self.clientListData.append(client_List)

                    })
                    self.tblListView.reloadData()
                }

                self.viewMainSpinner.isHidden = true
                self.viewSpinnerInner.stopAnimating()
            case.failure(let error):
                print(error.localizedDescription)
            }
        })
    }

现在,如您所见,在api调用时,我正在将活动api数据插入数据库表中的数据也已成功插入,但是当Internet连接被禁用时,我正在从表中检索数据,那么我无法正确输出数据,就像低于

首先,我向您显示保存在表上的实际值

预期产量

id: 1
client_id: 2
client_type: Local Authority
first_name: Lorem

我得到的输出

id: 1
client_id: 2
client_type: ��
first_name : ��

有时候我会得到如下输出

id: 1
client_id: 2
client_type: lorem
first_name : lorem

您可以看到在第三列中花了一些时间,我在两个字段中都获得了first_name值

我花了1天半的时间,但仍然没有得到解决方案,请有人帮我

1 个答案:

答案 0 :(得分:1)

在绑定之前,您应该将字符串转换为utf8。如下更改您的字符串绑定代码:

if sqlite3_bind_text(stmt, 2, (client_type as NSString).utf8String, -1, nil) != SQLITE_OK{
   let errmsg = String(cString: sqlite3_errmsg(self.db)!)
   print("failure binding name: \(errmsg)")
   return
}

if sqlite3_bind_text(stmt, 3, (first_name as NSString).utf8String, -1, nil) != SQLITE_OK{
   let errmsg = String(cString: sqlite3_errmsg(self.db)!)
   print("failure binding name: \(errmsg)")
   return
}