Proyectos de Subversion Iphone Microlearning - Inconcert

Rev

Rev 19 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
//
2
//  SyncAdapter.swift
3
//  twogetskills
4
//
5
//  Created by Efrain Yanez Recanatini on 2/24/22.
6
//
7
 
8
import Foundation
9
 
10
import Foundation
11
import Alamofire
12
import SwiftyJSON
21 efrain 13
import SwiftUI
14
import TTGSnackbar
1 efrain 15
 
16
class SyncAdapter
17
{
21 efrain 18
    private var appData = Environment(\.appData).wrappedValue
1 efrain 19
 
17 efrain 20
    private let syncDao : SyncDao = SyncDao()
15 efrain 21
    private var inProgress = false;
22
 
23
 
1 efrain 24
    @objc func updateTimerForeground() {
25
        if inProgress   {
26
            return
27
        }
28
 
15 efrain 29
 
1 efrain 30
 
31
        inProgress = true
32
        let myQue = DispatchQueue(label: "syncQuueForeground")
33
        myQue.async {
34
 
35
            if self.isCheckChangesRequired()  {
36
                self.checkChanges(isForeground:true) { success in
37
                    self.inProgress = false;
38
                }
39
            } else {
15 efrain 40
                self.sync(isForeground: true) { success in
1 efrain 41
                    self.inProgress = false;
42
                }
43
            }
44
        }
45
    }
46
 
47
 
48
 
49
     func isCheckChangesRequired() -> Bool {
50
        if !appData.userUuid.isEmpty && !appData.maxDateChanges.isEmpty {
51
 
52
 
53
            let formatterService = DateFormatter()
54
            formatterService.dateFormat = Constants.FORMAT_DATETIME_SERVICE
55
            guard let lastCheckChanges = formatterService.date(from: appData.lastCheckChanges) else {
56
                let now = Date()
57
                let dateFormatter = DateFormatter()
58
                dateFormatter.dateFormat = Constants.FORMAT_DATETIME_SERVICE
59
                let dateOn = dateFormatter.string(from: now)
60
 
61
                appData.lastCheckChanges = dateOn
62
                appData.save()
63
 
64
                return false
65
 
66
            }
67
 
68
 
69
            let now = Date()
70
 
71
 
72
            let diffComponents = Calendar.current.dateComponents([.minute], from: lastCheckChanges, to: now)
73
            let minutes = diffComponents.minute!
74
 
75
 
76
            return minutes > Constants.SYNC_CHECK_CHANGES_PERIOD
77
 
78
        }
79
 
80
        return false
81
    }
82
 
83
    func checkChanges(isForeground : Bool,  completionHandler : @escaping (_ success : Bool) -> Void) {
84
 
15 efrain 85
 
86
 
17 efrain 87
 
1 efrain 88
        if syncDao.countPendingRecords() > 0 {
89
            completionHandler(true)
90
        }
91
 
92
 
93
        var parameters = [String : String]()
17 efrain 94
        parameters[Constants.POST_MICROLEARNING_CHECK_CHANGES_FIELD_APPLICATION_ID] = "\(Config.APPLICATION_ID)"
95
        parameters[Constants.POST_MICROLEARNING_CHECK_CHANGES_FIELD_VARIANT_ID] = "\(Config.VARIANT_ID)"
96
        parameters[Constants.POST_MICROLEARNING_CHECK_CHANGES_FIELD_DEVICE_UUID] = appData.deviceUuid
1 efrain 97
 
17 efrain 98
        parameters[Constants.POST_MICROLEARNING_CHECK_CHANGES_FIELD_MAX_DATE_CHANGES] = appData.maxDateChanges
1 efrain 99
 
100
 
17 efrain 101
        parameters[Constants.POST_MICROLEARNING_CHECK_CHANGES_FIELD_IS_FOREGROUND] = isForeground ? "1" : "0"
1 efrain 102
 
103
 
104
 
105
 
17 efrain 106
        let capsuleDao = CapsuleDao()
1 efrain 107
        let capsules : [CapsuleModel] = capsuleDao.selectAll()
108
 
17 efrain 109
        parameters[Constants.POST_MICROLEARNING_CHECK_CHANGES_FIELD_MAX_IDS] = String(capsules.count)
1 efrain 110
 
111
        var i : Int = 0
112
        while i < capsules.count {
113
 
17 efrain 114
            parameters["\(Constants.POST_MICROLEARNING_CHECK_CHANGES_FIELD_ID)\(i+1)"] = "\(capsules[i].topicUuid)" + "|" + "\(capsules[i].uuid)"
1 efrain 115
 
116
            i += 1
117
        }
118
 
119
       // print(parameters)
120
 
121
        let headerSecurity : HeaderSecurity = HeaderSecurity()
122
 
123
        let headers: HTTPHeaders = [
124
            .init(name: Constants.HTTP_HEADER_SECURITY_TOKEN, value: appData.deviceUuid),
125
            .init(name: Constants.HTTP_HEADER_SECURITY_SECRET, value: headerSecurity.secret),
126
            .init(name: Constants.HTTP_HEADER_SECURITY_CREATED, value: String(headerSecurity.created)),
127
            .init(name: Constants.HTTP_HEADER_SECURITY_RAND, value: String(headerSecurity.rand)),
128
            .accept(Constants.HTTP_HEADER_ACCEPT)
129
        ]
130
 
131
        AF.request(Config.URL_CHECK_CHANGES, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON {response in
132
 
133
            switch response.result {
134
                case .success:
135
                    let result = try? JSON(data: response.data!)
136
                    if result?["success"] ?? "" != false{
137
 
138
 
139
 
140
                        if result?["data"] ?? "" != "" {
141
                            let now = Date()
142
                            let dateFormatter = DateFormatter()
143
                            dateFormatter.dateFormat = Constants.FORMAT_DATETIME_SERVICE
144
                            let dateOn = dateFormatter.string(from: now)
145
 
146
                            let max_date_changes = result!["data"]["max_date_changes"].string ?? ""
147
                            let snew_capsules =  result!["data"]["new_capsules"].string ?? ""
148
 
149
 
150
                            let new_capsules = Int(snew_capsules) ?? 0
151
 
152
 
153
                            var processChanges = new_capsules > 0
154
                            processChanges = processChanges || self.appData.maxDateChanges != max_date_changes
155
 
156
                            if processChanges {
157
                                self.appData.maxDateChanges = max_date_changes
158
                            }
159
 
160
                            self.appData.lastCheckChanges = dateOn
161
                            self.appData.save()
162
 
163
                            if new_capsules > 0  {
164
                                let userinfo = ["new_capsules" : String(new_capsules), "is_foreground" : (isForeground ? "1" : "0")]
165
 
166
                                NotificationCenter.default.post(name: Constants.NOTIFICATION_NAME_COMMAND_REFRESH_CONTENT , object: self, userInfo: userinfo)
167
                            }
168
 
169
 
170
 
171
                            if result?["data"]["rating_and_comments"]  ?? "" != ""  {
17 efrain 172
                                let capsuleDao = CapsuleDao()
1 efrain 173
                                var capsuleModel : CapsuleModel
174
 
175
                                for ratingAndComment in result!["data"]["rating_and_comments"] {
176
 
177
                                    let uuid = ratingAndComment.1["uuid"].string ?? ""
178
                                    let total_comments = Int(ratingAndComment.1["total_comments"].string ?? "0") ?? 0
179
                                    let total_rating = Decimal(Double(ratingAndComment.1["total_rating"].string ?? "0") ?? 0)
180
 
181
 
182
                                    if !uuid.isEmpty {
183
                                        capsuleModel = capsuleDao.selectByUuid(uuid: uuid)
184
                                        capsuleModel.totalRating = total_rating
185
                                        capsuleModel.totalComments = total_comments
186
                                        capsuleDao.update(capsule: capsuleModel)
187
                                    }
188
                                }
189
                            }
190
                        }
191
                    }
192
                break
193
                case .failure:
194
                   // print("JSON = \(String(describing: Error.self))")
15 efrain 195
 
17 efrain 196
 
1 efrain 197
                break
198
            }
17 efrain 199
 
1 efrain 200
        }
201
 
15 efrain 202
 
1 efrain 203
        completionHandler(true)
204
    }
205
 
206
 
19 efrain 207
 
15 efrain 208
    func sync(isForeground : Bool, completionHandler : @escaping (_ success : Bool) -> Void) {
17 efrain 209
 
15 efrain 210
        let recordsSync = syncDao.selectBatch()
1 efrain 211
 
212
        //print(recordsSync)
213
 
214
        if recordsSync.count > 0 {
215
            var availableForOtherOperation = true;
216
            for recordSync in recordsSync
217
            {
218
                if recordSync.type == Constants.SYNC_ADAPTER_TYPE_DEVICE {
219
                    availableForOtherOperation = false
220
                    registerDevice(record: recordSync)
221
                }
222
                else if availableForOtherOperation && recordSync.type == Constants.SYNC_ADAPTER_TYPE_FCM {
223
                    availableForOtherOperation = false
224
                    registerFcm(record: recordSync)
225
                }
226
            }
227
 
228
            if(availableForOtherOperation) {
229
 
230
                var parameters = [ String: String ]()
231
                var i : Int = 0
232
                for recordSync in recordsSync
233
                {
234
                    if recordSync.type == Constants.SYNC_ADAPTER_TYPE_SYNC {
235
                        i  += 1
236
                        let keyData = Constants.POST_SYNC_BATCH_FIELD_RECORD_DATA + String(i);
237
 
238
                        let keySyncId = Constants.POST_SYNC_BATCH_FIELD_RECORD_SYNC_ID + String(i);
239
 
240
                        //print("keyData = \(keyData) keySincId = \(keySyncId)")
241
 
242
                        parameters["\(keyData)"]  = "\(recordSync.data)"
243
 
244
                        parameters["\(keySyncId)"]  =  String(recordSync.id)
245
 
246
                    }
247
                }
248
 
249
                if i > 0 {
250
                    parameters[Constants.POST_SYNC_BATCH_FIELD_MAX_RECORDS] = "\(i)"
251
                    parameters[Constants.POST_SYNC_BATCH_FIELD_DEVICE_UUID] = appData.deviceUuid
17 efrain 252
                    parameters[Constants.POST_SYNC_BATCH_FIELD_APPLICATION_ID] = "\(Config.APPLICATION_ID)"
253
                    parameters[Constants.POST_SYNC_BATCH_FIELD_VARIANT_ID] = "\(Config.VARIANT_ID)"
1 efrain 254
 
255
                    sendSyncBatch(parameters: parameters)
256
                }
257
            }
258
        }
15 efrain 259
 
17 efrain 260
 
1 efrain 261
        completionHandler(true)
262
    }
263
 
264
    func sendSyncBatch(parameters : [String : String])
265
    {
266
        print("Send Sync Batch  ")
267
        //print(parameters)
268
 
269
 
270
        let headers: HTTPHeaders = [
271
            .accept(Constants.HTTP_HEADER_ACCEPT)
272
        ]
273
 
274
        AF.request(Config.URL_SYNC_BATCH, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON {response in
275
 
276
 
277
 
278
            switch response.result {
279
                case .success:
280
                    let result = try? JSON(data: response.data!)
281
                    if result?["success"] ?? "" != false{
282
 
283
                        if result?["data"] != "" {
284
 
285
                            for sync in result!["data"] {
286
                                //let success = sync.1["success"].string ?? ""
287
                                let sync_id = Int(sync.1["sync_id"].string ?? "0") ?? 0
288
                                if sync_id > 0 {
289
                                    self.syncDao.remove(id: sync_id)
290
                                }
291
                            }
292
                        }
293
                    }
294
                break
295
                case .failure:
296
                   // print("JSON = \(String(describing: Error.self))")
297
                break
298
            }
299
        }
300
 
301
 
302
    }
303
 
304
    func sendSync(record: SyncModel)
305
    {
306
        let parameters = [
17 efrain 307
            Constants.POST_SYNC_FIELD_APPLICATION_ID: "\(Config.APPLICATION_ID)",
308
            Constants.POST_SYNC_FIELD_VARIANT_ID: "\(Config.VARIANT_ID)",
1 efrain 309
            Constants.POST_SYNC_FIELD_DEVICE_UUID: "\(appData.deviceUuid)",
310
            Constants.POST_SYNC_FIELD_DATA: "\(record.data)",
311
            Constants.POST_SYNC_FIELD_SYNC_ID: "\(record.id)"
312
        ]
313
        let headers: HTTPHeaders = [
314
            .accept(Constants.HTTP_HEADER_ACCEPT)
315
        ]
316
 
317
        AF.request(Config.URL_SYNC, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON {response in
318
 
319
            //print("Send Sync  ")
320
 
321
            switch response.result {
322
                case .success:
323
                    let result = try? JSON(data: response.data!)
324
                    if result?["success"] ?? "" != false {
325
 
326
 
327
 
328
 
329
                        let sync_id = Int(result?["data"]["sync_id"].stringValue ?? "0") ?? 0
330
                        if sync_id > 0 {
331
                            self.syncDao.remove(id: sync_id)
332
                        }
333
                    }
334
                break
335
                case .failure:
336
                   // print("JSON = \(String(describing: Error.self))")
337
                break
338
            }
339
        }
340
    }
341
 
342
    func registerFcm(record: SyncModel) {
343
 
344
 
345
 
21 efrain 346
 
1 efrain 347
        let deviceUuid = appData.deviceUuid
348
        let parameters = [
17 efrain 349
            Constants.POST_FCM_FIELD_APPLICATION_ID: "\(Config.APPLICATION_ID)",
350
            Constants.POST_FCM_FIELD_VARIANT_ID: "\(Config.VARIANT_ID)",
1 efrain 351
            Constants.POST_FCM_FIELD_DEVICE_UUID: "\(deviceUuid)",
352
            Constants.POST_FCM_FIELD_TOKEN: "\(record.data)",
353
            Constants.POST_FCM_FIELD_SYNC_ID: "\(record.id)"
354
        ]
21 efrain 355
        print("Register FCM parameters: \(parameters)");
1 efrain 356
 
357
        let headers: HTTPHeaders = [
358
            .accept(Constants.HTTP_HEADER_ACCEPT)
359
        ]
360
 
361
        AF.request(Config.URL_FCM, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON{response in
362
 
21 efrain 363
            print("Register FCM Request")
1 efrain 364
 
365
            switch response.result {
366
                case .success:
367
                    let result = try? JSON(data: response.data!)
21 efrain 368
                    if result?["success"] ?? "" != false {
369
 
370
                        print("Register FCM success = true ")
371
 
372
                        let sync_id = Int(result?["data"]["sync_id"].stringValue ?? "0") ?? 0
373
                        if sync_id > 0 {
374
                            self.syncDao.remove(id: sync_id)
375
                        }
376
                    } else {
377
                        print("Register FCM success = false : \(result?["data"]))")
1 efrain 378
                    }
379
                    break
380
                case .failure:
21 efrain 381
                    print("Register  FCM failura : \(String(describing: Error.self))")
1 efrain 382
                    break
383
            }
384
        }
385
    }
386
 
387
 
388
    func registerDevice(record: SyncModel)
389
    {
390
 
391
 
21 efrain 392
 
1 efrain 393
        let version = UIDevice.current.systemVersion
394
        let model = UIDevice.current.localizedModel
395
 
396
 
397
 
398
        let parameters = [
17 efrain 399
            Constants.POST_DEVICE_FIELD_APPLICATION_ID: "\(Config.APPLICATION_ID)",
400
            Constants.POST_DEVICE_FIELD_VARIANT_ID: "\(Config.VARIANT_ID)",
1 efrain 401
            Constants.POST_DEVICE_FIELD_DEVICE_UUID: "\(record.data)",
402
            Constants.POST_DEVICE_FIELD_MANUFACTURER: "Apple",
403
            Constants.POST_DEVICE_FIELD_BRAND: "Apple",
404
            Constants.POST_DEVICE_FIELD_VERSION: "\(version)",
405
            Constants.POST_DEVICE_FIELD_MODEL: "\(model)",
406
            Constants.POST_DEVICE_FIELD_PLATFORM: "Iphone",
407
            Constants.POST_DEVICE_FIELD_SYNC_ID: "\(record.id)"
408
        ]
21 efrain 409
        print("Register Device parmameters: \(parameters)");
1 efrain 410
 
411
        let headers: HTTPHeaders = [
412
            .accept(Constants.HTTP_HEADER_ACCEPT)
413
        ]
414
 
415
 
21 efrain 416
        print("Register Device URL : \(Config.URL_DEVICE) ")
1 efrain 417
 
418
        AF.request(Config.URL_DEVICE, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON {response in
419
 
21 efrain 420
            print("Register Device Request")
1 efrain 421
 
422
            switch response.result {
423
                case .success:
424
                    let result = try? JSON(data: response.data!)
425
                    if result?["success"] ?? "" != false {
426
                        let aes = result?["data"]["aes"].stringValue ?? ""
427
                        let password = result?["data"]["password"].stringValue ?? ""
428
 
21 efrain 429
                        print("Register Device success = true aes : \(aes) password : \(password) ")
430
 
1 efrain 431
                        if !aes.isEmpty && !password.isEmpty {
432
 
433
                            self.appData.deviceAes = aes
434
                            self.appData.devicePassword = password
435
                            self.appData.save()
436
                        }
437
 
438
                        let sync_id = Int(result?["data"]["sync_id"].stringValue ?? "0") ?? 0
439
                        if sync_id > 0 {
440
                            self.syncDao.remove(id: sync_id)
441
                        }
21 efrain 442
                    } else {
443
                        print("Register Device success = false : \(result?["data"]))")
1 efrain 444
                    }
445
                break
446
                case .failure:
21 efrain 447
                    print("Register Device Failure : \(String(describing: Error.self))")
1 efrain 448
                break
449
            }
450
        }
451
    }
452
}