现在有很多的应用已经采用了WebView和html语言结合的开发模式。html5一直很火因为一份代码可以在多个平台上运用啊,效果各不相同都很美观,也越来越有一些公司直接招后台程序员和html5程序员,做完的产品再安卓也能用iOS也能用,不用再招双份的工程师了。应用程序一进去就全是UIWebView,里面发个请求到自己用html5做的页面,这就是一个应用!当然今天的主要不是说html5,是说html语言中JS代码和OC代码之间的传值。

先举例一个简单的用法:

我在模仿网易彩票做到设置页面的 常见问题板块时,扒到的素材是一个html网页格式的

也就是说只要设置好了这些按钮点进去都是一个页面,只是每一个按钮都绑定了一个 html.id的属性 ,会html语言的都知道 有了id属性可以直接跳到页面的该位置。

如图点击进入后 会跳到这个界面,点击了如何充值按钮,页面会自动跳到如何充值顶着边。如果点击了如何购彩,页面也会自动跳到自动购彩顶着边。当然了如果倒数第二个倒数第一个估计就跳不上去了,因为下面已经见底了拖上去会弹回来的所以跳不上去了,这点和C#开发的时候是一样的。

此功能的做法:

// 建立webView
UIWebView *web = (UIWebView *)self.view; // 发送请求前需要请求和请求的链接
NSURL *url = [[NSBundle mainBundle] URLForResource:_html.html withExtension:nil];
NSURLRequest *request = [NSURLRequest requestWithURL:url]; // $$$$$
[web loadRequest:request];
web.delegate = self;

首先要有webView啊,我是手码创建的

上面html是我的模型,html模型里html是一个链接打开本地的一个web文件。你也可以自己找好链接做一个plist再做一个模型

发送请求,接收数据之后,用webView加载数据

然后再给自己的webView设置代理为自己,然后遵守协议UIWebViewDelegate,就可以实现代理方法了

- (void)webViewDidFinishLoad:(UIWebView *)webView

这个方法在页面加载完成后会调用,在这个方法中来做些js的操作。

想做js的操作,一般都是先把你想要的js代码拼接接出一个字符串,再用这个方法传入这个字符串完成操作

    // 拼接一个脚本语言中的 自动定位代码
NSString *javascript = [NSString stringWithFormat:@"window.location.href = '#%@'",_html.ID]; // 加载完成后执行这个代码
[webView stringByEvaluatingJavaScriptFromString:javascript];

里面的html.ID是字符串中的一个id属性,控制往哪跳的。

这样核心功能就完成了。

下面再说一个高级点的用法

这是我在模仿网易新闻时做到的新闻详情界面,

如图点击其中的这个库里上篮这一行,进入的新闻详情页面是用html做的,扒到的数据就是这样了,但是数据只有乱七八糟的一大串字符,需要自己排版的,特别是图文混排有点麻烦。。这里今天就不说了,今天主要说下JS和OC间如何传值,关于图文混排 过几天有时间了再详细写一篇。(欢迎关注我评论我)

进去之后是一个新闻详情页面,里面是有图片的,有的图片很好看我就想保存,但是问题来了,webView里面的图片都是<div><img height= src=></img>什么什么的不是UI控件按钮可以绑定事件,imgView至少也可以监听手势点击,这个是网页啊,如何做到点击图片下面弹出一个shit问你保不保存?

这就用到JS代码和OC代码见的传值了,

一般大概思路是这边发请求,那边把请求拦下来,再扒出请求url里的字符串,再各种截取得到有用的数据

核心思路如下,从一半开始截的

 NSString *onload = @"this.onclick = function() {"
" window.location.href = 'sx:src=' +this.src;"
"};";
[imgHtml appendFormat:@"<img onload=\"%@\" width=\"%f\" height=\"%f\" src=\"%@\">",onload,width,height,detailImgModel.src];
// 结束标记
[imgHtml appendString:@"</div>"];
// 替换标记
[body replaceOccurrencesOfString:detailImgModel.ref withString:imgHtml options:NSCaseInsensitiveSearch range:NSMakeRange(0, body.length)];
}
return body;

其中onload就是加载完毕后才用,然后onclick是JS里的点击触发,window.location.href 是跳往哪里,后面是一个url 里面的协议头是sx:src= 后面是自己图片的src。 SX是我自己的符号。

就相当于我自己乱写了一个协议头sx://www.啥 ,有了协议头这就是一个跳转网页的请求 但是要注意的是,我把// 和www啥的省略了 但是前面这个sx:src=不能再省略了,如果再省略就不是协议头了,苹果就会自己给你加一个他的协议头很长很乱 后面接不住了。

然后写这个方法 ,webView的代理方法

这个方法是在即将发送请求时会被调用,返回值是一个BOOL类型,说白了就是让你控制什么请求允许发出去,什么请求拦下。

NSString *url = request.URL.absoluteString;
NSRange range = [url rangeOfString:@"sx:src="];
if (range.location != NSNotFound) {
NSInteger begin = range.location + range.length;
NSString *src = [url substringFromIndex:begin];
[self savePictureToAlbum:src];
return NO;
}
return YES;

先取出这个请求的全url再算出sx:src=这个字符串的范围,如果是别的真正的请求,是取不到值的,就是NSNotFound,这是允许发出去的

如果取到range了 那就是我写的这个请求,就从这个范围往后的字符串全截取下来,这就是html代码里那个图片的地址了this.src。

然后有了url链接就可以保存到相册了。

保存到相册那个方法里,有两种选择一种是重新下载保存,一种是从缓存中取,这种比较省流量。

        NSURLCache *cache =[NSURLCache sharedURLCache];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:src]];
NSData *imgData = [cache cachedResponseForRequest:request].data;
UIImage *image = [UIImage imageWithData:imgData];
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);

应该都能看懂的吧,大意就是通过这个url找到我上次请求中用这个url弄到的响应数据再转化成图片保存入相册。

到此就完成了JS与OC间的传值

当然如果只有这样那还远远不够

这里是只有一个保存图片的方法,如果以后又有很多需要拦截的方法,打电话或者发短信等各种各样的方法,都要一一判断就太麻烦了。

聪明的做法是把 需要调用的方法名 和 要传的参数 都通通写在url里让我拦

比如sx:call:&10086

然后我通过字符串的切割就可以 得到一个方法名 call:和一个参数10086

就可以调用- (void)call:(NSString *)phoneNumber  这个方法了。

