В этой статье:

Возобновление загрузки табличных данных в базу данных

Возобновление загрузки табличных данных без загрузки в базу данных

Возобновление загрузки ресурса в универсальном запросе к ресурсу

Возобновление загрузки ресурса

В мобильном приложении настраиваются параметры возобновления загрузки ресурса с сохранением состояния загрузки:

Если во время загрузки ресурса произошла ошибка или разрыв соединения с сервером мобильной платформы, мобильное приложение будет выполнять повторные попытки запроса ресурса.

Возобновление загрузки табличных данных в базу данных

Для получения табличных данных c загрузкой в базу данных создайте приложение «HHFWTableStreamRetry», в котором используются методы фреймворка:

Имя метода Краткое описание
initWithCredentials (_: host: environment: project: device:) Метод выполняет инициализацию фреймворка.
setDownloadPath(_:) Метод устанавливает путь к папке в директории мобильного приложения, где будут храниться файлы докачки.
auth (_: password:) Метод выполняет аутентификацию пользователя по логину и паролю.
openBase (_: key:) Метод открывает соединение с базой данных по указанному пути.
resources (_: password: handler:) Метод получает схемы доступных ресурсов и автоматически создает в базе данных соответствующие таблицы.
useDownload(_:) Метод включает или выключает возобновление загрузки ресурса.
tableStream (_: withCache: transactionID: tableCallParams: handler:) Метод загружает табличные данные в локальную базу данных.
getTablesName (_: resourceName: requestParams: tableName:) Метод возвращает наименование таблицы в локальной базе данных.
query (_: query:) Метод отправляет SQL-запрос к локальной базе данных.

Вспомогательные методы:

Имя метода Краткое описание
getURL (for:) Метод возвращает URL для файла с заданным именем в папке «Documents».
Тип возвращаемых данных: URL.
getRecords (from:) Метод возвращает значение для ключа «records» из json-результата SQL-запроса к локальной базе данных.
Тип возвращаемых данных: [[String: Any]]?
getTableNames (from:) Метод возвращает массив значений для ключей «name» из результата метода getRecords.
Тип возвращаемых данных: [String].
parseServerJSONResponse (json:) Метод возвращает результат преобразования json-строки в словарь.
Тип возвращаемых данных: [String: Any]?
getResponseStatus (from:) Метод возвращает значение для ключа «status» из json-результата запроса.
Тип возвращаемых данных: String?
getTableNamesInDatabase (_: forResource: originalTableName:) Метод возвращает массив имен таблиц, которые удовлетворяют указанным параметрам: расположение базы данных в директории приложения, имя ресурса и искомой таблицы.
Тип возвращаемых данных: [String].

Для установки количества повторений и интервала между ними используются свойства retryCount и retryIntervalSec экземпляра класса TableCallParams, который передается в качестве параметра в метод table.

Приложение «HHFWTableStreamRetry» состоит из одного экрана, текстового представления «UITextView» и кнопок «UIButton»:

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

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

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

При нажатии на кнопку выполняется запрос табличных данных для указанного ресурса. Результат выполнения запроса автоматически записывается в локальную базу данных.

  1. Нажмите кнопку «Perform SELECT».

При нажатии на кнопку выполняется SQL-запрос «SELECT * FROM table_name» к локальной базе данных.

Код приложения:

import UIKit
 
class ViewController: UIViewController {
 
    // Определим выходные данные
    @IBOutlet weak var resultTextView: UITextView!
    @IBOutlet weak var tableStreamButton: UIButton!
    @IBOutlet weak var queryButton: 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 tableStreamPressed(_ sender: UIButton) {
        let databaseName = "database.sqlite"
        self.loadTable(databaseName) { (jsonResult) in
            self.resultTextView.text = String(format: "%@", jsonResult)
        }
    }
 
    @IBAction func selectFromTablePressed(_ sender: Any?) {
        let databaseName = "database.sqlite"
        self.performSelect(databaseName, completion: { (jsonResult) in
            self.resultTextView.text = jsonResult
        })
    }
 
