Proyectos de Subversion Iphone Microlearning - Inconcert

Rev

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