NSRange range = [url rangeOfString:@"sx:"];
if (range.location != NSNotFound) {
NSUInteger loc = range.location + range.length;
NSString *path = [url substringFromIndex:loc];
// 获得方法和参数
NSArray *methodNameAndParam = [path componentsSeparatedByString:@"&"];
// 方法名
NSString *methodName = [methodNameAndParam firstObject];
// 调用方法
SEL selector = NSSelectorFromString(methodName);
if ([self respondsToSelector:selector]) { // 判断方法的目的: 防止因为方法不存在而报错

这一串代码写的很清楚了,获得方法名和参数,把字符串转化成SEL 然后下面就可以这么写了

调用打电话方法 call 传的值是 10086

如果遇到了有的方法需要传多个值。那就该这么写

sx:sendMsg:body:&18686652446&loveyou

通过切割可以得到方法名是 sendMsg:body:  要传的参数用&切开 就是这个(componentsSeparatedByString:@"&")得到两个参数电话号码和信息内容

然后就可以调用这个方法了

这里我要说一下

如果要传入3个4个好多个参数,要用到一个第三方框架

//  Copyright (c) 2015年 shangxianDante. All rights reserved.
// #import <Foundation/Foundation.h> @interface NSObject (Extension)
- (id)performSelector:(SEL)selector withObjects:(NSArray *)objects; @end
//  Copyright (c) 2015年 shangxianDante. All rights reserved.
// #import "NSObject+Extension.h" @implementation NSObject (Extension)
- (id)performSelector:(SEL)selector withObjects:(NSArray *)objects {
NSMethodSignature *signature = [self methodSignatureForSelector:selector];
if (signature) {
NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setTarget:self];
[invocation setSelector:selector];
for(int i = 0; i < [objects count]; i++){
id object = [objects objectAtIndex:i];
[invocation setArgument:&object atIndex: (i + 2)];
}
[invocation invoke];
if (signature.methodReturnLength) {
id anObject;
[invocation getReturnValue:&anObject];
return anObject;
} else {
return nil;
}
} else {
return nil;
}
}
@end

然后就可以用这个方法啦

最后我想再说个简单的小技巧

就是因为现在html5很火,就是一份代码在电脑是一个界面在手机又是一个界面,很漂亮。有时候可以直接搬过来用但是最下面的页脚(也许是广告)又不想要,就可以直接截了,把人家网站搬过来再把人家的页脚截了,有意思吧

- (void)viewDidLoad {
[super viewDidLoad]; NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://v3.bootcss.com/"]];
self.webView.delegate = self;
[self.webView loadRequest:request];
} #pragma mark - ******************** web代理方法
/**
* 网页加载完毕后调用
*/
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
NSString *js = @"document.getElementsByTagName('footer')[0].remove();";
[webView stringByEvaluatingJavaScriptFromString:js];

当然首先你肯定要用浏览器的开发者工具找到页脚这部分板块的名字叫footer啊,然后截了。

(董铂然博客所有文章都是原创欢迎评论和关注)

UIWebView的应用和其中的JS与OC间传值的更多相关文章

  1. 【转】使用JavaScriptCore在JS和OC间通信

    http://www.cocoachina.com/ios/20160623/16796.html iOS 开发中,我们时不时的需要加载一些 Web 页面,一些需求使用 Web 页面来实现可以更可控, ...

  2. JS和OC间的通信(使用JavaScriptCore)

    JavaScriptCore 时代的通讯 iOS 7 开始,苹果提供了一个叫作 JavaScriptCore 的框架,使用 JavaScriptCore 框架可以实现 OC 和 JS 的互相调用,而不 ...

  3. iOS下JS与OC互相调用(五)--UIWebView + WebViewJavascriptBridge

    WebViewJavascriptBridge是一个有点年代的JS与OC交互的库,使用该库的著名应用还挺多的,目前这个库有7000+star.我去翻看了它的第一版本已经是4年前了,在版本V4.1.4以 ...

  4. iOS下JS与OC互相调用(六)--WKWebView + WebViewJavascriptBridge

    上一篇文章介绍了UIWebView 如何通过WebViewJavascriptBridge 来实现JS 与OC 的互相调用,这一篇来介绍一下WKWebView 又是如何通过WebViewJavascr ...

  5. [iOS Hybrid实践:UIWebView中Html中用JS调用OC方法,OC执行JS代码]

    原理: 1.JS调用OC 每次webview执行跳转时都会被iOS给拦截,执行下面函数获得系统允许. 因此可以根据跳转信息转给系统,执行相应功能,比如打开相册等. // 网页中的每一个请求都会被触发 ...

  6. UIWebView中Html中用JS调用OC方法及OC执行JS代码

    HTML代码: <html> <head> <title>HTML中用JS调用OC方法</title> <meta http-equiv=&quo ...

  7. 史上最全的 UIWebview 的 JS 与 OC 交互

    来源:伯乐在线 - 键盘风筝 链接:http://ios.jobbole.com/89330/ 点击 → 申请加入伯乐在线专栏作者 其实一直想给大家整理一下JS与OC的交互,但是没有合适的机会,今天借 ...

  8. iOS下JS与OC互相调用(一)--UIWebView 拦截URL

    最近准备把之前用UIWebView实现的JS与原生相互调用功能,用WKWebView来替换.顺便搜索整理了一下JS 与OC 交互的方式,非常之多啊.目前我已知的JS 与 OC 交互的处理方式: * 1 ...

  9. UIWebView中JS与OC交互 WebViewJavascriptBridge的使用

    一.综述 现在很多的应用都会在多种平台上发布,所以很多程序猿们都开始使用Hybrid App的设计模式.就是在app上嵌入网页,只要写一份网页代码,就可以跑在不同的系统上.在iOS中,app多是通过W ...

随机推荐

  1. 【Java基础】RTTI与反射之Java

    一.引言 很多时候我们的程序可能需要在运行时识别对象和类的信息,比如多态就是基于运行时环境进行动态判断实际引用的对象.在运行时识别对象和类的信息主要有两种方式:1.RTTI,具体是Class对象,它假 ...

  2. Laravel5设计json api时候的一些道道

    对于返回数据格式没规整的问题 在开发api的时候,这个问题是和客户端交涉最多的问题,比如一个user结构,返回的字段原本是个user_name的,它应该是string类型.但是呢,由于数据库设计这个字 ...

  3. 解决The file “FWLifeApp” couldn’t be opened because you don’t have permission to view it.问题

    The file “FWLifeApp” couldn’t be opened because you don’t have permission to view it问题是因为项目文件中的Bundl ...

  4. Python语言特性之3:@staticmethod和@classmethod

    问题:Python中@staticmethod和@classmethod两种装饰器装饰的函数有什么不同? 原地址:http://stackoverflow.com/questions/136097/w ...

  5. Sublime Text2配置过程

    今天Sublime Text2不知道为什么突然崩溃了,一直不能运行,没办法只有重装了,重装后按我的用途重新配置了一下,现将配置过程记录下来以备将来不时之需 说明:配置是在windows系统上进行的,其 ...

  6. 从C#到Objective-C,循序渐进学习苹果开发(1)--准备开发账号和开发环境

    本随笔系列主要介绍从一个Windows平台从事C#开发到Mac平台苹果开发的一系列感想和体验历程,本系列文章是在起步阶段逐步积累的,希望带给大家更好,更真实的转换历程体验,因为一旦方方面面都精通了,也 ...

  7. 常用的一些SQL语句整理,也许有你想要的。

    本篇文章是对一些常用的sql语句进行了总结与分析,需要的朋友参考下,也许会有你需要的. 1.SQL行列转换 问题:假设有张学生成绩表(tb)如下:姓名 课程 分数张三 语文 74张三 数学 83张三 ...

  8. C#编程总结(六)异步编程

    C#编程总结(六)异步编程 1.什么是异步? 异步操作通常用于执行完成时间可能较长的任务,如打开大文件.连接远程计算机或查询数据库.异步操作在主应用程序线程以外的线程中执行.应用程序调用方法异步执行某 ...

  9. Ado.net 三[SQL注入,DataAdapter,sqlParameter,DataSet]

    1.SQL注入:SQL注入攻击是web应用程序的一种安全漏洞,可以将不安全的数据提交给运用程序,使应用程序在服务器上执行不安全的sql命令.使用该攻击可以轻松的登录运用程序. 例如:该管理员账号密码为 ...

  10. 启用数据库的 Service Broker

    --is_broker_enabled为0未启用,为1启用SELECT name,is_broker_enabled FROM sys.databases WHERE name = 'DBNAME' ...