Ver código fonte

1.添加第三方可以管理下载和上传 (上传未做 并且有屏蔽代码)

huangxiaodong 1 ano atrás
pai
commit
5655dd8cca
28 arquivos alterados com 4589 adições e 33 exclusões
  1. 182 0
      创维盒子/双子星云手机.xcodeproj/project.pbxproj
  2. 6 0
      创维盒子/双子星云手机/AppDelegate/PrefixHeader.pch
  3. 54 33
      创维盒子/双子星云手机/Class/Set/uploadFile/receiveView/receiveView.m
  4. 80 0
      创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/HWDownloadManager.h
  5. 17 0
      创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/NSString+SGHashString.h
  6. 43 0
      创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/NSString+SGHashString.m
  7. 22 0
      创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/NSURLSession+SGDownloadTask.h
  8. 42 0
      创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/NSURLSession+SGDownloadTask.m
  9. 59 0
      创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/SGCacheManager.h
  10. 219 0
      创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/SGCacheManager.m
  11. 90 0
      创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/SGDownloadManager.h
  12. 177 0
      创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/SGDownloadManager.m
  13. 100 0
      创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/SGDownloadOperation.h
  14. 268 0
      创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/SGDownloadOperation.m
  15. 55 0
      创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/SGDownloadQueue.h
  16. 406 0
      创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/SGDownloadQueue.m
  17. 37 0
      创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/SGDownloadSession.h
  18. 165 0
      创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/SGDownloadSession.m
  19. 184 0
      创维盒子/双子星云手机/Vendor/UploadManager/CWUploadManage/CWFileManager.h
  20. 492 0
      创维盒子/双子星云手机/Vendor/UploadManager/CWUploadManage/CWFileManager.m
  21. 90 0
      创维盒子/双子星云手机/Vendor/UploadManager/CWUploadManage/CWFileStreamSeparation.h
  22. 451 0
      创维盒子/双子星云手机/Vendor/UploadManager/CWUploadManage/CWFileStreamSeparation.m
  23. 114 0
      创维盒子/双子星云手机/Vendor/UploadManager/CWUploadManage/CWFileUploadManager.h
  24. 572 0
      创维盒子/双子星云手机/Vendor/UploadManager/CWUploadManage/CWFileUploadManager.m
  25. 15 0
      创维盒子/双子星云手机/Vendor/UploadManager/CWUploadManage/CWUploadTask+CheckInfo.h
  26. 123 0
      创维盒子/双子星云手机/Vendor/UploadManager/CWUploadManage/CWUploadTask+CheckInfo.m
  27. 77 0
      创维盒子/双子星云手机/Vendor/UploadManager/CWUploadManage/CWUploadTask.h
  28. 449 0
      创维盒子/双子星云手机/Vendor/UploadManager/CWUploadManage/CWUploadTask.m

+ 182 - 0
创维盒子/双子星云手机.xcodeproj/project.pbxproj

@@ -467,6 +467,56 @@
 		6BA08F092C0187DD00A2242D /* boxDownloadFileRecordCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA08F072C0187DC00A2242D /* boxDownloadFileRecordCell.m */; };
 		6BA08F0A2C0187DD00A2242D /* boxDownloadFileRecordCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA08F062C0187DC00A2242D /* boxDownloadFileRecordCell.h */; };
 		6BA08F0B2C0187DD00A2242D /* boxDownloadFileRecordCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA08F072C0187DC00A2242D /* boxDownloadFileRecordCell.m */; };
+		6BA08F1D2C01D01100A2242D /* HWDownloadManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA08F0C2C01D01000A2242D /* HWDownloadManager.h */; };
+		6BA08F1E2C01D01100A2242D /* HWDownloadManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA08F0C2C01D01000A2242D /* HWDownloadManager.h */; };
+		6BA08F1F2C01D01100A2242D /* NSString+SGHashString.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA08F0D2C01D01000A2242D /* NSString+SGHashString.h */; };
+		6BA08F202C01D01100A2242D /* NSString+SGHashString.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA08F0D2C01D01000A2242D /* NSString+SGHashString.h */; };
+		6BA08F212C01D01100A2242D /* NSString+SGHashString.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA08F0E2C01D01000A2242D /* NSString+SGHashString.m */; };
+		6BA08F222C01D01100A2242D /* NSString+SGHashString.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA08F0E2C01D01000A2242D /* NSString+SGHashString.m */; };
+		6BA08F232C01D01100A2242D /* NSURLSession+SGDownloadTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA08F0F2C01D01000A2242D /* NSURLSession+SGDownloadTask.h */; };
+		6BA08F242C01D01100A2242D /* NSURLSession+SGDownloadTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA08F0F2C01D01000A2242D /* NSURLSession+SGDownloadTask.h */; };
+		6BA08F252C01D01100A2242D /* NSURLSession+SGDownloadTask.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA08F102C01D01000A2242D /* NSURLSession+SGDownloadTask.m */; };
+		6BA08F262C01D01100A2242D /* NSURLSession+SGDownloadTask.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA08F102C01D01000A2242D /* NSURLSession+SGDownloadTask.m */; };
+		6BA08F272C01D01100A2242D /* SGCacheManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA08F112C01D01000A2242D /* SGCacheManager.h */; };
+		6BA08F282C01D01100A2242D /* SGCacheManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA08F112C01D01000A2242D /* SGCacheManager.h */; };
+		6BA08F292C01D01100A2242D /* SGCacheManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA08F122C01D01000A2242D /* SGCacheManager.m */; };
+		6BA08F2A2C01D01100A2242D /* SGCacheManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA08F122C01D01000A2242D /* SGCacheManager.m */; };
+		6BA08F2B2C01D01100A2242D /* SGDownloadManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA08F132C01D01000A2242D /* SGDownloadManager.h */; };
+		6BA08F2C2C01D01100A2242D /* SGDownloadManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA08F132C01D01000A2242D /* SGDownloadManager.h */; };
+		6BA08F2D2C01D01100A2242D /* SGDownloadManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA08F142C01D01000A2242D /* SGDownloadManager.m */; };
+		6BA08F2E2C01D01100A2242D /* SGDownloadManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA08F142C01D01000A2242D /* SGDownloadManager.m */; };
+		6BA08F2F2C01D01100A2242D /* SGDownloadOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA08F152C01D01000A2242D /* SGDownloadOperation.h */; };
+		6BA08F302C01D01100A2242D /* SGDownloadOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA08F152C01D01000A2242D /* SGDownloadOperation.h */; };
+		6BA08F312C01D01100A2242D /* SGDownloadOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA08F162C01D01000A2242D /* SGDownloadOperation.m */; };
+		6BA08F322C01D01100A2242D /* SGDownloadOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA08F162C01D01000A2242D /* SGDownloadOperation.m */; };
+		6BA08F332C01D01100A2242D /* SGDownloadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA08F172C01D01000A2242D /* SGDownloadQueue.h */; };
+		6BA08F342C01D01100A2242D /* SGDownloadQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA08F172C01D01000A2242D /* SGDownloadQueue.h */; };
+		6BA08F352C01D01100A2242D /* SGDownloadQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA08F182C01D01000A2242D /* SGDownloadQueue.m */; };
+		6BA08F362C01D01100A2242D /* SGDownloadQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA08F182C01D01000A2242D /* SGDownloadQueue.m */; };
+		6BA08F372C01D01100A2242D /* SGDownloadSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA08F192C01D01000A2242D /* SGDownloadSession.h */; };
+		6BA08F382C01D01100A2242D /* SGDownloadSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA08F192C01D01000A2242D /* SGDownloadSession.h */; };
+		6BA08F392C01D01100A2242D /* SGDownloadSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA08F1A2C01D01000A2242D /* SGDownloadSession.m */; };
+		6BA08F3A2C01D01100A2242D /* SGDownloadSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA08F1A2C01D01000A2242D /* SGDownloadSession.m */; };
+		6BA08F472C01D05B00A2242D /* CWFileManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA08F3B2C01D05B00A2242D /* CWFileManager.h */; };
+		6BA08F482C01D05B00A2242D /* CWFileManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA08F3B2C01D05B00A2242D /* CWFileManager.h */; };
+		6BA08F492C01D05B00A2242D /* CWFileManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA08F3C2C01D05B00A2242D /* CWFileManager.m */; };
+		6BA08F4A2C01D05B00A2242D /* CWFileManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA08F3C2C01D05B00A2242D /* CWFileManager.m */; };
+		6BA08F4B2C01D05B00A2242D /* CWFileStreamSeparation.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA08F3D2C01D05B00A2242D /* CWFileStreamSeparation.h */; };
+		6BA08F4C2C01D05B00A2242D /* CWFileStreamSeparation.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA08F3D2C01D05B00A2242D /* CWFileStreamSeparation.h */; };
+		6BA08F4D2C01D05B00A2242D /* CWFileStreamSeparation.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA08F3E2C01D05B00A2242D /* CWFileStreamSeparation.m */; };
+		6BA08F4E2C01D05B00A2242D /* CWFileStreamSeparation.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA08F3E2C01D05B00A2242D /* CWFileStreamSeparation.m */; };
+		6BA08F4F2C01D05B00A2242D /* CWFileUploadManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA08F3F2C01D05B00A2242D /* CWFileUploadManager.h */; };
+		6BA08F502C01D05B00A2242D /* CWFileUploadManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA08F3F2C01D05B00A2242D /* CWFileUploadManager.h */; };
+		6BA08F512C01D05B00A2242D /* CWFileUploadManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA08F402C01D05B00A2242D /* CWFileUploadManager.m */; };
+		6BA08F522C01D05B00A2242D /* CWFileUploadManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA08F402C01D05B00A2242D /* CWFileUploadManager.m */; };
+		6BA08F532C01D05B00A2242D /* CWUploadTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA08F412C01D05B00A2242D /* CWUploadTask.h */; };
+		6BA08F542C01D05B00A2242D /* CWUploadTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA08F412C01D05B00A2242D /* CWUploadTask.h */; };
+		6BA08F552C01D05B00A2242D /* CWUploadTask.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA08F422C01D05B00A2242D /* CWUploadTask.m */; };
+		6BA08F562C01D05B00A2242D /* CWUploadTask.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA08F422C01D05B00A2242D /* CWUploadTask.m */; };
+		6BA08F572C01D05B00A2242D /* CWUploadTask+CheckInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA08F432C01D05B00A2242D /* CWUploadTask+CheckInfo.h */; };
+		6BA08F582C01D05B00A2242D /* CWUploadTask+CheckInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA08F432C01D05B00A2242D /* CWUploadTask+CheckInfo.h */; };
+		6BA08F592C01D05B00A2242D /* CWUploadTask+CheckInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA08F442C01D05B00A2242D /* CWUploadTask+CheckInfo.m */; };
+		6BA08F5A2C01D05B00A2242D /* CWUploadTask+CheckInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA08F442C01D05B00A2242D /* CWUploadTask+CheckInfo.m */; };
 		6BA533382B16E65500D1CB5C /* TvStatusModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA533362B16E65500D1CB5C /* TvStatusModel.h */; };
 		6BA533392B16E65500D1CB5C /* TvStatusModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BA533372B16E65500D1CB5C /* TvStatusModel.m */; };
 		6BBB35D92AE7645200E4A59B /* RunInBackground.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 6BBB35D62AE7645200E4A59B /* RunInBackground.mp3 */; };
