UIWebView的应用和其中的JS与OC间传值

现在有很多的应用已经采用了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啊,然后截了。

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

时间: 2024-08-10 19:13:20

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

UIWebView和WKWebView的使用及js交互

UIWebView和WKWebView的使用及js交互 web页面和app直接的交互是很常见的东西,之前尝试过flex和js的相互调用以及android和js的相互调用,却只有ios没试过,据说比较复杂.周末花了点时间研究了一下,确实和其他的不太一样,但是 也不见复杂. 要知道的事情 ios的webview有2个类,一个叫UIWebView,另一个是WKWebView.两者的基础方法都差不多,本文重点是后者,他是取代UIWebView出现的,在app开发者若不需要兼容ios8之前版本,都应该使用

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

http://blog.csdn.net/u011619283/article/details/52135977 最近准备把之前用UIWebView实现的JS与原生相互调用功能,用WKWebView来替换.顺便搜索整理了一下JS 与OC 交互的方式,非常之多啊.目前我已知的JS 与 OC 交互的处理方式: * 1.在JS 中做一次URL跳转,然后在OC中拦截跳转.(这里分为UIWebView 和 WKWebView两种,去年因为还要兼容iOS 6,所以没办法只能采用UIWebView来做.) *

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

1.HTML页面 1 <html> 2 3 <head> 4 5 <title>HTML中用JS调用OC方法</title> 6 7 <meta http-equiv="Content-Type"content="text/html; charset=UTF-8"> 8 9 <script> 10 11 function test() 12 13 { 14 15 alert("test

UIWebView中JS与OC交互 WebViewJavascriptBridge的使用

一.综述 现在很多的应用都会在多种平台上发布,所以很多程序猿们都开始使用Hybrid App的设计模式.就是在app上嵌入网页,只要写一份网页代码,就可以跑在不同的系统上.在iOS中,app多是通过WebView来加载网页,由于功能需求等原因,代码中少不得要和跟网页交互. 二.原理 在iOS中,本地调用Javascript语言,是通过UIWebView中的实例方法stringByEvaluatingJavaScriptFromString:来实现的,该方法通过字符串对象的形式传入JS代码. [w

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

来源:伯乐在线 - 键盘风筝 链接:http://ios.jobbole.com/89330/ 点击 → 申请加入伯乐在线专栏作者 其实一直想给大家整理一下JS与OC的交互,但是没有合适的机会,今天借着微信小应用的发布,以及以后H5必定越来越流行,所以给大家整理一下. 交互方式有三种: 1.UIWebviewDelegate 2.JavaScriptCore 3.WebViewJavascriptBridge按照排序给大家介绍一下,我推荐前两种方法,第三种需要依赖第三方框架,并且不一定能拦截成功

转载 【iOS开发】网页JS与OC交互(JavaScriptCore) OC -----&gt;JS

目标 本文介绍利用苹果在iOS7时发布的JavaScriptCore.framework框架进行js与OC的交互.我们想要达到的目标是: OC调用网页上的js方法 网页js调用APP中的OC方法 JavaSciptCore.framework框架介绍 JavaScriptCore是webkit的一个重要组成部分,主要是对js进行解析和提供执行环境.具体介绍请看这篇简书的文章:JavaScriptCore 使用 准备环境 创建一个名为JS与OC交互Demo的iOS工程.然后在storyboard添

转载 -- 基于原生JS与OC方法互相调用并传值(附HTML代码)

最近项目里面有有个商品活动界面,要与web端传值,将用户在网页点击的商品id 传给客户端,也就是js交互,其实再说明白一点就是方法的互相调用而已. 本文叙述下如何进行原生的JavaScript交互 本文包括JS调用OC方法并传值,OC调用JS方法并传值 本来想把html放进服务器里面,然后访问,但是觉得如果html在本地加载更有助于理解,特把html放进项目里 HTML代码 <!DOCTYPE html> <html> <head> <meta charset=&

Js与OC交互

Js与OC交互 源码请点击github地址下载. 下面讲述实现OC和JS的交互,它们相互调用,其中需要写一个静态的HTML文件用于提供JS方法. 效果图如下: screen.png 一.OC调用JS: 不说闲话,看代码如下 需要先在js文件定义方法postStr供oc调用 function postStr(string) { return 'I am the return parameter JS, and param ' + string; } oc代码只需一句即可调用 NSString *s

[ios]js调用oc代码(oc)

用途:在ios开发中,经常回用到js调用oc代码的时候,例如在网页上有个拍照和打电话的按钮,想打开系统自带的拍照和电话的时候,就需要用到js调用oc代码的功能. 实现原理:在webView加载html网页的时候,没当发送一个请求,就会调用<UIWebViewDelegate>代理的 - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIW