Proyectos de Subversion Iphone Microlearning - Inconcert

Rev

Rev 15 | Rev 19 | 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
 
15 efrain 205
    func sync(isForeground : Bool, completionHandler : @escaping (_ success : Bool) -> Void) {
17 efrain 206
 
15 efrain 207
        let recordsSync = syncDao.selectBatch()
1 efrain 208
 
209
        //print(recordsSync)
210
 
211
        if recordsSync.count > 0 {
212
            var availableForOtherOperation = true;
213
            for recordSync in recordsSync
214
            {
215
                if recordSync.type == Constants.SYNC_ADAPTER_TYPE_DEVICE {
216
                    availableForOtherOperation = false
217
                    registerDevice(record: recordSync)
218
                }
219
                else if availableForOtherOperation && recordSync.type == Constants.SYNC_ADAPTER_TYPE_FCM {
220
                    availableForOtherOperation = false
221
                    registerFcm(record: recordSync)
222
                }
223
            }
224
 
225
            if(availableForOtherOperation) {
226
 
227
                var parameters = [ String: String ]()
228
                var i : Int = 0
229
                for recordSync in recordsSync
230
                {
231
                    if recordSync.type == Constants.SYNC_ADAPTER_TYPE_SYNC {
232
                        i  += 1
233
                        let keyData = Constants.POST_SYNC_BATCH_FIELD_RECORD_DATA + String(i);
234
 
235
                        let keySyncId = Constants.POST_SYNC_BATCH_FIELD_RECORD_SYNC_ID + String(i);
236
 
237
                        //print("keyData = \(keyData) keySincId = \(keySyncId)")
238
 
239
                        parameters["\(keyData)"]  = "\(recordSync.data)"
240
 
241
                        parameters["\(keySyncId)"]  =  String(recordSync.id)
242
 
243
                    }
244
                }
245
 
246
                if i > 0 {
247
                    parameters[Constants.POST_SYNC_BATCH_FIELD_MAX_RECORDS] = "\(i)"
248
                    parameters[Constants.POST_SYNC_BATCH_FIELD_DEVICE_UUID] = appData.deviceUuid
17 efrain 249
                    parameters[Constants.POST_SYNC_BATCH_FIELD_APPLICATION_ID] = "\(Config.APPLICATION_ID)"
250
                    parameters[Constants.POST_SYNC_BATCH_FIELD_VARIANT_ID] = "\(Config.VARIANT_ID)"
1 efrain 251
 
252
                    sendSyncBatch(parameters: parameters)
253
                }
254
            }
255
        }
15 efrain 256
 
17 efrain 257
 
1 efrain 258
        completionHandler(true)
259
    }
260
 
261
    func sendSyncBatch(parameters : [String : String])