@@ -1398,6 +1448,31 @@
 		6B97143E2BCD00C900CE0096 /* ComontAlretType2ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ComontAlretType2ViewController.m; sourceTree = "<group>"; };
 		6BA08F062C0187DC00A2242D /* boxDownloadFileRecordCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = boxDownloadFileRecordCell.h; sourceTree = "<group>"; };
 		6BA08F072C0187DC00A2242D /* boxDownloadFileRecordCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = boxDownloadFileRecordCell.m; sourceTree = "<group>"; };
+		6BA08F0C2C01D01000A2242D /* HWDownloadManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HWDownloadManager.h; sourceTree = "<group>"; };
+		6BA08F0D2C01D01000A2242D /* NSString+SGHashString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+SGHashString.h"; sourceTree = "<group>"; };
+		6BA08F0E2C01D01000A2242D /* NSString+SGHashString.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+SGHashString.m"; sourceTree = "<group>"; };
+		6BA08F0F2C01D01000A2242D /* NSURLSession+SGDownloadTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURLSession+SGDownloadTask.h"; sourceTree = "<group>"; };
+		6BA08F102C01D01000A2242D /* NSURLSession+SGDownloadTask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURLSession+SGDownloadTask.m"; sourceTree = "<group>"; };
+		6BA08F112C01D01000A2242D /* SGCacheManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SGCacheManager.h; sourceTree = "<group>"; };
+		6BA08F122C01D01000A2242D /* SGCacheManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SGCacheManager.m; sourceTree = "<group>"; };
+		6BA08F132C01D01000A2242D /* SGDownloadManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SGDownloadManager.h; sourceTree = "<group>"; };
+		6BA08F142C01D01000A2242D /* SGDownloadManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SGDownloadManager.m; sourceTree = "<group>"; };
+		6BA08F152C01D01000A2242D /* SGDownloadOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SGDownloadOperation.h; sourceTree = "<group>"; };
+		6BA08F162C01D01000A2242D /* SGDownloadOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SGDownloadOperation.m; sourceTree = "<group>"; };
+		6BA08F172C01D01000A2242D /* SGDownloadQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SGDownloadQueue.h; sourceTree = "<group>"; };
+		6BA08F182C01D01000A2242D /* SGDownloadQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SGDownloadQueue.m; sourceTree = "<group>"; };
+		6BA08F192C01D01000A2242D /* SGDownloadSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SGDownloadSession.h; sourceTree = "<group>"; };
+		6BA08F1A2C01D01000A2242D /* SGDownloadSession.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SGDownloadSession.m; sourceTree = "<group>"; };
+		6BA08F3B2C01D05B00A2242D /* CWFileManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CWFileManager.h; sourceTree = "<group>"; };
+		6BA08F3C2C01D05B00A2242D /* CWFileManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CWFileManager.m; sourceTree = "<group>"; };
+		6BA08F3D2C01D05B00A2242D /* CWFileStreamSeparation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CWFileStreamSeparation.h; sourceTree = "<group>"; };
+		6BA08F3E2C01D05B00A2242D /* CWFileStreamSeparation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CWFileStreamSeparation.m; sourceTree = "<group>"; };
+		6BA08F3F2C01D05B00A2242D /* CWFileUploadManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CWFileUploadManager.h; sourceTree = "<group>"; };
+		6BA08F402C01D05B00A2242D /* CWFileUploadManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CWFileUploadManager.m; sourceTree = "<group>"; };
+		6BA08F412C01D05B00A2242D /* CWUploadTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CWUploadTask.h; sourceTree = "<group>"; };
+		6BA08F422C01D05B00A2242D /* CWUploadTask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CWUploadTask.m; sourceTree = "<group>"; };
+		6BA08F432C01D05B00A2242D /* CWUploadTask+CheckInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CWUploadTask+CheckInfo.h"; sourceTree = "<group>"; };
+		6BA08F442C01D05B00A2242D /* CWUploadTask+CheckInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CWUploadTask+CheckInfo.m"; sourceTree = "<group>"; };
 		6BA533362B16E65500D1CB5C /* TvStatusModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TvStatusModel.h; sourceTree = "<group>"; };
 		6BA533372B16E65500D1CB5C /* TvStatusModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TvStatusModel.m; sourceTree = "<group>"; };
 		6BBB35D62AE7645200E4A59B /* RunInBackground.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = RunInBackground.mp3; sourceTree = "<group>"; };
@@ -2396,6 +2471,61 @@
 			path = model;
 			sourceTree = "<group>";
 		};
+		6BA08F1B2C01D01000A2242D /* SGDwonload */ = {
+			isa = PBXGroup;
+			children = (
+				6BA08F0C2C01D01000A2242D /* HWDownloadManager.h */,
+				6BA08F0D2C01D01000A2242D /* NSString+SGHashString.h */,
+				6BA08F0E2C01D01000A2242D /* NSString+SGHashString.m */,
+				6BA08F0F2C01D01000A2242D /* NSURLSession+SGDownloadTask.h */,
+				6BA08F102C01D01000A2242D /* NSURLSession+SGDownloadTask.m */,
+				6BA08F112C01D01000A2242D /* SGCacheManager.h */,
+				6BA08F122C01D01000A2242D /* SGCacheManager.m */,
+				6BA08F132C01D01000A2242D /* SGDownloadManager.h */,
+				6BA08F142C01D01000A2242D /* SGDownloadManager.m */,
+				6BA08F152C01D01000A2242D /* SGDownloadOperation.h */,
+				6BA08F162C01D01000A2242D /* SGDownloadOperation.m */,
+				6BA08F172C01D01000A2242D /* SGDownloadQueue.h */,
+				6BA08F182C01D01000A2242D /* SGDownloadQueue.m */,
+				6BA08F192C01D01000A2242D /* SGDownloadSession.h */,
+				6BA08F1A2C01D01000A2242D /* SGDownloadSession.m */,
+			);
+			path = SGDwonload;
+			sourceTree = "<group>";
+		};
+		6BA08F1C2C01D01000A2242D /* DownLoadManager */ = {
+			isa = PBXGroup;
+			children = (
+				6BA08F1B2C01D01000A2242D /* SGDwonload */,
+			);
+			path = DownLoadManager;
+			sourceTree = "<group>";
+		};
+		6BA08F452C01D05B00A2242D /* CWUploadManage */ = {
+			isa = PBXGroup;
+			children = (
+				6BA08F3B2C01D05B00A2242D /* CWFileManager.h */,
+				6BA08F3C2C01D05B00A2242D /* CWFileManager.m */,
+				6BA08F3D2C01D05B00A2242D /* CWFileStreamSeparation.h */,
+				6BA08F3E2C01D05B00A2242D /* CWFileStreamSeparation.m */,
+				6BA08F3F2C01D05B00A2242D /* CWFileUploadManager.h */,
+				6BA08F402C01D05B00A2242D /* CWFileUploadManager.m */,
+				6BA08F412C01D05B00A2242D /* CWUploadTask.h */,
+				6BA08F422C01D05B00A2242D /* CWUploadTask.m */,
+				6BA08F432C01D05B00A2242D /* CWUploadTask+CheckInfo.h */,
+				6BA08F442C01D05B00A2242D /* CWUploadTask+CheckInfo.m */,
+			);
+			path = CWUploadManage;
+			sourceTree = "<group>";
+		};
+		6BA08F462C01D05B00A2242D /* UploadManager */ = {
+			isa = PBXGroup;
+			children = (
+				6BA08F452C01D05B00A2242D /* CWUploadManage */,
+			);
+			path = UploadManager;
+			sourceTree = "<group>";
+		};
 		6BBB35D42AE7645200E4A59B /* BackgroundKeepAlive */ = {
 			isa = PBXGroup;
 			children = (
@@ -2509,6 +2639,8 @@
 		A003F6B727D841FF00715CBF /* Vendor */ = {
 			isa = PBXGroup;
 			children = (
+				6BA08F462C01D05B00A2242D /* UploadManager */,
+				6BA08F1C2C01D01000A2242D /* DownLoadManager */,
 				6B5BE5A52BFCCA1F00A1B9B3 /* TBPlayer */,
 				6B304E9C2BEF6879004F5580 /* TencentOpenAPI.framework */,
 				6BBB35DF2AE935C000E4A59B /* DDYLanguageTool */,
@@ -2846,6 +2978,7 @@
 				6B93548F2BF30A8C00AA8D31 /* editTypeBottomView.h in Headers */,
 				6BFF26992AFA16DA00FCB4F7 /* forgetSecretKeyViewController.h in Headers */,
 				6B45C4FD2B57BC87007E6911 /* cloudPhoneExtraFileListModel.h in Headers */,
+				6BA08F1D2C01D01100A2242D /* HWDownloadManager.h in Headers */,
 				6BFF26912AF9D88200FCB4F7 /* AuthCodeTextField.h in Headers */,
 				6B5D403B2B4BFEB9000965CF /* PlayerViewController+downloadThumbnailImage.h in Headers */,
 				184C8ADA2A949DAC00F26650 /* HaveNewVersionView.h in Headers */,
@@ -2860,6 +2993,7 @@
 				6B467BB32BC7E4360039A6A6 /* addLogObject.h in Headers */,
 				183AE6D12A8CA98C00B11CB0 /* CloudPhoneAPI.h in Headers */,
 				6B07AC252BF85859005C2B0E /* ShareRecordModel.h in Headers */,
+				6BA08F372C01D01100A2242D /* SGDownloadSession.h in Headers */,
 				6B5BE5932BFCA5FA00A1B9B3 /* videoPlayViewController.h in Headers */,
 				1868201D2AB97BE1005702A6 /* TipsQRCodeViewController.h in Headers */,
 				6B5B60602B3BC8DE009A2AE2 /* fileTransferPopView.h in Headers */,
@@ -2876,6 +3010,7 @@
 				6B1FBD262B4503E700926382 /* photosBackupsTaskModel.h in Headers */,
 				6B34DC4E2BF1BA11002DD1EF /* previewImageOrVideoViewController.h in Headers */,
 				6BFF26882AF8949F00FCB4F7 /* playerShowSecretkeyView.h in Headers */,
+				6BA08F4F2C01D05B00A2242D /* CWFileUploadManager.h in Headers */,
 				6B5BE5B42BFCCA2000A1B9B3 /* TBPlayer.h in Headers */,
 				6BF0F3D52AD3937B000AA133 /* DeviceThirdIdModel.h in Headers */,
 				6B2170982B15CD9200656670 /* NSDictionary+Log.h in Headers */,
@@ -2891,6 +3026,7 @@
 				6BF0F3D02AD391D8000AA133 /* connectDeviceManager.h in Headers */,
 				6B7EA7A42BF607FB002D5CC2 /* imageDetailsScrollViewController.h in Headers */,
 				6BFF26952AF9D8CC00FCB4F7 /* AuthCodeInputView.h in Headers */,
+				6BA08F232C01D01100A2242D /* NSURLSession+SGDownloadTask.h in Headers */,
 				6B1CC2C62B677F3E00AD4217 /* extraMediaEventModel.h in Headers */,
 				6B5B607A2B3E71B6009A2AE2 /* filePathCreatTableViewCell.h in Headers */,
 				18FCE5442AD136FF0020F623 /* ShortcutManager.h in Headers */,
@@ -2904,6 +3040,7 @@
 				18FCE53E2AD136670020F623 /* PlayerViewController+AdjustBtnFrame.h in Headers */,
 				6B5BE5812BFC81E300A1B9B3 /* NASFileAndFolderModel.h in Headers */,
 				6B7EA7BC2BF759AC002D5CC2 /* shareSecretTableViewCell.h in Headers */,
+				6BA08F472C01D05B00A2242D /* CWFileManager.h in Headers */,
 				6B05815B2AFC851E00D37290 /* mySetHeadView.h in Headers */,
 				6BF52CAD2AD82EA500A617DB /* PlayerControlButTipView.h in Headers */,
 				6B1FBD2A2B452B3800926382 /* backupsFileManager.h in Headers */,
@@ -2911,14 +3048,17 @@
 				6B4D23B12B33DDBC005B718A /* imageVersionRenewTipView.h in Headers */,
 				6B0582892B045E0B00D37290 /* uploadFileDataModel.h in Headers */,
 				6BA08F082C0187DD00A2242D /* boxDownloadFileRecordCell.h in Headers */,
+				6BA08F572C01D05B00A2242D /* CWUploadTask+CheckInfo.h in Headers */,
 				6BF52C972AD5546500A617DB /* SimplePing.h in Headers */,
 				6B3F96342AD2A15A008E349E /* netWorkManager.h in Headers */,
+				6BA08F332C01D01100A2242D /* SGDownloadQueue.h in Headers */,
 				6B7EA7B02BF73DEB002D5CC2 /* addShareModel.h in Headers */,
 				6B21708C2B14BDAA00656670 /* couldphoneSysInfoModel.h in Headers */,
 				6B72724F2B0B58E500C03F87 /* uploadFileRecordEditBottomView.h in Headers */,
 				6B6ABEE02BFF3DD000480BAC /* receiveHeadView.h in Headers */,
 				184C8ADD2A949DBD00F26650 /* HWVersionModel.h in Headers */,
 				6B05826F2AFF692700D37290 /* photoPreViewBottomView.h in Headers */,
+				6BA08F4B2C01D05B00A2242D /* CWFileStreamSeparation.h in Headers */,
 				6B7B65582AD9227700BE8CB3 /* PlayerViewController+otherDelegate.h in Headers */,
 				6B7272572B0DAF7600C03F87 /* couldPhoneBaseInfoModel.h in Headers */,
 				186820212AB98600005702A6 /* QRCodeScanViewController.h in Headers */,
@@ -2941,11 +3081,14 @@
 				6BED888E2B4E901900F76DDC /* downloadFileRecordCell.h in Headers */,
 				184C8ACC2A94557200F26650 /* HidenMaskSetViewController.h in Headers */,
 				6B6ABEF22BFF6B4C00480BAC /* boxSaveFileManager.h in Headers */,
+				6BA08F532C01D05B00A2242D /* CWUploadTask.h in Headers */,
 				6B9714402BCD00CA00CE0096 /* ComontAlretType2ViewController.h in Headers */,
 				18EC79DC2ABC109F0084836A /* SetPWDSecondViewController.h in Headers */,
 				6B1F7FCA2C0064B500954720 /* boxReceiveFileRecordCell.h in Headers */,
 				6B0582852B0457C400D37290 /* uploadFileManager.h in Headers */,
+				6BA08F1F2C01D01100A2242D /* NSString+SGHashString.h in Headers */,
 				6B9354A12BF37D2D00AA8D31 /* previewAudioOrDocumentViewController.h in Headers */,
+				6BA08F272C01D01100A2242D /* SGCacheManager.h in Headers */,
 				6B467BB92BC7F7D70039A6A6 /* fileUploadToFileCenterModel.h in Headers */,
 				6BFF268C2AF8E1C600FCB4F7 /* forgetPwdViewController.h in Headers */,
 				6BF52C992AD5546500A617DB /* Reachability.h in Headers */,
@@ -2975,6 +3118,7 @@
 				6B1FBD322B455DBD00926382 /* PlayerViewController+upLoadFile.h in Headers */,
 				6B72725B2B0E22D000C03F87 /* uploadFileRecordBgScorllView.h in Headers */,
 				6B1F7FD62C00772500954720 /* boxDownloadFileManager.h in Headers */,
+				6BA08F2B2C01D01100A2242D /* SGDownloadManager.h in Headers */,
 				18A909982ABC4A3300E6D2BE /* ComontAlretViewController.h in Headers */,
 				6B7272532B0CABC600C03F87 /* cachesFileManager.h in Headers */,
 				6B1FBD3E2B46875300926382 /* backupsFileRecordCell.h in Headers */,
@@ -2994,6 +3138,7 @@
 				6B7EA79E2BF5E0ED002D5CC2 /* NASMsgModel.h in Headers */,
 				18664FF62AC2B3A4008F8A61 /* ShearDeviceUDPManager.h in Headers */,
 				6B5BE5872BFC8B0B00A1B9B3 /* previewFileAndFolderSecondViewController.h in Headers */,
+				6BA08F2F2C01D01100A2242D /* SGDownloadOperation.h in Headers */,
 				18F9CAFF2ABD3643003FF71A /* ModifyPWDSecondViewController.h in Headers */,
 				6BF52CA12AD7C2F600A617DB /* inputPWDViewController.h in Headers */,
 				6B7EA7B62BF74BDB002D5CC2 /* shareBySecretView.h in Headers */,
@@ -3018,6 +3163,7 @@
 				6B9354902BF30A8C00AA8D31 /* editTypeBottomView.h in Headers */,
 				6BD5069F2B9576A4006E7CB0 /* forgetSecretKeyViewController.h in Headers */,
 				6BD506A02B9576A4006E7CB0 /* cloudPhoneExtraFileListModel.h in Headers */,
+				6BA08F1E2C01D01100A2242D /* HWDownloadManager.h in Headers */,
 				6BD506A12B9576A4006E7CB0 /* AuthCodeTextField.h in Headers */,
 				6BD506A22B9576A4006E7CB0 /* PlayerViewController+downloadThumbnailImage.h in Headers */,
 				6BD506A32B9576A4006E7CB0 /* HaveNewVersionView.h in Headers */,
@@ -3032,6 +3178,7 @@
 				6B467BB52BC7E4360039A6A6 /* addLogObject.h in Headers */,
 				6BD506A92B9576A4006E7CB0 /* CloudPhoneAPI.h in Headers */,
 				6B07AC282BF85859005C2B0E /* ShareRecordModel.h in Headers */,
+				6BA08F382C01D01100A2242D /* SGDownloadSession.h in Headers */,
 				6B5BE5952BFCA5FA00A1B9B3 /* videoPlayViewController.h in Headers */,
 				6BD506AA2B9576A4006E7CB0 /* TipsQRCodeViewController.h in Headers */,
 				6BD506AB2B9576A4006E7CB0 /* fileTransferPopView.h in Headers */,
@@ -3048,6 +3195,7 @@
 				6BD506B62B9576A4006E7CB0 /* photosBackupsTaskModel.h in Headers */,
 				6B34DC502BF1BA11002DD1EF /* previewImageOrVideoViewController.h in Headers */,
 				6BD506B72B9576A4006E7CB0 /* playerShowSecretkeyView.h in Headers */,
+				6BA08F502C01D05B00A2242D /* CWFileUploadManager.h in Headers */,
 				6B5BE5B52BFCCA2000A1B9B3 /* TBPlayer.h in Headers */,
 				6BD506B82B9576A4006E7CB0 /* DeviceThirdIdModel.h in Headers */,
 				6BD506B92B9576A4006E7CB0 /* NSDictionary+Log.h in Headers */,
@@ -3063,6 +3211,7 @@
 				6BD506C12B9576A4006E7CB0 /* connectDeviceManager.h in Headers */,
 				6B7EA7A62BF607FB002D5CC2 /* imageDetailsScrollViewController.h in Headers */,
 				6BD506C22B9576A4006E7CB0 /* AuthCodeInputView.h in Headers */,
+				6BA08F242C01D01100A2242D /* NSURLSession+SGDownloadTask.h in Headers */,
 				6BD506C32B9576A4006E7CB0 /* extraMediaEventModel.h in Headers */,
 				6BD506C42B9576A4006E7CB0 /* filePathCreatTableViewCell.h in Headers */,
 				6BD506C52B9576A4006E7CB0 /* ShortcutManager.h in Headers */,
@@ -3076,6 +3225,7 @@
 				6BD506CB2B9576A4006E7CB0 /* PlayerViewController+AdjustBtnFrame.h in Headers */,
 				6B5BE5832BFC81E300A1B9B3 /* NASFileAndFolderModel.h in Headers */,
 				6B7EA7BE2BF759AC002D5CC2 /* shareSecretTableViewCell.h in Headers */,
+				6BA08F482C01D05B00A2242D /* CWFileManager.h in Headers */,
 				6BD506CC2B9576A4006E7CB0 /* mySetHeadView.h in Headers */,
 				6BD506CD2B9576A4006E7CB0 /* PlayerControlButTipView.h in Headers */,
 				6BD506CE2B9576A4006E7CB0 /* backupsFileManager.h in Headers */,
@@ -3083,14 +3233,17 @@
 				6BD506D02B9576A4006E7CB0 /* imageVersionRenewTipView.h in Headers */,
 				6BD506D12B9576A4006E7CB0 /* uploadFileDataModel.h in Headers */,
 				6BA08F0A2C0187DD00A2242D /* boxDownloadFileRecordCell.h in Headers */,
+				6BA08F582C01D05B00A2242D /* CWUploadTask+CheckInfo.h in Headers */,
 				6BD506D22B9576A4006E7CB0 /* SimplePing.h in Headers */,
 				6BD506D32B9576A4006E7CB0 /* netWorkManager.h in Headers */,
+				6BA08F342C01D01100A2242D /* SGDownloadQueue.h in Headers */,
 				6B7EA7B22BF73DEB002D5CC2 /* addShareModel.h in Headers */,
 				6BD506D42B9576A4006E7CB0 /* couldphoneSysInfoModel.h in Headers */,
 				6BD506D52B9576A4006E7CB0 /* uploadFileRecordEditBottomView.h in Headers */,
 				6B6ABEE22BFF3DD000480BAC /* receiveHeadView.h in Headers */,
 				6BD506D62B9576A4006E7CB0 /* HWVersionModel.h in Headers */,
 				6BD506D72B9576A4006E7CB0 /* photoPreViewBottomView.h in Headers */,
+				6BA08F4C2C01D05B00A2242D /* CWFileStreamSeparation.h in Headers */,
 				6BD506D82B9576A4006E7CB0 /* PlayerViewController+otherDelegate.h in Headers */,
 				6BD506D92B9576A4006E7CB0 /* couldPhoneBaseInfoModel.h in Headers */,
 				6BD506DA2B9576A4006E7CB0 /* QRCodeScanViewController.h in Headers */,
@@ -3113,11 +3266,14 @@
 				6BD506E92B9576A4006E7CB0 /* downloadFileRecordCell.h in Headers */,
 				6BD506EA2B9576A4006E7CB0 /* HidenMaskSetViewController.h in Headers */,
 				6B6ABEF42BFF6B4C00480BAC /* boxSaveFileManager.h in Headers */,
+				6BA08F542C01D05B00A2242D /* CWUploadTask.h in Headers */,
 				6B9714412BCD00CA00CE0096 /* ComontAlretType2ViewController.h in Headers */,
 				6BD506EB2B9576A4006E7CB0 /* SetPWDSecondViewController.h in Headers */,
 				6B1F7FCC2C0064B500954720 /* boxReceiveFileRecordCell.h in Headers */,
 				6BD506EC2B9576A4006E7CB0 /* uploadFileManager.h in Headers */,
+				6BA08F202C01D01100A2242D /* NSString+SGHashString.h in Headers */,
 				6B9354A22BF37D2D00AA8D31 /* previewAudioOrDocumentViewController.h in Headers */,
+				6BA08F282C01D01100A2242D /* SGCacheManager.h in Headers */,
 				6B467BBB2BC7F7D70039A6A6 /* fileUploadToFileCenterModel.h in Headers */,
 				6BD506ED2B9576A4006E7CB0 /* forgetPwdViewController.h in Headers */,
 				6BD506EE2B9576A4006E7CB0 /* Reachability.h in Headers */,
@@ -3147,6 +3303,7 @@
 				6BD506FC2B9576A4006E7CB0 /* PlayerViewController+upLoadFile.h in Headers */,
 				6BD506FD2B9576A4006E7CB0 /* uploadFileRecordBgScorllView.h in Headers */,
 				6B1F7FD82C00772500954720 /* boxDownloadFileManager.h in Headers */,
+				6BA08F2C2C01D01100A2242D /* SGDownloadManager.h in Headers */,
 				6BD506FE2B9576A4006E7CB0 /* ComontAlretViewController.h in Headers */,
 				6BD506FF2B9576A4006E7CB0 /* cachesFileManager.h in Headers */,
 				6BD507002B9576A4006E7CB0 /* backupsFileRecordCell.h in Headers */,
@@ -3166,6 +3323,7 @@
 				6B7EA7A02BF5E0ED002D5CC2 /* NASMsgModel.h in Headers */,
 				6BD507072B9576A4006E7CB0 /* ShearDeviceUDPManager.h in Headers */,
 				6B5BE5892BFC8B0B00A1B9B3 /* previewFileAndFolderSecondViewController.h in Headers */,
+				6BA08F302C01D01100A2242D /* SGDownloadOperation.h in Headers */,
 				6BD507082B9576A4006E7CB0 /* ModifyPWDSecondViewController.h in Headers */,
 				6BD507092B9576A4006E7CB0 /* inputPWDViewController.h in Headers */,
 				6B7EA7B82BF74BDB002D5CC2 /* shareBySecretView.h in Headers */,
@@ -3563,6 +3721,7 @@
 				6BD507172B9576A4006E7CB0 /* fileTransferPopView.m in Sources */,
 				6BD507182B9576A4006E7CB0 /* Reachability.m in Sources */,
 				6BD507192B9576A4006E7CB0 /* ModifyPWDFirstViewController.m in Sources */,
+				6BA08F522C01D05B00A2242D /* CWFileUploadManager.m in Sources */,
 				6B1F7FCD2C0064B500954720 /* boxReceiveFileRecordCell.m in Sources */,
 				6BD5071A2B9576A4006E7CB0 /* AFURLResponseSerialization.m in Sources */,
 				6BD5071B2B9576A4006E7CB0 /* HWHistoryViewController.m in Sources */,
@@ -3574,6 +3733,7 @@
 				6BD507202B9576A4006E7CB0 /* NSArray+JSONModel.m in Sources */,
 				6BD507212B9576A4006E7CB0 /* HWAddBookmarkViewController.m in Sources */,
 				6BD507222B9576A4006E7CB0 /* AuthCodeTextField.m in Sources */,
+				6BA08F5A2C01D05B00A2242D /* CWUploadTask+CheckInfo.m in Sources */,
 				6BD507232B9576A4006E7CB0 /* ShearDeviceUDPManager.m in Sources */,
 				6BD507242B9576A4006E7CB0 /* filePathCreatPopView.m in Sources */,
 				6B9354AF2BF3879200AA8D31 /* shareRecordTableViewCell.m in Sources */,
@@ -3606,6 +3766,7 @@
 				6BD507372B9576A4006E7CB0 /* JSONModelError.m in Sources */,
 				6BD507382B9576A4006E7CB0 /* PlayerViewController+otherDelegate.mm in Sources */,
 				6BD507392B9576A4006E7CB0 /* downloadManager.m in Sources */,
+				6BA08F2E2C01D01100A2242D /* SGDownloadManager.m in Sources */,
 				6BD5073A2B9576A4006E7CB0 /* FMDatabaseQueue.m in Sources */,
 				6BD5073B2B9576A4006E7CB0 /* customLaunchView.m in Sources */,
 				6BD5073C2B9576A4006E7CB0 /* HWSetViewController.m in Sources */,
@@ -3658,6 +3819,7 @@
 				6B6ABEEF2BFF5B2F00480BAC /* receiveSaveRecordTableView.m in Sources */,
 				6BD507612B9576A4006E7CB0 /* FMDatabasePool.m in Sources */,
 				6BD507622B9576A4006E7CB0 /* iToast.m in Sources */,
+				6BA08F222C01D01100A2242D /* NSString+SGHashString.m in Sources */,
 				6BD507632B9576A4006E7CB0 /* HWPageListCell.m in Sources */,
 				6BD507642B9576A4006E7CB0 /* downloadFileRecordTableView.m in Sources */,
 				6BD507652B9576A4006E7CB0 /* HWHomeListCell.m in Sources */,
@@ -3671,6 +3833,7 @@
 				6BD5076B2B9576A4006E7CB0 /* JSONModel.m in Sources */,
 				6BD5076C2B9576A4006E7CB0 /* PlayerViewController+AppDelegate.m in Sources */,
 				6BD5076D2B9576A4006E7CB0 /* WHPingTester.m in Sources */,
+				6BA08F3A2C01D01100A2242D /* SGDownloadSession.m in Sources */,
 				6B467BB42BC7E4360039A6A6 /* addLogObject.m in Sources */,
 				6BD5076E2B9576A4006E7CB0 /* forgetPwdViewController.m in Sources */,
 				6BD5076F2B9576A4006E7CB0 /* uploadFileRecordTableViewHeadView.m in Sources */,
@@ -3682,8 +3845,10 @@
 				6B5BE5942BFCA5FA00A1B9B3 /* videoPlayViewController.m in Sources */,
 				6BD507742B9576A4006E7CB0 /* extraMediaEventModel.m in Sources */,
 				6BD507752B9576A4006E7CB0 /* couldPhoneFolderListModel.m in Sources */,
+				6BA08F362C01D01100A2242D /* SGDownloadQueue.m in Sources */,
 				6BD507762B9576A4006E7CB0 /* backupsFileManager.m in Sources */,
 				6BD507772B9576A4006E7CB0 /* forgetSecretKeyViewController.m in Sources */,
+				6BA08F262C01D01100A2242D /* NSURLSession+SGDownloadTask.m in Sources */,
 				6BD507782B9576A4006E7CB0 /* UITextfield+NLLimit.m in Sources */,
 				6BD507792B9576A4006E7CB0 /* ShowImageView.m in Sources */,
 				6B7EA7B92BF74BDB002D5CC2 /* shareBySecretView.m in Sources */,
@@ -3718,6 +3883,7 @@
 				6BD507912B9576A4006E7CB0 /* HWVersionModel.m in Sources */,
 				6B5BE57C2BFC767100A1B9B3 /* previewFileAndFolderViewController.m in Sources */,
 				6BD507922B9576A4006E7CB0 /* NSArray+Log.m in Sources */,
+				6BA08F4E2C01D05B00A2242D /* CWFileStreamSeparation.m in Sources */,
 				6BD507932B9576A4006E7CB0 /* ConnectTestViewController.m in Sources */,
 				6BD507942B9576A4006E7CB0 /* downloadFileRecordCell.m in Sources */,
 				6BD507952B9576A4006E7CB0 /* UIProgressView+AFNetworking.m in Sources */,
@@ -3731,12 +3897,14 @@
 				6BD5079D2B9576A4006E7CB0 /* UITextfield+NLLimit.m in Sources */,
 				6BD5079E2B9576A4006E7CB0 /* backupsFileRecordCell.m in Sources */,
 				6BD5079F2B9576A4006E7CB0 /* downLoadPreviewViewController.m in Sources */,
+				6BA08F2A2C01D01100A2242D /* SGCacheManager.m in Sources */,
 				6BD507A02B9576A4006E7CB0 /* playerShowSecretkeyView.m in Sources */,
 				6BD507A12B9576A4006E7CB0 /* uploadFileRecordCell.m in Sources */,
 				6BD507A22B9576A4006E7CB0 /* BaseNavigationController.m in Sources */,
 				6B34DC4F2BF1BA11002DD1EF /* previewImageOrVideoViewController.m in Sources */,
 				6BD507A32B9576A4006E7CB0 /* HWFolderModel.m in Sources */,
 				6BD507A42B9576A4006E7CB0 /* fileTransferPathCheckViewController.m in Sources */,
+				6BA08F562C01D05B00A2242D /* CWUploadTask.m in Sources */,
 				6B9354A92BF3848D00AA8D31 /* shareRecordViewController.m in Sources */,
 				6B7EA7A72BF607FB002D5CC2 /* imageDetailsScrollViewController.m in Sources */,
 				6BD507A52B9576A4006E7CB0 /* RCCommandHelp.m in Sources */,
@@ -3773,10 +3941,12 @@
 				6BD507C12B9576A4006E7CB0 /* FLAnimatedImageView.m in Sources */,
 				6BEA31772BB65606005167AA /* clearCacheAlretViewController.m in Sources */,
 				6BD507C22B9576A4006E7CB0 /* DeviceThirdIdModel.m in Sources */,
+				6BA08F322C01D01100A2242D /* SGDownloadOperation.m in Sources */,
 				6B07AC2D2BF8D38F005C2B0E /* NASFileAudioModel.m in Sources */,
 				6B9354A32BF37D2D00AA8D31 /* previewAudioOrDocumentViewController.m in Sources */,
 				6BD507C32B9576A4006E7CB0 /* HidenMaskSetViewController.m in Sources */,
 				6BD507C42B9576A4006E7CB0 /* filePathCreatTableViewCell.m in Sources */,
+				6BA08F4A2C01D05B00A2242D /* CWFileManager.m in Sources */,
 				6B6ABEE32BFF3DD000480BAC /* receiveHeadView.m in Sources */,
 				6BD507C52B9576A4006E7CB0 /* commandSendCheckModel.m in Sources */,
 				6BD507C62B9576A4006E7CB0 /* GuideView.m in Sources */,
@@ -3820,6 +3990,7 @@
 				6B5B60612B3BC8DE009A2AE2 /* fileTransferPopView.m in Sources */,
 				6BF52C962AD5546500A617DB /* Reachability.m in Sources */,
 				18F9CAFB2ABD35C4003FF71A /* ModifyPWDFirstViewController.m in Sources */,
+				6BA08F512C01D05B00A2242D /* CWFileUploadManager.m in Sources */,
 				6B1F7FCB2C0064B500954720 /* boxReceiveFileRecordCell.m in Sources */,
 				183AE6542A8A2CF000B11CB0 /* AFURLResponseSerialization.m in Sources */,
 				A0295B1227ED938B009C5D8B /* HWHistoryViewController.m in Sources */,
@@ -3831,6 +4002,7 @@
 				183AE6012A89CE3C00B11CB0 /* NSArray+JSONModel.m in Sources */,
 				A00221DB27EAFF4A00E45F78 /* HWAddBookmarkViewController.m in Sources */,
 				6BFF26922AF9D88200FCB4F7 /* AuthCodeTextField.m in Sources */,
+				6BA08F592C01D05B00A2242D /* CWUploadTask+CheckInfo.m in Sources */,
 				18664FF52AC2B3A4008F8A61 /* ShearDeviceUDPManager.m in Sources */,
 				6B5B60772B3E665E009A2AE2 /* filePathCreatPopView.m in Sources */,
 				6B9354AC2BF3879200AA8D31 /* shareRecordTableViewCell.m in Sources */,
@@ -3863,6 +4035,7 @@
 				183AE6052A89CE3C00B11CB0 /* JSONModelError.m in Sources */,
 				6B7B65592AD9227700BE8CB3 /* PlayerViewController+otherDelegate.mm in Sources */,
 				6B5D40402B4CE40F000965CF /* downloadManager.m in Sources */,
+				6BA08F2D2C01D01100A2242D /* SGDownloadManager.m in Sources */,
 				A08A950027E9A4E400C544BB /* FMDatabaseQueue.m in Sources */,
 				6BF52CA72AD7D3BE00A617DB /* customLaunchView.m in Sources */,
 				A031DD7A27EC713A00909527 /* HWSetViewController.m in Sources */,
@@ -3915,6 +4088,7 @@
 				6B6ABEED2BFF5B2F00480BAC /* receiveSaveRecordTableView.m in Sources */,
 				A08A950327E9A4E400C544BB /* FMDatabasePool.m in Sources */,
 				A003F6D327D8425C00715CBF /* iToast.m in Sources */,
+				6BA08F212C01D01100A2242D /* NSString+SGHashString.m in Sources */,
 				A08A94E027E9837600C544BB /* HWPageListCell.m in Sources */,
 				6BED888B2B4E819000F76DDC /* downloadFileRecordTableView.m in Sources */,
 				A084D69827E8657800054880 /* HWHomeListCell.m in Sources */,
@@ -3928,6 +4102,7 @@
 				183AE6042A89CE3C00B11CB0 /* JSONModel.m in Sources */,
 				18FCE5492AD15E750020F623 /* PlayerViewController+AppDelegate.m in Sources */,
 				6BF52C9A2AD5546500A617DB /* WHPingTester.m in Sources */,
+				6BA08F392C01D01100A2242D /* SGDownloadSession.m in Sources */,
 				6B467BB22BC7E4360039A6A6 /* addLogObject.m in Sources */,
 				6BFF268D2AF8E1C600FCB4F7 /* forgetPwdViewController.m in Sources */,
 				6B72724C2B0AF59200C03F87 /* uploadFileRecordTableViewHeadView.m in Sources */,
@@ -3939,8 +4114,10 @@
 				6B5BE5922BFCA5FA00A1B9B3 /* videoPlayViewController.m in Sources */,
 				6B1CC2C72B677F3E00AD4217 /* extraMediaEventModel.m in Sources */,
 				6B5D401B2B4A9850000965CF /* couldPhoneFolderListModel.m in Sources */,
+				6BA08F352C01D01100A2242D /* SGDownloadQueue.m in Sources */,
 				6B1FBD2B2B452B3800926382 /* backupsFileManager.m in Sources */,
 				6BFF269A2AFA16DA00FCB4F7 /* forgetSecretKeyViewController.m in Sources */,
+				6BA08F252C01D01100A2242D /* NSURLSession+SGDownloadTask.m in Sources */,
 				18E5572F2A3C6141005CC84B /* UITextfield+NLLimit.m in Sources */,
 				183AE6B72A8CA0C100B11CB0 /* ShowImageView.m in Sources */,
 				6B7EA7B72BF74BDB002D5CC2 /* shareBySecretView.m in Sources */,
@@ -3975,6 +4152,7 @@
 				184C8ADE2A949DBD00F26650 /* HWVersionModel.m in Sources */,
 				6B5BE57A2BFC767100A1B9B3 /* previewFileAndFolderViewController.m in Sources */,
 				6B21709D2B15CDB600656670 /* NSArray+Log.m in Sources */,
+				6BA08F4D2C01D05B00A2242D /* CWFileStreamSeparation.m in Sources */,
 				18FCE5352AD12FE00020F623 /* ConnectTestViewController.m in Sources */,
 				6BED888F2B4E901900F76DDC /* downloadFileRecordCell.m in Sources */,
 				183AE64C2A8A2CF000B11CB0 /* UIProgressView+AFNetworking.m in Sources */,
@@ -3988,12 +4166,14 @@
 				A003F6B427D841EE00715CBF /* UITextfield+NLLimit.m in Sources */,
 				6B1FBD3F2B46875300926382 /* backupsFileRecordCell.m in Sources */,
 				6B5D40242B4AA7BF000965CF /* downLoadPreviewViewController.m in Sources */,
+				6BA08F292C01D01100A2242D /* SGCacheManager.m in Sources */,
 				6BFF26892AF8949F00FCB4F7 /* playerShowSecretkeyView.m in Sources */,
 				6B8FF6C22B05B24D00800981 /* uploadFileRecordCell.m in Sources */,
 				A003F6A727D841C800715CBF /* BaseNavigationController.m in Sources */,
 				6B34DC4D2BF1BA11002DD1EF /* previewImageOrVideoViewController.m in Sources */,
 				A00221E427EB256D00E45F78 /* HWFolderModel.m in Sources */,
 				6B5B606F2B3D7E3B009A2AE2 /* fileTransferPathCheckViewController.m in Sources */,
+				6BA08F552C01D05B00A2242D /* CWUploadTask.m in Sources */,
 				6B9354A62BF3848D00AA8D31 /* shareRecordViewController.m in Sources */,
 				6B7EA7A52BF607FB002D5CC2 /* imageDetailsScrollViewController.m in Sources */,
 				183AE6B02A8C9EAB00B11CB0 /* RCCommandHelp.m in Sources */,
@@ -4030,10 +4210,12 @@
 				A003F6C127D841FF00715CBF /* FLAnimatedImageView.m in Sources */,
 				6BEA31762BB65606005167AA /* clearCacheAlretViewController.m in Sources */,
 				6BF0F3D62AD3937B000AA133 /* DeviceThirdIdModel.m in Sources */,
+				6BA08F312C01D01100A2242D /* SGDownloadOperation.m in Sources */,
 				6B07AC2C2BF8D38F005C2B0E /* NASFileAudioModel.m in Sources */,
 				6B9354A02BF37D2D00AA8D31 /* previewAudioOrDocumentViewController.m in Sources */,
 				184C8ACD2A94557200F26650 /* HidenMaskSetViewController.m in Sources */,
 				6B5B607B2B3E71B6009A2AE2 /* filePathCreatTableViewCell.m in Sources */,
+				6BA08F492C01D05B00A2242D /* CWFileManager.m in Sources */,
 				6B6ABEE12BFF3DD000480BAC /* receiveHeadView.m in Sources */,
 				6B1CC2CF2B6B6D6B00AD4217 /* commandSendCheckModel.m in Sources */,
 				18963B472AB84398006E7C50 /* GuideView.m in Sources */,

Diferenças do arquivo suprimidas por serem muito extensas
+ 6 - 0
创维盒子/双子星云手机/AppDelegate/PrefixHeader.pch


+ 54 - 33
创维盒子/双子星云手机/Class/Set/uploadFile/receiveView/receiveView.m

@@ -13,6 +13,7 @@
 #import "downStatusModel.h"
 #import "boxDownloadFileManager.h"
 #import "AFHTTPSessionManager.h"
+#import "SGDownloadManager.h"
 
 @interface receiveView ()
 {
@@ -32,6 +33,8 @@
     _isReceiveType = 1;
     [self drawAnyView];
     
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downloadTaskExeIng:) name:SGDownloadTaskExeing object:nil];
+
     return self;
 }
 
@@ -137,14 +140,32 @@
     }
 }
 
+- (void)downloadTaskExeIng:(NSNotification *)notification
+{
+    SGDownloadOperation *model = notification.userInfo.allValues.firstObject;
+    
+    mainBlock(^{
+        //[self refreshUIWithModel:model];
+    });
+    HLog(@"下载中 %lld",model.currentSize);
+}
+
 #pragma mark 获取本地数据库数据
 - (void)getAllDataFun{
     
-//    [self getBoxDownLoadDataFun];
-//    [self getBoxSaveDataFun];
+    [self getBoxDownLoadDataFun];
+    [self getBoxSaveDataFun];
     
-    NSString *urlstr = @"https://media.w3.org/2010/05/sintel/trailer.mp4";
-    NSString *url2 = @"http://transfertest.armclouding.com:11010/getFile?path=/mnt/media_rw/B80050B2005078F8/电影/IMG_0914.MP4";
+//    NSString *urlstr = @"https://media.w3.org/2010/05/sintel/trailer.mp4";
+//    NSString *url2 = @"http://transfertest.armclouding.com:11010/getFile?path=/mnt/media_rw/B80050B2005078F8/电影/IMG_0914.MP4";
+//    
+//    NSString* encodedUrl = [url2 stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
+//    NSURL *url = [NSURL URLWithString:encodedUrl];
+//    
+//    // 创建下载任务
+//    [[SGDownloadManager shareManager] downloadWithURL:url fileType:1 fileSize:0 complete:^(NSDictionary *respose, NSError *error) {
+//        HLog(@"%@---%@",respose, error);
+//    }];
     
 //    [[netWorkManager shareInstance] cloudPhoneDownloadCallBackCode:url success:^(id  _Nonnull responseObject) {
 //        
@@ -152,35 +173,35 @@
 //        
 //    }];
     
-    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
-    NSString *documentDir = [paths lastObject];
-    
-    
-    NSString* encodedUrl = [url2 stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
-    NSURL *url = [NSURL URLWithString:encodedUrl];
-    
-    NSURLRequest *request = [NSURLRequest requestWithURL:url];
-    NSURLSessionDownloadTask *task = [[AFHTTPSessionManager manager] downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
-          NSLog(@"%@", [NSString stringWithFormat:@"当前下载进度:%.2f%%",100.0 * downloadProgress.completedUnitCount / downloadProgress.totalUnitCount]);
-        } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
-            NSLog(@"临时文件路径: %@", targetPath);
-            
-            NSString *downloadPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent: @"Download"];
-            //打开文件管理器
-            NSFileManager *fileManager = [NSFileManager defaultManager];
-            //创建Download目录
-            [fileManager createDirectoryAtPath:downloadPath withIntermediateDirectories:YES attributes:nil error:nil];
-            //拼接文件路径
-            NSString *filePath = [downloadPath stringByAppendingPathComponent:response.suggestedFilename];
-            
-            NSURL *path = [NSURL fileURLWithPath:filePath];
-            [path URLByAppendingPathComponent:response.suggestedFilename];
-            return path;
-        } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
-            NSLog(@"本地存储路径: %@", filePath);
-        }];
-    
-    [task resume];
+//    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+//    NSString *documentDir = [paths lastObject];
+//    
+//    
+//    NSString* encodedUrl = [url2 stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
+//    NSURL *url = [NSURL URLWithString:encodedUrl];
+//    
+//    NSURLRequest *request = [NSURLRequest requestWithURL:url];
+//    NSURLSessionDownloadTask *task = [[AFHTTPSessionManager manager] downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
+//          NSLog(@"%@", [NSString stringWithFormat:@"当前下载进度:%.2f%%",100.0 * downloadProgress.completedUnitCount / downloadProgress.totalUnitCount]);
+//        } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
+//            NSLog(@"临时文件路径: %@", targetPath);
+//            
+//            NSString *downloadPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent: @"Download"];
+//            //打开文件管理器
+//            NSFileManager *fileManager = [NSFileManager defaultManager];
+//            //创建Download目录
+//            [fileManager createDirectoryAtPath:downloadPath withIntermediateDirectories:YES attributes:nil error:nil];
+//            //拼接文件路径
+//            NSString *filePath = [downloadPath stringByAppendingPathComponent:response.suggestedFilename];
+//            
+//            NSURL *path = [NSURL fileURLWithPath:filePath];
+//            [path URLByAppendingPathComponent:response.suggestedFilename];
+//            return path;
+//        } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
+//            NSLog(@"本地存储路径: %@", filePath);
+//        }];
+//    
+//    [task resume];
 }
 
 #pragma mark 读取保存到盒子的数据库

+ 80 - 0
创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/HWDownloadManager.h