    // Выполним инициализацию фреймворка
    private func initializeFramework() {
        let apiVersion: String = "v1"
        let host: String = "http://testmasterfmp.fsight.cloud/"
        let environment: String = "DocumentationExampleEnv"
        let project: String = "DocumentationExampleProj"
        let device: String = (UIDevice.current.identifierForVendor?.uuidString)!
        HHFWController.sharedInstance().initWithCredentials(
            apiVersion,
            host: host,
            environment: environment,
            project: project,
            device: device
        )
        let fileFolderPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).paths[0].appendingPathComponent("FilesForDownload", isDirectory: true).path
        HHFWController.sharedInstance().setDownloadPath(fileFolderPath)
    }
 
    // Выполним аутентификацию
    private func auth(completion: @escaping ()->()) {
        let username: String = "test"
        let password: String = "test123"
        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, password: "") { (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 loadTable(_ databaseName: String, completion: @escaping (NSDictionary)->()) {
        let resourceName = "FRUITS"
        let requestCallParams = RequestCallParams(defaultDb: ())
        let fullDatabaseURL = self.getURL(for: databaseName)
        requestCallParams?.dataBasePath = fullDatabaseURL.path
        requestCallParams?.retryCount = 10
        requestCallParams?.retryIntervalSec = 1
        HHFWController.sharedInstance().useDownload(true)
        HHFWController.sharedInstance().tableStream(resourceName, withCache: true, 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")
            }
        }
        HHFWController.sharedInstance().useDownload(false)
    }
 
    // Выполним запрос SELECT * FROM table
    private func performSelect(_ databaseName: String, completion: (String?) -> ()) {
        let resourceName = "FRUITS"
        let tableName = "output_table"
        if let databaseTableName = self.getTableNamesInDatabase(databaseName, forResource: resourceName, originalTableName: tableName).first {
            let query = "SELECT * FROM `\(databaseTableName)`"
            let jsonResult = HHFWController.sharedInstance().query("/Documents/\(databaseName)", query: query)
            completion(jsonResult)
        }
    }
 
    // Получим имена таблиц в локальной базе данных
    private func getTableNamesInDatabase(_ databaseName: String, forResource resourceName: String, originalTableName tableName: String) -> [String] {
        let tableNames = HHFWController.sharedInstance().getTablesName("/Documents/\(databaseName)", resourceName: resourceName, requestParams: "", tableName: tableName)
        return self.getTableNames(from: tableNames)
    }
 
    // Зададим методы для отображения элементов пользовательского интерфейса приложения
    private func deactivateButtons() {
        self.tableStreamButton.isEnabled = false
        self.queryButton.isEnabled = false
    }
 
    private func activateButtons() {
        self.tableStreamButton.isEnabled = true
        self.queryButton.isEnabled = true
    }
 
    // Вызовем вспомогательные классы
    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 getRecords(from json: String?) -> [[String: Any]]? {
        var resultRecords: [[String: Any]]? = nil
        if let jsonString = json {
            let jsonDict = parseServerJSONResponse(json: jsonString)
            if self.getResponseStatus(from: jsonDict) == "ok" {
                if let result = jsonDict?["result"] as? [String: Any],
                    let database = result["database"] as? [String:Any],
                    let records = database["records"] as? [[String: Any]] {
                    resultRecords = records
                }
            }
        }
        return resultRecords
    }
 
    private func getTableNames(from json: String?) -> [String] {
        var resultTableNames: [String] = []
        if let records = getRecords(from: json) {
            for record in records {
                if let tableName = record["name"] as? String {
                    resultTableNames.append(tableName)
                }
            }
        }
        return resultTableNames
    }
 
    private func parseServerJSONResponse(json: String) -> [String: Any]? {
        guard let responseData = json.data(using: .utf8) else { return nil }
        return try? JSONSerialization.jsonObject(with: responseData, options: []) as! [String: Any]
    }
 
    func getResponseStatus(from json: [String: Any]?) -> String? {
        return json?["status"] as? String
    }
}

Возобновление загрузки табличных данных без загрузки в базу данных

Для получения табличных данных без загрузки в базу данных создайте приложение «HHFWTableRetry», в котором используются методы фреймворка:

Имя метода Краткое описание
initWithCredentials (_: host: environment: project: device:) Метод выполняет инициализацию фреймворка.
auth (_: password:) Метод выполняет аутентификацию пользователя по логину и паролю.
table (_: transactionID: tableCallParams: handler:) Метод возвращает табличные данные ресурса без загрузки в базу данных.

Для установки количества повторений и интервала между ними используются свойства retryCount и retryIntervalSec экземпляра класса TableCallParams, который передается в качестве параметра в метод table.

Приложение «HHFWTableRetry» состоит из одного экрана, текстового представления «UITextView» и кнопки «UIButton»:

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

Для выполнения примера нажмите кнопку «Request Table». При нажатии на кнопку инициализируется запрос к ресурсу. Сервер мобильной платформы возвращает соответствующие табличные данные без загрузки в базу данных.

Код приложения:

import UIKit
 
class ViewController: UIViewController {
 
    // Определим выходные данные
    @IBOutlet weak var resultTextView: UITextView!
    @IBOutlet weak var tableRequestButton: UIButton!
 
    // Переопределим метод
    override func viewDidLoad() {
        super.viewDidLoad()
        self.deactivateButtons()
        self.initializeFramework()
        self.auth {
            self.activateButtons()
            self.resultTextView.text = "Authentication success"
        }
    }
 
