Для выполнения универсального запроса к ресурсу без загрузки в базу данных создайте приложение «HHFWCashByParams», в котором используются методы фреймворка:
Имя метода | Краткое описание |
initWithCredentials (_: host: environment: project: device:) | Метод выполняет инициализацию фреймворка. |
auth (_: password:) | Метод выполняет аутентификацию пользователя по логину и паролю. |
openBase (_: key:) | Метод открывает соединение с базой данных по указанному пути. |
resources (_: handler:) | Метод получает схемы доступных ресурсов и автоматически создает в базе данных соответствующие таблицы. |
tableStream (_: transactionID: requestCallParams: handler:) | Метод загружает табличные данные в локальную базу данных. |
getTablesName (_: resourceName: requestParams:) | Метод возвращает наименование таблицы в локальной базе данных. |
dropCache (_: resourceName: requestParams:) | Метод удаляет таблицы из базы данных. |
Вспомогательные методы:
Имя метода | Краткое описание |
getURL (for:) | Метод возвращает URL для файла с заданным именем в папке «Documents».
Тип возвращаемых данных: URL |
Перед созданием приложения убедитесь, что доступен ресурс в источнике данных PostgreSQL. Таблица содержит информацию о фруктах.
На сервере мобильной платформы содержатся два ресурса «fruits_get» и «fruits_insert_delete», которые обращаются к одной и той же таблице на удаленном сервере PostgreSQL. Ресурс «fruits_get» запрашивает и сохраняет данные и на мобильном устройстве. Ресурс «fruits_insert_delete» вставляет и удаляет строки на удаленном сервере PostgreSQL. В ответ возвращается обновленная таблица, которая записывается в локальную базу данных.
Приложение «HHFWCashByParams» состоит из одного экрана, текстового поля «UITextField», текстового представления «UITextView» и кнопок «UIButton»:
«TableStream without params». Добавление таблицы;
«TableStream Insert». Добавление строки в таблицу;
«TableStream Delete». Удаление строки из таблицы;
«Get table name». Получение наименования таблицы;
«Drop Cache». Удаление таблицы.
Примечание. При загрузке приложения выполняется аутентификация, кнопки недоступны. Если аутентификация выполнена успешно, то кнопки будут доступны и в текстовом поле появится надпись «Authentication and resources load success».
Для выполнения примера:
Нажмите кнопку «TableStream without params».
При нажатии на кнопку будут получены данные из ресурса «fruits_get».
При открытии локальной базы данных в любом удобном редакторе отображается таблица с наименованием «fruits_get_<some_stuff>_output_table», где:
fruits_get. Имя ресурса;
some_stuff. Хэш, рассчитанный из передаваемых параметров во время запроса tableStream. В данном случае хэш равен пустой строке, параметры не заданы;
output_table. Название таблицы.
Введите в текстовое поле значение «9999» для добавления строки через ресурс «fruits_insert_delete». Значение используется в параметрах, которые передаются при запросе «{"upsert_rows": [["9999", "NewApple9999"]], "delete_ids": null}».
Нажмите кнопку «TableStream Insert».
При нажатии на кнопку возвращается измененная таблица с другим наименованием.
В локальной базе данных создается новая таблица для ресурса «fruits_insert_delete», в которой добавлена строка с идентификатором «9999».
Во время запроса tableStream были переданы параметры, хэш в названии таблицы изменился.
Примечание. При добавлении новой строки будет создана новая таблица с другим хэшем. Если запрос передается с одинаковыми параметрами, то новая таблица не создается, а перезаписывается текущая.
Нажмите кнопку «TableStream without params» для обновления таблицы ресурса «fruits_get».
В таблице для ресурса «fruits_get» появилась новая строка с идентификатором «9999».
Введите в текстовое поле значение «9999» для удаления строки с тем же идентификатором.
Нажмите кнопку «TableStream Delete». В запросе указаны параметры «{"upsert_rows": null, "delete_ids": [["9999"]]}».
При нажатии на кнопку возвращается новая измененная таблица, так же как и при добавлении строки.
В локальной базе данных появилась новая таблица, в которой отсутствует строка с идентификатором «9999».
Введите в текстовое поле значение «9999» для получения наименований таблиц.
Нажмите кнопку «Get table name».
При нажатии на кнопку возвращаются наименования таблиц, которые были созданы при запросе к ресурсу «fruits_insert_delete» с параметрами «{"upsert_rows": null, "delete_ids": [["9999"]]}».
Нажмите кнопку «Drop Cache».
При нажатии на кнопку из локальной базы данных удаляются таблицы, которые были созданы при запросе к ресурсу «fruits_insert_delete» с параметрами «{"upsert_rows": null, "delete_ids": [["9999"]]}».
В локальной базе отсутствует таблица, которая была создана при добавлении новой строки.
Код приложения:
import UIKit
class ViewController: UIViewController {
// Определим выходные переменные
@IBOutlet weak var resultTextView: UITextView!
@IBOutlet weak var valueTextField: UITextField!
@IBOutlet weak var tableStreamButton: UIButton!
@IBOutlet weak var tableStreamInsertButton: UIButton!
@IBOutlet weak var tableStreamDeleteButton: UIButton!
@IBOutlet weak var getTableName: UIButton!
@IBOutlet weak var dropCacheButton: UIButton!
// Переопределим метод
override func viewDidLoad() {
super.viewDidLoad()
self.deactivateButtons()
self.initializeFramework()
self.auth {
let databaseName = "database.sqlite"
if self.openDatabase(databaseName) {
self.loadResourcesScheme(databaseName) {
self.activateButtons()
self.resultTextView.text = "Authentication and load resources success"
}
}
}
}
// Зададим метод, который будет выполняться при нажатии на кнопку
@IBAction func viewTapped(_ sender: UITapGestureRecognizer) {
self.valueTextField.resignFirstResponder()
}
@IBAction func tableStreamPressed(_ sender: UIButton) {
let databaseName = "database.sqlite"
self.tableStreamWithoutParams(databaseName) { (jsonResult) in
self.resultTextView.text = String(format: "%@", jsonResult)
}
}
@IBAction func tableStreamInsertPressed(_ sender: UIButton) {
let databaseName = "database.sqlite"
self.tableStreamInsert(databaseName) { (jsonResult) in
self.resultTextView.text = String(format: "%@", jsonResult)
}
}
@IBAction func tableStreamDeletePressed(_ sender: UIButton) {
let databaseName = "database.sqlite"
self.tableStreamDelete(databaseName) { (jsonResult) in
self.resultTextView.text = String(format: "%@", jsonResult)
}
}
@IBAction func getTableNamePressed(_ sender: UIButton) {
let databaseName = "database.sqlite"
self.resultTextView.text = self.getTableName(databaseName)
}
@IBAction func dropCachePressed(_ sender: UIButton) {
let databaseName = "database.sqlite"
self.resultTextView.text = self.dropCache(databaseName)
}
// Выполним инициализацию фреймворка
private func initializeFramework() {
let apiVersion: String = "v1"
let host: String = "http://testmasterfmp.fsight.cloud/"
let environment: String = "Leonid_environment"
let project: String = "Leonid_project"
let device: String = (UIDevice.current.identifierForVendor?.uuidString)!
HHFWController.sharedInstance().initWithCredentials(
apiVersion,
host: host,
environment: environment,
project: project,
device: device
)
}
// Выполним аутентификацию
private func auth(completion: @escaping ()->()) {
let username: String = "Leonid"
let password: String = "123123"
HHFWController.sharedInstance().auth(username, password: password){ (jsonResult) in
if let jsonDict = jsonResult as? NSDictionary,
let status = jsonDict["status"] as? String, status == "ok" {
print("Auth success")
completion()
} else {
print("Auth error")
}
}
}
// Откроем или создадим базу данных
private func openDatabase(_ databaseName: String) -> Bool {
let fullDatabaseURL = self.getURL(for: databaseName)
return HHFWController.sharedInstance().openBase(fullDatabaseURL.path, key: "")
}
// Загрузим схему ресурсов
private func loadResourcesScheme(_ databaseName: String, completion: @escaping ()->()) {
HHFWController.sharedInstance().resources(databaseName) { (jsonResult) in
if let jsonDict = jsonResult as? NSDictionary,
let status = jsonDict["status"] as? String, status == "ok" {
print("Load resources success")
completion()
} else {
print("Load resources error")
}
}
}
// Выполним запрос TableStream
private func tableStreamWithoutParams(_ databaseName: String, completion: @escaping (NSDictionary)->()) {
let resourceName = "fruits_get"
let requestCallParams = RequestCallParams(defaultDb: ())
let fullDatabaseURL = self.getURL(for: databaseName)
requestCallParams?.dataBasePath = fullDatabaseURL.path
HHFWController.sharedInstance().tableStream(resourceName, transactionID: nil, tableCallParams: requestCallParams) { (jsonResult) in
if let jsonDict = jsonResult as? NSDictionary,
let status = jsonDict["status"] as? String, status == "ok" {
print("Load table success")
completion(jsonDict)
} else {
print("Load table error")
}
}
}
private func tableStreamInsert(_ databaseName: String, completion: @escaping (NSDictionary)->()) {
guard let value = self.valueTextField.text else {return}
let resourceName = "fruits_insert_delete"
let requestCallParams = RequestCallParams(defaultDb: ())
let fullDatabaseURL = self.getURL(for: databaseName)
requestCallParams?.dataBasePath = fullDatabaseURL.path
requestCallParams?.data = "{\"upsert_rows\": [[\"" + value + "\", \"NewApple" + value + "\"]], \"delete_ids\": null}"
HHFWController.sharedInstance().tableStream(resourceName, transactionID: nil, tableCallParams: requestCallParams) { (jsonResult) in
if let jsonDict = jsonResult as? NSDictionary,
let status = jsonDict["status"] as? String, status == "ok" {
print("Load table success")
completion(jsonDict)
} else {
print("Load table error")
}
}
}
private func tableStreamDelete(_ databaseName: String, completion: @escaping (NSDictionary)->()) {
guard let value = self.valueTextField.text else {return}
let resourceName = "fruits_insert_delete"
let requestCallParams = RequestCallParams(defaultDb: ())
let fullDatabaseURL = self.getURL(for: databaseName)
requestCallParams?.dataBasePath = fullDatabaseURL.path
requestCallParams?.data = "{\"upsert_rows\": null, \"delete_ids\": [[\"" + value + "\"]]}"
HHFWController.sharedInstance().tableStream(resourceName, transactionID: nil, tableCallParams: requestCallParams) { (jsonResult) in
if let jsonDict = jsonResult as? NSDictionary,
let status = jsonDict["status"] as? String, status == "ok" {
print("Load table success")
completion(jsonDict)
} else {
print("Load table error")
}
}
}
// Получим имена таблиц в локальной базе данных
private func getTableName(_ databaseName: String) -> String? {
guard let value = self.valueTextField.text else {return nil}
let resourceName = "fruits_insert_delete"
let params = "{\"upsert_rows\": [[\"" + value + "\", \"NewApple" + value + "\"]], \"delete_ids\": null}"
return HHFWController.sharedInstance().getTablesName("/Documents/\(databaseName)", resourceName: resourceName, requestParams: params, tableName: "")
}
// Очистим кэш
private func dropCache(_ databaseName: String) -> String? {
guard let value = self.valueTextField.text else {return nil}
let resourceName = "fruits_insert_delete"
let params = "{\"upsert_rows\": [[\"" + value + "\", \"NewApple" + value + "\"]], \"delete_ids\": null}"
return HHFWController.sharedInstance().dropCache("/Documents/\(databaseName)", resourceName: resourceName, requestParams: params)
}
// Вызовем вспомогательные классы
private func getURL(for fileName: String) -> URL {
let paths: [URL] = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let fileURL: URL = paths[0].appendingPathComponent(fileName)
return fileURL
}
// Зададим методы для отображения элементов пользовательского интерфейса приложения
private func deactivateButtons() {
self.tableStreamButton.isEnabled = false
self.tableStreamInsertButton.isEnabled = false
self.tableStreamDeleteButton.isEnabled = false
self.getTableName.isEnabled = false
self.dropCacheButton.isEnabled = false
}
private func activateButtons() {
self.tableStreamButton.isEnabled = true
self.tableStreamInsertButton.isEnabled = true
self.tableStreamDeleteButton.isEnabled = true
self.getTableName.isEnabled = true
self.dropCacheButton.isEnabled = true
}
}
См. также:
Примеры использования iOS-фреймворка | Примеры работы с ресурсами