@@ -0,0 +1,80 @@
+//
+//  HWDownloadManager.h
+//  VclustersGemini
+//
+//  Created by 余衡武 on 2020/4/24.
+//  Copyright © 2020 APPLE. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "SGDownloadManager.h"
+#import "SGDownloadSession.h"
+#import "SGDownloadQueue.h"
+#import "SGDownloadOperation.h"
+#import "SGCacheManager.h"
+#import "NSString+SGHashString.h"
+#import "NSURLSession+SGDownloadTask.h"
+#import "HWDownloadModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/** 下载中通知 */
+#define  SGDownloadTaskExeing        @"SGDownloadTaskExeing"
+/** 下载失败通知 */
+#define  SGDownloadTaskExeError      @"SGDownloadTaskExeError"
+/** 下载完成通知 */
+#define  SGDownloadTaskExeEnd        @"SGDownloadTaskExeEnd"
+/** 下载暂停/取消通知 */
+#define  SGDownloadTaskExeSuspend    @"SGDownloadTaskExeSuspend"
+/** 删除下载任务通知 */
+#define  SGDownloadTaskExeDelete     @"SGDownloadTaskExeDelete"
+/** 移除loading通知 */
+#define  SGDownloadRemoveLoading     @"SGDownloadRemoveLoading"
+
+@interface HWDownloadManager : NSObject
+
+
+/** 操作记录plist文件保存路径 */
+@property (nonatomic,copy)NSString *plistPath;
+/** 登录账号信息字典 */
+@property (nonatomic,copy)NSDictionary *LoginInfo;
+/** 总任务数 */
+@property (nonatomic,strong)NSMutableArray *allTasks;
+/** 正在下载中的任务 */
+@property (nonatomic,strong)NSMutableArray *downloadingTasks;
+/** 等待下载的任务 */
+@property (nonatomic,strong)NSMutableArray *downloadWaitTasks;
+/** 最大下载任务数 */
+@property (nonatomic, assign) int downloadMaxNum;
+
+
+
+//获得管理类单例对象
++ (instancetype)shardInstance;
+
+/** 创建下载任务 */
+- (void)creatDownloadTaskWithModel:(HWDownloadModel *)model;
+
+/** 开启所有下载任务 */
+- (void)startAllDownloadTask;
+/** 暂停所有下载任务 */
+- (void)pauseAllDownloadTask;
+/** 清除所有下载任务 */
+- (void)clearAllDownloadTask;
+/** 清除选中的下载任务 */
+- (void)deleteSelectedDownloadTask;
+/** 清除指定的下载任务 */
+- (void)deleteDownloadTaskWithModel:(HWDownloadModel *)model;
+
+// 新建某一个下载任务
+- (void)startDownloadTaskWithModel:(HWDownloadModel *)model;
+// 开始某一个下载任务
+- (void)taskResumeWithModel:(HWDownloadModel *)model;
+// 暂停某一个下载任务
+- (void)pauseDownloadTaskWithModel:(HWDownloadModel *)model;
+// 恢复某一个下载任务
+- (void)resumeDownloadTaskWithModel:(HWDownloadModel *)model;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 17 - 0
创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/NSString+SGHashString.h

@@ -0,0 +1,17 @@
+//
+//  NSString+SGHashString.h
+//  OfflineBreakPointDownload
+//
+//  Created by Shangen Zhang on 16/11/27.
+//  Copyright © 2016年 Shangen Zhang. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+
+@interface NSString (SGHashString)
+
+/** 获取MD5加密哈希散列值字符串 */
+- (NSString *)sg_md5HashString;
+
+@end

+ 43 - 0
创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/NSString+SGHashString.m

@@ -0,0 +1,43 @@
+//
+//  NSString+SGHashString.m
+//  OfflineBreakPointDownload
+//
+//  Created by Shangen Zhang on 16/11/27.
+//  Copyright © 2016年 Shangen Zhang. All rights reserved.
+//
+
+#import "NSString+SGHashString.h"
+#import <CommonCrypto/CommonCrypto.h>
+
+@implementation NSString (SGHashString)
+#pragma mark - MD5加密
+- (NSString *)sg_md5HashString {
+    const char *str = self.UTF8String;
+    
+    uint8_t buffer[CC_MD5_DIGEST_LENGTH];
+    
+    CC_MD5(str, (CC_LONG)strlen(str), buffer);
+    
+    return [self sg_stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];
+    
+}
+
+/**
+ *  返回二进制 Bytes 流的字符串表示形式
+ *
+ *  @param bytes  二进制 Bytes 数组
+ *  @param length 数组长度
+ *
+ *  @return 字符串表示形式
+ */
+- (NSString *)sg_stringFromBytes:(uint8_t *)bytes length:(int)length {
+    NSMutableString *strM = [NSMutableString string];
+    
+    for (int i = 0; i < length; i++) {
+        [strM appendFormat:@"%02x", bytes[i]];
+    }
+    
+    return [strM copy];
+}
+
+@end

+ 22 - 0
创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/NSURLSession+SGDownloadTask.h

@@ -0,0 +1,22 @@
+//
+//  NSURLSession+SGDownloadTask.h
+//  OfflineBreakPointDownload
+//
+//  Created by Shangen Zhang on 2017/12/18.
+//  Copyright © 2017年 Shangen Zhang. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface NSURLSession (SGDownloadTask)
+
+/**
+ 构造一个从特定位置开始下载的任务
+
+ @param urlString 资源路径的URLstring
+ @param startSize 开始的位置
+ @return 下载任务
+ */
+- (NSURLSessionDataTask *)sg_downloadDataTaskWithURLString:(NSString *)urlString
+                                                  startSize:(int64_t)startSize;
+@end

+ 42 - 0
创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/NSURLSession+SGDownloadTask.m

@@ -0,0 +1,42 @@
+//
+//  NSURLSession+SGDownloadTask.m
+//  OfflineBreakPointDownload
+//
+//  Created by Shangen Zhang on 2017/12/18.
+//  Copyright © 2017年 Shangen Zhang. All rights reserved.
+//
+
+#import "NSURLSession+SGDownloadTask.h"
+
+@implementation NSURLSession (SGDownloadTask)
+- (NSURLSessionDataTask *)sg_downloadDataTaskWithURLString:(NSString *)urlString
+                                                  startSize:(int64_t)startSize {
+    // 校验URL
+    if (urlString.length == 0) {
+        return nil;
+    }
+    NSURL *url = [NSURL URLWithString:urlString];
+    if (url == nil) {
+        return nil;
+    }
+    
+    // 创建请求 设置请求下载的位置
+    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
+//    NSString *tokenStr = [[UseAccountManage shareInstance] cloudAutoh];
+//    [request setValue:tokenStr forHTTPHeaderField:@"Authorization"];
+    request.HTTPMethod = @"GET";
+    
+    /*
+     bytes=0-100    请求0-100
+     bytes=200-1000
+     bytes=200-     从200开始直到结尾
+     bytes=-100
+     */
+    NSString *rangeStr = [NSString stringWithFormat:@"bytes=%lld-",startSize];
+    
+    [request setValue:rangeStr forHTTPHeaderField:@"Range"];
+    
+    // 创建task
+    return [self dataTaskWithRequest:request];
+}
+@end

+ 59 - 0
创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/SGCacheManager.h

@@ -0,0 +1,59 @@
+//
+//  SGCacheManager.h
+//  OfflineBreakPointDownload
+//
+//  Created by Shangen Zhang on 16/11/26.
+//  Copyright © 2016年 Shangen Zhang. All rights reserved.
+//
+
+
+#define SG_EXTERN extern
+#import <Foundation/Foundation.h>
+
+
+//SG_EXTERN NSString const * filePath;
+//SG_EXTERN NSString const * fileSize;
+//SG_EXTERN NSString const * totalSize;
+//SG_EXTERN NSString const * fileName;
+//SG_EXTERN NSString const * fileUrl;
+//SG_EXTERN NSString const * isFinished;
+
+#define KFullPath [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]
+
+#define KFullDirector  [self getFullDirector]
+
+@interface SGCacheManager : NSObject
+
+/** 查询文件信息 */
++ (NSDictionary *)queryFileInfoWithUrl:(NSString *)url;
+
+/** 查询要下载的文件大小 */
++ (NSInteger)totalSizeWith:(NSString *)url;
+
+/** 记录要下载的文件大小 */
++ (BOOL)saveTotalSizeWithSize:(NSInteger)size forURL:(NSString *)url;
+
+/**  增加配置信息 */
++ (BOOL)saveFileInfoWithDict:(NSDictionary *)dict;
+
+
+/**  删除某个文件 */
++ (BOOL)deleteFileWithUrl:(NSString *)url;
+
+/**  清理所有下载文件及下载信息 */
++ (BOOL)clearDisks;
+
+/**  取消所有当前下载的文件 清理内存缓存的数据 */
++ (BOOL)clearMemory;
+
+/**  取消所有当前下载的文件 删除磁盘所有的下载 清理内存缓存的数据 */
++ (BOOL)clearMemoryAndDisk;
+
+
++ (NSString *)getFullDirector;
+
++ (NSString *)getNewPlistPath;
+
++ (NSMutableDictionary *)getDownloadList;
+
+@end

+ 219 - 0
创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/SGCacheManager.m

@@ -0,0 +1,219 @@
+//
+//  SGCacheManager.m
+//  OfflineBreakPointDownload
+//
+//  Created by Shangen Zhang on 16/11/26.
+//  Copyright © 2016年 Shangen Zhang. All rights reserved.
+//
+
+#import "SGCacheManager.h"
+#import "NSString+SGHashString.h"
+#import "CWFileManager.h"
+
+static NSMutableDictionary *_downloadList;
+
+static dispatch_semaphore_t _semaphore;
+
+
+//NSString const * filePath   =  @"filePath";
+//NSString const * fileSize   =  @"fileSize";
+//NSString const * fileName   =  @"fileName";
+//NSString const * fileUrl    =  @"fileUrl";
+//NSString const * isFinished =  @"isFinished";
+//NSString const * totalSize  =  @"totalSize";
+
+
+#define SGDownloadInfoPath  [self getNewPlistPath]
+
+#define SGDownloadList      [self getDownloadList]
+
+@interface SGCacheManager ()
+
+
+@end
+
+
+
+@implementation SGCacheManager
+
++ (void)initialize {
+    _semaphore = dispatch_semaphore_create(1);
+}
+
+#pragma mark-plist
++ (NSString *)getNewPlistPath {
+    
+    NSString *account = [HWDataManager getStringWithKey:Const_HWAccountPhoneNumber];
+    if (account.length != 0) {
+        NSString *fileFolder = kPath_YunPan_Download_Folder;
+        HLog(@"登录账号:%@", kPath_YunPan_Download_Folder);
+        return [fileFolder stringByAppendingPathComponent:@"downloadInfo.plist"];;
+    }else {
+        HLog(@"获取accout失败 创建下载plist文件失败!");
+        return @"";
+    }
+}
+
++ (NSString *)getFullDirector {
+
+    NSString *account = [HWDataManager getStringWithKey:Const_HWAccountPhoneNumber];
+    if (account.length != 0)
+     {
+         return kPath_YunPan_Download_Folder;;
+     }else {
+         HLog(@"获取accout失败 创建下载plist文件失败!");
+         return @"";
+     }
+}
+
++ (NSMutableDictionary *)getDownloadList {
+    
+    if (!_downloadList) { // 内存没有
+        _downloadList = [[NSDictionary dictionaryWithContentsOfFile:SGDownloadInfoPath] mutableCopy]; // 本地加载
+        if (!_downloadList) { // 本地没有,分配内存
+            _downloadList = [NSMutableDictionary dictionary];
+        }
+    }
+    return _downloadList;
+}
+
+#pragma mark - save
+//+ (void)didReciveDownloadCompleteNoti:(NSNotification *)noti {
+//
+//    // 缓存记录
+//    NSMutableDictionary *dictM = [noti.userInfo mutableCopy];
+//    
+//    // 从磁盘获取到下载了
+//    if ([noti.object integerValue] == 2 && ([self queryFileInfoWithUrl:dictM[fileUrl]])) {
+//        return;
+//    }
+//    
+//    // 缓存记录
+//    [dictM setObject:@(YES) forKey:isFinished];
+//    NSString *key = [dictM[fileUrl] sg_md5HashString];
+//    
+//    [SGDownloadList setObject:dictM forKey:key];
+//    
+//    [SGDownloadList writeToFile:SGDownloadInfoPath atomically:YES];
+//    
+//}
+
+#pragma mark - query
++ (NSDictionary *)queryFileInfoWithUrl:(NSString *)url {
+    // 本地查找
+    NSString *key = [[url lastPathComponent] stringByDeletingPathExtension];
+    NSMutableDictionary *dictM  = [[SGDownloadList objectForKey:key] mutableCopy];
+    
+    if (dictM) {
+        NSString *path = [KFullDirector stringByAppendingString:dictM[@"fileName"]];
+        [dictM setObject:path forKey:@"filePath"];
+        HLog(@"路径:%@", path);
+    }
+    
+    return dictM;
+    
+}
+
++ (NSInteger)totalSizeWith:(NSString *)url {
+    //NSNumber *size = [self queryFileInfoWithUrl:url][totalSize];
+    
+    return [[self queryFileInfoWithUrl:url][@"totalSize"] integerValue];
+}
+
+/** 记录要下载的文件大小 */
++ (BOOL)saveTotalSizeWithSize:(NSInteger)size forURL:(NSString *)url {
+    
+    return YES;
+}
+
+/**  增加配置信息 */
++ (BOOL)saveFileInfoWithDict:(NSDictionary *)dict {
+    
+    // 多账号下载 判断是否需要缓存记录
+    HLog(@"%@", dict);
+    if ([[dict allKeys] containsObject:@"fullPath"]) {
+        NSArray *fileArray = [[dict objectForKey:@"fullPath"] pathComponents];
+        NSString *filePathAccount = @"0";
+        if (fileArray.count > 3) {
+            filePathAccount = fileArray[fileArray.count - 3];
+        }
+
+        NSString *account = [HWDataManager getStringWithKey:Const_HWAccountPhoneNumber];
+        if (account.length == 0) {
+            HLog(@"获取accout失败");
+        }
+
+        if (![filePathAccount isEqualToString:account]) {
+            HLog(@"切换账号 文件缓存账号%@ 与 当前登录账号:%@ 不一致", filePathAccount, account);
+            return NO;
+        }
+    }
+    
+    
+    // 线程等待 (信号量 + 1)
+    dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_FOREVER);
+    
+    NSString *key = [[dict[@"url"] lastPathComponent] stringByDeletingPathExtension];
+    NSMutableDictionary *dictM =  SGDownloadList;
+    [dictM setObject:dict forKey:key];
+    BOOL flag = [dictM writeToFile:SGDownloadInfoPath atomically:YES];
+    
+    // 线程结束 (信号量 - 1)
+    dispatch_semaphore_signal(_semaphore);
+    
+    return flag;
+    
+}
+
+/**  删除配置信息 */
++ (BOOL)deleteFileWithUrl:(NSString *)url {
+    // 线程等待 分配信号量 (信号量 + 1)
+    dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_FOREVER);
+    
+    // 删除缓存的文件
+    NSString *fileFolder = kPath_YunPan_Download_Folder;
+    NSString *fileName = [url lastPathComponent];
+    NSString *fileURL = [fileFolder stringByAppendingPathComponent:fileName];
+
+    BOOL flag = [[NSFileManager defaultManager] removeItemAtPath:fileURL error:nil];
+//    BOOL flag = [[NSFileManager defaultManager] removeItemAtPath:dict[@"fullPath"] error:nil];
+    
+    // 删除plist的文件文件记录
+    NSString *key = [[url lastPathComponent] stringByDeletingPathExtension];
+//    NSDictionary *dict = SGDownloadList[key];
+    [SGDownloadList removeObjectForKey:key];
+    BOOL writeFlag = [SGDownloadList writeToFile:SGDownloadInfoPath atomically:YES];
+    
+    // 线程结束 释放信号量(信号量 - 1)
+    dispatch_semaphore_signal(_semaphore);
+    return (flag && writeFlag);
+}
+
+
+
+#pragma mark - 
+
++ (BOOL)clearDisks {
+    // 1.删除所有的文件下载信息关联表
+    // 2.删除cache 下的download文件夹
+   return  [[NSFileManager defaultManager] removeItemAtPath:KFullDirector error:nil];
+      
+}
+
+/**  取消所有当前下载的文件 清理内存缓存的数据 */
++ (BOOL)clearMemory {
+    // 删除信息关联
+    _downloadList = nil;
+    
+    return YES;
+}
+
+/**  取消所有当前下载的文件 删除磁盘所有的下载 清理内存缓存的数据 */
++ (BOOL)clearMemoryAndDisk {
+    return ([self clearMemory] && [self clearDisks]);
+}
+
+
+
+
+@end

+ 90 - 0
创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/SGDownloadManager.h

@@ -0,0 +1,90 @@
+//
+//  SGDownloadManager.h
+//  OfflineBreakPointDownload
+//
+//  Created by Shangen Zhang on 16/11/26.
+//  Copyright © 2016年 Shangen Zhang. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "SGDownloadOperation.h"
+
+/** 下载中通知 */
+#define  SGDownloadTaskExeing        @"SGDownloadTaskExeing"
+/** 下载失败通知 */
+#define  SGDownloadTaskExeError      @"SGDownloadTaskExeError"
+/** 下载完成通知 */
+#define  SGDownloadTaskExeEnd        @"SGDownloadTaskExeEnd"
+/** 下载暂停/等待中通知 */
+#define  SGDownloadTaskExeSuspend    @"SGDownloadTaskExeSuspend"
+/** 删除下载任务通知 */
+#define  SGDownloadTaskExeDelete     @"SGDownloadTaskExeDelete"
+/** 移除loading通知 */
+#define  SGDownloadRemoveLoading     @"SGDownloadRemoveLoading"
+
+/**
+ block 回调
+ */
+typedef void(^SGDownloadBeginBlock)(NSString * filePath);
+typedef void(^SGDownloadProgressBlock)(NSInteger completeSize,NSInteger expectSize);
+typedef void(^SGDownloadCompleteBlock)(NSDictionary *respose,NSError *error);
+
+
+/**
+ 下载管理
+ */
+@interface SGDownloadManager : NSObject
+
+/** 获取全部下载任务 */
+- (NSMutableArray *)getAllOperation;
+
+/** 实例化对象(单例) */
++ (instancetype)shareManager;
+
+#pragma mark - 添加下载任务同时开启任务下载
+/** 开启下载任务 监听完成下载 */
+- (void)downloadWithURL:(NSURL *)url
+               complete:(SGDownloadCompleteBlock)complete;
+
+- (void)downloadWithURL:(NSURL *)url
+               fileType:(NSInteger)fileType
+               fileSize:(NSInteger)fileSize
+               complete:(SGDownloadCompleteBlock)complete;
+
+/** 开启下载任务 监听下载进度、完成下载 */
+- (void)downloadWithURL:(NSURL *)url
+               progress:(SGDownloadProgressBlock)progress
+               complete:(SGDownloadCompleteBlock)complete;
+
+/** 开启下载任务 监听开始下载信息、下载进度、完成下载 */
+- (void)downloadWithURL:(NSURL *)url
+                  begin:(SGDownloadBeginBlock)begin
+               progress:(SGDownloadProgressBlock)progress
+               complete:(SGDownloadCompleteBlock)complete;
+
+
+
+#pragma mark - 队列中的任务进行操作
+/** 开始任务(不会自动添加任务,列队中没有就直接返回) */
+- (void)startDownLoadWithUrl:(NSString *)url;
+
+/** 暂停任务(暂停下载url内容的任务) */
+- (void)supendDownloadWithUrl:(NSString *)url;
+
+/** 取消任务(取消下载url内容的任务) */
+- (void)cancelDownloadWithUrl:(NSString *)url;
+
+
+/** 暂停当前所有的下载任务 下载任务不会从列队中删除 */
+- (void)suspendAllDownloadTask;
+
+/** 开启当前列队中所有被暂停的下载任务 */
+- (void)startAllDownloadTask;
+
+/** 停止当前所有的下载任务 调用此方法会清空所有列队下载任务 */
+- (void)stopAllDownloads;
+
+@end
+
+
+

+ 177 - 0
创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/SGDownloadManager.m

@@ -0,0 +1,177 @@
+//
+//  SGDownloadManager.m
+//  OfflineBreakPointDownload
+//
+//  Created by Shangen Zhang on 16/11/26.
+//  Copyright © 2016年 Shangen Zhang. All rights reserved.
+//
+
+#import "SGDownloadManager.h"
+#import "SGDownloadSession.h"
+#import "SGCacheManager.h"
+#import <MJExtension.h>
+
+@interface SGDownloadManager ()
+
+@property(nonatomic,strong) SGDownloadSession *downloadSession;
+
+@end
+
+
+@implementation SGDownloadManager
+
++ (instancetype)shareManager {
+    static SGDownloadManager *_instance;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        _instance = [[self alloc] init];
+        [_instance registeNotification];
+    });
+    return _instance;
+}
+
+- (NSMutableArray *)getAllOperation {
+    NSMutableDictionary *allOperationDict = [SGCacheManager getDownloadList];
+//    HLog(@"%@---%@", allOperation,allOperation.allKeys);
+    NSMutableArray *allOperationArray = [NSMutableArray array];
+    for (NSDictionary *dict in allOperationDict.allValues) {
+        SGDownloadOperation *operation = [SGDownloadOperation mj_objectWithKeyValues:dict];
+        [allOperationArray addObject:operation];
+    }
+    return allOperationArray;
+}
+
+#pragma mark-监听通知
+- (void)registeNotification {
+    
+//    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(exchanggeAccount) name:ExchangeLoginAccountNotification object:nil];
+//    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(exchanggeAccount) name:AccountLoginOutsideNotification object:nil];
+}
+
+- (void)exchanggeAccount {
+    HLog(@"切换账号");
+    [self suspendAllDownloadTask];
+    
+    [SGCacheManager clearMemory];
+}
+
+#pragma mark - 外界交互
+- (void)downloadWithURL:(NSURL *)url complete:(void(^)(NSDictionary *,NSError *))complete{
+    [self downloadWithURL:url begin:nil progress:nil complete:complete];
+}
+
+- (void)downloadWithURL:(NSURL *)url fileType:(NSInteger)fileType fileSize:(NSInteger)fileSize complete:(SGDownloadCompleteBlock)complete {
+    [self downloadWithURL:url fileType:fileType fileSize:fileSize begin:nil progress:nil complete:complete];
+}
+
+- (void)downloadWithURL:(NSURL *)url progress:(void(^)(NSInteger,NSInteger ))progress complete:(void(^)(NSDictionary *,NSError *))complete {
+    [self downloadWithURL:url begin:nil progress:progress complete:complete];
+}
+
+- (void)downloadWithURL:(NSURL *)url begin:(void(^)(NSString *))begin progress:(void(^)(NSInteger,NSInteger))progress complete:(void(^)(NSDictionary *,NSError *))complete {
+    
+    if (![url isKindOfClass:NSURL.class]) {
+        if ([url isKindOfClass:NSString.class]) {
+            url = [NSURL URLWithString:(NSString *)url];
+        }else {
+            // 失败回调
+            
+            return;
+        }
+    }
+    // 开启异步 操作
+    dispatch_async(dispatch_get_global_queue(0, 0), ^{
+        // 本地查找
+        NSDictionary *fileInfo = [SGCacheManager queryFileInfoWithUrl:url.absoluteString];
+        
+        // 本地存在直接返回
+        if (fileInfo && [fileInfo[@"currentSize"] integerValue] == [fileInfo[@"totalSize"] integerValue]) {
+            
+            dispatch_async(dispatch_get_main_queue(), ^{
+                !complete ? : complete(fileInfo,nil);
+            });
+            return;
+        }
+        
+        // 交给downloader下载
+        [self.downloadSession downloadWithURL:url begin:begin progress:progress complete:complete];
+    });
+    
+}
+
+- (void)downloadWithURL:(NSURL *)url fileType:(NSInteger)fileType fileSize:(NSInteger)fileSize begin:(void(^)(NSString *))begin progress:(void(^)(NSInteger,NSInteger))progress complete:(void(^)(NSDictionary *,NSError *))complete {
+    
+    if (![url isKindOfClass:NSURL.class]) {
+        if ([url isKindOfClass:NSString.class]) {
+            url = [NSURL URLWithString:(NSString *)url];
+        }else {
+            // 失败回调
+            
+            return;
+        }
+    }
+    // 开启异步 操作
+    dispatch_async(dispatch_get_global_queue(0, 0), ^{
+        // 本地查找
+        NSDictionary *fileInfo = [SGCacheManager queryFileInfoWithUrl:url.absoluteString];
+        
+        // 本地存在直接返回
+        if (fileInfo && [fileInfo[@"currentSize"] integerValue] == [fileInfo[@"totalSize"] integerValue]) {
+            
+            dispatch_async(dispatch_get_main_queue(), ^{
+                !complete ? : complete(fileInfo,nil);
+            });
+            return;
+        }
+        
+        // 交给downloader下载
+        [self.downloadSession downloadWithURL:url fileType:fileType fileSize:fileSize begin:begin progress:progress complete:complete];
+    });
+    
+}
+
+#pragma mark - 
+- (void)startDownLoadWithUrl:(NSString *)url {
+    // 开始下载
+    [self.downloadSession startDownLoadWithUrl:url];
+}
+
+- (void)supendDownloadWithUrl:(NSString *)url {
+    // 暂停下载
+    [self.downloadSession supendDownloadWithUrl:url];
+}
+
+- (void)cancelDownloadWithUrl:(NSString *)url {
+    // 取消下载
+    [self.downloadSession cancelDownloadWithUrl:url];
+}
+
+
+/** 暂停当前所有的下载任务 下载任务不会从列队中删除 */
+- (void)suspendAllDownloadTask {
+    [self.downloadSession suspendAllDownloads];
+}
+
+/** 开启当前列队中所有被暂停的下载任务 */
+- (void)startAllDownloadTask {
+    [self.downloadSession startAllDownloads];
+}
+
+/** 停止当前所有的下载任务 调用此方法会清空所有列队下载任务 */
+- (void)stopAllDownloads {
+    [self.downloadSession cancelAllDownloads];
+    self.downloadSession = nil;
+}
+
+#pragma mark - lazy load
+- (SGDownloadSession *)downloadSession {
+    if (!_downloadSession) {
+        _downloadSession = [[SGDownloadSession alloc] init];
+        
+    }
+    return _downloadSession;
+}
+
+
+
+@end

+ 100 - 0
创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/SGDownloadOperation.h

@@ -0,0 +1,100 @@
+//
+//  SGDownloadOperation.h
+//  OfflineBreakPointDownload
+//
+//  Created by Shangen Zhang on 16/11/26.
+//  Copyright © 2016年 Shangen Zhang. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "SGCacheManager.h"
+
+
+SG_EXTERN NSString * const SGDownloadCompleteNoti;
+
+typedef void(^SGReceiveResponseOperation)(NSString *filePath);
+typedef void(^SGReceivDataOperation)(NSInteger completeSize,NSInteger expectSize);
+typedef void(^SGCompleteOperation)(NSDictionary *respose,NSError *error);
+
+/** 下载状态*/
+typedef  enum : NSUInteger {
+    DownloadStateWaiting = 0,   /** 下载等待中 */
+    DownloadStateDoing,         /** 下载中 */
+    DownloadStateSuspended,     /** 下载暂停 */
+    DownloadStateCompleted,     /** 下载完成 */
+    DownloadStateFailed,        /** 下载失败 */
+} DownloadStateType;
+
+@protocol SGDownloadOperationProtocol <NSObject>
+                                    
+// 供queue管理方法
+
+// 处理响应值
+- (void)operateWithResponse:(NSURLResponse *)response;
+// 处理接收到的碎片
+- (void)operateWithReceivingData:(NSData *)data;
+// 处理完成回调
+- (void)operateWithComplete:(NSError *)error;
+
+
+/**
+ 设置block回调
+
+ @param didReceiveResponse 开始下载的回调
+ @param didReceivData 接收到下载的回调
+ @param didComplete 下载完成的回调
+ */
+- (void)configCallBacksWithDidReceiveResponse:(SGReceiveResponseOperation)didReceiveResponse
+                                didReceivData:(SGReceivDataOperation)didReceivData
+                                  didComplete:(SGCompleteOperation)didComplete;
+
+@end
+
+@interface SGDownloadOperation : NSObject <SGDownloadOperationProtocol>
+
+/** 绑定的标示及task的创建 */
+@property (readonly,nonatomic, copy)NSString *url;
+
+/** 下载任务 */
+@property (nonatomic,strong)NSURLSessionDataTask *dataTask;
+
+/** 文件句柄 可以记录文件的下载的位置 */
+@property (nonatomic,strong) NSFileHandle *handle;
+
+/** 下载的文件总大小 */
+@property (nonatomic,assign) int64_t totalSize;
+
+/** 当前下载了多少 */
+@property (nonatomic,assign) int64_t currentSize;
+
+/** 当前下载文件名称 */
+@property (nonatomic,copy) NSString *fileName;
+
+/** 当前下载文件沙盒全路径 */
+@property (nonatomic,copy) NSString *fullPath;
+
+/** 文件下载状态 */
+@property (nonatomic,assign) DownloadStateType downloadState;
+
+/** 下载完成-时间戳 */
+@property (nonatomic,assign)  NSInteger timeStamp;
+
+/** 文件类型 */
+@property (nonatomic,assign)  NSInteger fileType;
+
+/** 是否完成 */
+@property (nonatomic, assign)  NSInteger isFinished;
+
+
+
+// 创建下载操作任务
+- (instancetype)initWith:(NSString *)url session:(NSURLSession *)session;
+
+- (instancetype)initWith:(NSString *)url session:(NSURLSession *)session fileType:(NSInteger)fileType fileSize:(NSInteger)fileSize;
+
+
+
+- (NSDictionary *)downLoadInfoWithFinished:(BOOL)finished;
+
+@end
+

