JLChen
2021-05-18 a869383e163a18cdedcf587383c1eca043129754
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
//
//  Copyright © 2018年 Zhejiang Dahua Technology Co.,Ltd. All rights reserved.
//    OMS配置信息
//    1、型号信息文件 Support/OMS/Models/[Language]
//    2、引导信息文件 Support/OMS/Introductions/[MarketModel_Language]
 
import UIKit
 
class DHOMSConfigManager: NSObject, DHOMSConfigManagerProtocol {
 
    /// 由于和DHServiceProtocol协议相冲突,这里使用sharedManager替代
    @objc static let sharedManager = DHOMSConfigManager()
    
    var types: [DHOMSDeviceType] = [DHOMSDeviceType]()
    
    /// 市场型号对应的引导信息
    var dicIntoductions: [String: DHIntroductionParser] =  [String: DHIntroductionParser]()
    
    /// 市场型号对应的引导状态
    var dicIntroductionStatus = [String: Bool]()
    
    /// 标记设备型号是否更新成功
    var isUpdatedSuccessfully: Bool = false
    
    /// 更新型号列表时间
    private var updateTime: String = ""
 
    override init() {
        super.init()
        loadModelInfos()
    }
    
    static func isSingleton() -> Bool {
        return true
    }
    
    static func sharedInstance() -> Any! {
        return sharedManager
    }
 
    @objc func checkUpdateDeviceModels() {
        self.updateDeviceModels()
        //【*】使用本地时间进行检验
        //【*】更新列表
        if self.updateTime.count == 0 {
            self.updateDeviceModels()
        } else {
            LCAddDeviceInterface.checkDeviceIntroduction(withUpdateTime: self.updateTime, success: { (isUpdated) in
                if isUpdated {
                    self.updateDeviceModels()
                } else {
                    self.isUpdatedSuccessfully = true
                }
            }) { (error) in
                self.updateDeviceModels()
                self.addDeviceEndLog()
            }
        }
    }
    
    @objc func checkUpdateIntrodution(byMarketModel model: String) {
        //【*】异常处理
        if model.count == 0 {
            return
        }
        
        //【*】如果字典中没有引导信息,先从缓存文件进行加载
        if dicIntoductions[model] == nil {
            self.loadIntroduction(byMarketModel: model)
        }
        
        // 【*】正在更新,不需要处理
        if dicIntroductionStatus[model] == true {
            return
        }
        
        dicIntroductionStatus[model] = true
        
        //【*】如果加载了引导信息,进行check.
        if let introdctionParser = dicIntoductions[model] {
            if introdctionParser.updateTime.count == 0 {
                self.updateIntroduction(byMarketModel: model)
            } else {
                LCAddDeviceInterface.checkDeviceIntroduction(withUpdateTime: introdctionParser.updateTime, success: { (isUpdated) in
                                        if isUpdated {
                        self.updateIntroduction(byMarketModel: model)
                    } else {
                        self.dicIntroductionStatus[model] = false
                    }
                }) { (error) in
                    self.updateIntroduction(byMarketModel: model)
                }
            }
        } else {
            self.updateIntroduction(byMarketModel: model)
        }
    }
    
    // MARK: 取引导信息
    
    /// 根据市场型号获取具体引导信息
    ///
    /// - Parameters:
    ///   - marketModel: 市场型号
    func getIntroductionParser(marketModel: String) -> DHIntroductionParser? {
        return self.dicIntoductions[marketModel]
    }
    
    /// 登录后,加载指定的型号,如果缓存里面已经有,则不更新
    func preloadIntroductions() {
        let preloadModels = DHModuleConfig.shareInstance().preloadIntroductionModels()
        let language = currentLanguageCode()
        
        for marketModel in preloadModels {
            let path = self.deviceIntroductionInfosPath(byLanguage: language, marketModel: marketModel)
            if FileManager.default.fileExists(atPath: path) == false {
                checkUpdateIntrodution(byMarketModel: marketModel)
            }
        }
    }
    
    // MARK: Private
    private func updateDeviceModels() {
        LCAddDeviceInterface.queryAllProduct(withDeviceType: nil, success: { (dic) in
            if let time = dic["updateTime"] as? String {
                self.updateTime = time
            }
            if let deviceTypeConfigs = dic["deviceTypeConfigs"] as? [DHOMSDeviceType], deviceTypeConfigs.count > 0 {
                self.types.removeAll()
                self.types.append(contentsOf: deviceTypeConfigs)
                self.isUpdatedSuccessfully = true
                self.saveModelInfos()
 
                DispatchQueue.main.async {
                    let notification = NSNotification.Name(rawValue: "LCNotificationOMSIModelsUpdated")
                    NotificationCenter.default.post(name: notification, object: nil)
                }
            }
        }) { (error) in
            
        }
    }
    
