1. 使用
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"查看";
[self addWebView];
}
- (void)addWebView
{
_webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT - 64)];
/// 这是默认的策略
[self loadDataWithProtocol];
// 如果不想要webView 的回弹效果
_webView.scrollView.bounces = NO;
_webView.scalesPageToFit = YES ;
_webView.delegate = self;
// UIWebView 滚动的比较慢,这里设置为正常速度
self.webView.scrollView.decelerationRate = UIScrollViewDecelerationRateNormal;
[self.view addSubview:_webView];
}
2. 加载
2.1 带缓存加载 使用协议缓存, 需要 web 服务器支持. 默认策略
- (void)loadDataWithProtocol
{
NSURL *url = [NSURL URLWithString:@"http://m.XXXX.net"];
[NSURLRequest requestWithURL:url];
NSURLRequest *urlReq = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.f];
[self.webView loadRequest:urlReq];
// 等同于
//[_webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://m.XXXX.net"]]];
}
2.2 带缓存加载 新安装app 无缓存 会崩溃 (无用, 仅做记录)
- (void)loadDataUsingCache
{
NSURL *url = [NSURL URLWithString:@"http://www.XXXX.com"];
NSURLRequest *urlReq = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestReturnCacheDataDontLoad
timeoutInterval:10.f];
[_webView loadRequest:urlReq];
}
2.3 不带缓存加载 (无用, 仅做记录)
- (void)loadDataNoUsingCache
{
NSURL *url = [NSURL URLWithString:@"http://www.XXXX.com"];
NSURLRequest *urlReq = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:20.0];
[self.webView loadRequest:urlReq];
}
2.4 清除所有缓存 (无用, 仅做记录)
- (void)clearAllCache
{
// remove cache rsp
[[NSURLCache sharedURLCache] removeAllCachedResponses];
[[NSURLCache sharedURLCache] setDiskCapacity:0];
[[NSURLCache sharedURLCache] setMemoryCapacity:0];
}
3. 写cookie
3.1 要求( 仿照安卓的代码)
//写cookie, 页面根据cookie判断当前页面是在 "我" 还是 "查看" 里
cookieManager.setCookie(App.htmlurl, "wxTabIndex=0"); //"我" 界面为1, "查看" 为0
3.1 解决方案
/// 这里的 webViewDidFinishLoad内方法删除了其他的内容, 方便说明
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
[self changeCookie];
}
-(void)changeCookie
{
NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
[cookieProperties setObject:@"App.htmlurl" forKey:NSHTTPCookieName];
[cookieProperties setObject:@"wxTabIndex=0" forKey:NSHTTPCookieValue];
[cookieProperties setObject:@"www.XXXX.com" forKey:NSHTTPCookieDomain];
[cookieProperties setObject:@"/" forKey:NSHTTPCookiePath];
[cookieProperties setObject:@"0" forKey:NSHTTPCookieVersion];
NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
}
3.2 附注: 删除Cookie 和 查找Cookie (我没用到)
- (void)deleteCookie
{
NSLog(@"============删除cookie===============");
NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
//删除cookie
for (NSHTTPCookie *tempCookie in cookies) {
[cookieStorage deleteCookie:tempCookie];
}
//把cookie打印出来,检测是否已经删除
NSArray *cookiesAfterDelete = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
for (NSHTTPCookie *tempCookie in cookiesAfterDelete) {
NSLog(@"cookieAfterDelete: %@", tempCookie);
}
NSLog(@"\n");
}
- (void)searchCoookie
{
//获取cookie
NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
for (NSHTTPCookie *tempCookie in cookies) {
//打印获得的cookie
NSLog(@"getCookie: %@", tempCookie);
}
}
4. OC调用JS
4.1 要求1
每次切换到 "查看" 调用函数:
webView.loadUrl("javascript:XXXXXX.App.clickDevice(1)"); //页面处理需要
4.1 解决方案点击Tabbar的时候操作
- (void)tabBarSeleted:(NSNotification *)notification
{
[_webView stringByEvaluatingJavaScriptFromString:@"javascript:XXXXXX.App.clickDevice(1)"];
}
5. JS调用OC
5.1 创建 需要注册到JS的模型的类
JsObjCModel.h
#import <Foundation/Foundation.h>
#import <JavaScriptCore/JavaScriptCore.h>
@protocol JavaScriptObjectiveCDelegate <JSExport>
/// 网页调用这个方法 检测app蓝牙是否连接打印机
- (void)PrintConnect;
/// 如果连接, 网页会调用这个方法
- (void)PrintData:(NSString *)str;
@end
// 此模型用于注入JS的模型,这样就可以通过模型来调用方法。
@interface HYBJsObjCModel : NSObject <JavaScriptObjectiveCDelegate>
@property (nonatomic, weak) JSContext *jsContext;
@property (nonatomic, weak) UIWebView *webView;
@end
JsObjCModel.m
#import "JsObjCModel.h"
@implementation JsObjCModel
- (void)PrintConnect
{
NSLog(@"JS调用了OC的方法,检测打印机");
BOOL isConnection = [[BluetoothPrinterManager sharedManager] checkPrinterIsConnection];
if (isConnection) {
// JS调用后OC后,又通过OC调用JS 这里只是简单使用
[_webView stringByEvaluatingJavaScriptFromString:@"javascript:XXXX.App.setPrinterConnOk()"];
}
}
- (void)PrintData:(NSString *)str
{
NSLog(@"JS调用了OC的方法,PrintData-- %@", str);
[[BluetoothPrinterManager sharedManager] startPrintString:[NSString stringWithFormat:@"%@", str]];
// // JS调用后OC后,又通过OC调用JS,但是这个是没有传参数的
// JSValue *jsFunc = self.jsContext[@"jsFunc"];
// [jsFunc callWithArguments:nil];
}
使用
@interface DAViewController ()<UIWebViewDelegate, UIGestureRecognizerDelegate>
@property (nonatomic) UIWebView *webView;
@property (nonatomic, strong) JSContext *jsContext;
//返回按钮
@property (nonatomic, strong) UIBarButtonItem *webBackItem;
@property (nonatomic, strong) UIBarButtonItem *rightButton;
@end
创建
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
/// 加载网页完毕 再注入模型 (注入太早可能网页不会响应)
[self injectedObject:webView];
}
/// 注入模型
- (void)injectedObject:(UIWebView *)webView
{
self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
// 通过模型调用方法,这种方式更好些。
HYBJsObjCModel *model = [[HYBJsObjCModel alloc] init];
model.jsContext = self.jsContext;
model.webView = self.webView;
self.jsContext[@"java"] = model;
self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
context.exception = exceptionValue;
NSLog(@"异常信息:%@", exceptionValue);
};
}
6. 显示网页返回按钮
/// 网页加载完毕 判断 canGoBack
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
// 去掉网页 footer
[webView stringByEvaluatingJavaScriptFromString:@"document.getElementById('content-footer').remove();"];
//获取当前页面的title 修改导航栏标题
NSString *title= [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
[self.navigationItem setTitle:title];
//判断是否有上一层H5页面
if ([webView canGoBack]) {
//同时设置返回按钮和关闭按钮为导航栏左边的按钮
self.navigationItem.leftBarButtonItems = @[self.webBackItem];
} else {
self.navigationItem.leftBarButtonItems = @[];
}
}
/// 懒加载
- (UIBarButtonItem *)webBackItem
{
if (!_webBackItem) {
_webBackItem = [[UIBarButtonItem alloc] init];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
//这是一张“<”的图片,可以让美工给切一张
UIImage *image = [UIImage imageNamed:@"barbuttonicon_back"];
[btn setImage:image forState:UIControlStateNormal];
[btn setTitle:@"" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(backNative) forControlEvents:UIControlEventTouchUpInside];
[btn.titleLabel setFont:[UIFont systemFontOfSize:17]];
[btn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
//字体的多少为btn的大小
[btn sizeToFit];
//左对齐
btn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
//让返回按钮内容继续向左边偏移15,如果不设置的话,就会发现返回按钮离屏幕的左边的距离有点儿大,不美观
// btn.contentEdgeInsets = UIEdgeInsetsMake(0, -15, 0, 0);
btn.frame = CGRectMake(0, 0, 40, 40);
_webBackItem.customView = btn;
}
return _webBackItem;
}
//点击返回的方法
- (void)backNative
{
//判断是否有上一层H5页面
if ([self.webView canGoBack]) {
//如果有则返回
[self.webView goBack];
} else {
[self closeNative];
}
}
7. 一个网页登陆 刷新另外一个网页也登陆
tabbar 有三个按钮, 其中两个按钮都是网页webView. 一个网页登陆以后, 如果点击另外一个Tabbar, 也要让该webView登陆.并跳转到个人页面.
1, 在 AppDelegate 新建个属性
isLoginWeb
用来标记 是否已经登陆网页2, 如果一个webView登陆以后 就标记 这个
isLoginWeb
为YES
证明app内有人进行了登陆操作并登陆成功.3, 并在自身的 VC内也新建个属性
isLoginWeb
用来标记 自身是否已经登陆,
因为系统内其他VC已经登陆网页,并不代表自身Vc已经登陆网页.
登陆成功以后,也要把这个属性设置为YES4, 这个属性的 标记 肯定是在
webViewDidFinishLoad
来判断.
需要根据当前网页的URL 来进行判断. 因为登陆的网页,后缀是 带login
的.5, 点击Tabbar的时候根据 这两个属性 进行相应的操作
第1步
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
/// 是否已经登陆网页
@property (nonatomic, assign) BOOL isLoginWeb;
@end
第2步
@interface DAViewController ()<UIWebViewDelegate, UIGestureRecognizerDelegate>
@property (nonatomic) UIWebView *webView;
@property (nonatomic, strong) JSContext *jsContext;
/// 是否已经登陆网页
@property (nonatomic, assign) BOOL isLoginWeb;
//返回按钮
@property (nonatomic, strong) UIBarButtonItem *webBackItem;
@property (nonatomic, strong) UIBarButtonItem *rightButton;
@end
第3,4步
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSString *currentURL = webView.request.URL.absoluteString;
NSLog(@"currentURL -- %@", currentURL);
if ([currentURL isEqualToString:@"http://www.XXXX.com/Login"]) {
app.isLoginWeb = NO;
self.isLoginWeb = NO;
} else if ([currentURL isEqualToString:@"http://www.XXXX.com/Home"] ||[currentURL isEqualToString:@"www.XXXX.com/"]) {
app.isLoginWeb = YES;
self.isLoginWeb = YES;
[_webView stringByEvaluatingJavaScriptFromString:@"javascript:XXXXX.App.clickDevice(1)"];
} else {
app.isLoginWeb = YES;
self.isLoginWeb = YES;
}
}
第5步
- (void)tabBarSeleted:(NSNotification *)notification
{
AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate];
if (app.isLoginWeb && self.isLoginWeb) {
// 如果本VC 已经登陆, 就去调用JS函数 (产品需要)
[_webView stringByEvaluatingJavaScriptFromString:@"javascript:XXXX.App.clickDevice(1)"];
} else {
// 如果没有登陆, 就去从缓存中获取,如果缓存已经登陆,会自动登陆, 如果没有登陆,会跳转到登录页面.(这是webView自己做的缓存, 和我无关)
[self loadDataWithProtocol];
}
}