+ 268 - 0
创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/SGDownloadOperation.m

@@ -0,0 +1,268 @@
+//
+//  SGDownloadOperation.m
+//  OfflineBreakPointDownload
+//
+//  Created by Shangen Zhang on 16/11/26.
+//  Copyright © 2016年 Shangen Zhang. All rights reserved.
+//
+
+#import "SGDownloadOperation.h"
+#import "NSString+SGHashString.h"
+#import "NSURLSession+SGDownloadTask.h"
+#import "SGDownloadManager.h"
+
+NSString * const SGDownloadCompleteNoti = @"SGDownloadCompleteNoti";
+
+@interface SGDownloadOperation ()
+{
+    SGReceiveResponseOperation  _didReceiveResponseCallBack;
+    SGReceivDataOperation       _didReceivDataCallBack;
+    SGCompleteOperation         _didCompleteCallBack;
+}
+
+
+@end
+
+@implementation SGDownloadOperation
+
+- (instancetype)initWith:(NSString *)url session:(NSURLSession *)session {
+    
+    if (self = [super init]) {
+        _url = url;
+        // 初始化下载信息
+        _currentSize = [self getFileSizeWithURL:url];
+        
+        // 偏好设置里面存储总数据
+        _totalSize = [SGCacheManager totalSizeWith:url];
+        
+        _timeStamp = [iTools getNowTimeStamp];
+        // 校验
+        if (self.currentSize == self.totalSize && self.totalSize != 0) {
+            return nil;
+        }
+        
+        _downloadState = DownloadStateWaiting;
+        [SGCacheManager saveFileInfoWithDict:[self downLoadInfoWithFinished:NO]];
+        
+        _dataTask = [session sg_downloadDataTaskWithURLString:url startSize:_currentSize];
+    }
+    return _dataTask ? self : nil;
+}
+
+- (instancetype)initWith:(NSString *)url session:(NSURLSession *)session fileType:(NSInteger)fileType fileSize:(NSInteger)fileSize {
+    
+    if (self = [super init]) {
+        _url = url;
+        // 初始化下载信息
+        _currentSize = [self getFileSizeWithURL:url];
+        
+        // 偏好设置里面存储总数据
+        _totalSize = fileSize;
+        
+        _fileType = fileType;
+        
+        // 校验
+        if (self.currentSize == self.totalSize && self.totalSize != 0) {
+            return nil;
+        }
+        
+        _downloadState = DownloadStateWaiting;
+        [SGCacheManager saveFileInfoWithDict:[self downLoadInfoWithFinished:NO]];
+        
+        _dataTask = [session sg_downloadDataTaskWithURLString:url startSize:_currentSize];
+    }
+    return _dataTask ? self : nil;
+}
+
+#pragma mark - setups
+- (int64_t)getFileSizeWithURL:(NSString *)url {
+//    // md5文件名加密
+//    NSString *md5FielName = [[url lastPathComponent] stringByDeletingPathExtension];
+//    // 获取后缀名
+//    NSArray *subString = [[url lastPathComponent] componentsSeparatedByString:@"."];
+//    // 拼接后缀名
+    self.fileName = [url lastPathComponent];
+    
+    // 创建文件储存路径
+    if (![[NSFileManager defaultManager] fileExistsAtPath:[SGCacheManager getFullDirector]]) {
+        [[NSFileManager defaultManager] createDirectoryAtPath:[SGCacheManager getFullDirector] withIntermediateDirectories:YES attributes:nil error:nil];
+    }
+
+    // 设置下载路径
+    self.fullPath = [[SGCacheManager getFullDirector] stringByAppendingPathComponent:self.fileName];
+    
+    // 获取下载进度
+    NSDictionary *fileInfo = [[NSFileManager defaultManager] attributesOfItemAtPath:self.fullPath error:nil];
+    // 获取已下载的长度
+    return  [fileInfo[NSFileSize] longLongValue];
+}
+
+#pragma mark - SGDownloadOperationProtocol
+// 接收到相应时
+- (void)operateWithResponse:(NSURLResponse *)response {
+    // 总的size
+    if (self.currentSize + response.expectedContentLength == 0) {
+        HLog(@"下载数据回调异常");
+        return;
+    }
+    self.totalSize = self.currentSize + response.expectedContentLength;
+    
+    // 创建空的文件夹
+    if (self.currentSize == 0) {
+        // 创建空的文件
+        [[NSFileManager defaultManager]  createFileAtPath:self.fullPath contents:nil attributes:nil];
+    }
+    
+    // 创建文件句柄
+    self.handle = [NSFileHandle fileHandleForWritingAtPath:self.fullPath];
+    
+    // 文件句柄移动到文件末尾 位置 // 返回值是 unsign long long
+    [self.handle seekToEndOfFile];
+    
+    // 开始下载记录文件下载信息
+    _downloadState = DownloadStateDoing;
+    [SGCacheManager saveFileInfoWithDict:[self downLoadInfoWithFinished:NO]];
+    
+    // 回调给外界
+    if (_didReceiveResponseCallBack) {
+        dispatch_async(dispatch_get_main_queue(), ^{
+            self->_didReceiveResponseCallBack(self.fullPath);
+            
+        });
+        
+    }
+}
+
+- (void)operateWithReceivingData:(NSData *)data {
+    // 获得已经下载的文件大小
+    self.currentSize += data.length;
+    HLog(@"currentSize:%zd---progress:%.2f", self.currentSize, 1.00*self.currentSize/self.totalSize);
+    // 写入文件
+    [self.handle writeData:data];
+    
+    // 下载状态 通知代理
+    if (_didReceivDataCallBack) {
+        dispatch_async(dispatch_get_main_queue(), ^{
+            self->_didReceivDataCallBack((NSUInteger)self.currentSize,(NSUInteger)self.totalSize);
+            
+        });
+    }
+    
+    // 下载中通知
+    [self operationDoningWithOperation:self];
+}
+
+- (void)operateWithComplete:(NSError *)error {
+    // 关闭文件句柄
+    [self.handle closeFile];
+    // 释放文件句柄
+    self.handle = nil;
+    
+    // 完成下载 通知 block
+    if (error) {
+        [self completFailueWithError:error];
+    } else {
+        [self completCusesseWithCode:1];
+    }
+}
+
+- (void)configCallBacksWithDidReceiveResponse:(SGReceiveResponseOperation)didReceiveResponse
+                                didReceivData:(SGReceivDataOperation)didReceivData
+                                  didComplete:(SGCompleteOperation)didComplete {
+    _didReceiveResponseCallBack  = didReceiveResponse;
+    _didReceivDataCallBack       = didReceivData;
+    _didCompleteCallBack         = didComplete;
+    
+}
+
+#pragma mark - operations
+/** 成功回调 1代表下载后成功回调 2代表直接从磁盘中获取了 */
+- (void)completCusesseWithCode:(NSInteger)code {
+    // 获取下载信息
+    NSDictionary *dict = [self downLoadInfoWithFinished:YES];
+    
+    
+    // 通知
+    [[NSNotificationCenter defaultCenter] postNotificationName:SGDownloadCompleteNoti object:self userInfo:dict];
+    
+    if (code == 1) {
+        // 存储 文件下载信息
+        HLog(@"%zd", DownloadStateCompleted);
+        _downloadState = DownloadStateCompleted;
+        self.timeStamp = [iTools getNowTimeStamp];
+        [SGCacheManager saveFileInfoWithDict:dict];
+    }
+    
+    // 回到主线程 回调
+    if (_didCompleteCallBack) {
+        dispatch_async(dispatch_get_main_queue(), ^{
+            self->_didCompleteCallBack(dict,nil);
+        });
+    }
+    
+    // 成功通知
+    [self operationSuccessWithOperation:self];
+}
+
+/** 失败回调 */
+- (void)completFailueWithError:(NSError *)error {
+    
+    // 发通知
+    [[NSNotificationCenter defaultCenter] postNotificationName:SGDownloadCompleteNoti object:self userInfo:@{@"error":error}];
+    // 存储
+    _downloadState = DownloadStateFailed;
+    [SGCacheManager saveFileInfoWithDict:[self downLoadInfoWithFinished:NO]];
+    
+    // 回调
+    if (_didCompleteCallBack) {
+        dispatch_async(dispatch_get_main_queue(), ^{
+            self->_didCompleteCallBack(nil,error);
+        });
+    }
+    
+    // 失败通知
+    [self operationFailedWithOperation:self];
+}
+
+#pragma mark 发送通知
+// 失败某一个operation 保存本地 通知外界
+- (void)operationFailedWithOperation:(SGDownloadOperation *)operation {
+    HLog(@"SGDownloadTaskExeError");
+    operation.downloadState = DownloadStateFailed;
+    [SGCacheManager saveFileInfoWithDict:[operation downLoadInfoWithFinished:NO]];
+    [[NSNotificationCenter defaultCenter] postNotificationName:SGDownloadTaskExeError object:nil userInfo:@{@"operation" : operation}];
+}
+
+// 重启某一个operation 保存本地 通知外界
+- (void)operationDoningWithOperation:(SGDownloadOperation *)operation {
+    HLog(@"SGDownloadTaskExeing");
+//    operation.downloadState = DownloadStateDoing; // 暂停之后 数据回来 状态会被修改为下载中 不科学
+    [SGCacheManager saveFileInfoWithDict:[operation downLoadInfoWithFinished:NO]];
+    [[NSNotificationCenter defaultCenter] postNotificationName:SGDownloadTaskExeing object:nil userInfo:@{@"operation" : operation}];
+}
+
+// 等待某一个operation 保存本地 通知外界
+- (void)operationSuccessWithOperation:(SGDownloadOperation *)operation {
+    HLog(@"SGDownloadTaskExeEnd");
+    operation.downloadState = DownloadStateCompleted;
+    [SGCacheManager saveFileInfoWithDict:[operation downLoadInfoWithFinished:YES]];
+    [[NSNotificationCenter defaultCenter] postNotificationName:SGDownloadTaskExeEnd object:nil userInfo:@{@"operation" : operation}];
+}
+
+#pragma mark - get download info
+// 构造回调信息
+- (NSDictionary *)downLoadInfoWithFinished:(BOOL)finished {
+    HLog(@"%zd", self.downloadState);
+    return  @{
+                    @"url" : self.url,
+               @"fileName" : self.fileName,
+               @"fullPath" : self.fullPath,
+            @"currentSize" : @(self.currentSize),
+              @"totalSize" : @(self.totalSize),
+               @"fileType" : @(self.fileType),
+              @"timeStamp" : @(self.timeStamp),
+          @"downloadState" : @(self.downloadState),
+             @"isFinished" : @(finished)
+            };
+}
+@end

+ 55 - 0
创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/SGDownloadQueue.h

@@ -0,0 +1,55 @@
+//
+//  SGDownloadQueue.h
+//  OfflineBreakPointDownload
+//
+//  Created by Shangen Zhang on 16/11/26.
+//  Copyright © 2016年 Shangen Zhang. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+/** 下载处理 */
+typedef  enum : NSUInteger {
+    DownloadHandleTypeStart,    // 开始下载
+    DownloadHandleTypeSuspend,  // 暂停下载
+    DownloadHandleTypeCancel,   // 取消下载
+} DownloadHandleType;
+
+
+@interface SGDownloadQueue : NSObject
+
+/** 设置最大的并发下载个数 */
+@property (nonatomic, assign) NSInteger              maxCount;
+
+@property (nonatomic,strong) NSURLSession *session;
+
+// 添加下载任务
+- (void)addDownloadWithSession:(NSURLSession *)session
+                        URL:(NSURL *)url
+                      begin:(void(^)(NSString * filePath))begin
+                   progress:(void(^)(NSInteger completeSize,NSInteger expectSize))progress
+                   complete:(void(^)(NSDictionary *respose,NSError *error))complet;
+
+- (void)addDownloadWithSession:(NSURLSession *)session
+                        URL:(NSURL *)url
+                      fileType:(NSInteger)fileType
+                      fileSize:(NSInteger)fileSize
+                      begin:(void(^)(NSString * filePath))begin
+                   progress:(void(^)(NSInteger completeSize,NSInteger expectSize))progress
+                   complete:(void(^)(NSDictionary *respose,NSError *error))complet;
+
+// 对当前任务进行操作
+- (void)operateDownloadWithUrl:(NSString *)url session:(NSURLSession *)session handle:(DownloadHandleType)handle;
+
+// 取消所有任务
+//- (void)cancelAllTasks;
+- (void)suspendAllTasksWithSession:(NSURLSession *)session;
+- (void)startAllTasksWithSession:(NSURLSession *)session;
+
+// 供downloader 处理下载调用
+- (void)dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response;
+
+- (void)dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data;
+
+- (void)task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error;
+@end

+ 406 - 0
创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/SGDownloadQueue.m

@@ -0,0 +1,406 @@
+//
+//  SGDownloadQueue.m
+//  OfflineBreakPointDownload
+//
+//  Created by Shangen Zhang on 16/11/26.
+//  Copyright © 2016年 Shangen Zhang. All rights reserved.
+//
+
+#import "SGDownloadQueue.h"
+#import "SGDownloadOperation.h"
+#import "SGDownloadManager.h"
+#import "NSURLSession+SGDownloadTask.h"
+#import <MJExtension.h>
+
+@interface SGDownloadQueue ()
+// 列队管理集合
+@property (nonatomic,strong) NSMutableArray <SGDownloadOperation *> *operations;
+
+@end
+
+@implementation SGDownloadQueue
+
+- (instancetype)init {
+
+    if (self = [super init]) {
+        _maxCount = 3;
+        [self registeNotification];
+    }
+    return self;
+}
+
+- (void)dealloc {
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+}
+
+- (void)didResiveDownloadFileCompete:(NSNotification *)noti {
+    SGDownloadOperation *operation = noti.object;
+    if (operation) {
+        [self.operations removeObject:operation];
+    }
+}
+
+- (NSMutableArray *)getOperationDoing {
+    
+    NSMutableArray *doingArray = [NSMutableArray array];
+    for (SGDownloadOperation *operation in self.operations) {
+        if (operation.downloadState == DownloadStateDoing) {
+            [doingArray addObject:operation];
+        }
+    }
+    return doingArray;
+}
+
+- (NSMutableArray *)getOperationWaiting {
+    
+    NSMutableArray *waitingArray = [NSMutableArray array];
+    [self.operations enumerateObjectsUsingBlock:^(SGDownloadOperation * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+        
+        SGDownloadOperation *operation = (SGDownloadOperation *)obj;
+        if (operation.downloadState == DownloadStateWaiting) {
+            [waitingArray addObject:operation];
+        }
+    }];
+    return waitingArray;
+}
+
+#pragma mark - handle Out operations
+- (void)addDownloadWithSession:(NSURLSession *)session URL:(NSURL *)url begin:(void(^)(NSString *))begin progress:(void(^)(NSInteger,NSInteger))progress complete:(void(^)(NSDictionary *,NSError *))complet {
+    // 获取operation对象
+    SGDownloadOperation *operation = [self operationWithUrl:url.absoluteString];
+    
+    if (operation == nil) { // 之前不存在此任务
+        
+        operation = [[SGDownloadOperation alloc] initWith:url.absoluteString session:session];
+        
+        if (operation == nil) {
+            // 没有下载任务代表已下载完成
+            NSDictionary *fileInfo = [SGCacheManager queryFileInfoWithUrl:url.absoluteString];
+            if (fileInfo && complet) {
+                complet(fileInfo,nil);
+            }else {
+                complet(nil,[NSError errorWithDomain:@"构建下载任务失败" code:-1 userInfo:nil]);
+            }
+            return;
+        }
+        
+        [self.operations addObject:operation];
+    }
+    
+    // 回调赋值operation
+//    [operation configCallBacksWithDidReceiveResponse:begin didReceivData:progress didComplete:complet];
+    
+//    [operation.dataTask resume];
+    
+}
+
+- (void)addDownloadWithSession:(NSURLSession *)session URL:(NSURL *)url fileType:(NSInteger)fileType fileSize:(NSInteger)fileSize begin:(void(^)(NSString * filePath))begin progress:(void(^)(NSInteger completeSize,NSInteger expectSize))progress complete:(void(^)(NSDictionary *respose,NSError *error))complet {
+    // 获取operation对象
+    SGDownloadOperation *operation = [self operationWithUrl:url.absoluteString];
+    
+    if (operation == nil) { // 队列里不存在此任务
+        
+        operation = [[SGDownloadOperation alloc] initWith:url.absoluteString session:session fileType:fileType fileSize:fileSize];
+        
+        if (operation == nil) {
+            // 没有下载任务代表已下载完成
+            NSDictionary *fileInfo = [SGCacheManager queryFileInfoWithUrl:url.absoluteString];
+            if (fileInfo && complet) {
+                complet(fileInfo,nil);
+            }else {
+                complet(nil,[NSError errorWithDomain:@"构建下载任务失败" code:-1 userInfo:nil]);
+            }
+            return;
+        }
+        
+        [self.operations addObject:operation];
+    }
+    
+    // 回调赋值operation
+//    [operation configCallBacksWithDidReceiveResponse:begin didReceivData:progress didComplete:complet];
+    
+    if ([self getOperationDoing].count < self.maxCount) { // 下载中任务数少于最大任务限制
+        [operation.dataTask resume];
+        [self operationStartWithOperation:operation];
+    }else { // 下载中任务数大于最大任务限制
+//        [operation.dataTask suspend];
+        [self operationWaitingWithOperation:operation];
+//        HLog(@"下载中任务数等于最大任务限制:%zd",[self getOperationDoing].count);
+    }
+}
+
+- (void)operateDownloadWithUrl:(NSString *)url session:(NSURLSession *)session handle:(DownloadHandleType)handle {
+    // 1、任务列表里取任务
+    SGDownloadOperation *operation = [self operationWithUrl:url];
+    
+    // 2、本地plist文件里提取的任务
+    if (!operation) {
+        NSDictionary *dict = [SGCacheManager queryFileInfoWithUrl:url];
+        operation = [SGDownloadOperation mj_objectWithKeyValues:dict];
+    }
+
+    // 3、本地plist文件里提取的任务不存在dataTask
+    if (!operation.dataTask && operation.currentSize != operation.totalSize) {
+        operation.dataTask = [self.session sg_downloadDataTaskWithURLString:operation.url startSize:operation.currentSize];
+        [self.operations addObject:operation];
+    }
+    
+    if (operation) {
+        
+        switch (handle) {
+            case DownloadHandleTypeStart:
+                
+                switch (operation.dataTask.state) {
+                    case NSURLSessionTaskStateRunning:
+                        HLog(@"NSURLSessionTaskStateRunning");
+                        break;
+                    
+                    case NSURLSessionTaskStateSuspended:
+                        HLog(@"NSURLSessionTaskStateSuspended");
+                        operation.dataTask = [self.session sg_downloadDataTaskWithURLString:operation.url startSize:operation.currentSize];
+                        break;
+                        
+                    case NSURLSessionTaskStateCanceling:
+                        HLog(@"NSURLSessionTaskStateCanceling");
+                        operation.dataTask = [self.session sg_downloadDataTaskWithURLString:operation.url startSize:operation.currentSize];
+                        break;
+                        
+                    case NSURLSessionTaskStateCompleted:
+                        HLog(@"NSURLSessionTaskStateCompleted");
+                        break;
+                        
+                    default:
+                        break;
+                }
+                
+                if ([self getOperationDoing].count >= self.maxCount) { // 下载中任务数超过最大任务限制
+                    HLog(@"下载中的任务数超过最大限制")
+//                    [operation.dataTask suspend]; // 暂停
+                    [self operationWaitingWithOperation:operation];
+                    return;
+                }
+                
+                [operation.dataTask resume]; // 开始
+                [self operationStartWithOperation:operation];
+                break;
+            case DownloadHandleTypeSuspend:
+                [operation.dataTask suspend]; // 暂停
+                [self operationSuspendWithOperation:operation];
+                break;
+            case DownloadHandleTypeCancel:
+                if (operation.dataTask) { // 任务列表删除任务
+                    [operation.dataTask cancel];  // 取消
+                    [self.operations removeObject:operation];
+                }
+                [SGCacheManager deleteFileWithUrl:url];   // plist删除任务
+                [self operationDeleteWithOperation:operation];
+                break;
+        }
+    }
+}
+
+- (void)cancelAllTasks {
+    // 取消所有的任务
+    [self.operations enumerateObjectsUsingBlock:^(SGDownloadOperation * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+        [obj.dataTask cancel];
+    }];
+    // 清理内存
+    self.operations = nil;
+}
+
+- (void)suspendAllTasksWithSession:(NSURLSession *)session {
+    // 暂停所有的任务
+    [self.operations enumerateObjectsUsingBlock:^(SGDownloadOperation * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+        
+        SGDownloadOperation *operation = (SGDownloadOperation *)obj;
+        if (operation.currentSize != operation.totalSize) { // 暂停未完成的下载任务
+            if (!operation.dataTask) { // 给plist里的任务添加dataTask 添加到operations
+                operation.dataTask = [self.session sg_downloadDataTaskWithURLString:operation.url startSize:operation.currentSize];
+            }
+            [operation.dataTask suspend];
+            [self operationSuspendWithOperation:operation];
+        }else {
+            HLog(@"已完成的任务");
+        }
+
+    }];
+}
+
+- (void)startAllTasksWithSession:(NSURLSession *)session {
+    
+    // 开始所有的任务
+    [self.operations enumerateObjectsUsingBlock:^(SGDownloadOperation * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+        
+        SGDownloadOperation *operation = (SGDownloadOperation *)obj;
+        if (!operation.dataTask) { // 给plist里的任务添加dataTask 添加到operations
+            operation.dataTask = [self.session sg_downloadDataTaskWithURLString:operation.url startSize:operation.currentSize];
+        }
+  
+        if ([self getOperationDoing].count < self.maxCount) { // 下载中任务数少于最大任务限制
+            
+            switch (operation.dataTask.state) {
+                case NSURLSessionTaskStateRunning:
+                    HLog(@"NSURLSessionTaskStateRunning");
+                    break;
+                
+                case NSURLSessionTaskStateSuspended:
+                    HLog(@"NSURLSessionTaskStateSuspended");
+                    break;
+                    
+                case NSURLSessionTaskStateCanceling:
+                    HLog(@"NSURLSessionTaskStateCanceling");
+                    operation.dataTask = [self.session sg_downloadDataTaskWithURLString:operation.url startSize:operation.currentSize];
+                    break;
+                    
+                case NSURLSessionTaskStateCompleted:
+                    HLog(@"NSURLSessionTaskStateCompleted");
+                    break;
+                    
+                default:
+                    break;
+            }
+            
+            [operation.dataTask resume]; // 开始
+            [self operationStartWithOperation:operation];
+        }else { // 下载中任务数大于最大任务限制
+//            [operation.dataTask suspend];
+            [self operationWaitingWithOperation:operation];
+    //        HLog(@"下载中任务数等于最大任务限制:%zd",[self getOperationDoing].count);
+        }
+
+    }];
+}
+
+#pragma mark-监听通知
+- (void)registeNotification {
+    // 监听完成通知
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didResiveDownloadFileCompete:) name:SGDownloadCompleteNoti object:nil];
+    
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskExeEnd:) name:SGDownloadTaskExeEnd object:nil];
+//    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskExeEnd:) name:SGDownloadTaskExeError object:nil];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskExeEnd:) name:SGDownloadTaskExeSuspend object:nil];
+//    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskExeEnd:) name:SGDownloadTaskExeDelete object:nil];
+}
+    
+- (void)taskExeEnd:(NSNotification *)notification
+{
+    NSMutableArray *operationWaiting = [self getOperationWaiting];
+    
+    [operationWaiting enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+        SGDownloadOperation *operation = obj;
+        if ([self getOperationDoing].count < self.maxCount) {
+            [self operateDownloadWithUrl:operation.url session:self.session handle:DownloadHandleTypeStart];
+            
+        }else {
+            *stop = YES;
+        }
+    }];
+}
+
+#pragma mark 发送通知
+// 暂停某一个operation 保存本地 通知外界
+- (void)operationSuspendWithOperation:(SGDownloadOperation *)operation {
+    operation.downloadState = DownloadStateSuspended;
+    [SGCacheManager saveFileInfoWithDict:[operation downLoadInfoWithFinished:NO]];
+    [[NSNotificationCenter defaultCenter] postNotificationName:SGDownloadTaskExeSuspend object:nil userInfo:@{@"operation" : operation}];
+}
+
+// 重启某一个operation 保存本地 通知外界
+- (void)operationStartWithOperation:(SGDownloadOperation *)operation {
+    operation.downloadState = DownloadStateDoing;
+    [SGCacheManager saveFileInfoWithDict:[operation downLoadInfoWithFinished:NO]];
+    [[NSNotificationCenter defaultCenter] postNotificationName:SGDownloadTaskExeing object:nil userInfo:@{@"operation" : operation}];
+}
+
+// 等待某一个operation 保存本地 通知外界
+- (void)operationWaitingWithOperation:(SGDownloadOperation *)operation {
+    operation.downloadState = DownloadStateWaiting;
+    [SGCacheManager saveFileInfoWithDict:[operation downLoadInfoWithFinished:NO]];
+    [[NSNotificationCenter defaultCenter] postNotificationName:SGDownloadTaskExeSuspend object:nil userInfo:@{@"operation" : operation}];
+}
+
+// 删除某一个operation 保存本地 通知外界
+- (void)operationDeleteWithOperation:(SGDownloadOperation *)operation {
+    [[NSNotificationCenter defaultCenter] postNotificationName:SGDownloadTaskExeDelete object:nil userInfo:nil];
+}
+
+#pragma mark - handle download
+- (void)dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response {
+    [[self oprationWithDataTask:dataTask] operateWithResponse:response];
+}
+
+- (void)dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
+    [[self oprationWithDataTask:dataTask] operateWithReceivingData:data];
+}
+
+
+- (void)task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
+    [[self oprationWithDataTask:task] operateWithComplete:error];
+}
+
+
+#pragma mark - query operation
+- (SGDownloadOperation *)operationWithUrl:(NSString *)url{
+    __block SGDownloadOperation *operation = nil;
+    
+    [self.operations enumerateObjectsUsingBlock:^(SGDownloadOperation * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+        if ([obj.url isEqualToString:url]) {
+            operation = obj;
+            *stop = YES;
+        }
+    }];
+    
+    return operation;
+}
+
+// 寻找operation
+- (SGDownloadOperation *)oprationWithDataTask:(NSURLSessionTask *)dataTask {
+    __block SGDownloadOperation *operation = nil;
+    
+    [self.operations enumerateObjectsUsingBlock:^(SGDownloadOperation * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+        if (obj.dataTask == dataTask) {
+            operation = obj;
+            *stop = YES;
+        }
+    }];
+    
+    return operation;
+}
+
+#pragma mark - lazy load 
+- (NSMutableArray<SGDownloadOperation *> *)operations {
+    
+    if (!_operations) {
+        _operations = [NSMutableArray array];
+        [self addOperationsFromPlist];
+    }
+    return _operations;
+}
+
+- (void)addOperationsFromPlist {
+    
+    [self.operations removeAllObjects];
+    
+    NSMutableArray *operations = [[SGDownloadManager shareManager] getAllOperation];
+    for (SGDownloadOperation *operationPlist in operations) {
+        
+        // 1、任务列表里取任务
+        SGDownloadOperation *operation = [self operationWithUrl:operationPlist.url];
+        
+        // 2、本地plist文件里提取的任务
+        if (!operation) {
+            NSDictionary *dict = [SGCacheManager queryFileInfoWithUrl:operationPlist.url];
+            operation = [SGDownloadOperation mj_objectWithKeyValues:dict];
+        }
+
+        // 3、本地plist文件里提取的任务不存在dataTask
+        if (!operation.dataTask) {
+            operation.dataTask = [self.session sg_downloadDataTaskWithURLString:operation.url startSize:operation.currentSize];
+            operation.handle = [NSFileHandle fileHandleForWritingAtPath:operation.fullPath];
+//            [operation configCallBacksWithDidReceiveResponse:begin didReceivData:progress didComplete:complet];
+            [self.operations addObject:operation];
+        }
+    }
+}
+
+@end