    private func updateIntroduction(byMarketModel model: String) {
        let notification = NSNotification.Name(rawValue: "LCNotificationOMSIntrodutionUpdated")
        LCAddDeviceInterface.getDeviceIntroduction(forDeviceModel: model, success: { (introduction) in
            self.dicIntoductions[model] = DHIntroductionParser(introduction: introduction)
            self.dicIntroductionStatus[model] = false
 
            //updateTime有值时才缓存,可能返回的数据为空,用此进行判断
            if introduction.updateTime.count > 0 {
                self.saveIntroduction(byMarketModel: model, introduction: introduction)
            }
 
            NotificationCenter.default.post(name: notification, object: nil, userInfo: ["MarketModel": model])
        }) { (error) in
            self.dicIntroductionStatus[model] = false
            NotificationCenter.default.post(name: notification, object: nil, userInfo: ["MarketModel": model])
            print("🍎🍎🍎 \(NSStringFromClass(self.classForCoder))::Update introduction failed...")
        }
    }
    
    // MARK: OMS Cache
    @objc func clearOMSCache() {
        let folder = cacheFolderPath()
    
        do {
            try FileManager.default.removeItem(atPath: folder)
            //清除缓存成功,同时清除内存缓存
            self.dicIntoductions.removeAll()
        } catch {
            print("🍎🍎🍎 \(NSStringFromClass(self.classForCoder))::Clear oms cache failed...")
        }
    }
    
    @objc func cacheFolderPath() -> String {
        let folder = (DHFileManager.supportFolder() as NSString).appendingPathComponent("OMS")
        return folder
    }
    
    // MARK: Save & Load
    private func deviceModelInfosPath(byLanguage: String) -> String {
        let folder = (cacheFolderPath() as NSString).appendingPathComponent("Models")
        if FileManager.default.fileExists(atPath: folder) == false {
            try?FileManager.default.createDirectory(atPath: folder, withIntermediateDirectories: true, attributes: nil)
        }
        let filePath = (folder as NSString).appendingPathComponent(byLanguage)
        return filePath
    }
    
    private func deviceIntroductionInfosPath(byLanguage: String, marketModel: String) -> String {
        let folder = (cacheFolderPath() as NSString).appendingPathComponent("Introductions")
        if FileManager.default.fileExists(atPath: folder) == false {
            try?FileManager.default.createDirectory(atPath: folder, withIntermediateDirectories: true, attributes: nil)
        }
        let filePath = (folder as NSString).appendingPathComponent("\(marketModel)_\(byLanguage)")
        return filePath
    }
    
    private func loadModelInfos() {
        let language = currentLanguageCode()
        let path = self.deviceModelInfosPath(byLanguage: language)
        if let dic = NSKeyedUnarchiver.unarchiveObject(withFile: path) as? [String: Any] {
            if let time = dic["updateTime"] as? String {
                self.updateTime = time
            }
            
            if let deviceTypeConfigs = dic["deviceTypeConfigs"] as? [DHOMSDeviceType] {
                self.types = deviceTypeConfigs
            }
        }
    }
    
    private func saveModelInfos() {
        let language = currentLanguageCode()
        let path = self.deviceModelInfosPath(byLanguage: language)
        let dic = ["updateTime": updateTime, "deviceTypeConfigs": types] as [String: Any]
    
        let result = NSKeyedArchiver.archiveRootObject(dic, toFile: path)
        print("🍎🍎🍎 \(NSStringFromClass(self.classForCoder))::Save models,result:\(result)")
    }
    
    private func loadIntroduction(byMarketModel marketModel: String) {
        let language = currentLanguageCode()
        let path = self.deviceIntroductionInfosPath(byLanguage: language, marketModel: marketModel)
        if let introduction = NSKeyedUnarchiver.unarchiveObject(withFile: path) as? DHOMSIntroductionInfo {
            let parser = DHIntroductionParser(introduction: introduction)
            self.dicIntoductions[marketModel] = parser
        }
    }
    
    private func saveIntroduction(byMarketModel marketModel: String, introduction: DHOMSIntroductionInfo) {
        let language = currentLanguageCode()
        let path = self.deviceIntroductionInfosPath(byLanguage: language, marketModel: marketModel)
        let result = NSKeyedArchiver.archiveRootObject(introduction, toFile: path)
        print("🍎🍎🍎 \(NSStringFromClass(self.classForCoder))::Save models,result:\(result)")
    }
    
    
    // MARK: 添加设备结束log
    private func addDeviceEndLog() {
        
    }
}
 
 
extension DHOMSConfigManager {
    func currentLanguageCode() -> String {
        if let language = NSLocale.preferredLanguages.first {
            if language.hasPrefix("zh") {
                return language.contains("zh-Hant") ? "zh-TW" : "zh-CN"
            }
            
            return language
        }
        
        return ""
    }
}