    // Зададим метод, который будет выполняться при нажатии на кнопку
    @IBAction func tableRequestPressed(_ sender: UIButton) {
        self.tableRequest { (jsonResult) in
            self.resultTextView.text = String(format: "%@", jsonResult)
        }
    }
 
    // Выполним инициализацию фреймворка
    private func initializeFramework() {
        let apiVersion: String = "v1"
        let host: String = "http://testmasterfmp.fsight.cloud/"
        let environment: String = "DocumentationExampleEnv"
        let project: String = "DocumentationExampleProj"
        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 = "test"
        let password: String = "test123"
        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")
            }
        }
    }
 
    // Выполним запрос Table
    private func tableRequest(completion: @escaping (NSDictionary)->()) {
        let resourceName = "FRUITS"
        let tableCallParams = TableCallParams(defaultProperty: ())
        tableCallParams?.retryCount = 10
        tableCallParams?.retryIntervalSec = 1
        HHFWController.sharedInstance().table(resourceName, transactionID: nil, tableCallParams: tableCallParams) { (jsonResult) in
            if let jsonDict = jsonResult as? NSDictionary,
                let status = jsonDict["status"] as? String, status == "ok" {
                print("Table request success")
                completion(jsonDict)
            } else {
                print("Table request error")
            }
        }
    }
 
    // Зададим методы для отображения элементов пользовательского интерфейса приложения
    private func deactivateButtons() {
        self.tableRequestButton.isEnabled = false
    }
 
    private func activateButtons() {
        self.tableRequestButton.isEnabled = true
    }
}

Возобновление загрузки ресурса в универсальном запросе к ресурсу

Для выполнения универсального запроса к ресурсу без загрузки в базу данных создайте приложение «HHFWRequestRetry», в котором используются методы фреймворка:

Имя метода Краткое описание
initWithCredentials (_: host: environment: project: device:) Метод выполняет инициализацию фреймворка.
auth (_: password:) Метод выполняет аутентификацию пользователя по логину и паролю.
request (_: requestCallParams: handler:) Метод отправляет универсальный запрос к ресурсу без загрузки в базу данных.

Для установки количества повторений и интервала между ними используются свойства retryCount и retryIntervalSec экземпляра класса RequestCallParams, который передается в качестве параметра в метод request.

Приложение «HHFWRequestRetry» состоит из одного экрана, текстового представления «UITextView» и кнопки «UIButton»:

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

Для выполнения примера нажмите кнопку «Perform request». При нажатии на кнопку инициализируется запрос к ресурсу. Сервер мобильной платформы возвращает соответствующие данные.

Код приложения:

import UIKit
 
class ViewController: UIViewController {
 
    // Определим выходные данные
    @IBOutlet weak var resultTextView: UITextView!
    @IBOutlet weak var requestButton: UIButton!
 
    // Переопределим метод
    override func viewDidLoad() {
        super.viewDidLoad()
        self.deactivateButtons()
        self.initializeFramework()
        self.auth {
            self.activateButton()
            self.resultTextView.text = "Authentication success"
        }
    }
 
    // Зададим метод, который будет выполняться при нажатии на кнопку
    @IBAction func requestPressed(_ sender: UIButton) {
        self.performRequest { (jsonDict) in
            self.resultTextView.text = String(format: "%@", jsonDict)
        }
    }
 
    // Выполним инициализацию фреймворка
    private func initializeFramework() {
        let apiVersion: String = "v1"
        let host: String = "http://testmasterfmp.fsight.cloud/"
        let environment: String = "DocumentationExampleEnv"
        let project: String = "DocumentationExampleProj"
        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 = "test"
        let password: String = "test123"
        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")
            }
        }
    }
 
    // Выполним запрос Request
    private func performRequest(completion: @escaping (NSDictionary)->()) {
        let resourceName = "FRUITS"
        let requestCallParams = RequestCallParams(defaultProperty: ())
        requestCallParams?.retryCount = 10
        requestCallParams?.retryIntervalSec = 1
        HHFWController.sharedInstance().request(resourceName, requestCallParams: requestCallParams) { (jsonResult) in
            if let jsonDict = jsonResult as? NSDictionary,
                let status = jsonDict["status"] as? String, status == "ok" {
                print("Request success")
                completion(jsonDict)
            } else {
                print("Request error")
            }
        }
    }
 
    // Зададим методы для отображения элементов пользовательского интерфейса приложения
    private func deactivateButtons() {
        self.requestButton.isEnabled = false
    }
 
    private func activateButton() {
        self.requestButton.isEnabled = true
    }
}

См. также:

Примеры использования iOS-фреймворка | Примеры работы с ресурсами