+ 37 - 0
创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/SGDownloadSession.h

@@ -0,0 +1,37 @@
+//
+//  SGDownloader.h
+//  OfflineBreakPointDownload
+//
+//  Created by Shangen Zhang on 16/11/26.
+//  Copyright © 2016年 Shangen Zhang. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "SGDownloadManager.h"
+
+@interface SGDownloadSession : NSObject
+
+// 接口回调
+- (void)downloadWithURL:(NSURL *)url
+                  begin:(void(^)(NSString *))begin
+               progress:(void(^)(NSInteger,NSInteger))progress
+               complete:(void(^)(NSDictionary *,NSError *))complet;
+
+- (void)downloadWithURL:(NSURL *)url
+               fileType:(NSInteger)fileType
+               fileSize:(NSInteger)fileSize
+                  begin:(void(^)(NSString *))begin
+               progress:(void(^)(NSInteger,NSInteger))progress
+               complete:(void(^)(NSDictionary *,NSError *))complet;
+
+
+- (void)startDownLoadWithUrl:(NSString *)url;
+
+- (void)supendDownloadWithUrl:(NSString *)url;
+
+- (void)cancelDownloadWithUrl:(NSString *)url;
+
+- (void)cancelAllDownloads;
+- (void)startAllDownloads;
+- (void)suspendAllDownloads;
+@end

+ 165 - 0
创维盒子/双子星云手机/Vendor/DownLoadManager/SGDwonload/SGDownloadSession.m

@@ -0,0 +1,165 @@
+//
+//  SGDownloader.m
+//  OfflineBreakPointDownload
+//
+//  Created by Shangen Zhang on 16/11/26.
+//  Copyright © 2016年 Shangen Zhang. All rights reserved.
+//
+
+#import "SGDownloadSession.h"
+#import "SGDownloadQueue.h"
+
+@interface SGDownloadSession () <NSURLSessionDataDelegate>
+
+/** session 可以支持多个任务下载,创建一次就可以 */
+@property (nonatomic,strong) NSURLSession *session;
+
+/** 下载列队管理 专门负责接收到数据时分配给不同operation */
+@property (nonatomic,strong) SGDownloadQueue *queue;
+
+@end
+
+
+@implementation SGDownloadSession
+// 添加任务
+- (void)downloadWithURL:(NSURL *)url begin:(void(^)(NSString *))begin progress:(void(^)(NSInteger,NSInteger))progress complete:(void(^)(NSDictionary *,NSError *))complet {
+    // 交给列队管理
+    [self.queue addDownloadWithSession:self.session URL:url begin:begin progress:progress complete:complet];
+}
+
+- (void)downloadWithURL:(NSURL *)url fileType:(NSInteger)fileType fileSize:(NSInteger)fileSize begin:(void(^)(NSString *))begin progress:(void(^)(NSInteger,NSInteger))progress complete:(void(^)(NSDictionary *,NSError *))complet {
+    // 交给列队管理
+    [self.queue addDownloadWithSession:self.session URL:url fileType:fileType fileSize:fileSize begin:begin progress:progress complete:complet];
+}
+
+#pragma mark - 操作任务接口
+- (void)startDownLoadWithUrl:(NSString *)url {
+    [self.queue operateDownloadWithUrl:url session:self.session handle:DownloadHandleTypeStart];
+}
+
+- (void)supendDownloadWithUrl:(NSString *)url {
+    [self.queue operateDownloadWithUrl:url session:self.session handle:DownloadHandleTypeSuspend];
+}
+
+- (void)cancelDownloadWithUrl:(NSString *)url {
+    [self.queue operateDownloadWithUrl:url session:self.session handle:DownloadHandleTypeCancel];
+}
+
+- (void)cancelAllDownloads {
+    
+    dispatch_async(dispatch_get_global_queue(0, 0), ^{
+        // 取消所有session的任务
+        // 耗时操作
+        // 会调用 URLSession:task:didCompleteWithError: 方法抛出error取消
+        [self.session invalidateAndCancel];
+    });
+}
+- (void)startAllDownloads {
+    [self.queue startAllTasksWithSession:self.session];
+}
+- (void)suspendAllDownloads {
+    [self.queue suspendAllTasksWithSession:self.session];
+}
+
+#pragma mark - <NSURLSessionDataDelegate>
+
+// ssl 服务 证书信任
+- (void)URLSession:(NSURLSession *)session
+didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
+ completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{
+    if(![challenge.protectionSpace.authenticationMethod isEqualToString:@"NSURLAuthenticationMethodServerTrust"]) {
+        return;
+    }
+    
+    // 信任该插件
+    NSURLCredential *credential = [[NSURLCredential alloc] initWithTrust:challenge.protectionSpace.serverTrust];
+    // 第一个参数 告诉系统如何处置
+    completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
+}
+
+//当请求协议是https的时候回调用该方法
+//Challenge 挑战 质询(受保护空间)
+//NSURLAuthenticationMethodServerTrust 服务器信任证书
+- (void)URLSession:(NSURLSession *)session
+              task:(NSURLSessionTask *)task
+didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
+ completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * __nullable credential))completionHandler {
+    
+    if(![challenge.protectionSpace.authenticationMethod isEqualToString:@"NSURLAuthenticationMethodServerTrust"]) {
+        return;
+    }
+    
+    // 信任该插件
+    NSURLCredential *credential = [[NSURLCredential alloc] initWithTrust:challenge.protectionSpace.serverTrust];
+    // 第一个参数 告诉系统如何处置
+    completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
+    
+}
+
+
+// 接受到响应调用
+- (void)URLSession:(NSURLSession *)session
+          dataTask:(NSURLSessionDataTask *)dataTask
+didReceiveResponse:(NSURLResponse *)response
+ completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {
+    
+    // 将响应交给列队处理
+    [self.queue dataTask:dataTask didReceiveResponse:response];
+    
+    // 允许下载
+    completionHandler(NSURLSessionResponseAllow);
+}
+
+// 接受到数据碎片 的时候调用,调用多次
+- (void)URLSession:(NSURLSession *)session
+          dataTask:(NSURLSessionDataTask *)dataTask
+    didReceiveData:(NSData *)data {
+    // 接收到session 下载碎片交个列队管理
+    [self.queue dataTask:dataTask didReceiveData:data];
+}
+
+// <NSURLSessionDataDelegate> 完成下载
+- (void)URLSession:(NSURLSession *)session
+              task:(NSURLSessionTask *)task
+didCompleteWithError:(nullable NSError *)error {
+    [self.queue task:task didCompleteWithError:error];
+}
+
+- (void)URLSession:(NSURLSession *)session
+              task:(NSURLSessionTask *)task
+ needNewBodyStream:(void (^)(NSInputStream * _Nullable bodyStream))completionHandler {
+    
+}
+
+- (void)URLSession:(NSURLSession *)session
+              task:(NSURLSessionTask *)task
+   didSendBodyData:(int64_t)bytesSent
+    totalBytesSent:(int64_t)totalBytesSent
+totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend {
+    
+}
+
+#pragma mark - lazy load
+- (NSURLSession *)session {
+    if (!_session) {
+        NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
+        // 设置请求超时
+        config.timeoutIntervalForRequest = -1;
+//        config.networkServiceType = NSURLNetworkServiceTypeVideo;
+        config.timeoutIntervalForResource = -1;
+//        config.TLSMaximumSupportedProtocol = kSSLProtocolAll;
+        
+        _session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue currentQueue]];
+    }
+    
+    return _session;
+}
+
+- (SGDownloadQueue *)queue {
+    if (!_queue) {
+        _queue = [[SGDownloadQueue alloc] init];
+        _queue.session = self.session;
+    }
+    return _queue;
+}
+@end

+ 184 - 0
创维盒子/双子星云手机/Vendor/UploadManager/CWUploadManage/CWFileManager.h

@@ -0,0 +1,184 @@
+//
+//  CWUploadTask.m
+//  uploadFileDemo
+//
+//  Created by hyjet on 2018/3/9.
+//  Copyright © 2018年 uploadFileDemo. All rights reserved.
+//
+#import <UIKit/UIKit.h>
+
+//#define uploadPlist @"uploadPlist/upload.plist"
+
+@interface CWFileManager : NSObject
+
+#pragma mark - 沙盒目录相关
+// 沙盒的主目录路径
++ (NSString *)homeDir;
+// 沙盒中Documents的目录路径
++ (NSString *)documentsDir;
+// 沙盒中Library的目录路径
++ (NSString *)libraryDir;
+// 沙盒中Libarary/Preferences的目录路径
++ (NSString *)preferencesDir;
+// 沙盒中Library/Caches的目录路径
++ (NSString *)cachesDir;
+// 沙盒中tmp的目录路径
++ (NSString *)tmpDir;
+
+#pragma mark - 遍历文件夹
+/**
+ 文件遍历
+ 
+ @param path 目录的绝对路径
+ @param deep 是否深遍历 (1. 浅遍历:返回当前目录下的所有文件和文件夹;
+ 2. 深遍历:返回当前目录下及子目录下的所有文件和文件夹)
+ @return 遍历结果数组
+ */
++ (NSArray *)listFilesInDirectoryAtPath:(NSString *)path deep:(BOOL)deep;
+// 遍历沙盒主目录
++ (NSArray *)listFilesInHomeDirectoryByDeep:(BOOL)deep;
+// 遍历Documents目录
++ (NSArray *)listFilesInDocumentDirectoryByDeep:(BOOL)deep;
+// 遍历Library目录
++ (NSArray *)listFilesInLibraryDirectoryByDeep:(BOOL)deep;
+// 遍历Caches目录
++ (NSArray *)listFilesInCachesDirectoryByDeep:(BOOL)deep;
+// 遍历tmp目录
++ (NSArray *)listFilesInTmpDirectoryByDeep:(BOOL)deep;
+//遍历指定文件夹目录
++ (NSArray *)listFilesInCoustomDirectoryByDeep:(NSString*)path deepBool:(BOOL)deep;
+
+#pragma mark - 获取文件属性
+// 根据key获取文件某个属性
++ (id)attributeOfItemAtPath:(NSString *)path forKey:(NSString *)key;
+// 根据key获取文件某个属性(错误信息error)
++ (id)attributeOfItemAtPath:(NSString *)path forKey:(NSString *)key error:(NSError **)error;
+// 获取文件属性集合
++ (NSDictionary *)attributesOfItemAtPath:(NSString *)path;
+// 获取文件属性集合(错误信息error)
++ (NSDictionary *)attributesOfItemAtPath:(NSString *)path error:(NSError **)error;
+
+#pragma mark - 创建文件(夹)
+// 创建文件夹
++ (BOOL)createDirectoryAtPath:(NSString *)path;
+// 创建文件夹(错误信息error)
++ (BOOL)createDirectoryAtPath:(NSString *)path error:(NSError **)error;
+// 创建文件
++ (BOOL)createFileAtPath:(NSString *)path;
+// 创建文件(错误信息error)
++ (BOOL)createFileAtPath:(NSString *)path error:(NSError **)error;
+// 创建文件,是否覆盖
++ (BOOL)createFileAtPath:(NSString *)path overwrite:(BOOL)overwrite;
+// 创建文件,是否覆盖(错误信息error)
++ (BOOL)createFileAtPath:(NSString *)path overwrite:(BOOL)overwrite error:(NSError **)error;
+// 创建文件,文件内容
++ (BOOL)createFileAtPath:(NSString *)path content:(NSObject *)content;
+// 创建文件,文件内容(错误信息error)
++ (BOOL)createFileAtPath:(NSString *)path content:(NSObject *)content error:(NSError **)error;
+// 创建文件,文件内容,是否覆盖
++ (BOOL)createFileAtPath:(NSString *)path content:(NSObject *)content overwrite:(BOOL)overwrite;
+// 创建文件,文件内容,是否覆盖(错误信息error)
++ (BOOL)createFileAtPath:(NSString *)path content:(NSObject *)content overwrite:(BOOL)overwrite error:(NSError **)error;
+// 获取创建文件时间
++ (NSDate *)creationDateOfItemAtPath:(NSString *)path;
+// 获取创建文件时间(错误信息error)
++ (NSDate *)creationDateOfItemAtPath:(NSString *)path error:(NSError **)error;
+// 获取文件修改时间
++ (NSDate *)modificationDateOfItemAtPath:(NSString *)path;
+// 获取文件修改时间(错误信息error)
++ (NSDate *)modificationDateOfItemAtPath:(NSString *)path error:(NSError **)error;
+
+#pragma mark - 删除文件(夹)
+// 删除文件
++ (BOOL)removeItemAtPath:(NSString *)path;
+// 删除文件(错误信息error)
++ (BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error;
+// 清空Caches文件夹
++ (BOOL)clearCachesDirectory;
+// 清空tmp文件夹
++ (BOOL)clearTmpDirectory;
+
+#pragma mark - 复制文件(夹)
+// 复制文件
++ (BOOL)copyItemAtPath:(NSString *)path toPath:(NSString *)toPath;
+// 复制文件(错误信息error)
++ (BOOL)copyItemAtPath:(NSString *)path toPath:(NSString *)toPath error:(NSError **)error;
+// 复制文件,是否覆盖
++ (BOOL)copyItemAtPath:(NSString *)path toPath:(NSString *)toPath overwrite:(BOOL)overwrite;
+// 复制文件,是否覆盖(错误信息error)
++ (BOOL)copyItemAtPath:(NSString *)path toPath:(NSString *)toPath overwrite:(BOOL)overwrite error:(NSError **)error;
+
+#pragma mark - 移动文件(夹)
+// 移动文件
++ (BOOL)moveItemAtPath:(NSString *)path toPath:(NSString *)toPath;
+// 移动文件(错误信息error)
++ (BOOL)moveItemAtPath:(NSString *)path toPath:(NSString *)toPath error:(NSError **)error;
+// 移动文件,是否覆盖
++ (BOOL)moveItemAtPath:(NSString *)path toPath:(NSString *)toPath overwrite:(BOOL)overwrite;
+// 移动文件,是否覆盖(错误信息error)
++ (BOOL)moveItemAtPath:(NSString *)path toPath:(NSString *)toPath overwrite:(BOOL)overwrite error:(NSError **)error;
+
+#pragma mark - 根据URL获取文件名
+// 根据文件路径获取文件名称,是否需要后缀
++ (NSString *)fileNameAtPath:(NSString *)path suffix:(BOOL)suffix;
+// 获取文件所在的文件夹路径
++ (NSString *)directoryAtPath:(NSString *)path;
+// 根据文件路径获取文件扩展类型
++ (NSString *)suffixAtPath:(NSString *)path;
+
+#pragma mark - 判断文件(夹)是否存在
+// 判断文件路径是否存在
++ (BOOL)isExistsAtPath:(NSString *)path;
+// 判断路径是否为空(判空条件是文件大小为0,或者是文件夹下没有子文件)
++ (BOOL)isEmptyItemAtPath:(NSString *)path;
+// 判断路径是否为空(错误信息error)
++ (BOOL)isEmptyItemAtPath:(NSString *)path error:(NSError **)error;
+// 判断目录是否是文件夹
++ (BOOL)isDirectoryAtPath:(NSString *)path;
+// 判断目录是否是文件夹(错误信息error)
++ (BOOL)isDirectoryAtPath:(NSString *)path error:(NSError **)error;
+// 判断目录是否是文件
++ (BOOL)isFileAtPath:(NSString *)path;
+// 判断目录是否是文件(错误信息error)
++ (BOOL)isFileAtPath:(NSString *)path error:(NSError **)error;
+// 判断目录是否可以执行
++ (BOOL)isExecutableItemAtPath:(NSString *)path;
+// 判断目录是否可读
++ (BOOL)isReadableItemAtPath:(NSString *)path;
+// 判断目录是否可写
++ (BOOL)isWritableItemAtPath:(NSString *)path;
+
+#pragma mark - 获取文件(夹)大小
+// 获取目录大小
++ (NSNumber *)sizeOfItemAtPath:(NSString *)path;
+// 获取目录大小(错误信息error)
++ (NSNumber *)sizeOfItemAtPath:(NSString *)path error:(NSError **)error;
+// 获取文件大小
++ (NSNumber *)sizeOfFileAtPath:(NSString *)path;
+// 获取文件大小(错误信息error)
++ (NSNumber *)sizeOfFileAtPath:(NSString *)path error:(NSError **)error;
+// 获取文件夹大小
++ (NSNumber *)sizeOfDirectoryAtPath:(NSString *)path;
+// 获取文件夹大小(错误信息error)
++ (NSNumber *)sizeOfDirectoryAtPath:(NSString *)path error:(NSError **)error;
+
+// 获取目录大小,返回格式化后的数值
++ (NSString *)sizeFormattedOfItemAtPath:(NSString *)path;
+// 获取目录大小,返回格式化后的数值(错误信息error)
++ (NSString *)sizeFormattedOfItemAtPath:(NSString *)path error:(NSError **)error;
+// 获取文件大小,返回格式化后的数值
++ (NSString *)sizeFormattedOfFileAtPath:(NSString *)path;
+// 获取文件大小,返回格式化后的数值(错误信息error)
++ (NSString *)sizeFormattedOfFileAtPath:(NSString *)path error:(NSError **)error;
+// 获取文件夹大小,返回格式化后的数值
++ (NSString *)sizeFormattedOfDirectoryAtPath:(NSString *)path;
+// 获取文件夹大小,返回格式化后的数值(错误信息error)
++ (NSString *)sizeFormattedOfDirectoryAtPath:(NSString *)path error:(NSError **)error;
+
+#pragma mark - 写入文件内容
+// 写入文件内容
++ (BOOL)writeFileAtPath:(NSString *)path content:(NSObject *)content;
+// 写入文件内容(错误信息error)
++ (BOOL)writeFileAtPath:(NSString *)path content:(NSObject *)content error:(NSError **)error;
+
+@end

+ 492 - 0
创维盒子/双子星云手机/Vendor/UploadManager/CWUploadManage/CWFileManager.m

@@ -0,0 +1,492 @@
+//
+//  CWUploadTask.m
+//  uploadFileDemo
+//
+//  Created by hyjet on 2018/3/9.
+//  Copyright © 2018年 uploadFileDemo. All rights reserved.
+
+#import "CWFileManager.h"
+
+@interface CWFileManager ()
+
+@property (strong, nonatomic) NSFileManager *manager;
+
+@end
+
+
+@implementation CWFileManager
+
+#pragma mark - 沙盒目录相关
++ (NSString *)homeDir {
+    return NSHomeDirectory();
+}
+
++ (NSString *)documentsDir {
+    return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
+}
+
++ (NSString *)libraryDir {
+    return [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];;
+}
+
++ (NSString *)preferencesDir {
+    NSString *libraryDir = [self libraryDir];
+    return [libraryDir stringByAppendingPathComponent:@"Preferences"];
+}
+
++ (NSString *)cachesDir {
+    return [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
+}
+
++ (NSString *)tmpDir {
+    return NSTemporaryDirectory();
+}
+#pragma mark - 遍历文件夹
++ (NSArray *)listFilesInDirectoryAtPath:(NSString *)path deep:(BOOL)deep {
+    NSArray *listArr;
+    NSError *error;
+    NSFileManager *manager = [NSFileManager defaultManager];
+    if (deep) {
+        // 深遍历
+        NSArray *deepArr = [manager subpathsOfDirectoryAtPath:path error:&error];
+        if (!error) {
+            listArr = deepArr;
+        }else {
+            listArr = nil;
+        }
+    }else {
+        // 浅遍历
+        NSArray *shallowArr = [manager contentsOfDirectoryAtPath:path error:&error];
+        if (!error) {
+            listArr = shallowArr;
+        }else {
+            listArr = nil;
+        }
+    }
+    return listArr;
+}
+
++ (NSArray *)listFilesInHomeDirectoryByDeep:(BOOL)deep {
+    return [self listFilesInDirectoryAtPath:[self homeDir] deep:deep];
+}
+
++ (NSArray *)listFilesInLibraryDirectoryByDeep:(BOOL)deep {
+    return [self listFilesInDirectoryAtPath:[self libraryDir] deep:deep];
+}
+
++ (NSArray *)listFilesInDocumentDirectoryByDeep:(BOOL)deep {
+    return [self listFilesInDirectoryAtPath:[self documentsDir] deep:deep];
+}
+
++ (NSArray *)listFilesInTmpDirectoryByDeep:(BOOL)deep {
+    return [self listFilesInDirectoryAtPath:[self tmpDir] deep:deep];
+}
+
++ (NSArray *)listFilesInCachesDirectoryByDeep:(BOOL)deep {
+    return [self listFilesInDirectoryAtPath:[self cachesDir] deep:deep];
+}
+
++ (NSArray *)listFilesInCoustomDirectoryByDeep:(NSString*)path deepBool:(BOOL)deep{
+    if (![CWFileManager isExistsAtPath:path]) {
+        return @[];
+    }
+    return [self listFilesInDirectoryAtPath:path deep:deep];
+}
+
+#pragma mark - 获取文件属性
++ (id)attributeOfItemAtPath:(NSString *)path forKey:(NSString *)key {
+    return [[self attributesOfItemAtPath:path] objectForKey:key];
+}
+
++ (id)attributeOfItemAtPath:(NSString *)path forKey:(NSString *)key error:(NSError *__autoreleasing *)error {
+    return [[self attributesOfItemAtPath:path error:error] objectForKey:key];
+}
+
++ (NSDictionary *)attributesOfItemAtPath:(NSString *)path {
+    return [self attributesOfItemAtPath:path error:nil];
+}
+
++ (NSDictionary *)attributesOfItemAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
+    return [[NSFileManager defaultManager] attributesOfItemAtPath:path error:error];
+}
+
+#pragma mark - 创建文件(夹)
++ (BOOL)createDirectoryAtPath:(NSString *)path {
+    return [self createDirectoryAtPath:path error:nil];
+}
+
++ (BOOL)createDirectoryAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
+    NSFileManager *manager = [NSFileManager defaultManager];
+    BOOL isSuccess = [manager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:error];
+    return isSuccess;
+}
+
++ (BOOL)createFileAtPath:(NSString *)path {
+    return [self createFileAtPath:path content:nil overwrite:YES error:nil];
+}
+
++ (BOOL)createFileAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
+    return [self createFileAtPath:path content:nil overwrite:YES error:error];
+}
+
++ (BOOL)createFileAtPath:(NSString *)path overwrite:(BOOL)overwrite {
+    return [self createFileAtPath:path content:nil overwrite:overwrite error:nil];
+}
+
++ (BOOL)createFileAtPath:(NSString *)path overwrite:(BOOL)overwrite error:(NSError *__autoreleasing *)error {
+    return [self createFileAtPath:path content:nil overwrite:overwrite error:error];
+}
+
++ (BOOL)createFileAtPath:(NSString *)path content:(NSObject *)content {
+    return [self createFileAtPath:path content:content overwrite:YES error:nil];
+}
+
++ (BOOL)createFileAtPath:(NSString *)path content:(NSObject *)content error:(NSError *__autoreleasing *)error {
+    return [self createFileAtPath:path content:content overwrite:YES error:error];
+}
+
++ (BOOL)createFileAtPath:(NSString *)path content:(NSObject *)content overwrite:(BOOL)overwrite {
+    return [self createFileAtPath:path content:content overwrite:overwrite error:nil];
+}
+
++ (BOOL)createFileAtPath:(NSString *)path content:(NSObject *)content overwrite:(BOOL)overwrite error:(NSError *__autoreleasing *)error {
+    // 如果文件夹路径不存在,那么先创建文件夹
+    NSString *directoryPath = [self directoryAtPath:path];
+    if (![self isExistsAtPath:directoryPath]) {
+        // 创建文件夹
+        if (![self createDirectoryAtPath:directoryPath error:error]) {
+            return NO;
+        }
+    }
+    // 如果文件存在,并不想覆盖,那么直接返回YES。
+    if (!overwrite) {
+        if ([self isExistsAtPath:path]) {
+            return YES;
+        }
+    }
+    // 创建文件
+    BOOL isSuccess = [[NSFileManager defaultManager] createFileAtPath:path contents:nil attributes:nil];
+    if (content) {
+        [self writeFileAtPath:path content:content error:error];
+    }
+    return isSuccess;
+}
+
++ (NSDate *)creationDateOfItemAtPath:(NSString *)path {
+    return [self creationDateOfItemAtPath:path error:nil];
+}
+
++ (NSDate *)creationDateOfItemAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
+    return (NSDate *)[self attributeOfItemAtPath:path forKey:NSFileCreationDate error:error];
+}
+
++ (NSDate *)modificationDateOfItemAtPath:(NSString *)path {
+    return [self modificationDateOfItemAtPath:path error:nil];
+}
+
++ (NSDate *)modificationDateOfItemAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
+    return (NSDate *)[self attributeOfItemAtPath:path forKey:NSFileModificationDate error:error];
+}
+
+#pragma mark - 删除文件(夹)
++ (BOOL)removeItemAtPath:(NSString *)path {
+    return [self removeItemAtPath:path error:nil];
+}
+
++ (BOOL)removeItemAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
+    return [[NSFileManager defaultManager] removeItemAtPath:path error:error];
+}
+
++ (BOOL)clearCachesDirectory {
+    NSArray *subFiles = [self listFilesInCachesDirectoryByDeep:NO];
+    BOOL isSuccess = YES;
+    
+    for (NSString *file in subFiles) {
+        NSString *absolutePath = [[self cachesDir] stringByAppendingPathComponent:file];
+        isSuccess &= [self removeItemAtPath:absolutePath];
+    }
+    return isSuccess;
+}
+
++ (BOOL)clearTmpDirectory {
+    NSArray *subFiles = [self listFilesInTmpDirectoryByDeep:NO];
+    BOOL isSuccess = YES;
+    
+    for (NSString *file in subFiles) {
+        NSString *absolutePath = [[self tmpDir] stringByAppendingPathComponent:file];
+        isSuccess &= [self removeItemAtPath:absolutePath];
+    }
+    return isSuccess;
+}
+
+#pragma mark - 复制文件(夹)
++ (BOOL)copyItemAtPath:(NSString *)path toPath:(NSString *)toPath {
+    return [self copyItemAtPath:path toPath:toPath overwrite:NO error:nil];
+}
+
++ (BOOL)copyItemAtPath:(NSString *)path toPath:(NSString *)toPath error:(NSError *__autoreleasing *)error {
+    return [self copyItemAtPath:path toPath:toPath overwrite:NO error:error];
+}
+
++ (BOOL)copyItemAtPath:(NSString *)path toPath:(NSString *)toPath overwrite:(BOOL)overwrite {
+    return [self copyItemAtPath:path toPath:toPath overwrite:overwrite error:nil];
+}
+
++ (BOOL)copyItemAtPath:(NSString *)path toPath:(NSString *)toPath overwrite:(BOOL)overwrite error:(NSError *__autoreleasing *)error {
+    // 先要保证源文件路径存在,不然抛出异常
+    if (![self isExistsAtPath:path]) {
+        [NSException raise:@"非法的源文件路径" format:@"源文件路径%@不存在,请检查源文件路径", path];
+        return NO;
+    }
+    NSString *toDirPath = [self directoryAtPath:toPath];
+    if (![self isExistsAtPath:toDirPath]) {
+        // 创建复制路径
+        if (![self createDirectoryAtPath:toDirPath error:error]) {
+            return NO;
+        }
+    }
+    // 如果覆盖,那么先删掉原文件
+    if (overwrite) {
+        if ([self isExistsAtPath:toPath]) {
+            [self removeItemAtPath:toPath error:error];
+        }
+    }
+    // 复制文件
+    BOOL isSuccess = [[NSFileManager defaultManager] copyItemAtPath:path toPath:toPath error:error];
+    
+    return isSuccess;
+}
+
+#pragma mark - 移动文件(夹)
++ (BOOL)moveItemAtPath:(NSString *)path toPath:(NSString *)toPath {
+    return [self moveItemAtPath:path toPath:toPath overwrite:NO error:nil];
+}
+
++ (BOOL)moveItemAtPath:(NSString *)path toPath:(NSString *)toPath error:(NSError *__autoreleasing *)error {
+    return [self moveItemAtPath:path toPath:toPath overwrite:NO error:error];
+}
+
++ (BOOL)moveItemAtPath:(NSString *)path toPath:(NSString *)toPath overwrite:(BOOL)overwrite {
+    return [self moveItemAtPath:path toPath:toPath overwrite:overwrite error:nil];
+}
+
++ (BOOL)moveItemAtPath:(NSString *)path toPath:(NSString *)toPath overwrite:(BOOL)overwrite error:(NSError *__autoreleasing *)error {
+    // 先要保证源文件路径存在,不然抛出异常
+    if (![self isExistsAtPath:path]) {
+        [NSException raise:@"非法的源文件路径" format:@"源文件路径%@不存在,请检查源文件路径", path];
+        return NO;
+    }
+    NSString *toDirPath = [self directoryAtPath:toPath];
+    if (![self isExistsAtPath:toDirPath]) {
+        // 创建移动路径
+        if (![self createDirectoryAtPath:toDirPath error:error]) {
+            return NO;
+        }
+    }
+    // 如果覆盖,那么先删掉原文件
+    if ([self isExistsAtPath:toPath]) {
+        if (overwrite) {
+            [self removeItemAtPath:toPath error:error];
+        }else {
+            [self removeItemAtPath:path error:error];
+            return YES;
+        }
+    }
+    
+    // 移动文件 用copy复制 不要用move剪切
+    BOOL isSuccess = [[NSFileManager defaultManager] copyItemAtPath:path toPath:toPath error:error];
+    
+    return isSuccess;
+}
+
+#pragma mark - 根据URL获取文件名
++ (NSString *)fileNameAtPath:(NSString *)path suffix:(BOOL)suffix {
+    NSString *fileName = [path lastPathComponent];
+    if (!suffix) {
+        fileName = [fileName stringByDeletingPathExtension];
+    }
+    return fileName;
+}
+
++ (NSString *)directoryAtPath:(NSString *)path {
+    return [path stringByDeletingLastPathComponent];
+}
+
++ (NSString *)suffixAtPath:(NSString *)path {
+    return [path pathExtension];
+}
+
+#pragma mark - 判断文件(夹)是否存在
++ (BOOL)isExistsAtPath:(NSString *)path {
+    return [[NSFileManager defaultManager] fileExistsAtPath:path];
+}
+
++ (BOOL)isEmptyItemAtPath:(NSString *)path {
+    return [self isEmptyItemAtPath:path error:nil];
+}
+
++ (BOOL)isEmptyItemAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
+    return ([self isFileAtPath:path error:error] &&
+            [[self sizeOfItemAtPath:path error:error] intValue] == 0) ||
+    ([self isDirectoryAtPath:path error:error] &&
+     [[self listFilesInDirectoryAtPath:path deep:NO] count] == 0);
+}
+
++ (BOOL)isDirectoryAtPath:(NSString *)path {
+    return [self isDirectoryAtPath:path error:nil];
+}
+
++ (BOOL)isDirectoryAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
+    return ([self attributeOfItemAtPath:path forKey:NSFileType error:error] == NSFileTypeDirectory);
+}
+
++ (BOOL)isFileAtPath:(NSString *)path {
+    return [self isFileAtPath:path error:nil];
+}
+
++ (BOOL)isFileAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
+    return ([self attributeOfItemAtPath:path forKey:NSFileType error:error] == NSFileTypeRegular);
+}
+
++ (BOOL)isExecutableItemAtPath:(NSString *)path {
+    return [[NSFileManager defaultManager] isExecutableFileAtPath:path];
+}
+
++ (BOOL)isReadableItemAtPath:(NSString *)path {
+    return [[NSFileManager defaultManager] isReadableFileAtPath:path];
+}
++ (BOOL)isWritableItemAtPath:(NSString *)path {
+    return [[NSFileManager defaultManager] isWritableFileAtPath:path];
+}
+
+#pragma mark - 获取文件(夹)大小
++ (NSNumber *)sizeOfItemAtPath:(NSString *)path {
+    return [self sizeOfItemAtPath:path error:nil];
+}
+
++ (NSNumber *)sizeOfItemAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
+    return (NSNumber *)[self attributeOfItemAtPath:path forKey:NSFileSize error:error];
+}
+
++ (NSNumber *)sizeOfFileAtPath:(NSString *)path {
+    return [self sizeOfFileAtPath:path error:nil];
+}
+
++ (NSNumber *)sizeOfFileAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
+    if ([self isFileAtPath:path error:error]) {
+        return [self sizeOfItemAtPath:path error:error];
+    }
+    return nil;
+}
+
++ (NSNumber *)sizeOfDirectoryAtPath:(NSString *)path {
+    return [self sizeOfDirectoryAtPath:path error:nil];
+}
+
++ (NSNumber *)sizeOfDirectoryAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
+    if ([self isDirectoryAtPath:path error:error]) {
+        NSArray *subPaths = [self listFilesInDirectoryAtPath:path deep:YES];
+        NSEnumerator *contentsEnumurator = [subPaths objectEnumerator];
+        
+        NSString *file;
+        unsigned long long int folderSize = 0;
+        
+        while (file = [contentsEnumurator nextObject]) {
+            NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[path stringByAppendingPathComponent:file] error:nil];
+            folderSize += [[fileAttributes objectForKey:NSFileSize] intValue];
+        }
+        return [NSNumber numberWithUnsignedLongLong:folderSize];
+    }
+    return nil;
+}
+
++ (NSString *)sizeFormattedOfItemAtPath:(NSString *)path {
+    return [self sizeFormattedOfItemAtPath:path error:nil];
+}
+
++ (NSString *)sizeFormattedOfItemAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
+    NSNumber *size = [self sizeOfItemAtPath:path error:error];
+    if (size) {
+        return [self sizeFormatted:size];
+    }
+    return nil;
+}
+
++ (NSString *)sizeFormattedOfFileAtPath:(NSString *)path {
+    return [self sizeFormattedOfFileAtPath:path error:nil];
+}
+
++ (NSString *)sizeFormattedOfFileAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
+    NSNumber *size = [self sizeOfFileAtPath:path error:error];
+    if (size) {
+        return [self sizeFormatted:size];
+    }
+    return nil;
+}
+
++ (NSString *)sizeFormattedOfDirectoryAtPath:(NSString *)path {
+    return [self sizeFormattedOfDirectoryAtPath:path error:nil];
+}
+
++ (NSString *)sizeFormattedOfDirectoryAtPath:(NSString *)path error:(NSError *__autoreleasing *)error {
+    NSNumber *size = [self sizeOfDirectoryAtPath:path error:error];
+    if (size) {
+        return [self sizeFormatted:size];
+    }
+    return nil;
+}
+
+#pragma mark - 写入文件内容
++ (BOOL)writeFileAtPath:(NSString *)path content:(NSObject *)content {
+    return [self writeFileAtPath:path content:content error:nil];
+}
+
++ (BOOL)writeFileAtPath:(NSString *)path content:(NSObject *)content error:(NSError *__autoreleasing *)error {
+    if (!content) {
+        [NSException raise:@"非法的文件内容" format:@"文件内容不能为nil"];
+        return NO;
+    }
+    if ([self isExistsAtPath:path]) {
+        if ([content isKindOfClass:[NSMutableArray class]]) {
+            [(NSMutableArray *)content writeToFile:path atomically:YES];
+        }else if ([content isKindOfClass:[NSArray class]]) {
+            [(NSArray *)content writeToFile:path atomically:YES];
+        }else if ([content isKindOfClass:[NSMutableData class]]) {
+            [(NSMutableData *)content writeToFile:path atomically:YES];
+        }else if ([content isKindOfClass:[NSData class]]) {
+            [(NSData *)content writeToFile:path atomically:YES];
+        }else if ([content isKindOfClass:[NSMutableDictionary class]]) {
+            [(NSMutableDictionary *)content writeToFile:path atomically:YES];
+        }else if ([content isKindOfClass:[NSDictionary class]]) {
+            [(NSDictionary *)content writeToFile:path atomically:YES];
+        }else if ([content isKindOfClass:[NSJSONSerialization class]]) {
+            [(NSDictionary *)content writeToFile:path atomically:YES];
+        }else if ([content isKindOfClass:[NSMutableString class]]) {
+            [[((NSString *)content) dataUsingEncoding:NSUTF8StringEncoding] writeToFile:path atomically:YES];
+        }else if ([content isKindOfClass:[NSString class]]) {
+            [[((NSString *)content) dataUsingEncoding:NSUTF8StringEncoding] writeToFile:path atomically:YES];
+        }else if ([content isKindOfClass:[UIImage class]]) {
+            [UIImagePNGRepresentation((UIImage *)content) writeToFile:path atomically:YES];
+        }else if ([content conformsToProtocol:@protocol(NSCoding)]) {
+            [NSKeyedArchiver archiveRootObject:content toFile:path];
+        }else {
+            [NSException raise:@"非法的文件内容" format:@"文件类型%@异常,无法被处理。", NSStringFromClass([content class])];
+            
+            return NO;
+        }
+    }else {
+        return NO;
+    }
+    return YES;
+}
+
+#pragma mark - private methods
++ (BOOL)isNotError:(NSError **)error {
+    return ((error == nil) || ((*error) == nil));
+}
+
++(NSString *)sizeFormatted:(NSNumber *)size {
+    return [NSByteCountFormatter stringFromByteCount:[size unsignedLongLongValue] countStyle:NSByteCountFormatterCountStyleFile];
+}
+
+@end