262
    {
263
        print("Send Sync Batch  ")
264
        //print(parameters)
265
 
266
 
267
        let headers: HTTPHeaders = [
268
            .accept(Constants.HTTP_HEADER_ACCEPT)
269
        ]
270
 
271
        AF.request(Config.URL_SYNC_BATCH, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON {response in
272
 
273
 
274
 
275
            switch response.result {
276
                case .success:
277
                    let result = try? JSON(data: response.data!)
278
                    if result?["success"] ?? "" != false{
279
 
280
                        if result?["data"] != "" {
281
 
282
                            for sync in result!["data"] {
283
                                //let success = sync.1["success"].string ?? ""
284
                                let sync_id = Int(sync.1["sync_id"].string ?? "0") ?? 0
285
                                if sync_id > 0 {
286
                                    self.syncDao.remove(id: sync_id)
287
                                }
288
                            }
289
                        }
290
                    }
291
                break
292
                case .failure:
293
                   // print("JSON = \(String(describing: Error.self))")
294
                break
295
            }
296
        }
297
 
298
 
299
    }
300
 
301
    func sendSync(record: SyncModel)
302
    {
303
        let parameters = [
17 efrain 304
            Constants.POST_SYNC_FIELD_APPLICATION_ID: "\(Config.APPLICATION_ID)",
305
            Constants.POST_SYNC_FIELD_VARIANT_ID: "\(Config.VARIANT_ID)",
1 efrain 306
            Constants.POST_SYNC_FIELD_DEVICE_UUID: "\(appData.deviceUuid)",
307
            Constants.POST_SYNC_FIELD_DATA: "\(record.data)",
308
            Constants.POST_SYNC_FIELD_SYNC_ID: "\(record.id)"
309
        ]
310
        let headers: HTTPHeaders = [
311
            .accept(Constants.HTTP_HEADER_ACCEPT)
312
        ]
313
 
314
        AF.request(Config.URL_SYNC, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON {response in
315
 
316
            //print("Send Sync  ")
317
 
318
            switch response.result {
319
                case .success:
320
                    let result = try? JSON(data: response.data!)
321
                    if result?["success"] ?? "" != false {
322
 
323
 
324
 
325
 
326
                        let sync_id = Int(result?["data"]["sync_id"].stringValue ?? "0") ?? 0
327
                        if sync_id > 0 {
328
                            self.syncDao.remove(id: sync_id)
329
                        }
330
                    }
331
                break
332
                case .failure:
333
                   // print("JSON = \(String(describing: Error.self))")
334
                break
335
            }
336
        }
337
    }
338
 
339
    func registerFcm(record: SyncModel) {
340
 
341
 
342
 
343
        let deviceUuid = appData.deviceUuid
344
        let parameters = [
17 efrain 345
            Constants.POST_FCM_FIELD_APPLICATION_ID: "\(Config.APPLICATION_ID)",
346
            Constants.POST_FCM_FIELD_VARIANT_ID: "\(Config.VARIANT_ID)",
1 efrain 347
            Constants.POST_FCM_FIELD_DEVICE_UUID: "\(deviceUuid)",
348
            Constants.POST_FCM_FIELD_TOKEN: "\(record.data)",
349
            Constants.POST_FCM_FIELD_SYNC_ID: "\(record.id)"
350
        ]
351
 
352
        let headers: HTTPHeaders = [
353
            .accept(Constants.HTTP_HEADER_ACCEPT)
354
        ]
355
 
356
        AF.request(Config.URL_FCM, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON{response in
357
 
358
            print("Send FCM")
359
 
360
            switch response.result {
361
                case .success:
362
                    let result = try? JSON(data: response.data!)
363
                    let sync_id = Int(result?["data"]["sync_id"].stringValue ?? "0") ?? 0
364
                    if sync_id > 0 {
365
                        self.syncDao.remove(id: sync_id)
366
                    }
367
                    break
368
                case .failure:
369
                   // print("JSON = \(String(describing: Error.self))")
370
                    break
371
            }
372
        }
373
    }
374
 
375
 
376
    func registerDevice(record: SyncModel)
377
    {
378
 
379
 
380
        let version = UIDevice.current.systemVersion
381
        let model = UIDevice.current.localizedModel
382
 
383
 
384
 
385
        let parameters = [
17 efrain 386
            Constants.POST_DEVICE_FIELD_APPLICATION_ID: "\(Config.APPLICATION_ID)",
387
            Constants.POST_DEVICE_FIELD_VARIANT_ID: "\(Config.VARIANT_ID)",
1 efrain 388
            Constants.POST_DEVICE_FIELD_DEVICE_UUID: "\(record.data)",
389
            Constants.POST_DEVICE_FIELD_MANUFACTURER: "Apple",
390
            Constants.POST_DEVICE_FIELD_BRAND: "Apple",
391
            Constants.POST_DEVICE_FIELD_VERSION: "\(version)",
392
            Constants.POST_DEVICE_FIELD_MODEL: "\(model)",
393
            Constants.POST_DEVICE_FIELD_PLATFORM: "Iphone",
394
            Constants.POST_DEVICE_FIELD_SYNC_ID: "\(record.id)"
395
        ]
396
 
397
        let headers: HTTPHeaders = [
398
            .accept(Constants.HTTP_HEADER_ACCEPT)
399
        ]
400
 
401
 
402
        print("URL DEVICE : \(Config.URL_DEVICE) ")
403
 
404
        AF.request(Config.URL_DEVICE, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON {response in
405
 
406
            print("Send Device: ")
407
 
408
            switch response.result {
409
                case .success:
410
                    let result = try? JSON(data: response.data!)
411
                    if result?["success"] ?? "" != false {
412
                        let aes = result?["data"]["aes"].stringValue ?? ""
413
                        let password = result?["data"]["password"].stringValue ?? ""
414
 
415
                        if !aes.isEmpty && !password.isEmpty {
416
 
417
                            self.appData.deviceAes = aes
418
                            self.appData.devicePassword = password
419
                            self.appData.save()
420
                        }
421
 
422
                        let sync_id = Int(result?["data"]["sync_id"].stringValue ?? "0") ?? 0
423
                        if sync_id > 0 {
424
                            self.syncDao.remove(id: sync_id)
425
                        }
426
                    }
427
                break
428
                case .failure:
429
                    //print("JSON = \(String(describing: Error.self))")
430
                break
431
            }
432
        }
433
    }
434
}