Proyectos de Subversion Iphone Microlearning - Inconcert

Rev

Rev 1 | 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
{
15 efrain 16
    private let database = Database.sharedInstance
1 efrain 17
 
18
    private var appData = AppData.sharedInstance
19
 
15 efrain 20
 
21
    private var syncDao : SyncDao
22
    private var inProgress = false;
23
 
24
 
1 efrain 25
    @objc func updateTimerForeground() {
26
        if inProgress   {
27
            return
28
        }
29
 
15 efrain 30
 
1 efrain 31
 
32
        inProgress = true
33
        let myQue = DispatchQueue(label: "syncQuueForeground")
34
        myQue.async {
35
 
36
            if self.isCheckChangesRequired()  {
37
                self.checkChanges(isForeground:true) { success in
38
                    self.inProgress = false;
39
                }
40
            } else {
15 efrain 41
                self.sync(isForeground: true) { success in
1 efrain 42
                    self.inProgress = false;
43
                }
44
            }
45
        }
46
    }
47
 
48
 
49
 
50
     func isCheckChangesRequired() -> Bool {
51
        if !appData.userUuid.isEmpty && !appData.maxDateChanges.isEmpty {
52
 
53
 
54
            let formatterService = DateFormatter()
55
            formatterService.dateFormat = Constants.FORMAT_DATETIME_SERVICE
56
            guard let lastCheckChanges = formatterService.date(from: appData.lastCheckChanges) else {
57
                let now = Date()
58
                let dateFormatter = DateFormatter()
59
                dateFormatter.dateFormat = Constants.FORMAT_DATETIME_SERVICE
60
                let dateOn = dateFormatter.string(from: now)
61
 
62
                appData.lastCheckChanges = dateOn
63
                appData.save()
64
 
65
                return false
66
 
67
            }
68
 
69
 
70
            let now = Date()
71
 
72
 
73
            let diffComponents = Calendar.current.dateComponents([.minute], from: lastCheckChanges, to: now)
74
            let minutes = diffComponents.minute!
75
 
76
 
77
            return minutes > Constants.SYNC_CHECK_CHANGES_PERIOD
78
 
79
        }
80
 
81
        return false
82
    }
83
 
84
    func checkChanges(isForeground : Bool,  completionHandler : @escaping (_ success : Bool) -> Void) {
85
 
15 efrain 86
        database.open()
87
        syncDao = SyncDao(db: db)
88
 
89
 
1 efrain 90
        if syncDao.countPendingRecords() > 0 {
91
            completionHandler(true)
92
        }
93
 
94
 
95
        var parameters = [String : String]()
96
        parameters[Constants.POST_MICROLEARNING_CHECK_CHANGES_DEVICE_UUID] = appData.deviceUuid
97
 
98
        parameters[Constants.POST_MICROLEARNING_CHECK_CHANGES_MAX_DATE_CHANGES] = appData.maxDateChanges
99
 
100
 
101
        parameters[Constants.POST_MICROLEARNING_CHECK_CHANGES_IS_FOREGROUND] = isForeground ? "1" : "0"
102
 
103
 
104
 
105
 
106
        let capsuleDao = CapsuleDao.sharedInstance
107
        let capsules : [CapsuleModel] = capsuleDao.selectAll()
108
 
109
        parameters[Constants.POST_MICROLEARNING_CHECK_CHANGES_MAX_IDS] = String(capsules.count)
110
 
111
        var i : Int = 0
112
        while i < capsules.count {
113
 
114
            parameters["\(Constants.POST_MICROLEARNING_CHECK_CHANGES_ID)\(i+1)"] = "\(capsules[i].topicUuid)" + "|" + "\(capsules[i].uuid)"
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"]  ?? "" != ""  {
15 efrain 172
                                let capsuleDao = CapsuleDao(db: database)
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
 
1 efrain 196
                break
197
            }
15 efrain 198
            database.close()
1 efrain 199
        }
200
 
15 efrain 201
 
1 efrain 202
        completionHandler(true)
203
    }
204
 
205
 
