В этой статье:
Возобновление загрузки табличных данных в базу данных
Возобновление загрузки табличных данных без загрузки в базу данных
Возобновление загрузки ресурса в универсальном запросе к ресурсу
В мобильном приложении настраиваются параметры возобновления загрузки ресурса с сохранением состояния загрузки:
количество повторений загрузки ресурса;
интервал повторений в секундах.
Если во время загрузки ресурса произошла ошибка или разрыв соединения с сервером мобильной платформы, мобильное приложение будет выполнять повторные попытки запроса ресурса.
Для получения табличных данных 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»:
«Perform TableStream». Запрос табличных данных для указанного ресурса;
«Perform SELECT». SQL-запрос к локальной базе данных.
Примечание. При загрузке приложения выполняется аутентификация, кнопки недоступны. Если аутентификация выполнена успешно, то кнопки будут доступны и в текстовом поле появится надпись «Authentication and resources load success».
Для выполнения примера:
Нажмите кнопку «Perform TableStream».
При нажатии на кнопку выполняется запрос табличных данных для указанного ресурса. Результат выполнения запроса автоматически записывается в локальную базу данных.
Нажмите кнопку «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»:
«Request Table». Получение табличных данных без загрузки в базу данных.
Примечание. При загрузке приложения выполняется аутентификация, кнопка недоступна. Если аутентификация выполнена успешно, то кнопка будет доступна и в текстовом поле появится надпись «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»:
«Perform request». Выполнение запроса к ресурсу без загрузки в базу данных.
Примечание. При загрузке приложения выполняется аутентификация, кнопка недоступна. Если аутентификация выполнена успешно, то кнопка будет доступна и в текстовом поле появится надпись «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-фреймворка | Примеры работы с ресурсами