Кэш по параметрам внутри устройства

Для выполнения универсального запроса к ресурсу без загрузки в базу данных создайте приложение «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»:

Примечание. При загрузке приложения выполняется аутентификация, кнопки недоступны. Если аутентификация выполнена успешно, то кнопки будут доступны и в текстовом поле появится надпись «Authentication and resources load success».

Для выполнения примера:

  1. Нажмите кнопку «TableStream without params».

При нажатии на кнопку будут получены данные из ресурса «fruits_get».

При открытии локальной базы данных в любом удобном редакторе отображается таблица с наименованием «fruits_get_<some_stuff>_output_table», где:

  1. Введите в текстовое поле значение «9999» для добавления строки через ресурс «fruits_insert_delete». Значение используется в параметрах, которые передаются при запросе «{"upsert_rows": [["9999", "NewApple9999"]], "delete_ids": null}».

  2. Нажмите кнопку «TableStream Insert».

При нажатии на кнопку возвращается измененная таблица с другим наименованием.

В локальной базе данных создается новая таблица для ресурса «fruits_insert_delete», в которой добавлена строка с идентификатором «9999».

Во время запроса tableStream были переданы параметры, хэш в названии таблицы изменился.

Примечание. При добавлении новой строки будет создана новая таблица с другим хэшем. Если запрос передается с одинаковыми параметрами, то новая таблица не создается, а перезаписывается текущая.

  1. Нажмите кнопку «TableStream without params» для обновления таблицы ресурса «fruits_get».

В таблице для ресурса «fruits_get» появилась новая строка с идентификатором «9999».

  1. Введите в текстовое поле значение «9999» для удаления строки с тем же идентификатором.

  1. Нажмите кнопку «TableStream Delete». В запросе указаны параметры «{"upsert_rows": null, "delete_ids": [["9999"]]}».

При нажатии на кнопку возвращается новая измененная таблица, так же как и при добавлении строки.

В локальной базе данных появилась новая таблица, в которой отсутствует строка с идентификатором «9999».

  1. Введите в текстовое поле значение «9999» для получения наименований таблиц.

  1. Нажмите кнопку «Get table name».

При нажатии на кнопку возвращаются наименования таблиц, которые были созданы при запросе к ресурсу «fruits_insert_delete» с параметрами «{"upsert_rows": null, "delete_ids": [["9999"]]}».

  1. Нажмите кнопку «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-фреймворка | Примеры работы с ресурсами