15 efrain 206
    func sync(isForeground : Bool, completionHandler : @escaping (_ success : Bool) -> Void) {
207
        database.open()
208
        syncDao = SyncDao(db: db)
209
        let recordsSync = syncDao.selectBatch()
1 efrain 210
 
211
        //print(recordsSync)
212
 
213
        if recordsSync.count > 0 {
214
            var availableForOtherOperation = true;
215
            for recordSync in recordsSync
216
            {
217
                if recordSync.type == Constants.SYNC_ADAPTER_TYPE_DEVICE {
218
                    availableForOtherOperation = false
219
                    registerDevice(record: recordSync)
220
                }
221
                else if availableForOtherOperation && recordSync.type == Constants.SYNC_ADAPTER_TYPE_FCM {
222
                    availableForOtherOperation = false
223
                    registerFcm(record: recordSync)
224
                }
225
            }
226
 
227
            if(availableForOtherOperation) {
228
 
229
                var parameters = [ String: String ]()
230
                var i : Int = 0
231
                for recordSync in recordsSync
232
                {
233
                    if recordSync.type == Constants.SYNC_ADAPTER_TYPE_SYNC {
234
                        i  += 1
235
                        let keyData = Constants.POST_SYNC_BATCH_FIELD_RECORD_DATA + String(i);
236
 
237
                        let keySyncId = Constants.POST_SYNC_BATCH_FIELD_RECORD_SYNC_ID + String(i);
238
 
239
                        //print("keyData = \(keyData) keySincId = \(keySyncId)")
240
 
241
                        parameters["\(keyData)"]  = "\(recordSync.data)"
242
 
243
                        parameters["\(keySyncId)"]  =  String(recordSync.id)
244
 
245
                    }
246
                }
247
 
248
                if i > 0 {
249
                    parameters[Constants.POST_SYNC_BATCH_FIELD_MAX_RECORDS] = "\(i)"
250
                    parameters[Constants.POST_SYNC_BATCH_FIELD_DEVICE_UUID] = appData.deviceUuid
251
 
252
                    sendSyncBatch(parameters: parameters)
253
 
254
                }
255
 
256
 
257
            }
15 efrain 258
 
259
 
1 efrain 260
        }
15 efrain 261
 
262
        database.close()
1 efrain 263
        completionHandler(true)
264
    }
265
 
266
    func sendSyncBatch(parameters : [String : String])
267
    {
268
        print("Send Sync Batch  ")
269
        //print(parameters)
270
 
271
 
272
        let headers: HTTPHeaders = [
273
            .accept(Constants.HTTP_HEADER_ACCEPT)
274
        ]
275
 
276
        AF.request(Config.URL_SYNC_BATCH, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON {response in
277
 
278
 
279
 
280
            switch response.result {
281
                case .success:
282
                    let result = try? JSON(data: response.data!)
283
                    if result?["success"] ?? "" != false{
284
 
285
                        if result?["data"] != "" {
286
 
287
                            for sync in result!["data"] {
288
                                //let success = sync.1["success"].string ?? ""
289
                                let sync_id = Int(sync.1["sync_id"].string ?? "0") ?? 0
290
                                if sync_id > 0 {
291
                                    self.syncDao.remove(id: sync_id)
292
                                }
293
                            }
294
                        }
295
                    }
296
                break
297
                case .failure:
298
                   // print("JSON = \(String(describing: Error.self))")
299
                break
300
            }
301
        }
302
 
303
 
304
    }
305
 
306
    func sendSync(record: SyncModel)
307
    {
308
        let parameters = [
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
 
346
        let deviceUuid = appData.deviceUuid
347
        let parameters = [
348
            Constants.POST_FCM_FIELD_APPLICATION_ID: "\(Constants.GLOBAL_APPLICATION_ID)",
349
            Constants.POST_FCM_FIELD_DEVICE_UUID: "\(deviceUuid)",
350
            Constants.POST_FCM_FIELD_TOKEN: "\(record.data)",
351
            Constants.POST_FCM_FIELD_SYNC_ID: "\(record.id)"
352
        ]
353
 
354
        let headers: HTTPHeaders = [
355
            .accept(Constants.HTTP_HEADER_ACCEPT)
356
        ]
357
 
358
        AF.request(Config.URL_FCM, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON{response in
359
 
360
            print("Send FCM")
361
 
362
            switch response.result {
363
                case .success:
364
                    let result = try? JSON(data: response.data!)
365
                    let sync_id = Int(result?["data"]["sync_id"].stringValue ?? "0") ?? 0
366
                    if sync_id > 0 {
367
                        self.syncDao.remove(id: sync_id)
368
                    }
369
                    break
370
                case .failure:
371
                   // print("JSON = \(String(describing: Error.self))")
372
                    break
373
            }
374
        }
375
    }
376
 
377
 
378
    func registerDevice(record: SyncModel)
379
    {
380
 
381
 
382
        let version = UIDevice.current.systemVersion
383
        let model = UIDevice.current.localizedModel
384
 
385
 
386
 
387
        let parameters = [
388
            Constants.POST_DEVICE_FIELD_APPLICATION_ID: "1",
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
}