+ 90 - 0
创维盒子/双子星云手机/Vendor/UploadManager/CWUploadManage/CWFileStreamSeparation.h

@@ -0,0 +1,90 @@
+//
+//  CWFileStreamSeparation.h
+//  uploadFileDemo
+//
+//  Created by hyjet on 2018/3/9.
+//  Copyright © 2018年 uploadFileDemo. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+typedef enum : NSUInteger {
+    CWUploadStatusWaiting = 0,//任务队列等待
+    CWUploadStatusUpdownloading,//上传中
+    CWUploadStatusPaused,//暂停
+    CWUploadStatusFinished,//上传成功
+    CWUploadStatusFailed //上传失败
+} CWUploadStatus;//任务状态
+
+#define CWStreamFragmentMaxSize         1024 * 1024 // 500KB
+
+
+@class CWStreamFragment;
+
+/**
+ * 文件流操作类
+ */
+@interface CWFileStreamSeparation : NSObject<NSCoding>
+@property (nonatomic, copy) NSString    *fileName;//包括文件后缀名的文件名
+@property (nonatomic, strong)  NSData   *imageData; //文件预览图
+@property (nonatomic, assign)  NSInteger timeStamp;    //时间戳
+@property (nonatomic, assign) NSUInteger fileSize;//文件大小
+@property (nonatomic, copy) NSString *filePath;;//文件所在的文件目录
+@property (nonatomic, copy) NSString *uploadLocation;;//上传到服务器的文件目录
+@property (nonatomic, assign)CWUploadStatus fileStatus;//文件状态
+@property (nonatomic, copy)NSString *md5String;//文件md5编码名称
+@property (nonatomic, strong) NSArray<CWStreamFragment*> *streamFragments;//文件分片数组
+@property (nonatomic, copy) NSString *bizId;
+
+@property (nonatomic,assign)double progressRate;//上传进度
+@property (nonatomic,assign)NSInteger uploadDateSize;//已上传文件大小
+
+@property (nonatomic,assign)NSInteger select;  // 是否被选中
+
+
+/** description */
+@property (readonly, copy) NSString *description;
+
+//若为读取文件数据,打开一个已存在的文件。
+//若为写入文件数据,如果文件不存在,会创建的新的空文件。(创建FileStreamer对象就可以直接使用fragments(分片数组)属性)
+- (instancetype)initFileOperationAtPath:(NSString*)path forReadOperation:(BOOL)isReadOperation;
+
+- (instancetype)initFileOperationAtPath:(NSString*)path forReadOperation:(BOOL)isReadOperation uploadLocation:(NSString *)uploadLocation imageData:(NSData *)imageData;
+
+//获取当前偏移量
+- (NSUInteger)offsetInFile;
+
+//设置偏移量, 仅对读取设置
+- (void)seekToFileOffset:(NSUInteger)offset;
+
+//将偏移量定位到文件的末尾
+- (NSUInteger)seekToEndOfFile;
+
+//关闭文件
+- (void)closeFile;
+
+#pragma mark - 读操作
+//通过分片信息读取对应的片数据
+- (NSData*)readDateOfFragment:(CWStreamFragment*)fragment;
+
+//从当前文件偏移量开始
+- (NSData*)readDataOfLength:(NSUInteger)bytes;
+
+//从当前文件偏移量开始
+- (NSData*)readDataToEndOfFile;
+
+#pragma mark - 写操作
+//写入文件数据
+- (void)writeData:(NSData *)data;
+
++(NSString*)fileKeyMD5WithPath:(NSString*)path;
+
+@end
+
+//上传文件片
+@interface CWStreamFragment : NSObject<NSCoding>
+@property (nonatomic,copy)NSString          *fragmentId;    //片的唯一标识
+@property (nonatomic,assign)NSUInteger      fragmentSize;   //片的大小
+@property (nonatomic,assign)NSUInteger      fragementOffset;//片的偏移量
+@property (nonatomic,assign)BOOL            fragmentStatus; //上传状态 YES上传成功
+@end

+ 451 - 0
创维盒子/双子星云手机/Vendor/UploadManager/CWUploadManage/CWFileStreamSeparation.m

@@ -0,0 +1,451 @@
+//
+//  CWFileStreamSeparation.m
+//  uploadFileDemo
+//
+//  Created by hyjet on 2018/3/9.
+//  Copyright © 2018年 uploadFileDemo. All rights reserved.
+//
+
+#import "CWFileStreamSeparation.h"
+#import "CWFileManager.h"
+#import <CommonCrypto/CommonDigest.h>
+#import "objc/runtime.h"
+
+#pragma mark - CWFileStreamSeparation
+#define FileHashDefaultChunkSizeForReadingData 1024*8
+
+@interface CWFileStreamSeparation ()
+//@property (nonatomic, copy) NSString                          *fileName;
+//@property (nonatomic, assign) NSUInteger                      fileSize;
+//@property (nonatomic, strong) NSArray<CWStreamFragment*>      *streamFragments;
+@property (nonatomic, strong) NSFileHandle                    *readFileHandle;
+@property (nonatomic, strong) NSFileHandle                    *writeFileHandle;
+@property (nonatomic, assign) BOOL                            isReadOperation;
+//@property (nonatomic,assign)double progressRate;
+//@property (nonatomic,assign)NSInteger uploadDateSize;
+@end
+
+@implementation CWFileStreamSeparation
+
+-(NSString *)description{
+    unsigned int count;
+    const char *clasName = object_getClassName(self);
+    NSMutableString *string = [NSMutableString stringWithFormat:@"<%s: %p>:[ \n",clasName, self];
+    Class clas = NSClassFromString([NSString stringWithCString:clasName encoding:NSUTF8StringEncoding]);
+    Ivar *ivars = class_copyIvarList(clas, &count);
+    for (int i = 0; i < count; i++) {
+        @autoreleasepool {
+            Ivar ivar = ivars[i];
+            const char *name = ivar_getName(ivar);
+            //得到类型
+            NSString *type = [NSString stringWithCString:ivar_getTypeEncoding(ivar) encoding:NSUTF8StringEncoding];
+            NSString *key = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];
+            id value = [self valueForKey:key];
+            //确保BOOL 值输出的是YES 或 NO,这里的B是我打印属性类型得到的……
+            if ([type isEqualToString:@"B"]) {
+                value = (value == 0 ? @"NO" : @"YES");
+            }
+            [string appendFormat:@"\t%@: %@\n",[self delLine:key], value];
+        }
+    }
+    [string appendFormat:@"]"];
+    return string;
+}
+//因为ivar_getName得到的是一个带有下划线的名字,去掉下划线看起来更漂亮
+-(NSString *)delLine:(NSString *)string{
+    if ([string hasPrefix:@"_"]) {
+        return [string substringFromIndex:1];
+    }
+    return string;
+}
+
++ (NSString *)fileKey {
+    
+    CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault);
+    CFStringRef cfstring = CFUUIDCreateString(kCFAllocatorDefault, uuid);
+    const char *cStr = CFStringGetCStringPtr(cfstring,CFStringGetFastestEncoding(cfstring));
+    unsigned char result[16];
+    CC_MD5( cStr, (unsigned int)strlen(cStr), result );
+    CFRelease(uuid);
+    CFRelease(cfstring);
+    
+    return [NSString stringWithFormat:
+            @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%08lx",
+            result[0], result[1], result[2], result[3],
+            result[4], result[5], result[6], result[7],
+            result[8], result[9], result[10], result[11],
+            result[12], result[13], result[14], result[15],
+            (unsigned long)(arc4random() % NSUIntegerMax)];
+}
+
++ (NSString *)fileKeyMD5WithPath:(NSString*)path
+{
+    return (__bridge_transfer NSString *)FileMD5HashCreateWithPath((__bridge CFStringRef)path, FileHashDefaultChunkSizeForReadingData);
+//    NSString *fileName = [path lastPathComponent];
+//    return [RSATool md5Encrypt:fileName];
+}
+
+CFStringRef FileMD5HashCreateWithPath(CFStringRef filePath,size_t chunkSizeForReadingData) {
+    // Declare needed variables
+    CFStringRef result = NULL;
+    CFReadStreamRef readStream = NULL;
+    // Get the file URL
+    CFURLRef fileURL =
+    CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
+                                  (CFStringRef)filePath,
+                                  kCFURLPOSIXPathStyle,
+                                  (Boolean)false);
+    if (!fileURL) goto done;
+    // Create and open the read stream
+    readStream = CFReadStreamCreateWithFile(kCFAllocatorDefault,
+                                            (CFURLRef)fileURL);
+    if (!readStream) goto done;
+    bool didSucceed = (bool)CFReadStreamOpen(readStream);
+    if (!didSucceed) goto done;
+    // Initialize the hash object
+    CC_MD5_CTX hashObject;
+    CC_MD5_Init(&hashObject);
+    // Make sure chunkSizeForReadingData is valid
+    if (!chunkSizeForReadingData) {
+        chunkSizeForReadingData = FileHashDefaultChunkSizeForReadingData;
+    }
+    // Feed the data to the hash object
+    bool hasMoreData = true;
+    while (hasMoreData) {
+        uint8_t buffer[chunkSizeForReadingData];
+        CFIndex readBytesCount = CFReadStreamRead(readStream,(UInt8 *)buffer,(CFIndex)sizeof(buffer));
+        if (readBytesCount == -1) break;
+        if (readBytesCount == 0) {
+            hasMoreData = false;
+            continue;
+        }
+        CC_MD5_Update(&hashObject,(const void *)buffer,(CC_LONG)readBytesCount);
+    }
+    // Check if the read operation succeeded
+    didSucceed = !hasMoreData;
+    // Compute the hash digest
+    unsigned char digest[CC_MD5_DIGEST_LENGTH];
+    CC_MD5_Final(digest, &hashObject);
+    // Abort if the read operation failed
+    if (!didSucceed) goto done;
+    // Compute the string result
+    char hash[2 * sizeof(digest) + 1];
+    for (size_t i = 0; i < sizeof(digest); ++i) {
+        snprintf(hash + (2 * i), 3, "%02x", (int)(digest[i]));
+    }
+    result = CFStringCreateWithCString(kCFAllocatorDefault,(const char *)hash,kCFStringEncodingUTF8);
+    
+done:
+    if (readStream) {
+        CFReadStreamClose(readStream);
+        CFRelease(readStream);
+    }
+    if (fileURL) {
+        CFRelease(fileURL);
+    }
+    return result;
+}
+
+
+- (void)encodeWithCoder:(NSCoder *)aCoder {
+    
+    [aCoder encodeObject:[self fileName] forKey:@"fileName"];
+    [aCoder encodeObject:[self imageData] forKey:@"imageData"];
+    [aCoder encodeObject:[NSNumber numberWithDouble:[self timeStamp]] forKey:@"timeStamp"];
+    [aCoder encodeObject:[self uploadLocation] forKey:@"uploadLocation"];
+    [aCoder encodeObject:[NSNumber numberWithUnsignedInteger:[self fileSize]] forKey:@"fileSize"];
+    [aCoder encodeObject:[NSNumber numberWithInteger:[self fileStatus]] forKey:@"fileStatus"];
+    [aCoder encodeObject:[self filePath] forKey:@"filePath"];
+    [aCoder encodeObject:[self md5String] forKey:@"md5String"];
+    [aCoder encodeObject:[self streamFragments] forKey:@"streamFragments"];
+    [aCoder encodeObject:[self bizId] forKey:@"bizId"];
+    [aCoder encodeObject:[NSNumber numberWithUnsignedInteger:[self uploadDateSize]] forKey:@"uploadDateSize"];
+    [aCoder encodeObject:[NSNumber numberWithDouble:[self progressRate]] forKey:@"progressRate"];
+}
+
+- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
+    self = [super init];
+    if (self != nil) {
+        [self setFileName:[aDecoder decodeObjectForKey:@"fileName"]];
+        [self setImageData:[aDecoder decodeObjectForKey:@"imageData"]];
+        [self setTimeStamp:[[aDecoder decodeObjectForKey:@"timeStamp"] integerValue]];
+        [self setUploadLocation:[aDecoder decodeObjectForKey:@"uploadLocation"]];
+        [self setFileStatus:[[aDecoder decodeObjectForKey:@"fileStatus"] intValue]];
+        [self setFileSize:[[aDecoder decodeObjectForKey:@"fileSize"] unsignedIntegerValue]];
+        [self setFilePath:[aDecoder decodeObjectForKey:@"filePath"]];
+        [self setMd5String:[aDecoder decodeObjectForKey:@"md5String"]];
+        [self setStreamFragments:[aDecoder decodeObjectForKey:@"streamFragments"]];
+        [self setBizId:[aDecoder decodeObjectForKey:@"bizId"]];
+        [self setProgressRate:[[aDecoder decodeObjectForKey:@"progressRate"] doubleValue]];
+        [self setUploadDateSize:[[aDecoder decodeObjectForKey:@"uploadDateSize"] unsignedIntegerValue]];
+    }
+    
+    return self;
+}
+
+- (BOOL)getFileInfoAtPath:(NSString*)path {
+    
+    NSFileManager *fileMgr = [NSFileManager defaultManager];
+    if (![fileMgr fileExistsAtPath:path]) {
+        HLog(@"文件不存在:%@",path);
+        return NO;
+    }
+    
+    self.filePath = path;
+    
+    NSDictionary *attr =[fileMgr attributesOfItemAtPath:path error:nil];
+    self.fileSize = attr.fileSize;
+    
+    self.md5String = [CWFileStreamSeparation fileKeyMD5WithPath:path];
+    
+    self.bizId=[[NSUUID UUID] UUIDString];
+    
+    self.uploadDateSize = 0;
+    self.progressRate = 0.00;
+
+    NSString *fileName = [path lastPathComponent];
+    self.fileName = fileName;
+    
+    self.fileStatus = CWUploadStatusWaiting;
+    
+    return YES;
+}
+
+- (BOOL)getFileInfoAtPath:(NSString*)path uploadLocation:(NSString *)uploadLocation imageData:(NSData *)imageData {
+    
+    NSFileManager *fileMgr = [NSFileManager defaultManager];
+    if (![fileMgr fileExistsAtPath:path]) {
+        HLog(@"文件不存在:%@",path);
+        return NO;
+    }
+    
+    self.filePath = path;
+    
+    self.uploadLocation = uploadLocation;
+    self.imageData = imageData;
+    self.timeStamp = [[NSDate date] timeIntervalSince1970];
+    
+    NSDictionary *attr =[fileMgr attributesOfItemAtPath:path error:nil];
+    self.fileSize = attr.fileSize;
+    
+    self.md5String = [CWFileStreamSeparation fileKeyMD5WithPath:path];
+    
+    self.bizId=[[NSUUID UUID] UUIDString];
+    
+    self.uploadDateSize = 0;
+    self.progressRate = 0.00;
+
+    NSString *fileName = [path lastPathComponent];
+    self.fileName = fileName;
+    
+    self.fileStatus = CWUploadStatusWaiting;
+    
+    return YES;
+}
+
+
+// 若为读取文件数据,打开一个已存在的文件。
+// 若为写入文件数据,如果文件不存在,会创建的新的空文件。
+- (instancetype)initFileOperationAtPath:(NSString*)path forReadOperation:(BOOL)isReadOperation {
+    
+    if (self = [super init]) {
+        self.isReadOperation = isReadOperation;
+        if (_isReadOperation) {
+            if (![self getFileInfoAtPath:path]) {
+                return nil;
+            }
+            self.readFileHandle = [NSFileHandle fileHandleForReadingAtPath:path];
+            [self cutFileForFragments];
+        } else {
+            NSFileManager *fileMgr = [NSFileManager defaultManager];
+            if (![fileMgr fileExistsAtPath:path]) {
+                [fileMgr createFileAtPath:path contents:nil attributes:nil];
+            }
+            
+            if (![self getFileInfoAtPath:path]) {
+                return nil;
+            }
+            
+            self.writeFileHandle = [NSFileHandle fileHandleForWritingAtPath:path];
+        }
+    }
+    
+    return self;
+}
+
+// 若为读取文件数据,打开一个已存在的文件。
+// 若为写入文件数据,如果文件不存在,会创建的新的空文件。
+- (instancetype)initFileOperationAtPath:(NSString*)path forReadOperation:(BOOL)isReadOperation uploadLocation:(NSString *)uploadLocation imageData:(NSData *)imageData {
+    
+    if (self = [super init]) {
+        self.isReadOperation = isReadOperation;
+        if (_isReadOperation) {
+            if (![self getFileInfoAtPath:path uploadLocation:uploadLocation imageData:imageData]) {
+                return nil;
+            }
+            self.readFileHandle = [NSFileHandle fileHandleForReadingAtPath:path];
+            [self cutFileForFragments];
+        } else {
+            NSFileManager *fileMgr = [NSFileManager defaultManager];
+            if (![fileMgr fileExistsAtPath:path]) {
+                [fileMgr createFileAtPath:path contents:nil attributes:nil];
+            }
+            
+            if (![self getFileInfoAtPath:path uploadLocation:uploadLocation imageData:imageData]) {
+                return nil;
+            }
+            
+            self.writeFileHandle = [NSFileHandle fileHandleForWritingAtPath:path];
+        }
+    }
+    
+    return self;
+}
+
+#pragma mark - 读操作
+//切分文件片段
+- (void)cutFileForFragments {
+    
+    NSUInteger offset = CWStreamFragmentMaxSize;
+    // 块数
+    NSUInteger chunks = (_fileSize%offset==0)?(_fileSize/offset):(_fileSize/(offset) + 1);
+    
+    NSMutableArray<CWStreamFragment *> *fragments = [[NSMutableArray alloc] initWithCapacity:0];
+    for (NSUInteger i = 0; i < chunks; i ++) {
+        
+        CWStreamFragment *fFragment = [[CWStreamFragment alloc] init];
+        fFragment.fragmentStatus = NO;
+        fFragment.fragmentId = [[self class] fileKey];
+        fFragment.fragementOffset = i * offset;
+        
+        if (i != chunks - 1) {
+            fFragment.fragmentSize = offset;
+        } else {
+            fFragment.fragmentSize = _fileSize - fFragment.fragementOffset;
+        }
+        
+        [fragments addObject:fFragment];
+    }
+    
+    self.streamFragments = fragments;
+}
+
+//通过分片信息读取对应的片数据
+- (NSData*)readDateOfFragment:(CWStreamFragment*)fragment {
+    HLog(@"del 2024525  暂未做");
+    /* hxd del 2024525  暂未做
+    if (self.readFileHandle==nil) {
+        
+        NSDictionary *loginDict = [[UseAccountManage shareInstance] getLoginInfo];
+        if ([[loginDict allKeys] containsObject:@"account"])
+         {
+             NSString *fileFolder = kPath_YunPan_Upload_Folder;
+             NSString *fileName = [_filePath lastPathComponent];
+             NSString *fileURL = [fileFolder stringByAppendingPathComponent:fileName];
+             self.readFileHandle = [NSFileHandle fileHandleForReadingAtPath:fileURL];
+         }else {
+             HLog(@"未登录 读取缓存文件失败!");
+         }
+    }
+
+    if (fragment) {
+        [self seekToFileOffset:fragment.fragementOffset];
+        return [_readFileHandle readDataOfLength:fragment.fragmentSize];
+    }
+    [self closeFile];
+     */
+    return nil;
+}
+
+- (NSData*)readDataOfLength:(NSUInteger)bytes {
+    return [_readFileHandle readDataOfLength:bytes];
+}
+
+
+- (NSData*)readDataToEndOfFile {
+    return [_readFileHandle readDataToEndOfFile];
+}
+
+#pragma mark - 写操作
+
+// 写入文件数据
+- (void)writeData:(NSData *)data {
+    [_writeFileHandle writeData:data];
+}
+
+#pragma mark - common
+// 获取当前偏移量
+- (NSUInteger)offsetInFile{
+    if (_isReadOperation) {
+        return [_readFileHandle offsetInFile];
+    }
+    
+    return [_writeFileHandle offsetInFile];
+}
+
+// 设置偏移量,仅对读取设置
+- (void)seekToFileOffset:(NSUInteger)offset {
+    [_readFileHandle seekToFileOffset:offset];
+}
+
+// 将偏移量定位到文件的末尾
+- (NSUInteger)seekToEndOfFile{
+    if (_isReadOperation) {
+        return (NSUInteger)[_readFileHandle seekToEndOfFile];
+    }
+    
+    return [_writeFileHandle seekToEndOfFile];
+}
+
+// 关闭文件
+- (void)closeFile {
+    if (_isReadOperation) {
+        [_readFileHandle closeFile];
+    } else {
+        [_writeFileHandle closeFile];
+    }
+}
+
+//归档
++ (void)archerTheDictionary:(NSDictionary *)dict file:(NSString *)path{
+    
+    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:dict];
+    BOOL finish = [data writeToFile:path atomically:YES];
+    if (finish) HLog(@"归档成功");
+    
+}
+
+//解档
++ (NSMutableDictionary *)unArcherThePlist:(NSString *)path{
+    NSMutableDictionary *dic = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
+    return dic;
+}
+
+@end
+
+
+
+
+@implementation CWStreamFragment
+
+- (void)encodeWithCoder:(NSCoder *)aCoder {
+    
+    [aCoder encodeObject:[self fragmentId] forKey:@"fragmentId"];
+    [aCoder encodeObject:[NSNumber numberWithUnsignedInteger:[self fragmentSize]] forKey:@"fragmentSize"];
+    [aCoder encodeObject:[NSNumber numberWithUnsignedInteger:[self fragementOffset]] forKey:@"fragementOffset"];
+    [aCoder encodeObject:[NSNumber numberWithUnsignedInteger:[self fragmentStatus]] forKey:@"fragmentStatus"];
+}
+
+- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
+    self = [super init];
+    if (self != nil) {
+        [self setFragmentId:[aDecoder decodeObjectForKey:@"fragmentId"]];
+        [self setFragmentSize:[[aDecoder decodeObjectForKey:@"fragmentSize"] unsignedIntegerValue]];
+        [self setFragementOffset:[[aDecoder decodeObjectForKey:@"fragementOffset"] unsignedIntegerValue]];
+        [self setFragmentStatus:[[aDecoder decodeObjectForKey:@"fragmentStatus"] boolValue]];
+    }
+    
+    return self;
+}
+
+@end

