Network.swift 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. //
  2. // Network.swift
  3. // Runner
  4. //
  5. // Created by Yayan Dwi on 20/04/20.
  6. // Copyright © 2020 The Chromium Authors. All rights reserved.
  7. //
  8. import Foundation
  9. import Alamofire
  10. public class Network {
  11. let uploadGroup = DispatchGroup()
  12. private var path = ""
  13. private var fileId = ""
  14. private var fileSize = 0
  15. private var isCancel = false
  16. private var progress = 0.0
  17. private var CHUNK_SIZE = 200 * 1024
  18. private var UPLOAD_URL = Utils.getURLBase() + "uploader"
  19. public init() {}
  20. public func upload(name: String, completion: @escaping (Bool, Double)->()) {
  21. DispatchQueue(label: "Network").async {
  22. do {
  23. let fileManager = FileManager.default
  24. let documentDir = try fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
  25. let fileDir = documentDir.appendingPathComponent(name)
  26. let path = fileDir.path
  27. if FileManager.default.fileExists(atPath: path) {
  28. let attrib = try FileManager.default.attributesOfItem(atPath: path)
  29. let fileSize = attrib[.size] as! Int
  30. let fileName = (path as NSString).lastPathComponent
  31. //print(("file exists: \(path) -> \(fileSize)")
  32. if (fileSize > self.CHUNK_SIZE) {
  33. DigiX.putUploadFile(forKey: fileName, uploader: self)
  34. //print(("[bytes_processing] Size: " + String(fileSize))
  35. var totalPart = fileSize / self.CHUNK_SIZE
  36. if (fileSize % self.CHUNK_SIZE > 0) {
  37. totalPart += 1
  38. }
  39. do {
  40. let outputFileHandle = try FileHandle(forReadingFrom: URL(fileURLWithPath: path))
  41. var data = outputFileHandle.readData(ofLength: self.CHUNK_SIZE)
  42. var index = 0
  43. while !data.isEmpty {
  44. if self.isCancel {
  45. completion(false, Double(0))
  46. break
  47. }
  48. self.uploadGroup.enter()
  49. //print(("[bytes_processing] Sending bytes part #" + String(index + 1) + " of " + String(totalPart) + " --> " + String(data.count))
  50. let message = CoreMessage_TMessageBank.getUploadFile(p_image_id: fileName, file_size: String(fileSize), part_of: String(index), part_size: String(totalPart), p_file: [UInt8] (data))
  51. if let response = DigiX.write(message: message), response.isEmpty {
  52. completion(false, self.progress)
  53. break
  54. }
  55. //print(("[bytes_processing] part #" + String(index + 1) + " of " + String(totalPart) + " uploading...")
  56. let wait = self.uploadGroup.wait(timeout: .now() + 30)
  57. //print(("[bytes_processing] part #" + String(index + 1) + " of " + String(totalPart) + " wait!", wait)
  58. if wait == DispatchTimeoutResult.timedOut {
  59. completion(false, self.progress)
  60. DigiX.removeUploadFile(forKey: fileName)
  61. self.uploadGroup.leave()
  62. break
  63. }
  64. self.progress = Double(index + 1) / Double(totalPart) * 100
  65. completion(true, self.progress)
  66. //print(("[bytes_processing] part #" + String(index + 1) + " of " + String(totalPart) + " uploaded!")
  67. data = outputFileHandle.readData(ofLength: self.CHUNK_SIZE)
  68. index = index + 1
  69. }
  70. outputFileHandle.closeFile()
  71. _ = DigiX.removeUploadFile(forKey: fileName)
  72. } catch {
  73. //print(error.localizedDescription)
  74. }
  75. }
  76. else {
  77. let data = try Data(contentsOf: URL(fileURLWithPath: path))
  78. let message = CoreMessage_TMessageBank.getUploadFile(p_image_id: fileName, file_size: String(fileSize), part_of: "0", part_size: "0", p_file: [UInt8] (data))
  79. guard let response = DigiX.write(message: message), !response.isEmpty else {
  80. completion(false, self.progress)
  81. return
  82. }
  83. //print(("[bytes_processing] File uploaded!")
  84. completion(response.count > 1, 100)
  85. }
  86. } else {
  87. //print(("file not exists \(name)")
  88. completion(false, 0)
  89. }
  90. } catch {
  91. //print(error.localizedDescription)
  92. }
  93. }
  94. }
  95. public func upload(fileUrl: URL, completion: @escaping (Bool, Double)->()) {
  96. DispatchQueue(label: "Network").async {
  97. do {
  98. if FileManager.default.fileExists(atPath: fileUrl.path) {
  99. let path = fileUrl.path
  100. let attrib = try FileManager.default.attributesOfItem(atPath: path)
  101. let fileSize = attrib[.size] as! Int
  102. let fileName = (path as NSString).lastPathComponent
  103. //print(("file exists: \(path) -> \(fileSize)")
  104. if (fileSize > self.CHUNK_SIZE) {
  105. DigiX.putUploadFile(forKey: fileName, uploader: self)
  106. //print(("[bytes_processing] Size: " + String(fileSize))
  107. var totalPart = fileSize / self.CHUNK_SIZE
  108. if (fileSize % self.CHUNK_SIZE > 0) {
  109. totalPart += 1
  110. }
  111. do {
  112. let outputFileHandle = try FileHandle(forReadingFrom: URL(fileURLWithPath: path))
  113. var data = outputFileHandle.readData(ofLength: self.CHUNK_SIZE)
  114. var index = 0
  115. while !data.isEmpty {
  116. if self.isCancel {
  117. completion(false, Double(0))
  118. break
  119. }
  120. self.uploadGroup.enter()
  121. //print(("[bytes_processing] Sending bytes part #" + String(index + 1) + " of " + String(totalPart) + " --> " + String(data.count))
  122. let message = CoreMessage_TMessageBank.getUploadFile(p_image_id: fileName, file_size: String(fileSize), part_of: String(index), part_size: String(totalPart), p_file: [UInt8] (data))
  123. if let response = DigiX.write(message: message), response.isEmpty {
  124. completion(false, self.progress)
  125. break
  126. }
  127. //print(("[bytes_processing] part #" + String(index + 1) + " of " + String(totalPart) + " uploading...")
  128. let wait = self.uploadGroup.wait(timeout: .now() + 30)
  129. //print(("[bytes_processing] part #" + String(index + 1) + " of " + String(totalPart) + " wait!", wait)
  130. if wait == DispatchTimeoutResult.timedOut {
  131. completion(false, self.progress)
  132. DigiX.removeUploadFile(forKey: fileName)
  133. self.uploadGroup.leave()
  134. break
  135. }
  136. self.progress = Double(index + 1) / Double(totalPart) * 100
  137. completion(true, self.progress)
  138. //print(("[bytes_processing] part #" + String(index + 1) + " of " + String(totalPart) + " uploaded!")
  139. data = outputFileHandle.readData(ofLength: self.CHUNK_SIZE)
  140. index = index + 1
  141. }
  142. outputFileHandle.closeFile()
  143. _ = DigiX.removeUploadFile(forKey: fileName)
  144. } catch {
  145. //print(error.localizedDescription)
  146. }
  147. }
  148. else {
  149. let data = try Data(contentsOf: URL(fileURLWithPath: path))
  150. let message = CoreMessage_TMessageBank.getUploadFile(p_image_id: fileName, file_size: String(fileSize), part_of: "0", part_size: "0", p_file: [UInt8] (data))
  151. guard let response = DigiX.write(message: message), !response.isEmpty else {
  152. completion(false, self.progress)
  153. return
  154. }
  155. //print(("[bytes_processing] File uploaded!")
  156. completion(response.count > 1, 100)
  157. }
  158. } else {
  159. //print(("file not exists \(fileUrl)")
  160. completion(false, 0)
  161. }
  162. } catch {
  163. //print(error.localizedDescription)
  164. }
  165. }
  166. }
  167. public func uploadHTTP(name: String, completion: @escaping (Bool, Double, [String:Any]?)->()) {
  168. _ = uploadHTTP(UPLOAD_URL, filename: [name], completion: completion)
  169. }
  170. public func uploadHTTP(fileUrl: URL, completion: @escaping (Bool, Double, [String:Any]?)->()) {
  171. _ = uploadHTTP(UPLOAD_URL, files: [fileUrl], completion: completion)
  172. }
  173. public func uploadHTTP(_ endUrl: String, files: [URL] = [], filename: [String] = [], parameters: [String : Any] = [:], completion: @escaping (Bool, Double, [String:Any]?)->()) -> UploadRequest {
  174. var filesIn = [URL]()
  175. filesIn.append(contentsOf: files)
  176. if !filename.isEmpty {
  177. do {
  178. let fileManager = FileManager.default
  179. let documentDir = try fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
  180. for name in filename {
  181. let fileDir = documentDir.appendingPathComponent(name)
  182. let path = fileDir.path
  183. if FileManager.default.fileExists(atPath: path) {
  184. let fileURL = URL(fileURLWithPath: path)
  185. filesIn.append(fileURL)
  186. }
  187. }
  188. }
  189. catch {}
  190. }
  191. let uploadRequest = AF.upload(multipartFormData: { (multipartFormData: MultipartFormData) in
  192. for (key, value) in parameters {
  193. multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key as String)
  194. //print(multipartFormData)
  195. }
  196. for i in 0..<filesIn.count {
  197. multipartFormData.append(filesIn[i], withName: "file\(i+1)", fileName: filesIn[i].lastPathComponent, mimeType: "application/octet-stream")
  198. DigiX.putUploadFile(forKey: filesIn[i].lastPathComponent, uploader: self)
  199. //print(multipartFormData)
  200. }
  201. }, to: endUrl)
  202. .responseJSON { result in
  203. if let successResponse = result.value as? [String:Any] {
  204. print("Response success")
  205. for url in filesIn {
  206. DigiX.removeUploadFile(forKey: url.lastPathComponent)
  207. }
  208. completion(true,100,successResponse)
  209. }
  210. else {
  211. let statusCode = result.response?.statusCode
  212. print("Response fail: \(statusCode)")
  213. completion(false,0,nil)
  214. }
  215. }
  216. .uploadProgress { progress in
  217. print("Response progress: \(progress.fractionCompleted*100)")
  218. let frac = progress.fractionCompleted*100
  219. if frac != 100.0 {
  220. completion(!progress.isCancelled,frac,nil)
  221. }
  222. }
  223. return uploadRequest
  224. }
  225. public func cancel() {
  226. self.isCancel = true
  227. }
  228. }