Proyectos de Subversion Iphone Microlearning - Nuevo Interface

Rev

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