+ 114 - 0
创维盒子/双子星云手机/Vendor/UploadManager/CWUploadManage/CWFileUploadManager.h

@@ -0,0 +1,114 @@
+//
+//  CWFileUploadManager.h
+//  uploadFileDemo
+//
+//  Created by hyjet on 2018/3/9.
+//  Copyright © 2018年 uploadFileDemo. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "CWFileStreamSeparation.h"
+#import "CWUploadTask.h"
+#import "CWFileManager.h"
+#import "CWUploadTask+CheckInfo.h"
+
+/** 删除/清空上传任务通知 */
+#define CWUploadTaskExeDelete          @"CWUploadTaskExeDelete"
+
+@interface CWFileUploadManager : NSObject
+//总的文件分片模型数
+@property (nonatomic,readonly)NSMutableDictionary *fileStreamDict;
+
+//总任务数
+@property (nonatomic,readonly)NSMutableDictionary *allTasks;
+
+//正在上传中的任务
+@property (nonatomic,readonly)NSMutableDictionary *uploadingTasks;
+
+//正在等待上传的任务
+@property (nonatomic,readonly)NSMutableDictionary *uploadWaitTasks;
+
+//已经上传完的任务
+@property (nonatomic,readonly)NSMutableDictionary *uploadEndTasks;
+
+//同时上传的任务数
+@property (nonatomic,readonly)NSInteger uploadMaxNum;
+
+//云盘剩余空间
+@property (nonatomic,assign) int64_t leftStore;
+
+//配置的上传路径
+@property (nonatomic,readonly)NSURL *url;
+
+//配置的请求体
+@property (nonatomic,readonly)NSMutableURLRequest *request;
+
+//操作记录plist文件保存路径
+@property (nonatomic,copy)NSString *plistPath;
+
+//获得管理类单例对象
++ (instancetype)shardUploadManager;
+
+//配置全局默认参数
+/**
+ @param request 默认请求头
+ @param num 最大任务数
+ */
+- (void)config:(NSMutableURLRequest * _Nonnull)request maxTask:(NSInteger)num;
+
+//根据文件路径创建上传任务
+- (CWUploadTask *_Nullable)createUploadTask:(NSString *_Nonnull)filePath;
+
+//根据文件路径 服务器路径创建上传任务
+- (CWUploadTask *_Nullable)createUploadTask:(NSString *_Nonnull)filePath uploadLocation:(NSString *_Nonnull)uploadLocation imageData:(NSData *_Nullable)imageData;
+
+//云手机上传 写入plist文件
+- (void)createUploadTaskWithParams:(NSDictionary *)params;
+
+/**
+ 暂停一个上传任务
+ 
+ @param fileStream 上传文件的路径
+ */
+- (void)pauseUploadTask:(CWFileStreamSeparation *_Nonnull)fileStream;
+
+/**
+ 继续开始一个上传任务
+ 
+ @param fileStream 上传文件的路径
+ */
+- (void)resumeUploadTask:(CWFileStreamSeparation *_Nonnull)fileStream;
+
+/**
+ 删除一个上传任务,同时会删除当前任务上传的缓存数据
+ 
+ @param fileStream 上传文件的路径
+ */
+- (void)removeUploadTask:(CWFileStreamSeparation *_Nonnull)fileStream;
+
+/**
+ 暂停所有上传任务
+ */
+- (void)pauseAllUploadTask;
+
+/**
+ 启动所有上传任务
+ */
+- (void)resumeAllUploadTask;
+
+/**
+ 删除所有上传任务
+ */
+- (void)removeAllUploadTask;
+
+#pragma mark - 相册文件写入Cache
+/// 将相册里的视频文件缓存到Cache
+- (NSString *_Nullable)writeVideoDataFromURL:(NSURL *_Nullable)url uploadLocation:(NSString *_Nullable)uploadLocation;
+
+/// 将相册里的图片文件缓存到Cache
+- (NSString *_Nullable)writeIamgeData:(NSData *_Nullable)data iamgeName:(NSString *_Nullable)iamgeName uploadLocation:(NSString *_Nullable)uploadLocation;
+
+- (NSString *_Nullable)writeIamgeDataToLocal:(NSData *_Nullable)data;
+
+@end
+

+ 572 - 0
创维盒子/双子星云手机/Vendor/UploadManager/CWUploadManage/CWFileUploadManager.m

@@ -0,0 +1,572 @@
+//
+//  CWFileUploadManager.m
+//  uploadFileDemo
+//
+//  Created by hyjet on 2018/3/9.
+//  Copyright © 2018年 uploadFileDemo. All rights reserved.
+//
+
+#import "CWFileUploadManager.h"
+//#import "CWFileStreamSeparation.h"
+//#import "CWUploadTask.h"
+//#import "CWFileManager.h"
+
+//#define plistPath [[CWFileManager cachesDir] stringByAppendingPathComponent:uploadPlist]
+#define default_max @"uploadMax"
+
+@interface CWFileUploadManager ()
+
+@property (nonatomic,strong)NSMutableDictionary *fileStreamDict;
+
+@property (nonatomic,strong)NSMutableDictionary *allTasks;
+
+//正在上传中的任务
+@property (nonatomic,strong)NSMutableDictionary *uploadingTasks;
+
+//正在等待上传的任务
+@property (nonatomic,strong)NSMutableDictionary *uploadWaitTasks;
+
+//已经上传完的任务
+@property (nonatomic,strong)NSMutableDictionary *uploadEndTasks;
+
+@property (nonatomic,assign)NSInteger uploadMaxNum;
+
+@property (nonatomic,strong)NSURL *url;
+@property (nonatomic,strong)NSMutableURLRequest *request;
+
+@property (nonatomic,copy)NSString *uploadLocation;
+
+@end
+
+@implementation CWFileUploadManager
+
+static CWFileUploadManager * _instance;
+
+- (NSString *)getNewPlistPath {
+
+    NSString *account = [HWDataManager getStringWithKey:Const_HWAccountPhoneNumber];
+    if (account.length != 0) {
+         NSString *fileFolder = kPath_YunPan_Upload_Folder;
+         return [fileFolder stringByAppendingPathComponent:@"uploadPlist.plist"];
+     }else {
+         HLog(@"未登录 读取plist缓存文件失败!");
+         return @"";
+     }
+}
+
+-(NSMutableDictionary *)fileStreamDict{
+    if (!_fileStreamDict) {
+        _fileStreamDict = [NSMutableDictionary dictionary];
+    }
+    return _fileStreamDict;
+}
+
+- (NSMutableDictionary *)allTasks
+{
+    if (!_allTasks) {
+        _allTasks = [_instance allUploadTasks];
+    }
+    return _allTasks;
+}
+
+- (NSMutableDictionary *)uploadingTasks
+{
+    return [self allUploadingTasks];
+}
+
+- (NSMutableDictionary *)uploadWaitTasks
+{
+    return [self allUploadWaitTasks];
+}
+
+- (NSMutableDictionary *)uploadEndTasks
+{
+    return [self allUploadEndTasks];
+}
+
++ (instancetype)shardUploadManager {
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        _instance = [[self alloc] init];
+        [_instance registeNotification];
+        [_instance defaultsTask];
+        _instance.plistPath = [_instance getNewPlistPath];
+    });
+    return _instance;
+}
+
++ (CWUploadTask *)startUploadWithPath:(NSString *)path
+{
+    //是否是在册任务
+    if (![CWFileUploadManager isUploadTask:path]) {
+        [_instance taskRecord:path];
+        
+    }
+    return [_instance continuePerformTaskWithFilePath:path];
+}
+
+- (CWUploadTask *_Nullable)createUploadTask:(NSString *_Nonnull)filePath
+{
+    //是否是在册任务
+    if (![CWFileUploadManager isUploadTask:filePath]) {
+        [_instance taskRecord:filePath];
+        
+    }
+    return [self continuePerformTaskWithFilePath:filePath];
+}
+
+- (CWUploadTask *_Nullable)createUploadTask:(NSString *_Nonnull)filePath uploadLocation:(NSString *_Nonnull)uploadLocation imageData:(NSData *_Nullable)imageData {
+    
+    //是否是在册任务
+    if (![CWFileUploadManager isUploadTask:filePath]) {
+        [_instance taskRecord:filePath uploadLocation:uploadLocation imageData:imageData];
+        
+    }
+    return [self continuePerformTaskWithFilePath:filePath];
+}
+
+//云手机上传 写入plist文件
+- (void)createUploadTaskWithParams:(NSDictionary *)params {
+    
+    CWFileStreamSeparation *fileStream = [[CWFileStreamSeparation alloc] init];
+    NSString *path = [NSString stringWithFormat:@"%@", [params objectForKey:@"path"]];
+    fileStream.fileName = path.lastPathComponent;
+    fileStream.fileSize = [[params objectForKey:@"length"] integerValue];
+    fileStream.uploadDateSize = [[params objectForKey:@"length"] integerValue];
+    fileStream.progressRate = 1.00;
+    fileStream.bizId=[[NSUUID UUID] UUIDString];
+    fileStream.timeStamp = [iTools getNowTimeStamp];
+    fileStream.fileStatus = CWUploadStatusFinished;
+    
+    [self.fileStreamDict setObject:fileStream forKey:path.lastPathComponent];
+    CWUploadTask *uploadTask = self.allTasks[path.lastPathComponent];
+    if (!uploadTask) {
+        uploadTask = [CWUploadTask initWithStreamModel:fileStream];
+        [self.allTasks setObject:uploadTask forKey:path.lastPathComponent];
+    }
+    
+    [self archerTheDictionary:_fileStreamDict file:self.plistPath];
+    HLog(@"%@---%@", self.fileStreamDict, self.allTasks);
+    [[NSNotificationCenter defaultCenter] postNotificationName:CWUploadTaskExeEnd object:nil userInfo:@{@"fileStream":fileStream}];
+    
+}
+
+//配置全局默认的参数
+- (void)config:(NSMutableURLRequest *)request maxTask:(NSInteger)num
+{
+    if (!request.URL) {
+        HLog(@"request缺少URL");
+    }
+    [HWDataManager setIntegerWithKey:default_max value:num];
+    self.uploadMaxNum = 3;
+    self.url = request.URL;
+    self.request = request;
+}
+
+//设置最大任务数
+- (void)setUploadMaxNum:(NSInteger)uploadMaxNum
+{
+    if (_uploadMaxNum<3) {
+        _uploadMaxNum = uploadMaxNum;
+    }else if (_uploadMaxNum<0){
+        _uploadMaxNum = 3;
+    }else if(_uploadMaxNum>=3){
+        _uploadMaxNum = 3;
+    }
+}
+
+- (void)defaultsTask{
+    NSInteger tmpMax = [HWDataManager getIntegerWithKey:default_max];
+    self.uploadMaxNum = tmpMax?tmpMax:3;
+}
+
+/**
+ 暂停一个上传任务
+ */
+- (void)pauseUploadTask:(CWFileStreamSeparation *_Nonnull)fileStream
+{
+    CWUploadTask *task = [self.allTasks objectForKey:fileStream.fileName];
+    [task taskCancel];
+}
+
+/**
+ 继续开始一个上传任务
+ */
+- (void)resumeUploadTask:(CWFileStreamSeparation *_Nonnull)fileStream
+{
+    CWUploadTask *task = [self.allTasks objectForKey:fileStream.fileName];
+    [task taskResume];
+}
+
+/**
+ 删除一个上传任务,同时会删除当前任务上传的缓存数据
+ */
+- (void)removeUploadTask:(CWFileStreamSeparation *_Nonnull)fileStream
+{
+    CWUploadTask *task = [self.allTasks objectForKey:fileStream.fileName];
+    
+    [task taskCancel];
+    
+    if ([[self.allTasks allKeys] containsObject:fileStream.fileName]) {
+        [self.allTasks removeObjectForKey:fileStream.fileName];
+    }
+    
+    if ([[self.uploadingTasks allKeys] containsObject:fileStream.fileName]) {
+        [self.uploadingTasks removeObjectForKey:fileStream.fileName];
+    }
+
+    if (_fileStreamDict[fileStream.fileName]) {
+        _fileStreamDict = [self unArcherThePlist:self.plistPath];
+    }
+    [_fileStreamDict removeObjectForKey:fileStream.fileName];
+    
+    [self archerTheDictionary:_fileStreamDict file:self.plistPath];
+    
+    // 删除本地缓存的文件
+    NSString *fileFolder = kPath_YunPan_Upload_Folder;
+    NSString *fileName = fileStream.fileName;
+    NSString *fileURL = [fileFolder stringByAppendingPathComponent:fileName];
+//    HLog(@"%@--%@", fileURL, dict[@"fullPath"]);
+    if ([CWFileManager isExistsAtPath:fileURL]) {
+        BOOL flag = [[NSFileManager defaultManager] removeItemAtPath:fileURL error:nil];
+        HLog(@"上传文件删除结果:%d", flag);
+    }else {
+        HLog(@"上传文件删除失败 文件不存在");
+    }
+
+}
+
+/**
+ 暂停所有的上传任务
+ */
+- (void)pauseAllUploadTask
+{
+    for (CWUploadTask *task in [self.allTasks allValues]) {
+        [task taskCancel];
+    }
+}
+
+/**
+ 启动所有上传任务
+ */
+- (void)resumeAllUploadTask {
+    
+    if (self.allTasks.count == 0) {
+        return;
+    }
+
+    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
+    [self.allTasks enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
+        CWUploadTask *task = obj;
+        if (task.fileStream.fileStatus == CWUploadStatusFinished || task.fileStream.progressRate == 1) { // 已完成的任务
+            HLog(@"该任务已完成---文件名:%@ 进度:%.2f 状态:%ld", task.fileStream.fileName, task.fileStream.progressRate, task.fileStream.fileStatus);
+        }else { // 所有未完成任务
+            [dic setObject:task forKey:key];
+            [task taskResume];
+        }
+    }];
+    
+//    NSArray *array = [dic allValues];
+//    NSArray *sortDesc = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"timeStamp" ascending:YES]];
+//    NSArray *sortedArr = [array sortedArrayUsingDescriptors:sortDesc];
+}
+
+/**
+删除所有的上传任务
+ */
+- (void)removeAllUploadTask
+{
+    for (CWUploadTask *task in [self.allTasks allValues]) {
+        [self removeUploadTask:task.fileStream];
+    }
+}
+
+/**
+ 获取所有文件分片模型的上传任务字典
+ */
+- (NSMutableDictionary<NSString*,CWUploadTask*>*_Nullable)allUploadTasks
+{
+    if (self.fileStreamDict.count == 0) {
+        self.fileStreamDict = [self unArcherThePlist:self.plistPath];
+    }
+    NSDictionary *tmpDict = _allTasks?_allTasks:@{};
+    NSMutableDictionary *fileWithTasks = [CWUploadTask uploadTasksWithDict:_instance.fileStreamDict];
+    
+    [fileWithTasks addEntriesFromDictionary:tmpDict];
+    return fileWithTasks;
+}
+
+- (NSMutableDictionary<NSString*,CWUploadTask*>*_Nullable)allUploadWaitTasks
+{
+    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
+    [self.allTasks enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
+        CWUploadTask *task = obj;
+        if (task.fileStream.fileStatus == CWUploadStatusWaiting &&
+            task.fileStream.fileStatus != CWUploadStatusFailed) {
+            [dic setObject:task forKey:key];
+        }
+    }];
+    return dic;
+}
+
+- (NSMutableDictionary<NSString*,CWUploadTask*>*_Nullable)allUploadEndTasks
+{
+    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
+    [self.uploadingTasks enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
+        CWUploadTask *task = obj;
+        if (task.fileStream.fileStatus == CWUploadStatusFinished) {
+            [dic setObject:task forKey:key];
+        }
+    }];
+    return dic;
+}
+
+- (NSMutableDictionary<NSString*,CWUploadTask*>*_Nullable)allUploadingTasks
+{
+    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
+    [self.allTasks enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
+        CWUploadTask *task = obj;
+        if (task.fileStream.fileStatus == CWUploadStatusUpdownloading) {
+            [dic setObject:task forKey:key];
+        }
+    }];
+
+    return dic;
+}
+
+#pragma 工具方法
+- (CWUploadTask *)continuePerformTaskWithFilePath:(NSString *)path{
+    
+    //获取任务数据字段
+    CWFileStreamSeparation *fstream = [self.fileStreamDict objectForKey:path.lastPathComponent];
+    CWUploadTask *uploadTask = self.allTasks[path.lastPathComponent];
+    if (!uploadTask) {
+        uploadTask = [CWUploadTask initWithStreamModel:fstream];
+        [self.allTasks setObject:uploadTask forKey:path.lastPathComponent];
+    }
+//    [uploadTask taskResume];
+    return uploadTask;
+}
+
++ (BOOL)isUploadTask:(NSString *)path{
+    _instance = [CWFileUploadManager shardUploadManager];
+    if (![CWFileManager isFileAtPath:_instance.plistPath]) {
+        [CWFileManager createFileAtPath:_instance.plistPath overwrite:NO];
+    }
+    _instance.fileStreamDict = [_instance unArcherThePlist:_instance.plistPath];
+    if (_instance.fileStreamDict[path.lastPathComponent] == nil) {
+        return NO;
+    }else{
+        return YES;
+    }
+}
+
+//新建任务分片模型并存入plist文件
+- (CWFileStreamSeparation * _Nullable)taskRecord:(NSString *)path{
+    
+    CWFileStreamSeparation *file = [[CWFileStreamSeparation alloc] initFileOperationAtPath:path forReadOperation:YES];
+    [self.fileStreamDict setObject:file forKey:path.lastPathComponent];
+    
+    [self archerTheDictionary:_fileStreamDict file:self.plistPath];
+    
+    return file;
+}
+
+//新建任务分片模型并存入plist文件
+- (CWFileStreamSeparation * _Nullable)taskRecord:(NSString *)path uploadLocation:(NSString *)uploadLocation imageData:(NSData *)imageData {
+    
+    CWFileStreamSeparation *file = [[CWFileStreamSeparation alloc] initFileOperationAtPath:path forReadOperation:YES uploadLocation:uploadLocation imageData:imageData];
+    [self.fileStreamDict setObject:file forKey:path.lastPathComponent];
+    
+    [self archerTheDictionary:_fileStreamDict file:self.plistPath];
+    
+    return file;
+}
+
+#pragma mark - notification
+
+- (void)registeNotification{
+    HLog(@"del 2024525  暂未做");
+    /* hxd del 2024525  暂未做
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil];
+    
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskExeEnd:) name:CWUploadTaskExeEnd object:nil];
+    
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskExeSuspend:) name:CWUploadTaskExeSuspend object:nil];
+    
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskExeError:) name:CWUploadTaskExeError object:nil];
+    
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(accountChange) name:ChangeAccountNotification object:nil];
+
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(exchanggeAccount) name:ExchangeLoginAccountNotification object:nil];
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(exchanggeAccount) name:AccountLoginOutsideNotification object:nil];
+     */
+}
+
+//app启动或者app从后台进入前台都会调用这个方法
+- (void)applicationBecomeActive{
+    [self uploadingTasksItemExe];
+}
+
+- (void)taskExeSuspend:(NSNotification *)notification
+{
+    CWFileStreamSeparation *fs = notification.userInfo.allValues.firstObject;
+    [self.uploadingTasks removeObjectForKey:fs.fileName];
+    
+    [self.allTasks enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
+        CWUploadTask *task = obj;
+        if (task.fileStream.fileStatus == CWUploadStatusWaiting &&
+            self.uploadingTasks.allValues.count < self.uploadMaxNum) {
+            [[CWFileUploadManager shardUploadManager] resumeUploadTask:task.fileStream];
+        }
+    }];
+    
+    [self allUploadingTasks];
+}
+
+- (void)taskExeEnd:(NSNotification *)notification
+{
+    CWFileStreamSeparation *fs = notification.userInfo.allValues.firstObject;
+    [self.uploadingTasks removeObjectForKey:fs.fileName];
+    [self.uploadWaitTasks enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
+        CWUploadTask *task = obj;
+        if (self.uploadingTasks.allValues.count < self.uploadMaxNum) {
+            [task taskResume];
+        }else{
+            *stop = YES;
+        }
+    }];
+    [self allUploadingTasks];
+}
+
+- (void)taskExeError:(NSNotification *)notification
+{
+    CWFileStreamSeparation *fs = notification.userInfo[@"fileStream"];
+    NSError *error = (NSError *)notification.userInfo[@"error"];
+    [self.uploadingTasks removeObjectForKey:fs.fileName];
+    HLog(@"taskError:%@",error);
+}
+
+- (void)uploadingTasksItemExe{
+    NSDictionary *dict = [NSDictionary dictionaryWithDictionary:self.uploadingTasks];
+    [self.uploadingTasks removeAllObjects];
+    [dict enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
+        CWUploadTask *task = obj;
+        [task taskResume];
+    }];
+    [self.uploadWaitTasks enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
+        CWUploadTask *task = obj;
+        if (self.uploadingTasks.allValues.count<self.uploadMaxNum) {
+            [task taskResume];
+        }else{
+            *stop = YES;
+        }
+    }];
+    [self allUploadingTasks];
+}
+
+- (void)accountChange { // 修改账号
+    self.plistPath = [self getNewPlistPath];
+}
+
+- (void)exchanggeAccount { // 切换账号
+    HLog(@"切换账号");
+    
+    [self pauseAllUploadTask]; // 暂停所有上传任务
+    
+    self.plistPath = [self getNewPlistPath];
+    [self.allTasks removeAllObjects];
+    self.allTasks = nil;
+    [self.fileStreamDict removeAllObjects];
+    [self clearCookies];
+}
+
+// 清空Cookie
+- (void)clearCookies {
+    
+    NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
+    NSArray *cookieArray = [NSArray arrayWithArray:[cookieJar cookies]];
+    for(id obj in cookieArray)
+    {
+        [cookieJar deleteCookie:obj];
+    }
+}
+
+#pragma mark - tools
+//归档
+- (void)archerTheDictionary:(NSDictionary *)dict file:(NSString *)path{
+    [HWDataManager archiveObject:dict toPlistPath:path];
+}
+
+//解档
+- (NSMutableDictionary *)unArcherThePlist:(NSString *)path{
+    NSMutableDictionary *dic = [HWDataManager readObjectFromPlistPath:path];
+    return dic;
+}
+
+#pragma mark - 相册文件写入Cache
+/// 将相册里的视频文件缓存到Cache
+- (NSString *_Nullable)writeVideoDataFromURL:(NSURL *_Nullable)url uploadLocation:(NSString *_Nullable)uploadLocation {
+    
+    NSString *account = [HWDataManager getStringWithKey:Const_HWAccountPhoneNumber];
+    if (account.length != 0) {
+         NSString *fileFolder = kPath_YunPan_Upload_Folder;
+         NSString *originalPath = [url.absoluteString stringByReplacingOccurrencesOfString:@"file://" withString:@""];
+         NSString *fileName;
+//         fileName = [NSString stringWithFormat:@"%@/%@", uploadLocation,fileName];
+         fileName = [NSString stringWithFormat:@"%@",  [iTools getNowTimeStampString]];
+         
+         NSString *videoName = [NSString stringWithFormat:@"SZX%@.mp4", fileName];
+         NSString *sandboxPath = [fileFolder stringByAppendingPathComponent:videoName];
+         NSError * error = nil;
+         BOOL isSuccess = [CWFileManager moveItemAtPath:originalPath toPath:sandboxPath overwrite:YES error:&error];
+         HLog(@"保存相册视频文件:%@到Caches:%@是否成功:%d error:%@", originalPath, sandboxPath,isSuccess,error);
+         return sandboxPath;
+     }else {
+         HLog(@"未登录 缓存视频文件失败!");
+         return nil;
+     }
+    
+
+}
+
+/// 将相册里的图片文件缓存到Cache
+- (NSString *_Nullable)writeIamgeData:(NSData *_Nullable)data iamgeName:(NSString *_Nullable)iamgeName uploadLocation:(NSString *_Nullable)uploadLocation {
+     NSString *account = [HWDataManager getStringWithKey:Const_HWAccountPhoneNumber];
+
+    if (account.length != 0) {
+         NSString *fileFolder = kPath_YunPan_Upload_Folder;
+         NSString *fileName = [NSString stringWithFormat:@"SZX%@",  [iTools getNowTimeStampString]];
+         
+         NSString *videoName = [NSString stringWithFormat:@"%@.PNG", fileName];
+         NSString *sandboxPath = [fileFolder stringByAppendingPathComponent:videoName];
+         BOOL isSuccess = [data writeToFile:sandboxPath atomically:YES];
+         HLog(@"保存相册图片文件到Caches是否成功:%d", isSuccess);
+         return sandboxPath;
+     }else {
+         HLog(@"未登录 缓存图片文件失败!");
+         return nil;
+     }
+
+}
+
+- (NSString *_Nullable)writeIamgeDataToLocal:(NSData *_Nullable)data {
+
+     NSString *account = [HWDataManager getStringWithKey:Const_HWAccountPhoneNumber];
+     if (account.length != 0) {
+         NSString *fileFolder = kPath_YunPan_Upload_Folder;
+         NSString *fileName = [NSString stringWithFormat:@"SZX%@",  [iTools getNowTimeStampString]];
+         
+         NSString *videoName = [NSString stringWithFormat:@"%@.PNG", fileName];
+         NSString *sandboxPath = [fileFolder stringByAppendingPathComponent:videoName];
+         BOOL isSuccess = [data writeToFile:sandboxPath atomically:YES];
+         HLog(@"保存相册图片文件到Caches是否成功:%d", isSuccess);
+         return sandboxPath;
+     }else {
+         HLog(@"未登录 缓存图片文件失败!");
+         return nil;
+     }
+
+}
+
+@end

+ 15 - 0
创维盒子/双子星云手机/Vendor/UploadManager/CWUploadManage/CWUploadTask+CheckInfo.h

@@ -0,0 +1,15 @@
+//
+//  CWUploadTask+CheckInfo.h
+//  uploadFileDemo
+//
+//  Created by hyjet on 2018/3/9.
+//  Copyright © 2018年 uploadFileDemo. All rights reserved.
+//
+
+#import "CWUploadTask.h"
+
+@interface CWUploadTask (CheckInfo)
+
+- (void)checkParamFromServer:(CWFileStreamSeparation *_Nonnull)fileStream
+              paramCallback:(void(^ _Nullable)(NSString *_Nonnull chunkNumName,NSDictionary *_Nullable param))paramBlock;
+@end

+ 123 - 0
创维盒子/双子星云手机/Vendor/UploadManager/CWUploadManage/CWUploadTask+CheckInfo.m

