下面进入正题
看一下需求
1.通过一个下载链接下载资源包,解压后再去加载
2.跟网页有交互,页面如下
实现思路
1.下载
2.解压
3.加载
4.交互
下载
我们用的是基于AFNetworking封装的下载方法, 用WebModel调用
接口
//
// WebModel.h
// git发贴专业测试
//
// Created by Mac on 16/4/5.
// Copyright © 2016年 Mac. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <AFNetworking.h>
#import <UnzipKit.h>
@interface WebModel : NSObject
/**
* @author 嘴爷, 2016-04-05 15:04:25
*
* @brief 测试专用,创建一个AFHTTPRequestOperationManager单例(中止下载时候使用)
*
* @return AFHTTPRequestOperationManager单例
*/
+ (AFHTTPRequestOperationManager *)sharedInstance;
/**
* @author 嘴爷, 2016-04-05 16:04:53
*
* @brief 根据url停止某个请求
*
* @param url 待停止请求的特征url
*/
+ (void)kickOffOldMe:(NSString *)url;
/**
* @author 嘴爷, 2016-04-05 15:04:37
*
* @brief 下载文件
*
* @param paramDic 附加的请求参数
* @param requestURL 下载地址
* @param savedPath 保存路径
* @param success 下载成功的回调
* @param failure 下载失败的回调
* @param progress 实时下载进度
*/
+ (void)asyncDownloadWithParams:(NSDictionary *)param
url:(NSString*)url
savedPath:(NSString*)savedPath
successBlock:(void (^)(AFHTTPRequestOperation *operation, id responseObject))successBlock
errorBlock:(void (^)(AFHTTPRequestOperation *operation, NSError *error))errorBlock
progress:(void (^)(float progress))progress;
/**
* @author 嘴爷, 2016-05-03 09:05:04
*
* @brief 解压文件
*
* @param fromPath 待解压文件的位置
* @param toPath 解压到的位置
* @param progress 解压进度
*/
+(void)unArchiveFromPath:(NSString*)fromPath toPath:(NSString*)toPath progress:(void (^)(CGFloat percentDecompressed))progress;
/**
* @author 嘴爷, 2016-05-03 10:05:27
*
* @brief 返回的绝对为字符串,不管是NULL nil 还是数字
*
* @param string 待处理的对象
*
* @return 字符串
*/
+ (NSString *) getBlankString:(id)string;
@end
实现
//
// WebModel.m
// git发贴专业测试
//
// Created by Mac on 16/4/5.
// Copyright © 2016年 Mac. All rights reserved.
//
#import "WebModel.h"
#import <AFHTTPRequestOperationManager.h>
#import <AFURLRequestSerialization.h>
@implementation WebModel
//下载
+(void)asyncDownloadWithParams:(NSDictionary *)param url:(NSString *)url savedPath:(NSString *)savedPath successBlock:(void (^)(AFHTTPRequestOperation *, id))successBlock errorBlock:(void (^)(AFHTTPRequestOperation *, NSError *))errorBlock progress:(void (^)(float))progress{
// 下载前停止当前的下载
[self kickOffOldMe:url];
AFHTTPRequestSerializer* serializer = [AFHTTPRequestSerializer serializer];
NSMutableURLRequest* request = [serializer requestWithMethod:@"GET" URLString:url parameters:param error:nil];
AFHTTPRequestOperation* operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
// 加入到一个全局的队列 为了便于管理
[[WebModel sharedInstance].operationQueue addOperation:operation];
[operation setOutputStream:[NSOutputStream outputStreamToFileAtPath:savedPath append:NO]];
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
float p = (float)totalBytesRead / totalBytesExpectedToRead;
if (progress) progress(p);
}];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation * _Nonnull operation, id _Nonnull responseObject) {
if(successBlock) successBlock(operation, responseObject);
} failure:^(AFHTTPRequestOperation * _Nonnull operation, NSError * _Nonnull error) {
if(errorBlock) errorBlock(operation, error);
}];
[operation start];
}
//解压
+(void)unArchiveFromPath:(NSString*)fromPath toPath:(NSString*)toPath progress:(void (^)(CGFloat percentDecompressed))progress{
// 下载之前删除之前的目标文件
NSError* fileError = nil;
NSFileManager* fm = [NSFileManager defaultManager];
if ([fm fileExistsAtPath:toPath]) {
[fm removeItemAtPath:toPath error:&fileError];
NSLog(@"删除之前的目标文件%@", fileError);
}
BOOL fileAtPathIsArchive = [UZKArchive pathIsAZip:fromPath];//判断是否是zip文件
if (!fileAtPathIsArchive) {
return;
}
NSError *archiveError = nil;
UZKArchive* archive = [[UZKArchive alloc] initWithPath:fromPath error:&archiveError];
[archive extractFilesTo:toPath overwrite:YES progress:^(UZKFileInfo * _Nonnull currentFile, CGFloat percentArchiveDecompressed) {
if(progress) progress(percentArchiveDecompressed);
NSLog(@"解压进度%f", percentArchiveDecompressed);
} error:&archiveError];
// 解压完成后删除这个zip包
NSError* deleteError = nil;
if ([fm fileExistsAtPath:fromPath]) {
// [fm removeItemAtPath:fromPath error:&deleteError];
[archive deleteFile:fromPath error:&deleteError];
NSLog(@"删除ZIP源文件%@", fileError);
}
}
//线程单例
+(AFHTTPRequestOperationManager *)sharedInstance{
static id sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:@""]];
});
return sharedInstance;
}
//取消队列中的某个线程(根据url判断)
+ (void)kickOffOldMe:(NSString *)url{
for (AFHTTPRequestOperation *item in [WebModel sharedInstance].operationQueue.operations) {
if ([item.request.URL.absoluteString containsString:url]) {
[item cancel];
}
}
}
//去除null
+ (NSString *) getBlankString:(id)string{
if (string == nil || string == NULL) {
return @"";
}
if ([string isKindOfClass:[NSNull class]]) {
return @"";
}
// if ([[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length]==0) {
// return @"";
// }
return [NSString stringWithFormat:@"%@", string];
}
@end
下载位置输出:
/Users/mac/Library/Developer/CoreSimulator/Devices/B8AD0EB2-2053-404A-AFC8-B61C909277D7/data/Containers/Data/Application/F8CEF99E-502C-4BCE-9D68-F3656FFC102F/Library/Caches/webZIP/text.zip
解压
我们用的是基于UnzipKit封装的解压方法, 用WebModel调用
接口
详见下载里的 WebModel
下载和解压的文件如下图
加载webView
打开text文件夹
找到.html文件
url只要引用到这个.html文件就可以了 如果需要传入参数,可以像get请求那样,如下
//通过本地文件加载web页
-(void)loadWebView{
//引用到.html文件
NSString* htmlPath = [[self getZIPPath] stringByAppendingFormat:@"/text/lastFigures/lastFigures.html"];
NSString* path = [htmlPath stringByAppendingFormat:@"?token=%@&get_url=%@", @"3ea964864d920892bc9b20142de6a3abef04f87b",
// path = @"/Users/mac/Downloads/lastFigures(1)/lastFigures.html";//本地测试路径
NSLog(@"webPath:%@", path);
NSURL* url = [NSURL URLWithString:path];
NSURLRequest* request = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:request];
}
看下运行效果
交互
可以直接用webView方法调用,或者用三方的WebViewJavascriptBridge直接用,其中webHandler方法可以直接在webView创建出来后直接调用
#pragma mark -
#pragma mark - webMethod
//webView字体缩小
- (void)zoomIn{
[self.webView stringByEvaluatingJavaScriptFromString:@"fontZoomB()"];
}
//webView字体放大
- (void)zoomOut{
[self.webView stringByEvaluatingJavaScriptFromString:@"fontZoomA()"];
}
//网页刷新字体缩放
- (void)reloadWebData{
[self.webView stringByEvaluatingJavaScriptFromString:@"reload()"];
}
///处理网页事件
-(void)webHandler{
[WebViewJavascriptBridge enableLogging];
self.brige = [WebViewJavascriptBridge bridgeForWebView:self.webView];
[self.brige setWebViewDelegate:self];
// 注册下拉刷新方法 等待JS调用
[self.brige registerHandler:@"onPullRefreshSuccess" handler:^(id data, WVJBResponseCallback responseCallback) {
NSLog(@"下拉刷新执行了 %@", data);
}];
// 注册点击头像方法 等待JS调用
[self.brige registerHandler:@"gotoMemberInfoViewController" handler:^(id data, WVJBResponseCallback responseCallback) {
NSLog(@"点到头像了 人员ID %@", data);
}];
// 调用JS方法 JS需要注册监听
// id data = @{ @"greetingFromObjC": @"Hi there, JS!" };
// [self.brige callHandler:@"onPullRefreshSuccess" data:data responseCallback:^(id responseData) {
// NSLog(@"onPullRefreshSuccess执行了");
// }];
}