JhtLoadDocView.m 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. //
  2. // JhtLoadDocView.m
  3. // JhtDocViewerDemo
  4. //
  5. // GitHub主页: https://github.com/jinht
  6. // CSDN博客: http://blog.csdn.net/anticipate91
  7. //
  8. // Created by Jht on 2017/10/19.
  9. // Copyright © 2017年 JhtDocViewer. All rights reserved.
  10. //
  11. #import "JhtLoadDocView.h"
  12. #import "JhtFileModel.h"
  13. #import "JhtDocWebView.h"
  14. #import "JhtDownloadView.h"
  15. #import "JhtDefaultManager.h"
  16. #import "JhtDownloadRequest.h"
  17. #import "JhtDocViewer_Define.h"
  18. #import "JhtDocFileOperations.h"
  19. #import "JhtNetworkCheckTools.h"
  20. #import "JhtDownTipsDumpingView.h"
  21. #import "JhtLoadDocViewParamModel.h"
  22. #import "OtherOpenButtonParamModel.h"
  23. #import "JhtShowDumpingViewParamModel.h"
  24. @interface JhtLoadDocView () <UIAlertViewDelegate> {
  25. finishedDownloadCompletionHandler _block;
  26. finishShareHandler _shareblock;
  27. // 当前 文件model
  28. JhtFileModel *_currentFileModel;
  29. // errorView 父View(一般为self.navigationController.view)
  30. UIView *_errorFView;
  31. }
  32. /** 下载 View */
  33. @property (nonatomic, strong) JhtDownloadView *downloadView;
  34. /** 文件操作类 */
  35. @property (nonatomic, strong) JhtDocFileOperations *fileUtil;
  36. /** webView展示页 */
  37. @property (nonatomic, strong) JhtDocWebView *docWebView;
  38. /** 加载Doc的webView */
  39. @property (nonatomic, strong) WKWebView *wkWebView;
  40. /** 阻尼下拉动画View */
  41. @property (nonatomic, strong) UIView *dumpingView;
  42. /** JhtLoadDocView 配置Model */
  43. @property (nonatomic, strong) JhtLoadDocViewParamModel *loadDocViewParamModel;
  44. /** JhtShowDumpingView 配置Model */
  45. @property (nonatomic, strong) JhtShowDumpingViewParamModel *showDumpingViewParamModel;
  46. @end
  47. #define KB (1024)
  48. #define MB (KB * 1024)
  49. #define GB (MB * 1024)
  50. /** 状态栏 + 导航栏的高度 */
  51. #define KLDVStatusAndNavBarHeight (KStatusBarHeight + 44)
  52. @implementation JhtLoadDocView
  53. #pragma mark - Public Method
  54. - (instancetype)initWithFrame:(CGRect)frame fileModel:(JhtFileModel *)fileModel showErrorViewOfFatherView:(UIView *)errorFView loadDocViewParamModel:(JhtLoadDocViewParamModel *)loadDocViewParamModel showDumpingViewParamModel:(JhtShowDumpingViewParamModel *)showDumpingViewParamModel otherOpenButtonParamModel:(OtherOpenButtonParamModel *)otherOpenButtonParamModel {
  55. self = [super initWithFrame:frame];
  56. if (self) {
  57. _currentFileModel = fileModel;
  58. _errorFView = errorFView;
  59. self.loadDocViewParamModel = loadDocViewParamModel;
  60. self.showDumpingViewParamModel = showDumpingViewParamModel;
  61. self.otherOpenButtonParamModel = otherOpenButtonParamModel;
  62. // 创建文件工具类
  63. [self ldvCreatefileUtil];
  64. // CreateUI
  65. [self ldvCreateUI];
  66. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  67. // 清理几天前 downloadFilesPath && otherAppFilesPath 文件
  68. [self.fileUtil cleanFileAfterDays:self.loadDocViewParamModel.daysAgo filePathArray:nil];
  69. });
  70. }
  71. return self;
  72. }
  73. -(void)finishedDownloadCompletionHandler:(finishedDownloadCompletionHandler)block {
  74. _block = block;
  75. }
  76. -(void)finishShareHandler:(finishShareHandler)block {
  77. _shareblock = block;
  78. }
  79. -(void)previewFileView:(BOOL)b {
  80. if (b) {
  81. [UIView animateWithDuration:0.5 animations:^{
  82. [self.docWebView setY:self.height];
  83. } completion:^(BOOL finished) {
  84. }];
  85. }else {
  86. [UIView animateWithDuration:0.5 animations:^{
  87. [self.docWebView setY:0];
  88. } completion:^(BOOL finished) {
  89. }];
  90. }
  91. }
  92. #pragma mark - Private Method
  93. /** 创建文件工具类 */
  94. - (void)ldvCreatefileUtil {
  95. _fileUtil = [JhtDocFileOperations sharedInstance];
  96. _fileUtil.fileName = _currentFileModel.fileName;
  97. }
  98. #pragma mark UI
  99. /** CreateUI */
  100. - (void)ldvCreateUI {
  101. self.backgroundColor = [UIColor whiteColor];
  102. NSFileManager *fileManager = [NSFileManager defaultManager];
  103. NSString *filePath = [_fileUtil stitchLocalFilePath];
  104. if ([fileManager fileExistsAtPath:filePath]) {
  105. [self ldvCreateDownloadUI:YES];
  106. }else {
  107. [self ldvCreateDownloadUI:NO];
  108. }
  109. }
  110. /** 获取本地文件大小 */
  111. - (long long)ldvFileSizeForPath:(NSString *)filePath {
  112. NSFileManager *manager = [NSFileManager defaultManager];
  113. if ([manager fileExistsAtPath:filePath]) {
  114. return [[manager attributesOfItemAtPath:filePath error:nil] fileSize];
  115. }
  116. return 0;
  117. }
  118. /** 生成下载页面 */
  119. - (void)ldvCreateDownloadUI:(BOOL)isExists{
  120. // 下载文件View
  121. self.downloadView = [[JhtDownloadView alloc] initWithFrame:CGRectMake(0, 0, FrameW, FrameH - KLDVStatusAndNavBarHeight) downloadingHint:self.loadDocViewParamModel.downloadingHint lostNetHint:self.loadDocViewParamModel.lostNetHint downloadProgressTintColor:self.loadDocViewParamModel.downloadProgressTintColor fileModel:_currentFileModel withExists:isExists];
  122. __weak typeof(self) weakSelf = self;
  123. // 点击block 0-重新加载,1-点击关闭
  124. [self.downloadView clickBtnBlock:^(NSInteger index) {
  125. if (index == 0) {// 重新加载
  126. [self ldvDrawProgressUIForDowningFile];
  127. [weakSelf ldvRetryClick];
  128. } else if (index == 3) { //分享点击
  129. NSString *pathUrl = [[self->_fileUtil stitchLocalFilePath] stringByRemovingPercentEncoding];
  130. if (self->_shareblock) {
  131. self->_shareblock(pathUrl);
  132. }
  133. } else if (index == 2) { //预览页面
  134. [weakSelf ldvCreateWebView];
  135. NSString *pathUrl = [[self->_fileUtil stitchLocalFilePath] stringByRemovingPercentEncoding];
  136. if (self->_block) {
  137. self->_block(pathUrl);
  138. }
  139. [self previewFileView:false];
  140. }else { //点击关闭
  141. [weakSelf ldvCloseClick];
  142. }
  143. }];
  144. [self addSubview:self.downloadView];
  145. // 是否具备下载条件(网络 && 存储空间)
  146. [self ldvJudgeDownloadConditions];
  147. }
  148. #pragma mark 判断是否具备下载条件(网络 && 存储空间)
  149. /** 判断是否具备下载条件(网络) */
  150. - (void)ldvJudgeDownloadConditions {
  151. if ([self ldvCurrentFreeDiskSpaceToFileSize] < 0) {// 内存不足
  152. [self ldvShowDumpingView:self.loadDocViewParamModel.notEnoughMemoryHint];
  153. self.downloadView.downloadBtn.hidden = NO;
  154. } else {
  155. if (([JhtNetworkCheckTools currentNetWork_Status] == NetWorkStatus_2G) || ([JhtNetworkCheckTools currentNetWork_Status] == NetWorkStatus_3G) || ([JhtNetworkCheckTools currentNetWork_Status] == NetWorkStatus_4G)) {
  156. UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"下载流量提醒" message:@"当前处于非wifi环境,继续查看将会产生手机流量" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
  157. alert.tag = 123;
  158. [alert show];
  159. } else if ([JhtNetworkCheckTools currentNetWork_Status] == NetWorkStatus_None) {
  160. } else {
  161. }
  162. }
  163. }
  164. /** 获取当前设备硬盘存储容量 与文件大小 做差 < 0 说明内存不足 */
  165. - (CGFloat)ldvCurrentFreeDiskSpaceToFileSize {
  166. long long freeSpace = [[[[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil] objectForKey:NSFileSystemFreeSize] longLongValue];
  167. // 去除200M左右保护空间
  168. freeSpace -= (200 * 1024 * 1024);
  169. double bytes = 1.0 * freeSpace;
  170. double kigabytes = bytes / KB;
  171. double megabytes = bytes / MB;
  172. double gigabytes = bytes / GB;
  173. // Bytes,KB,MB,GB
  174. if ([_currentFileModel.fileSize rangeOfString:@"KB"].length) {
  175. return kigabytes - [[_currentFileModel.fileSize componentsSeparatedByString:@"KB"][0] floatValue];
  176. } else if ([_currentFileModel.fileSize rangeOfString:@"GB"].length) {
  177. return gigabytes - [[_currentFileModel.fileSize componentsSeparatedByString:@"GB"][0] floatValue];
  178. } else if ([_currentFileModel.fileSize rangeOfString:@"MB"].length) {
  179. return megabytes - [[_currentFileModel.fileSize componentsSeparatedByString:@"MB"][0] floatValue];
  180. } else if ([_currentFileModel.fileSize rangeOfString:@"Bytes"].length) {
  181. return bytes - [[_currentFileModel.fileSize componentsSeparatedByString:@"Bytes"][0] floatValue];
  182. } else {
  183. // 做的兼容处理,如果给的_currentFileModel.fileSize不符合规则,那么就不比较,直接返回1
  184. return 1;
  185. }
  186. }
  187. #pragma mark 绘制下载进度状况
  188. /** 绘制下载进度状况 */
  189. - (void)ldvDrawProgressUIForDowningFile {
  190. self.downloadView.fileProgressView.hidden = NO;
  191. self.downloadView.downloadingStateLabel.hidden = NO;
  192. self.downloadView.closeBtn.hidden = NO;
  193. self.downloadView.downloadBtn.hidden = YES;
  194. /** 下载文件功能
  195. * URLString: 要下载文件的URL
  196. * downloadFileProgress: 下载的进度条,百分比
  197. * setupFilePath: 设置下载的路径
  198. * downloadCompletionHandler: 下载完成后(下载完成后可拿到存储的路径)
  199. */
  200. [JhtDownloadRequest createDownloadFileWithURLString:_currentFileModel.url downloadFileProgress:^(NSProgress *downloadProgress) {
  201. dispatch_async(dispatch_get_main_queue(), ^{
  202. [self.downloadView.fileProgressView setProgress:downloadProgress.fractionCompleted animated:YES];
  203. });
  204. } setupFilePath:^NSURL *(NSURLResponse *response) {
  205. NSString *cachePath = [NSString stringWithFormat:@"%@", self->_currentFileModel.fileName];
  206. NSString *filePath = [self->_fileUtil stitchDownloadFilePath];
  207. BOOL isDir = NO;
  208. NSFileManager *fileManager = [NSFileManager defaultManager];
  209. BOOL existed = [fileManager fileExistsAtPath:filePath isDirectory:&isDir];
  210. if (!(isDir == YES && existed == YES)) {
  211. [fileManager createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:nil];
  212. }
  213. NSString *localPath = [filePath stringByAppendingPathComponent:cachePath];
  214. return [NSURL fileURLWithPath:localPath];
  215. } downloadCompletionHandler:^(NSURL *filePath, NSError *error) {
  216. NSLog(@"fileDownloadError ==> %@", error);
  217. if (!error) {
  218. NSString *filePath = [self->_fileUtil stitchLocalFilePath];
  219. CGFloat fileSize = [self ldvFileSizeForPath:filePath];
  220. self.downloadView.fileProgressView.hidden = YES;
  221. self.downloadView.closeBtn.hidden = YES;
  222. self.downloadView.downloadBtn.hidden = YES;
  223. self.downloadView.downloadingStateLabel.hidden = NO;
  224. self.downloadView.downloadingStateLabel.text = [NSString stringWithFormat:@"文件大小:%@",[NSByteCountFormatter stringFromByteCount:fileSize countStyle:NSByteCountFormatterCountStyleFile]];
  225. if(self->_currentFileModel.viewFileType==Type_Unknow) {
  226. self.downloadView.openBtn.hidden = YES;
  227. self.downloadView.shareBtn.hidden = NO;
  228. }else{
  229. self.downloadView.openBtn.hidden = NO;
  230. self.downloadView.shareBtn.hidden = YES;
  231. }
  232. } else {
  233. self.downloadView.downloadingStateLabel.text = self.loadDocViewParamModel.downloadFailedHint;
  234. self.downloadView.downloadBtn.hidden = NO;
  235. // 文件下载失败时,清除文件路径
  236. [self->_fileUtil removeFileWhenDownloadFileFailure];
  237. }
  238. }];
  239. }
  240. #pragma mark - WebView
  241. /** 创建WebView */
  242. - (void)ldvCreateWebView {
  243. // 网络下载成功,本地路径
  244. NSString *filePath = [_fileUtil stitchLocalFilePath];
  245. // 非网络下载的路径
  246. if (_currentFileModel.fileAbsolutePath) {
  247. filePath = _currentFileModel.fileAbsolutePath;
  248. }
  249. [self addSubview:self.docWebView];
  250. self.docWebView.filePath = filePath;
  251. self.docWebView.otherOpenButtonParamModel = self.otherOpenButtonParamModel;
  252. }
  253. #pragma mark - Getter
  254. - (JhtDocWebView *)docWebView {
  255. if (!_docWebView) {
  256. _docWebView = [[JhtDocWebView alloc] initWithFrame:CGRectMake(0, FrameH, FrameW, FrameH)];
  257. }
  258. return _docWebView;
  259. }
  260. - (WKWebView *)wkWebView {
  261. return self.docWebView.wkWebView;
  262. }
  263. - (JhtLoadDocViewParamModel *)loadDocViewParamModel {
  264. if (!_loadDocViewParamModel) {
  265. _loadDocViewParamModel = [[JhtLoadDocViewParamModel alloc] init];
  266. }
  267. NSDictionary *dic = [JhtDefaultManager getConfigDataWithType:JhtDefaultType_LoadDocViewParam];
  268. _loadDocViewParamModel.lostNetHint = (_loadDocViewParamModel.lostNetHint.length > 0 ? _loadDocViewParamModel.lostNetHint : dic[@"lostNetHint"]);
  269. _loadDocViewParamModel.notEnoughMemoryHint = (_loadDocViewParamModel.notEnoughMemoryHint.length > 0 ? _loadDocViewParamModel.notEnoughMemoryHint : dic[@"notEnoughMemoryHint"]);
  270. if ([JhtNetworkCheckTools currentNetWork_Status] == NetWorkStatus_None) {
  271. _loadDocViewParamModel.downloadingHint = _loadDocViewParamModel.lostNetHint;
  272. } else {
  273. _loadDocViewParamModel.downloadingHint = (_loadDocViewParamModel.downloadingHint.length > 0 ? _loadDocViewParamModel.downloadingHint : dic[@"downloadingHint"]);
  274. }
  275. if ([JhtNetworkCheckTools currentNetWork_Status] == NetWorkStatus_None) {
  276. _loadDocViewParamModel.downloadFailedHint = _loadDocViewParamModel.lostNetHint;
  277. } else {
  278. _loadDocViewParamModel.downloadFailedHint = (_loadDocViewParamModel.downloadFailedHint.length > 0 ? _loadDocViewParamModel.downloadFailedHint : dic[@"downloadFailedHint"]);
  279. }
  280. _loadDocViewParamModel.daysAgo = (_loadDocViewParamModel.daysAgo > [dic[@"daysAgo"] integerValue] ? _loadDocViewParamModel.daysAgo : [dic[@"daysAgo"] integerValue]);
  281. _loadDocViewParamModel.downloadProgressTintColor = (_loadDocViewParamModel.downloadProgressTintColor ? _loadDocViewParamModel.downloadProgressTintColor : UIColorFromRGB(0x61CBF5));
  282. return _loadDocViewParamModel;
  283. }
  284. - (JhtShowDumpingViewParamModel *)showDumpingViewParamModel {
  285. if (!_showDumpingViewParamModel) {
  286. _showDumpingViewParamModel = [[JhtShowDumpingViewParamModel alloc] init];
  287. }
  288. _showDumpingViewParamModel.showViewFrame = (!CGRectEqualToRect(_showDumpingViewParamModel.showViewFrame, CGRectZero)) ? _showDumpingViewParamModel.showViewFrame : CGRectMake(0, 0, FrameW, 65);
  289. _showDumpingViewParamModel.showBackgroundColor = _showDumpingViewParamModel.showBackgroundColor ? _showDumpingViewParamModel.showBackgroundColor : [UIColor whiteColor];
  290. _showDumpingViewParamModel.showBackgroundImageName = _showDumpingViewParamModel.showBackgroundImageName.length ? _showDumpingViewParamModel.showBackgroundImageName : @"dumpView";
  291. _showDumpingViewParamModel.formerWarningIconFrame = (!CGRectEqualToRect(_showDumpingViewParamModel.formerWarningIconFrame, CGRectZero)) ? _showDumpingViewParamModel.formerWarningIconFrame : CGRectMake(15, (_showDumpingViewParamModel.showViewFrame.size.height - 35) + ((KSDPMShowLabelHeight - 20) / 2.0), 20, 20);
  292. _showDumpingViewParamModel.showLabelFrame = (_showDumpingViewParamModel.showLabelFrame.size.height > 0 && _showDumpingViewParamModel.showLabelFrame.size.width > 0) ? _showDumpingViewParamModel.showLabelFrame : CGRectMake(CGRectGetMaxX(_showDumpingViewParamModel.formerWarningIconFrame) + 8, _showDumpingViewParamModel.showViewFrame.size.height - 35, _showDumpingViewParamModel.showViewFrame.size.width - (CGRectGetMaxX(_showDumpingViewParamModel.formerWarningIconFrame) + 8) * 2, KSDPMShowLabelHeight);
  293. _showDumpingViewParamModel.showTextColor = _showDumpingViewParamModel.showTextColor ? _showDumpingViewParamModel.showTextColor : UIColorFromRGB(0x666666);
  294. _showDumpingViewParamModel.showTextFont = _showDumpingViewParamModel.showTextFont ? _showDumpingViewParamModel.showTextFont : [UIFont boldSystemFontOfSize:15];
  295. return _showDumpingViewParamModel;
  296. }
  297. #pragma mark Getter Method
  298. /** 重新加载按钮触发方法 */
  299. - (void)ldvRetryClick {
  300. if ([JhtNetworkCheckTools currentNetWork_Status] == NetWorkStatus_None) {
  301. [self ldvShowDumpingView:self.loadDocViewParamModel.lostNetHint];
  302. // 改变下载过程中提示文字
  303. self.downloadView.downloadingStateLabel.text = self.loadDocViewParamModel.downloadingHint;
  304. // 隐藏进度条和关闭按钮
  305. self.downloadView.fileProgressView.hidden = YES;
  306. self.downloadView.closeBtn.hidden = YES;
  307. return;
  308. }
  309. self.downloadView.downloadingStateLabel.text = self.loadDocViewParamModel.downloadingHint;
  310. self.downloadView.downloadBtn.hidden = YES;
  311. // 断是否具备下载条件(网络 && 存储空间)
  312. [self ldvJudgeDownloadConditions];
  313. }
  314. /** 红色那个关闭点击事件 */
  315. - (void)ldvCloseClick {
  316. [_fileUtil removeFileWhenDownloadFileFailure];
  317. // 停止 下载文件
  318. [JhtDownloadRequest stopDownloadFile];
  319. self.downloadView.fileProgressView.progress = 0;
  320. }
  321. /** 展示弹框 */
  322. - (void)ldvShowDumpingView:(NSString *)title {
  323. if (_errorFView) {
  324. [JhtDownTipsDumpingView showWithFView:_errorFView text:title showDumpingViewParamModel:self.showDumpingViewParamModel];
  325. }
  326. }
  327. #pragma mark - Setter
  328. - (void)setOtherOpenButtonParamModel:(OtherOpenButtonParamModel *)otherOpenButtonParamModel {
  329. _otherOpenButtonParamModel = otherOpenButtonParamModel;
  330. self.docWebView.otherOpenButtonParamModel = _otherOpenButtonParamModel;
  331. }
  332. #pragma mark - UIAlertViewDelegate
  333. - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
  334. if (alertView.tag == 123) {
  335. if (buttonIndex == 1) {// 开始下载
  336. [self ldvDrawProgressUIForDowningFile];
  337. } else {
  338. // 展示下载
  339. self.downloadView.fileProgressView.hidden = YES;
  340. self.downloadView.closeBtn.hidden = YES;
  341. self.downloadView.downloadBtn.hidden = NO;
  342. self.downloadView.downloadingStateLabel.hidden = NO;
  343. self.downloadView.downloadingStateLabel.text = @"该文件暂不支持在线预览,请下载后查看";
  344. }
  345. }
  346. }
  347. @end