现在混合式移动端开发越来越流行,因为开发成本上、速度上都比传统的 app开发要好,混合式开发是传统模式与PC网页端相结合的模式。
在android开发中有WebView作为混合开发的桥梁,当然iOS中也有同样一个UIWebView组件作为混合模式开发的桥梁。
UIWebView简介
UIWebView是UIKit库下内置的浏览器控件,它继承自UIView。可以通过UIWebView浏览网页,打开文档等多种功能。系统自带的Safari就是UIWebView实现的。
UIWebView的属性
@property (nullable, nonatomic, readonly, strong) NSURLRequest *request; //URL请求
@property (nonatomic, readonly, getter=canGoBack) BOOL canGoBack; //获取能否返回上一级
@property (nonatomic, readonly, getter=canGoForward) BOOL canGoForward; //获取能否跳转下一级
@property (nonatomic, readonly, getter=isLoading) BOOL loading; //获取是否正在加载数据
@property (nonatomic) BOOL scalesPageToFit; //适应屏幕大小
@property (nonatomic) BOOL detectsPhoneNumbers NS_DEPRECATED_IOS(2_0, 3_0); //iOS 2 -iOS 3 ,已经禁用,自动监测网页上的电话号码,单击可以拨打。
//此属性可以设定使电话号码、网址、电子邮件和符合格式的日期等文字改变为链接文字,电话号码点击后可以拨出电话,
//网址点击后会用Safari打开,电子邮件会用mail打开,而符合格式的日期会弹出一个ActionSheet,有创建事件,在Calender中显示和拷贝三个选项。
@property (nonatomic) UIDataDetectorTypes dataDetectorTypes NS_AVAILABLE_IOS(3_0);
@property (nonatomic) BOOL allowsInlineMediaPlayback NS_AVAILABLE_IOS(4_0); // iPhone Safari defaults to NO. iPad Safari defaults to YES
//设置网页中的视频是否自动播放,默认YES
@property (nonatomic) BOOL mediaPlaybackRequiresUserAction NS_AVAILABLE_IOS(4_0); // iPhone and iPad Safari both default to YES
//设置音频播放是否支持air play功能,默认YES
@property (nonatomic) BOOL mediaPlaybackAllowsAirPlay NS_AVAILABLE_IOS(5_0); // iPhone and iPad Safari both default to YES
//是否网页内容下载完毕才开始渲染web视图,默认NO
@property (nonatomic) BOOL suppressesIncrementalRendering NS_AVAILABLE_IOS(6_0); // iPhone and iPad Safari both default to NO
//设置用户交互 默认YES
@property (nonatomic) BOOL keyboardDisplayRequiresUserAction NS_AVAILABLE_IOS(6_0); // default is YES
//一种模式,枚举,当网页的大小超出View时,将网页以翻页的效果展示
typedef NS_ENUM(NSInteger, UIWebPaginationMode) {
UIWebPaginationModeUnpaginated, //不使用翻页效果
UIWebPaginationModeLeftToRight, //将网页超出部分分页,从左向右进行翻页
UIWebPaginationModeTopToBottom, //将网页超出部分分页,从上向下进行翻页
UIWebPaginationModeBottomToTop, //将网页超出部分分页,从下向上进行翻页
UIWebPaginationModeRightToLeft //将网页超出部分分页,从右向左进行翻页
} __TVOS_PROHIBITED;
@property (nonatomic) UIWebPaginationMode paginationMode NS_AVAILABLE_IOS(7_0);
@property (nonatomic) UIWebPaginationBreakingMode paginationBreakingMode NS_AVAILABLE_IOS(7_0); //设置分页模式
@property (nonatomic) CGFloat pageLength NS_AVAILABLE_IOS(7_0); //设置每一页的长度
@property (nonatomic) CGFloat gapBetweenPages NS_AVAILABLE_IOS(7_0); //设置每一页的间距
@property (nonatomic, readonly) NSUInteger pageCount NS_AVAILABLE_IOS(7_0); //分页数
//分屏中是否播放(iOS 9的新特性)
@property (nonatomic) BOOL allowsPictureInPictureMediaPlayback NS_AVAILABLE_IOS(9_0);
//长按链接是否支持预览(支持3D Touch的设备,iOS 9 新特性,默认:NO)
@property (nonatomic) BOOL allowsLinkPreview NS_AVAILABLE_IOS(9_0); // default is NO
UIWebView的方法
- (void)loadRequest:(NSURLRequest *)request; //设置加载URL请求
- (void)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL; //如果网页是国际通用的UTF-8编码的,也可以用这个方法加载数据。
- (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)textEncodingName baseURL:(NSURL *)baseURL; //以二进制的方式加载数据
- (void)reload; //刷新WebView页面
- (void)stopLoading; //停止加载WebView页面
- (void)goBack; //返回上一级
- (void)goForward; //跳转下一级
- (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script; //OC与JS交互
UIWebView的代理方法
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType; //webView即将加载的时候,通过返回值确定是否加载,是枚举值
typedef NS_ENUM(NSInteger, UIWebViewNavigationType) {
UIWebViewNavigationTypeLinkClicked, //点击了一个链接
UIWebViewNavigationTypeFormSubmitted, //提交了一个表单
UIWebViewNavigationTypeBackForward, //点击前进或者返回
UIWebViewNavigationTypeReload, //点击重新加载
UIWebViewNavigationTypeFormResubmitted, //重复提交表单
UIWebViewNavigationTypeOther //其他
} __TVOS_PROHIBITED;
- (void)webViewDidStartLoad:(UIWebView *)webView; //webView开始加载的时候
- (void)webViewDidFinishLoad:(UIWebView *)webView; //webView结束加载的时候
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error; //webView加载出错的时候
UIWebView中OC与JS交互
网页不仅是展示页面,也是一个交互页面,当用户想从网页调用系统方法,或者系统想更改网页的内容时,就涉及到了OC与JS之间的交互。OC与JS交互有多种方法。
OC 与 JS 交互方法一:
1.1 OC调用JS
OC调用JS指的是用户可以在手机上通过app对app里的网页进行增删改查,但是我们是不能直接修改网页的内容的,只能通过JS动态来修改。
总体来说如下是使用方法:
// OC -> JS
-(void)webViewDidFinishLoad:(UIWebView *)webView {
[webView stringByEvaluatingJavaScriptFromString :@“这里是JS语法”];
}
1.2 JS调用OC
JS调用OC一般是指,页面中某些功能需要调用系统的方法,html和JS无法直接和系统交互,只能通知web View,然后webView获取到消息,
传递OC实现JS调用OC,比如点击网页上的电话号码实现打电话的需求。
//JS -> OC
/*先在网页中设定好响应方法和协议,然后让网页响应这个协议并赋值给 window.location.href ,这样拦截所有请求的
shouldStartLoadWithRequest代理方法就会接收到这个规定好的协议,按照这个协议转化成SEL方法,
然后去执行就好了,就实现了JS 调用OC
*/
OC 与 JS 交互方法二:
iOS 7之后,苹果发布了JavaScriptCore.framework,它使得JS与OC的交互更加方便了。使用时首先导入JavaScriptCore库。
2.1 OC调用JS
举例如下:
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
//网页加载完成调用此方法
//首先创建JSContext 对象(此处通过当前webView的键获取到jscontext)
JSContext *context=[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
NSString *alertJS=@"alert('test js OC')"; //准备执行的js代码,此处为弹出alert “test js OC”
[context evaluateScript:alertJS];//通过oc方法调用js的alert
}
2.2 JS调用OC
JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
//未登录或者token失效,请求登录,toLoginByAPP是与服务器约定一致的方法名
context[@"toLoginByAPP"] = ^() {
NSLog(@"+++++++Begin toLoginByAPP+++++++");
NSArray *args = [JSContext currentArguments];
for (JSValue *jsVal1 in args) {
NSLog(@"toLoginByAPP:%@", jsVal1);
}
JSValue *this = [JSContext currentThis];
NSLog(@"toLoginByAPP——this: %@",this);
dispatch_async(dispatch_get_main_queue(), ^{
//登录的操作代码
});
NSLog(@"+++++++end toLoginByAPP+++++++");
};
OC 与 JS 交互方法三:
当然也有一些第三方实现交互的方式,这里就不再多说了。