123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 |
- import Cocoa
- import Foundation
- import ZipArchive
- let xmlURLString = KMLightMemberConfig().kResourceServerURL
- let kResourcePath = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first?.path
- enum KMResourceDownloadState {
- case none
- case unzipFailed
- case moveFailed
- case success
- case retry
- }
- class KMResourceDownloadManager: NSObject {
- static let manager = KMResourceDownloadManager()
-
- var downloadTask: URLSessionDownloadTask?
- var progressBlock: ((Double) -> Void)?
- var downloadResultBlock: ((Bool, KMResourceDownloadState) -> Void)?
- var reachabilityAlert: NSAlert?
-
-
- func downloadFramework(progress: @escaping (Double) -> Void, result: @escaping (Bool, KMResourceDownloadState) -> Void) {
- self.progressBlock = progress
- self.downloadResultBlock = result
-
- KMRequestServer.requestServer.reachabilityStatusChange { [weak self] status in
- if status == .notReachable {
- KMPrint("无网络")
- self?.downloadTask?.cancel()
- self?.downloadTask = nil
- self?.downloadResultBlock?(false, .none)
- DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.2, execute: { [weak self] in
- if self?.reachabilityAlert == nil {
- self?.reachabilityAlert = NSAlert()
- self?.reachabilityAlert?.messageText = NSLocalizedString("Network Disconnected", comment: "")
- self?.reachabilityAlert?.informativeText = NSLocalizedString("Please connect to the internet and download again.", comment: "")
- self?.reachabilityAlert?.addButton(withTitle: NSLocalizedString("Retry", comment: ""))
- self?.reachabilityAlert?.addButton(withTitle: NSLocalizedString("Cancel", comment: ""))
- var window = NSWindow.currentWindow()
- if window != nil {
- self?.reachabilityAlert?.beginSheetModal(for: window) { result in
- if (result == .alertSecondButtonReturn) {
- self?.reachabilityAlert = nil
- self?.cancelDownload()
- } else if result == .alertFirstButtonReturn {
- self?.reachabilityAlert = nil
- self?.downloadResultBlock?(false, .retry)
- self?.cancelDownload()
- return
- }
- self?.reachabilityAlert = nil
- }
- } else {
- self?.reachabilityAlert = nil
- }
- } else {
- self?.reachabilityAlert = nil
- }
- })
- } else {
- KMPrint("有网络")
- }
- }
-
- if self.downloadTask == nil {
- self.downloadXML { [unowned self] content in
- let urlString = self.dealXML(content: content)
-
- if let url = URL(string: urlString) {
- let configuration = URLSessionConfiguration.default
- let session = URLSession(configuration: configuration, delegate: self, delegateQueue: nil)
- let downloadTask = session.downloadTask(with: url)
- downloadTask.resume()
- self.downloadTask = downloadTask
- } else {
- dealDownloadResult(isSuccess: false, state: .none)
- }
- }
- } else {
- dealDownloadResult(isSuccess: false, state: .none)
- }
- }
-
- func documentAIBundleExists() -> Bool {
- let filePath: String = kResourcePath! + "/DocumentAI.bundle"
- let fileManager = FileManager.default
- debugPrint(filePath)
- debugPrint(FileManager.default.temporaryDirectory.appendingPathComponent("XMLResources"))
- let exists = fileManager.fileExists(atPath: filePath as String)
- if exists {
- self.checkDocumentAIVersion()
- } else {
- self.removeXml()
- }
- return exists
- }
-
- func cancelDownload() {
- downloadTask?.cancel()
- downloadTask = nil
- progressBlock = nil
- downloadResultBlock = nil
- }
-
-
- func dealDownloadResult(isSuccess: Bool, state: KMResourceDownloadState) {
- DispatchQueue.main.async {
- self.downloadResultBlock?(isSuccess, state)
- self.cancelDownload()
- }
- }
-
- func checkDocumentAIVersion() {
- self.downloadXML { [unowned self] content in
- let urlString = self.dealXML(content: content)
- if urlString.count != 0 {
- let filePath: String = kResourcePath! + "/DocumentAI.bundle"
- try?FileManager.default.removeItem(atPath: filePath)
-
- self.removeXml()
- }
- }
- }
- }
- extension KMResourceDownloadManager: XMLParserDelegate {
- func downloadXML(completion: @escaping (_ content: String) -> Void) {
-
- if let xmlURL = URL(string: xmlURLString) {
-
- let request = URLRequest(url: xmlURL)
-
- let session = URLSession.shared
-
- let task = session.dataTask(with: request) { (data, response, error) in
- if let error = error {
-
- print("Error: \(error)")
- } else if let data = data {
-
- if let xmlString = String(data: data, encoding: .utf8) {
-
- print("XML Data: \(xmlString)")
- completion(xmlString)
- }
- }
- }
-
-
- task.resume()
- } else {
-
- print("Invalid URL")
- completion("")
- }
- }
-
- func removeXml() {
- let fileManager = FileManager.default
- let folderURL = fileManager.temporaryDirectory.appendingPathComponent("XMLResources")
- let xmlURL = folderURL.appendingPathComponent("DocumentAI.xml")
- try?FileManager.default.removeItem(at: xmlURL)
- }
-
- func dealXML(content: String) -> String {
-
- let xmlContent = content
-
- let fileManager = FileManager.default
- let folderURL = fileManager.temporaryDirectory.appendingPathComponent("XMLResources")
- try? fileManager.createDirectory(at: folderURL, withIntermediateDirectories: true, attributes: nil)
-
- let xmlURL = folderURL.appendingPathComponent("TempDocumentAI.xml")
- try? xmlContent.write(to: xmlURL, atomically: true, encoding: .utf8)
-
-
- var localVersion = "0.0"
- var appVersion = "1.0.0"
-
- if let xmlData = try? Data(contentsOf: self.fetchXMLURL()) {
- let xmlParser = XMLParser(data: xmlData)
- let xmlDelegate = XMLDelegate()
- xmlParser.delegate = xmlDelegate
-
- if xmlParser.parse() {
- localVersion = xmlDelegate.version ?? "1.0.0"
- }
- }
-
-
- if let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String {
- appVersion = version
- print("应用程序版本号:\(appVersion)")
- } else {
- print("无法获取应用程序版本号。")
- }
-
- if let xmlData = try? Data(contentsOf: xmlURL) {
- let xmlParser = XMLParser(data: xmlData)
- let xmlDelegate = XMLDelegate()
- xmlParser.delegate = xmlDelegate
-
- if xmlParser.parse() {
-
- if let xmlVersion = xmlDelegate.version {
- if xmlVersion > localVersion {
- if let minVersion = xmlDelegate.minVersion {
- if appVersion >= minVersion {
-
- let resourceURL = xmlDelegate.resourceURL
- print("Download resource from \(resourceURL)")
- return resourceURL ?? ""
- } else {
- print("No need to download resources. Already up to date.")
- }
- }
- } else {
- print("No need to download resources. Already up to date.")
- }
- }
- } else {
-
- }
- } else {
-
- }
- return ""
- }
-
- func fetchXMLURL() -> URL {
-
- let fileManager = FileManager.default
- let folderURL = fileManager.temporaryDirectory.appendingPathComponent("XMLResources")
- try? fileManager.createDirectory(at: folderURL, withIntermediateDirectories: true, attributes: nil)
-
- let xmlURL = folderURL.appendingPathComponent("DocumentAI.xml")
- return xmlURL
- }
-
- func writeXML(content: String) {
- let xmlURL = self.fetchXMLURL()
- try? content.write(to: xmlURL, atomically: true, encoding: .utf8)
- }
-
- func xmlResourceDownloadSuccess() {
- let fileManager = FileManager.default
- let folderURL = fileManager.temporaryDirectory.appendingPathComponent("XMLResources")
- let xmlURL = folderURL.appendingPathComponent("DocumentAI.xml")
- let tempXmlURL = folderURL.appendingPathComponent("TempDocumentAI.xml")
- try?fileManager.removeItem(at: xmlURL)
-
- do {
-
- try fileManager.moveItem(atPath: tempXmlURL.path, toPath: xmlURL.path)
- print("文件重命名成功:\(xmlURL.path)")
- } catch {
-
- print("文件重命名失败:\(error)")
- }
- }
- }
- extension KMResourceDownloadManager {
-
- func unzipFramework(at zipURL: URL, to destinationPath: String) {
- let fileManager = FileManager.default
- var success = false
- if zipURL.pathExtension == "zip" {
- success = SSZipArchive.unzipFile(atPath: zipURL.path, toDestination: destinationPath)
- } else {
-
-
- }
-
- if success {
- print("File unzipped successfully!")
- try? fileManager.removeItem(at: zipURL)
- } else {
- print("Failed to unzip file.")
- dealDownloadResult(isSuccess: false, state: .unzipFailed)
- }
- }
-
- func loadFramework(destinationPath: String) {
- let fileManager = FileManager.default
- let bundlePath = destinationPath + "/DocumentAI.bundle"
-
- if fileManager.fileExists(atPath: bundlePath) {
- if let bundle = Bundle(path: bundlePath) {
-
-
- print("Framework loaded successfully!")
- } else {
- print("Error loading bundle.")
- dealDownloadResult(isSuccess: false, state: .none)
- }
- } else {
- dealDownloadResult(isSuccess: false, state: .none)
- }
- }
- }
- extension KMResourceDownloadManager: URLSessionDelegate, URLSessionDownloadDelegate {
-
- func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
- let progress = Double(totalBytesWritten) / Double(totalBytesExpectedToWrite)
- print("Download progress: \(progress)")
- progressBlock?(progress)
- }
-
- func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
- guard let destinationPath = kResourcePath else {
- return
- }
-
- let fileManager = FileManager.default
- let destinationURL = URL(fileURLWithPath: destinationPath).appendingPathComponent("DocumentAI.bundle.zip")
-
- do {
- try fileManager.moveItem(at: location, to: destinationURL)
- print("Framework downloaded and installed successfully!")
- unzipFramework(at: destinationURL, to: destinationPath)
- dealDownloadResult(isSuccess: true, state: .success)
- self.xmlResourceDownloadSuccess()
- } catch {
- print("Failed to move framework: \(error)")
- dealDownloadResult(isSuccess: false, state: .moveFailed)
- }
- }
- }
- class XMLDelegate: NSObject, XMLParserDelegate {
- var currentElement: String = ""
- var version: String?
- var minVersion: String?
- var resourceURL: String?
-
- func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
- currentElement = elementName
- }
-
- func parser(_ parser: XMLParser, foundCharacters string: String) {
- if currentElement == "version" {
- if version == nil {
- version = string
- }
- } else if currentElement == "resourceURL" {
- if resourceURL == nil {
- resourceURL = string
- }
- } else if currentElement == "minVersion" {
- if minVersion == nil {
- minVersion = string
- }
- }
- }
- }
|