@@ -0,0 +1,123 @@
+//
+//  CWUploadTask+CheckInfo.m
+//  uploadFileDemo
+//
+//  Created by hyjet on 2018/3/9.
+//  Copyright © 2018年 uploadFileDemo. All rights reserved.
+//
+
+#import "CWUploadTask+CheckInfo.h"
+#import "CWFileStreamSeparation.h"
+
+
+#define CURRENT_API @""
+
+#define GETPOSTFLOWCHUNKAPI       @"/nextcloud/index.php/apps/rcapi/ajax/upload.php"/*断点续传*/
+
+@implementation CWUploadTask (CheckInfo)
+
+- (void)checkParamFromServer:(CWFileStreamSeparation *_Nonnull)fileStream paramCallback:(void(^ _Nullable)(NSString *_Nonnull chunkNumName,NSDictionary *_Nullable param))paramBlock
+{
+    
+    HLog(@"del 2024525  暂未做");
+    /* hxd del 2024525  暂未做
+    HLog(@"GET之前——--文件名:%@ 已上传完进度:%.2f 上传状态:%ld", fileStream.fileName, fileStream.progressRate, fileStream.fileStatus);
+//    HLog(@"IP地址:%@", [iPhone phoneDeviceIPAddress]);
+    /// 请求URL
+    NSDictionary *dictLogin = [[UseAccountManage shareInstance] getLoginInfo];
+    NSString *mCloudService = @"";
+    if (dictLogin && [[dictLogin allKeys] containsObject:@"nextCloudIp"])
+    {
+        mCloudService = [NSString stringWithFormat:@"http://%@",[dictLogin objectForKey:@"nextCloudIp"]];
+    }
+    else
+    {
+        return;
+    }
+    NSString *urlString = [mCloudService stringByAppendingString:GETPOSTFLOWCHUNKAPI];
+
+    for (NSInteger i=0; i<fileStream.streamFragments.count; i++) {
+        CWStreamFragment *fragment = fileStream.streamFragments[i];
+        if (fragment.fragmentStatus) { // 已上传
+            continue;
+        }else { // 未上传
+            NSString *flowFilename = fileStream.fileName;
+            NSString *flowFilenameWithoutPoint = [flowFilename stringByReplacingOccurrencesOfString:@"." withString:@""];
+            NSString *flowIdentifier = [NSString stringWithFormat:@"%ld-%@", fileStream.fileSize, flowFilenameWithoutPoint];
+            NSString *flowRelativePath = @"";
+            if ([fileStream.uploadLocation isEqualToString:@"/"]) {
+                flowRelativePath = [NSString stringWithFormat:@"%@", flowFilename];
+            }else {
+                flowRelativePath = [NSString stringWithFormat:@"%@/%@", fileStream.uploadLocation, flowFilename];
+            }
+            /// 请求参数paramsDict
+            NSMutableDictionary *paramsDict = [[NSMutableDictionary alloc] init];
+            [paramsDict setValue:@(i+1) forKey:@"flowChunkNumber"]; // 当前第几块
+            [paramsDict setValue:@(CWStreamFragmentMaxSize) forKey:@"flowChunkSize"];   // 块定义上传大小
+            [paramsDict setValue:@(fragment.fragmentSize) forKey:@"flowCurrentChunkSize"];  // 当前块大小
+            [paramsDict setValue:@(fileStream.fileSize) forKey:@"flowTotalSize"];  // 总大小
+            [paramsDict setValue:flowIdentifier forKey:@"flowIdentifier"];  // 标识符【规则:总大小-文件名+文件后缀】
+            [paramsDict setValue:flowFilename forKey:@"flowFilename"];  // 文件名
+            [paramsDict setValue:flowRelativePath forKey:@"flowRelativePath"]; // 文件存储路径
+            [paramsDict setValue:@(fileStream.streamFragments.count) forKey:@"flowTotalChunks"];  // 块总数
+//            NSString *args = [iTools getJSONStringFromDictionary:paramsDict];
+//            HLog(@"GET——URL:%@---params:%@", urlString,paramsDict);
+            /// 拼接参数
+            NSString *requestURLString = [NSString stringWithFormat:@"%@?flowChunkNumber=%ld&flowChunkSize=%d&flowCurrentChunkSize=%ld&flowTotalSize=%ld&flowIdentifier=%@&flowFilename=%@&flowRelativePath=%@&flowTotalChunks=%ld", urlString, (i+1), CWStreamFragmentMaxSize, fragment.fragmentSize, fileStream.fileSize, flowIdentifier, flowFilename, flowRelativePath, fileStream.streamFragments.count];
+            NSString *requestURLEncodedString = [requestURLString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; // URL中不能有中文
+
+            /// 创建请求 设置请求头Authorization
+            NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:requestURLEncodedString]];
+            NSString *tokenStr = @"";
+            if (dictLogin && [[dictLogin allKeys] containsObject:@"token"]) {
+                tokenStr = [[UseAccountManage shareInstance] cloudAutoh];
+                if (tokenStr.length == 0) {
+                    HLog(@"POST:未能成功获取到Authorization");
+                    return;
+                }
+            }else {
+                HLog(@"POST:未能成功获取到Authorization");
+                return;
+            }
+
+            [request setValue:tokenStr forHTTPHeaderField:@"Authorization"];
+            [request setValue:fileStream.md5String forHTTPHeaderField:@"onlycrypt"]; // 文件MD5值
+            request.HTTPMethod = @"GET";// 设置请求类型 先GET查询 再POST上传
+            NSURLSession *session = [NSURLSession sharedSession];
+  
+            //发送请求
+            NSURLSessionDataTask *postTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
+                if (error == nil) {
+                    //解析得到的数据
+                    NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+                    HLog(@"GET之后:获取断点续传分片信息成功 校验参数 更新paramsDict  返回:%@", dict);
+                    paramBlock(@"flowChunkNumber",paramsDict);
+                }else {
+                    HLog(@"GET之后:获取断点续传分片信息失败 %@", error);
+                }
+                
+                [self clearCookies];
+            }];
+            
+            [postTask resume];
+            
+            
+            break;
+            
+        }
+    }
+     */
+}
+
+// 清空Cookie
+- (void)clearCookies {
+    
+    NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
+    NSArray *cookieArray = [NSArray arrayWithArray:[cookieJar cookies]];
+    for(id obj in cookieArray)
+    {
+        [cookieJar deleteCookie:obj];
+    }
+}
+
+@end

+ 77 - 0
创维盒子/双子星云手机/Vendor/UploadManager/CWUploadManage/CWUploadTask.h

@@ -0,0 +1,77 @@
+//
+//  CWUploadTask.h
+//  CWPlayer
+//
+//  Created by hyjet on 2017/10/12.
+//  Copyright © 2017年 CWPlayer. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+@class CWFileStreamSeparation;
+
+#ifdef __cplusplus
+#define TASK_EXTERN        extern "C" __attribute__((visibility ("default")))
+#else
+#define TASK_EXTERN            extern __attribute__((visibility ("default")))
+#endif
+
+/**
+ 通知监听上传状态的key
+ */
+TASK_EXTERN NSString * _Nonnull const CWUploadTaskExeing;      //上传中
+TASK_EXTERN NSString * _Nonnull const CWUploadTaskExeError;    //上传失败
+TASK_EXTERN NSString * _Nonnull const CWUploadTaskExeEnd;      //上传完成
+TASK_EXTERN NSString * _Nonnull const CWUploadTaskExeSuspend;  //上传暂停/取消
+
+typedef void(^finishHandler)(CWFileStreamSeparation * _Nullable fileStream, NSError * _Nullable error);
+
+typedef void(^success)(CWFileStreamSeparation * _Nullable fileStream);
+
+@interface CWUploadTask : NSObject
+
+@property (nonatomic,readonly,strong)CWFileStreamSeparation *_Nullable fileStream;
+//当前上传任务的URL
+@property (nonatomic,readonly,strong)NSURL * _Nullable url;
+//当前上传任务的参数
+@property (nonatomic,readonly,strong)NSMutableDictionary * _Nullable param;
+//任务对象的执行状态
+//@property (nonatomic,readonly,assign)NSURLSessionTaskState taskState;
+//上传任务的唯一ID
+@property (nonatomic,readonly,copy)NSString * _Nullable ID;
+//任务时间戳
+@property (nonatomic, assign)  NSInteger timeStamp;    //时间戳
+
+/**
+ 根据一个文件分片模型创建一个上传任务,执行 taskResume 方法开始上传
+ 使用 listenTaskExeCallback 方法传递block进行回调监听
+ 同时也可以选择实现协议方法进行回调监听
+ */
++ (instancetype _Nonnull )initWithStreamModel:(CWFileStreamSeparation * _Nonnull)fileStream;
+
+/**
+ 监听一个已存在的上传任务的状态
+ */
+- (void)listenTaskExeCallback:(finishHandler _Nonnull)block
+                      success:(success _Nonnull)successBlock;
+
+/**
+ 根据一个文件分片模型的字典创建一个上传任务(处于等待状态)字典
+ */
++ (NSMutableDictionary<NSString*,CWUploadTask*> *_Nullable)uploadTasksWithDict:(NSDictionary<NSString*,CWFileStreamSeparation*> *_Nullable)dict;
+
+/**
+ 根据一个文件分片模型创建一个上传任务,执行 startExe 方法开始上传,结果会由block回调出来
+ */
+- (instancetype _Nonnull)initWithStreamModel:(CWFileStreamSeparation *_Nonnull)fileStream
+                                      finish:(finishHandler _Nonnull)block
+                                     success:(success _Nonnull)successBlock;
+
+
+//继续/开始上传
+- (void)taskResume;
+
+//取消/暂停上传
+- (void)taskCancel;
+
+
+@end

+ 449 - 0
创维盒子/双子星云手机/Vendor/UploadManager/CWUploadManage/CWUploadTask.m

@@ -0,0 +1,449 @@
+//
+//  CWUploadTask.m
+//  uploadFileDemo
+//
+//  Created by hyjet on 2018/3/9.
+//  Copyright © 2018年 uploadFileDemo. All rights reserved.
+//
+
+#import "CWUploadTask.h"
+#import "CWFileUploadManager.h"
+#import "CWFileStreamSeparation.h"
+#import "CWFileManager.h"
+#import "CWUploadTask+CheckInfo.h"
+
+//分隔符
+#define Boundary @"1a2b3c"
+//一般换行
+#define Wrap1 @"\r\n"
+//key-value换行
+#define Wrap2 @"\r\n\r\n"
+//开始分割
+#define StartBoundary [NSString stringWithFormat:@"--%@%@",Boundary,Wrap1]
+//文件分割完成
+#define EndBody [NSString stringWithFormat:@"--%@--",Boundary]
+//一个片段上传失败默认重试3次
+#define REPEAT_MAX 3
+
+//#define plistPath [[CWFileManager cachesDir] stringByAppendingPathComponent:uploadPlist]
+
+#define GETPOSTFLOWCHUNKAPI       @"/nextcloud/index.php/apps/rcapi/ajax/upload.php"/*断点续传*/
+
+NSString *const CWUploadTaskExeing = @"TaskExeing";
+NSString *const CWUploadTaskExeError = @"TaskExeError";
+NSString *const CWUploadTaskExeEnd = @"TaskExeEnd";
+NSString *const CWUploadTaskExeSuspend = @"TaskExeSuspend";
+
+@interface CWUploadTask ()
+
+//@property (nonatomic,strong)NSURLSessionUploadTask *uploadTask;
+
+//@property (nonatomic,strong)NSMutableURLRequest *request;
+
+//@property (nonatomic,readwrite)NSURLSessionTaskState taskState;
+
+@property (nonatomic,readwrite)NSURL * url;
+
+@property (nonatomic,readwrite)NSString *ID;
+
+@property (nonatomic,readwrite)NSMutableDictionary *param;//上传时参数
+
+@property (nonatomic,readwrite)CWFileStreamSeparation *fileStream;
+
+@property (nonatomic,copy)finishHandler finishBlock;//片段上传成功上传的回调block
+
+@property (nonatomic,copy)success successBlock;//整体上传成功上传的回调block
+
+@property (nonatomic,copy)NSString *chunkNumName;//片段编号这一参数的参数名
+
+@property (nonatomic,copy)NSDictionary *lastParam;//片段完成上传后的参数
+
+@property (nonatomic,assign)NSInteger chunkNo;//片段完成上传后的编号
+
+@property (nonatomic,assign)NSInteger taskRepeatNum;//重试次数
+
+@property (nonatomic,assign)BOOL isSuspendedState;//记录状态更改
+
+@property (nonatomic,strong)CWFileUploadManager *uploadManager;
+
+@end
+
+@implementation CWUploadTask
+
+-(CWFileUploadManager *)uploadManager
+{
+    if (!_uploadManager) {
+        _uploadManager = [CWFileUploadManager shardUploadManager];
+    }
+    return _uploadManager;
+}
+
+
+- (void)setFileStream:(CWFileStreamSeparation *)fileStream
+{
+    _fileStream.fileStatus = CWUploadStatusWaiting;
+    _taskRepeatNum = 0;
+    _ID = fileStream.md5String;
+    for (NSInteger idx=0; idx<fileStream.streamFragments.count; idx++) {
+        CWStreamFragment *fragment = fileStream.streamFragments[idx];
+        if (!fragment.fragmentStatus) {
+            _chunkNo = idx;
+        }
+    }
+    _fileStream = fileStream;
+}
+
+
++ (NSMutableDictionary<NSString*,CWUploadTask*> *)uploadTasksWithDict:(NSDictionary<NSString*,CWFileStreamSeparation*> *)dict{
+    NSMutableDictionary *taskDict = [NSMutableDictionary dictionary];
+    for (NSString *key in dict.allKeys) {
+        CWFileStreamSeparation *fs = [dict objectForKey:key];
+        CWUploadTask *task = [CWUploadTask initWithStreamModel:fs];
+        [taskDict setValue:task forKey:key];
+    }
+    return taskDict;
+}
+
++ (instancetype)initWithStreamModel:(CWFileStreamSeparation *)fileStream
+{
+    CWUploadTask *task = [CWUploadTask new];
+    task.fileStream = fileStream;
+    task.timeStamp = [iTools getNowTimeStamp];
+    task.isSuspendedState = NO;
+    task.url = [CWFileUploadManager shardUploadManager].url;
+    return task;
+}
+
+- (void)listenTaskExeCallback:(finishHandler _Nonnull)block success:(success)successBlock
+{
+    self.finishBlock = block;
+    self.successBlock = successBlock;
+    if (_finishBlock) _finishBlock(_fileStream,nil);
+}
+
+
+- (instancetype _Nonnull)initWithStreamModel:(CWFileStreamSeparation *)fileStream finish:(finishHandler _Nonnull)block success:(success)successBlock
+
+{
+    if (self = [super init]) {
+        self.fileStream = fileStream;
+        _finishBlock = block;
+        _successBlock = successBlock;
+    }
+    return self;
+}
+
+//-(NSMutableURLRequest*)uploadRequest
+//{
+//    if ([CWFileUploadManager shardUploadManager].request) {
+//        _request = [CWFileUploadManager shardUploadManager].request;
+//    }else{
+//        HLog(@"请配置上传任务的request");
+//    }
+//    return _request;
+//
+//}
+
+-(NSData*)taskRequestBodyWithParam:(NSDictionary *)param uploadData:(NSData *)data
+{
+    NSMutableData* totlData=[NSMutableData new];
+
+    NSArray* allKeys=[param allKeys];
+    for (int i=0; i<allKeys.count; i++)
+    {
+        
+        NSString *disposition = [NSString stringWithFormat:@"%@Content-Disposition: form-data; name=\"%@\"%@",StartBoundary,allKeys[i],Wrap2];
+        NSString* object=[param objectForKey:allKeys[i]];
+        disposition =[disposition stringByAppendingString:[NSString stringWithFormat:@"%@",object]];
+        disposition =[disposition stringByAppendingString:Wrap1];
+        [totlData appendData:[disposition dataUsingEncoding:NSUTF8StringEncoding]];
+        
+    }
+    NSString *body=[NSString stringWithFormat:@"%@Content-Disposition: form-data; name=\"picture\"; filename=\"%@\";Content-Type:video/mpeg4%@",StartBoundary,@"file",Wrap2];
+    [totlData appendData:[body dataUsingEncoding:NSUTF8StringEncoding]];
+    [totlData appendData:data];
+    [totlData appendData:[Wrap1 dataUsingEncoding:NSUTF8StringEncoding]];
+    [totlData appendData:[EndBody dataUsingEncoding:NSUTF8StringEncoding]];
+    
+    
+    return totlData;
+}
+
+/**
+ *  GET:上传任务 获取上传文件相关信息
+ */
+- (void)getFileInfo
+{
+    __weak typeof(self) weekSelf = self;
+    [self checkParamFromServer:self.fileStream paramCallback:^(NSString * _Nonnull chunkNumName, NSDictionary * _Nullable param) {
+        weekSelf.chunkNumName = chunkNumName;
+        weekSelf.param = [NSMutableDictionary dictionaryWithDictionary:param];
+        [weekSelf startExe];
+    }];
+}
+
+/**
+*  POST:上传任务 获取上传文件相关信息
+*/
+- (void)startExe{
+    HLog(@"del 2024525  暂未做");
+    /* hxd del 2024525  暂未做
+     
+    if (_isSuspendedState) {
+        HLog(@"暂停上传");
+        [self taskCancel];
+        return;
+    }
+    
+    //判断无参数的情况下先将文件信息上传并获得参数
+    if (!_param) [self getFileInfo];
+    dispatch_group_t group = dispatch_group_create();
+    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
+    dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
+    
+    if (_fileStream.fileStatus == CWUploadStatusFinished && _successBlock) {
+        _successBlock(_fileStream);
+        [self sendNotionWithKey:CWUploadTaskExeEnd userInfo:@{@"fileStream":_fileStream}];
+        return;
+    };
+    
+    CWStreamFragment *fragment;
+    for (NSInteger i=0; i<_fileStream.streamFragments.count; i++) {
+        fragment = _fileStream.streamFragments[i];
+        if (fragment.fragmentStatus) { // 已上传
+            continue;
+        }else { // 未上传
+            [self->_param setObject:[NSString stringWithFormat:@"%zd",(i+1)] forKey:@"flowChunkNumber"];
+            [self->_param setObject:@(fragment.fragmentSize) forKey:@"flowCurrentChunkSize"];
+            
+            dispatch_group_async(group, queue, ^{
+               @autoreleasepool {
+                   NSData *data = [self->_fileStream readDateOfFragment:fragment];
+                   self.lastParam = self->_param;
+                   
+//                   if ([CWFileUploadManager shardUploadManager].leftStore < data.length) { // 云盘空间不足
+//
+//                       // 分片上传失败
+//                       self->_fileStream.fileStatus = CWUploadStatusFailed;
+//                       self->_fileStream.timeStamp = [iTools getNowTimeStamp];
+//                       [self archTaskFileStream];
+//                       // 分片上传失败通知 刷新列表
+//                       dispatch_async(dispatch_get_main_queue(), ^{
+//                           NSString *error = @"云盘剩余空间不足";
+//                           [self sendNotionWithKey:CWUploadTaskExeError userInfo:@{@"fileStream":self->_fileStream,@"error":error}];
+//                           [self sendNotionWithKey:CloudStoreIsFullNotification userInfo:@{}];
+//                       });
+//                       [self deallocSession];
+//                       return;
+//                   }
+
+                   HLog(@"POST之前——--文件名:%@ 已上传完进度:%.2f 上传状态:%ld", self->_fileStream.fileName, self->_fileStream.progressRate, self->_fileStream.fileStatus);
+                   [[UseAccountManage shareInstance] doUploadInfoWithParams:self->_param md5string:self->_fileStream.md5String data:data success:^(id  _Nonnull responseObject) {
+
+                       self->_taskRepeatNum = 0;
+                       fragment.fragmentStatus = YES;
+                       [self archTaskFileStream];
+                       self->_chunkNo = i+1;
+                       
+                       dispatch_async(dispatch_get_main_queue(), ^{
+
+                           if (self->_fileStream.streamFragments.count == self->_chunkNo) {
+                               // 分片上传成功 是最后一片 上传完
+                               self->_fileStream.fileStatus = CWUploadStatusFinished;
+                               self->_fileStream.progressRate = 1.00;
+                               self->_fileStream.uploadDateSize = self->_fileStream.fileSize;
+                               self->_fileStream.timeStamp = [iTools getNowTimeStamp];
+                               [self archTaskFileStream];
+                               
+                               HLog(@"POST之后——--文件名:%@ 已上传完进度:%.2f 上传状态:%ld", self->_fileStream.fileName, self->_fileStream.progressRate, self->_fileStream.fileStatus);
+                               
+                               // 上传完成通知 刷新完成列表
+                               dispatch_async(dispatch_get_main_queue(), ^{
+                                   if (self->_finishBlock) self->_finishBlock(self->_fileStream,nil);
+                                   [self sendNotionWithKey:CWUploadTaskExeEnd userInfo:@{@"fileStream":self->_fileStream}];
+                               });
+                               
+                           }else {
+                               // 分片上传成功 不是最后一片 上传中
+                               if (self->_fileStream.uploadDateSize > self->_chunkNo * CWStreamFragmentMaxSize) { // 上传进度异常
+                                   HLog(@"上传进度异常");
+                               }else {
+//                               self->_fileStream.fileStatus = CWUploadStatusUpdownloading;
+                                   self->_fileStream.progressRate = self->_chunkNo * 1.00 / self->_fileStream.streamFragments.count;
+                                   self->_fileStream.uploadDateSize = self->_chunkNo * CWStreamFragmentMaxSize;
+                                   self->_fileStream.timeStamp = [iTools getNowTimeStamp];
+                                   [self archTaskFileStream];
+                                   
+                                   HLog(@"POST之后——--文件名:%@ 已上传完进度:%.2f 上传状态:%ld", self->_fileStream.fileName, self->_fileStream.progressRate, self->_fileStream.fileStatus);
+                                    
+                                    // 上传中通知 刷新上传进度
+                                    dispatch_async(dispatch_get_main_queue(), ^{
+                                        if (self->_finishBlock) self->_finishBlock(self->_fileStream,nil);
+                                        [self sendNotionWithKey:CWUploadTaskExeing userInfo:@{@"fileStream":self->_fileStream,@"lastParam":self->_lastParam,@"indexNo":@(self->_chunkNo)}];
+                                    });
+                               }
+
+                               /// 继续GET
+                               [self getFileInfo];
+                           }
+                           
+                         [self deallocSession];
+                           
+                       });
+                       dispatch_semaphore_signal(semaphore);
+
+                   } faild:^(NSError * _Nonnull error) {
+                       
+                       if (self->_taskRepeatNum<REPEAT_MAX) { // 分片上传失败 重试3次
+                           
+                            self->_taskRepeatNum++;
+                            [self startExe];
+                        }else{
+                            // 分片上传失败
+                            self->_fileStream.fileStatus = CWUploadStatusFailed;
+//                            self->_fileStream.progressRate = (self->_chunkNo-1) / self->_fileStream.streamFragments.count;
+//                            self->_fileStream.uploadDateSize = (self->_chunkNo-1) * CWStreamFragmentMaxSize;
+                            self->_fileStream.timeStamp = [iTools getNowTimeStamp];
+                            [self archTaskFileStream];
+                            
+                            HLog(@"POST之后——--文件名:%@ 已上传完进度:%.2f 上传状态:%ld", self->_fileStream.fileName, self->_fileStream.progressRate, self->_fileStream.fileStatus);
+                            
+                            // 分片上传失败通知 刷新列表
+                            dispatch_async(dispatch_get_main_queue(), ^{
+                                if (self->_finishBlock) self->_finishBlock(self->_fileStream,error);
+                                [self sendNotionWithKey:CWUploadTaskExeError userInfo:@{@"fileStream":self->_fileStream,@"error":error}];
+                            });
+                            
+                            [self deallocSession];
+                            return;
+                        }
+                       
+                   }];
+                   
+                   dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
+               }
+           });
+            break;
+        }
+    }
+    
+    dispatch_group_notify(group, queue, ^{
+        
+        if (self->_fileStream.progressRate != 1) {
+            HLog(@"dispatch_group_notify: %.2f", self->_fileStream.progressRate);
+            return;
+        }
+        
+        self->_fileStream.fileStatus = CWUploadStatusFinished;
+        self->_fileStream.timeStamp = [iTools getNowTimeStamp];
+        [self archTaskFileStream];
+        dispatch_async(dispatch_get_main_queue(), ^{
+            if (self->_finishBlock) self->_finishBlock(self->_fileStream,nil);
+            [self sendNotionWithKey:CWUploadTaskExeEnd userInfo:@{@"fileStream":self->_fileStream}];
+        });
+        [self deallocSession];
+    });
+     */
+}
+
+- (void)taskResume{
+    
+    _isSuspendedState = NO;
+    if (self.uploadManager.uploadingTasks.allValues.count >= self.uploadManager.uploadMaxNum) { // 超过最大限制数量3个
+        
+        self.fileStream.fileStatus = CWUploadStatusWaiting;
+        [self archTaskFileStream];
+        HLog(@"状态修改——--文件名:%@ 已上传完进度:%.2f 上传状态:%ld", self.fileStream.fileName, self.fileStream.progressRate, self.fileStream.fileStatus);
+        
+        dispatch_async(dispatch_get_main_queue(), ^{
+            if (self->_successBlock)  self->_successBlock(self->_fileStream);
+            [self sendNotionWithKey:CWUploadTaskExeSuspend userInfo:@{@"fileStream":self->_fileStream}];
+        });
+        return;
+    }else {
+        
+        self.fileStream.fileStatus = CWUploadStatusUpdownloading;
+        [self archTaskFileStream];
+        HLog(@"状态修改——--文件名:%@ 已上传完进度:%.2f 上传状态:%ld", self.fileStream.fileName, self.fileStream.progressRate, self.fileStream.fileStatus);
+        
+        dispatch_async(dispatch_get_main_queue(), ^{
+            if (self->_successBlock)  self->_successBlock(self->_fileStream);
+            [self sendNotionWithKey:CWUploadTaskExeing userInfo:@{@"fileStream":self->_fileStream}];
+        });
+        
+        [self getFileInfo]; // 启动上传任务 先get 后post
+    }
+    
+}
+
+- (void)taskCancel{
+    
+    _fileStream.fileStatus = CWUploadStatusPaused;
+    [self archTaskFileStream];
+    _isSuspendedState = YES;
+    
+    dispatch_async(dispatch_get_main_queue(), ^{
+        if (self->_finishBlock) self->_finishBlock(self->_fileStream,nil);
+        [self sendNotionWithKey:CWUploadTaskExeSuspend userInfo:@{@"fileStream":self->_fileStream}];
+    });
+}
+
+- (void)deallocSession{
+    _taskRepeatNum = 0;
+}
+
+#pragma mark -- tools
+
+- (void)archTaskFileStream{
+    
+    NSArray *fileArray = [self->_fileStream.filePath pathComponents];
+    NSString *filePathAccount = @"0";
+    if (fileArray.count > 3) {
+        filePathAccount = fileArray[fileArray.count - 3];
+    }
+    
+    NSArray *plistArray = [[CWFileUploadManager shardUploadManager].plistPath pathComponents];
+    NSString *plistPathAccount = @"1";
+    if (plistArray.count > 3) {
+        plistPathAccount = plistArray[plistArray.count - 3];
+    }
+    
+//    HLog(@"文件缓存账号:%@ 与 plist文件账号:%@", filePathAccount, plistPathAccount);
+    if (![filePathAccount isEqualToString:plistPathAccount]) {
+//        HLog(@"切换账号 文件缓存账号%@ 与 plist文件账号:%@ 不一致", filePathAccount, plistPathAccount);
+        return;
+    }
+    
+    NSMutableDictionary *fsDic = [CWUploadTask unArcherThePlist:[CWFileUploadManager shardUploadManager].plistPath];
+    if (!fsDic) {
+        fsDic = [NSMutableDictionary dictionary];
+    }
+    [fsDic setObject:_fileStream forKey:_fileStream.fileName];
+    [CWUploadTask archerTheDictionary:fsDic file:[CWFileUploadManager shardUploadManager].plistPath];
+}
+
+
+//归档
++ (void)archerTheDictionary:(NSDictionary *)dict file:(NSString *)path{
+    
+    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:dict];
+    BOOL finish = [data writeToFile:path atomically:YES];
+    if (finish) {};
+    
+}
+
+//解档
++ (NSMutableDictionary *)unArcherThePlist:(NSString *)path{
+    NSMutableDictionary *dic = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
+    return dic;
+}
+
+- (void)sendNotionWithKey:(NSString *)key userInfo:(NSDictionary *)dict{
+    //创建通知
+    NSNotification *notification =[NSNotification notificationWithName:key object:nil userInfo:dict];
+    //通过通知中心发送通知
+    [[NSNotificationCenter defaultCenter] postNotification:notification];
+    
+}
+
+@end