Rev 15 | Rev 19 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
//
// SyncAdapter.swift
// twogetskills
//
// Created by Efrain Yanez Recanatini on 2/24/22.
//
import Foundation
import Foundation
import Alamofire
import SwiftyJSON
class SyncAdapter
{
private var appData = AppData.sharedInstance
private let syncDao : SyncDao = SyncDao()
private var inProgress = false;
@objc func updateTimerForeground() {
if inProgress {
return
}
inProgress = true
let myQue = DispatchQueue(label: "syncQuueForeground")
myQue.async {
if self.isCheckChangesRequired() {
self.checkChanges(isForeground:true) { success in
self.inProgress = false;
}
} else {
self.sync(isForeground: true) { success in
self.inProgress = false;
}
}
}
}
func isCheckChangesRequired() -> Bool {
if !appData.userUuid.isEmpty && !appData.maxDateChanges.isEmpty {
let formatterService = DateFormatter()
formatterService.dateFormat = Constants.FORMAT_DATETIME_SERVICE
guard let lastCheckChanges = formatterService.date(from: appData.lastCheckChanges) else {
let now = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = Constants.FORMAT_DATETIME_SERVICE
let dateOn = dateFormatter.string(from: now)
appData.lastCheckChanges = dateOn
appData.save()
return false
}
let now = Date()
let diffComponents = Calendar.current.dateComponents([.minute], from: lastCheckChanges, to: now)
let minutes = diffComponents.minute!
return minutes > Constants.SYNC_CHECK_CHANGES_PERIOD
}
return false
}
func checkChanges(isForeground : Bool, completionHandler : @escaping (_ success : Bool) -> Void) {
if syncDao.countPendingRecords() > 0 {
completionHandler(true)
}
var parameters = [String : String]()
parameters[Constants.POST_MICROLEARNING_CHECK_CHANGES_FIELD_APPLICATION_ID] = "\(Config.APPLICATION_ID)"
parameters[Constants.POST_MICROLEARNING_CHECK_CHANGES_FIELD_VARIANT_ID] = "\(Config.VARIANT_ID)"
parameters[Constants.POST_MICROLEARNING_CHECK_CHANGES_FIELD_DEVICE_UUID] = appData.deviceUuid
parameters[Constants.POST_MICROLEARNING_CHECK_CHANGES_FIELD_MAX_DATE_CHANGES] = appData.maxDateChanges
parameters[Constants.POST_MICROLEARNING_CHECK_CHANGES_FIELD_IS_FOREGROUND] = isForeground ? "1" : "0"
let capsuleDao = CapsuleDao()
let capsules : [CapsuleModel] = capsuleDao.selectAll()
parameters[Constants.POST_MICROLEARNING_CHECK_CHANGES_FIELD_MAX_IDS] = String(capsules.count)
var i : Int = 0
while i < capsules.count {
parameters["\(Constants.POST_MICROLEARNING_CHECK_CHANGES_FIELD_ID)\(i+1)"] = "\(capsules[i].topicUuid)" + "|" + "\(capsules[i].uuid)"
i += 1
}
// print(parameters)
let headerSecurity : HeaderSecurity = HeaderSecurity()
let headers: HTTPHeaders = [
.init(name: Constants.HTTP_HEADER_SECURITY_TOKEN, value: appData.deviceUuid),
.init(name: Constants.HTTP_HEADER_SECURITY_SECRET, value: headerSecurity.secret),
.init(name: Constants.HTTP_HEADER_SECURITY_CREATED, value: String(headerSecurity.created)),
.init(name: Constants.HTTP_HEADER_SECURITY_RAND, value: String(headerSecurity.rand)),
.accept(Constants.HTTP_HEADER_ACCEPT)
]
AF.request(Config.URL_CHECK_CHANGES, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON {response in
switch response.result {
case .success:
let result = try? JSON(data: response.data!)
if result?["success"] ?? "" != false{
if result?["data"] ?? "" != "" {
let now = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = Constants.FORMAT_DATETIME_SERVICE
let dateOn = dateFormatter.string(from: now)
let max_date_changes = result!["data"]["max_date_changes"].string ?? ""
let snew_capsules = result!["data"]["new_capsules"].string ?? ""
let new_capsules = Int(snew_capsules) ?? 0
var processChanges = new_capsules > 0
processChanges = processChanges || self.appData.maxDateChanges != max_date_changes
if processChanges {
self.appData.maxDateChanges = max_date_changes
}
self.appData.lastCheckChanges = dateOn
self.appData.save()
if new_capsules > 0 {
let userinfo = ["new_capsules" : String(new_capsules), "is_foreground" : (isForeground ? "1" : "0")]
NotificationCenter.default.post(name: Constants.NOTIFICATION_NAME_COMMAND_REFRESH_CONTENT , object: self, userInfo: userinfo)
}
if result?["data"]["rating_and_comments"] ?? "" != "" {
let capsuleDao = CapsuleDao()
var capsuleModel : CapsuleModel
for ratingAndComment in result!["data"]["rating_and_comments"] {
let uuid = ratingAndComment.1["uuid"].string ?? ""
let total_comments = Int(ratingAndComment.1["total_comments"].string ?? "0") ?? 0
let total_rating = Decimal(Double(ratingAndComment.1["total_rating"].string ?? "0") ?? 0)
if !uuid.isEmpty {
capsuleModel = capsuleDao.selectByUuid(uuid: uuid)
capsuleModel.totalRating = total_rating
capsuleModel.totalComments = total_comments
capsuleDao.update(capsule: capsuleModel)
}
}
}
}
}
break
case .failure:
// print("JSON = \(String(describing: Error.self))")
break
}
}
completionHandler(true)
}
func sync(isForeground : Bool, completionHandler : @escaping (_ success : Bool) -> Void) {
let recordsSync = syncDao.selectBatch()
//print(recordsSync)
if recordsSync.count > 0 {
var availableForOtherOperation = true;
for recordSync in recordsSync
{
if recordSync.type == Constants.SYNC_ADAPTER_TYPE_DEVICE {
availableForOtherOperation = false
registerDevice(record: recordSync)
}
else if availableForOtherOperation && recordSync.type == Constants.SYNC_ADAPTER_TYPE_FCM {
availableForOtherOperation = false
registerFcm(record: recordSync)
}
}
if(availableForOtherOperation) {
var parameters = [ String: String ]()
var i : Int = 0
for recordSync in recordsSync
{
if recordSync.type == Constants.SYNC_ADAPTER_TYPE_SYNC {
i += 1
let keyData = Constants.POST_SYNC_BATCH_FIELD_RECORD_DATA + String(i);
let keySyncId = Constants.POST_SYNC_BATCH_FIELD_RECORD_SYNC_ID + String(i);
//print("keyData = \(keyData) keySincId = \(keySyncId)")
parameters["\(keyData)"] = "\(recordSync.data)"
parameters["\(keySyncId)"] = String(recordSync.id)
}
}
if i > 0 {
parameters[Constants.POST_SYNC_BATCH_FIELD_MAX_RECORDS] = "\(i)"
parameters[Constants.POST_SYNC_BATCH_FIELD_DEVICE_UUID] = appData.deviceUuid
parameters[Constants.POST_SYNC_BATCH_FIELD_APPLICATION_ID] = "\(Config.APPLICATION_ID)"
parameters[Constants.POST_SYNC_BATCH_FIELD_VARIANT_ID] = "\(Config.VARIANT_ID)"
sendSyncBatch(parameters: parameters)
}
}
}
completionHandler(true)
}
func sendSyncBatch(parameters : [String : String])
{
print("Send Sync Batch ")
//print(parameters)
let headers: HTTPHeaders = [
.accept(Constants.HTTP_HEADER_ACCEPT)
]
AF.request(Config.URL_SYNC_BATCH, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON {response in
switch response.result {
case .success:
let result = try? JSON(data: response.data!)
if result?["success"] ?? "" != false{
if result?["data"] != "" {
for sync in result!["data"] {
//let success = sync.1["success"].string ?? ""
let sync_id = Int(sync.1["sync_id"].string ?? "0") ?? 0
if sync_id > 0 {
self.syncDao.remove(id: sync_id)
}
}
}
}
break
case .failure:
// print("JSON = \(String(describing: Error.self))")
break
}
}
}
func sendSync(record: SyncModel)
{
let parameters = [
Constants.POST_SYNC_FIELD_APPLICATION_ID: "\(Config.APPLICATION_ID)",
Constants.POST_SYNC_FIELD_VARIANT_ID: "\(Config.VARIANT_ID)",
Constants.POST_SYNC_FIELD_DEVICE_UUID: "\(appData.deviceUuid)",
Constants.POST_SYNC_FIELD_DATA: "\(record.data)",
Constants.POST_SYNC_FIELD_SYNC_ID: "\(record.id)"
]
let headers: HTTPHeaders = [
.accept(Constants.HTTP_HEADER_ACCEPT)
]
AF.request(Config.URL_SYNC, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON {response in
//print("Send Sync ")
switch response.result {
case .success:
let result = try? JSON(data: response.data!)
if result?["success"] ?? "" != false {
let sync_id = Int(result?["data"]["sync_id"].stringValue ?? "0") ?? 0
if sync_id > 0 {
self.syncDao.remove(id: sync_id)
}
}
break
case .failure:
// print("JSON = \(String(describing: Error.self))")
break
}
}
}
func registerFcm(record: SyncModel) {
let deviceUuid = appData.deviceUuid
let parameters = [
Constants.POST_FCM_FIELD_APPLICATION_ID: "\(Config.APPLICATION_ID)",
Constants.POST_FCM_FIELD_VARIANT_ID: "\(Config.VARIANT_ID)",
Constants.POST_FCM_FIELD_DEVICE_UUID: "\(deviceUuid)",
Constants.POST_FCM_FIELD_TOKEN: "\(record.data)",
Constants.POST_FCM_FIELD_SYNC_ID: "\(record.id)"
]
let headers: HTTPHeaders = [
.accept(Constants.HTTP_HEADER_ACCEPT)
]
AF.request(Config.URL_FCM, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON{response in
print("Send FCM")
switch response.result {
case .success:
let result = try? JSON(data: response.data!)
let sync_id = Int(result?["data"]["sync_id"].stringValue ?? "0") ?? 0
if sync_id > 0 {
self.syncDao.remove(id: sync_id)
}
break
case .failure:
// print("JSON = \(String(describing: Error.self))")
break
}
}
}
func registerDevice(record: SyncModel)
{
let version = UIDevice.current.systemVersion
let model = UIDevice.current.localizedModel
let parameters = [
Constants.POST_DEVICE_FIELD_APPLICATION_ID: "\(Config.APPLICATION_ID)",
Constants.POST_DEVICE_FIELD_VARIANT_ID: "\(Config.VARIANT_ID)",
Constants.POST_DEVICE_FIELD_DEVICE_UUID: "\(record.data)",
Constants.POST_DEVICE_FIELD_MANUFACTURER: "Apple",
Constants.POST_DEVICE_FIELD_BRAND: "Apple",
Constants.POST_DEVICE_FIELD_VERSION: "\(version)",
Constants.POST_DEVICE_FIELD_MODEL: "\(model)",
Constants.POST_DEVICE_FIELD_PLATFORM: "Iphone",
Constants.POST_DEVICE_FIELD_SYNC_ID: "\(record.id)"
]
let headers: HTTPHeaders = [
.accept(Constants.HTTP_HEADER_ACCEPT)
]
print("URL DEVICE : \(Config.URL_DEVICE) ")
AF.request(Config.URL_DEVICE, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON {response in
print("Send Device: ")
switch response.result {
case .success:
let result = try? JSON(data: response.data!)
if result?["success"] ?? "" != false {
let aes = result?["data"]["aes"].stringValue ?? ""
let password = result?["data"]["password"].stringValue ?? ""
if !aes.isEmpty && !password.isEmpty {
self.appData.deviceAes = aes
self.appData.devicePassword = password
self.appData.save()
}
let sync_id = Int(result?["data"]["sync_id"].stringValue ?? "0") ?? 0
if sync_id > 0 {
self.syncDao.remove(id: sync_id)
}
}
break
case .failure:
//print("JSON = \(String(describing: Error.self))")
break
}
}
}
}