Здравствуйте, я реализую sqlite3 для своего быстрого приложения и моего требования, мое приложение работает онлайн и офлайн, поэтому данные, которые я получаю из своего живого API, я храню в таблице sqlite, поэтому сначала я покажу вам свой код шаг за шагом
ниже я покажу вам код, из которого я могу получить статус, если подключение к Интернету в enable или нет
Проверить код подключения к Интернету
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()
}
}
Как вы можете видеть в моем коде, когда пользователь включает Интернет, в это время я создаю таблицу базы данных, а затем, после того, как я вызываю 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 в реальном времени в таблицу базы данных, данные также вставляются успешно, но когда подключение к Интернету отключено, я извлекаю данные из таблицы, тогда я не получаю правильный вывод, как показано ниже
Сначала я покажу вам фактическое значение, которое я сохранил в таблице.
Ожидаемый результат
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 с половиной дня, но до сих пор не нашел решения, пожалуйста, помогите мне





Вы должны преобразовать свои строки в 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
}
@VishalParmar: Только изменить это для второй и третьей привязки, верно? Не для первого?
@VishalParmarL Это интересно, позвольте мне создать пример проекта и попробовать его. Дай мне минуту.
@VishalParmar Обновил мой ответ, пожалуйста, проверьте
тогда он дает мне такое предложение Value of type 'String' has no member 'utf8String'; did you mean 'utf8CString'?
и если я исправляю предложение, то после того, как я получаю такую ошибку Cannot convert value of type 'ContiguousArray<CChar>' (aka 'ContiguousArray<Int8>') to expected argument type 'UnsafePointer<Int8>?'
Хорошо, позвольте мне попробовать и сказать вам
Давайте продолжить обсуждение в чате.
Пожалуйста, помогите мне, пожалуйста, мое сообщение в чате
если я поставлю
utf8, то я получаю вот такую ошибкуCannot convert value of type 'String.UTF8View' to expected argument type 'UnsafePointer<Int8>?'