之前一个ios项目中,需要通过UIWebview来打开一个静态页面,并在静态页面中

调用相关object-c代码。

一、以前使用js调用object-c的方法

关于如何使用javascript调用object-c中的函数和方法,我搜索了好久

网上所有的方法,基本都指明了一个方向,那就是在UIWebview中载入的js代码中

通过改变document.locations=“”,然后回调UIWebview的

-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType

函数,在上面这个函数中,通过截取NSURLRequest解析js中传递过来的参数,再根据参数

来选择早已定义好的方法。

有没有别的方法呢? 我找了几个月,没找到!但是有一个转机。

我偶然知道了 javascriptCore.framework 这个库

于是事情有了转机。

二、在js中直接调用oc的方法

废话不多说,现在看看如何在UIWebView的javascript中调用oc的方法

首先在建立一个UIWebView,代码如下:

 //
// webview.m
// login
//
// Created by wangdan on 15-3-19.
// Copyright (c) 2015年 wangdan. All rights reserved.
// #import "webview.h"
#import <javascriptcore javascriptcore.h=""> @implementation webview -(id)initWithFrame:(CGRect)frame
{
self=[super initWithFrame:frame]; if( self ){
self.webview=[[UIWebView alloc]initWithFrame:CGRectMake(, , self.bounds.size.width, )];
self.webview.backgroundColor=[UIColor lightGrayColor];
NSString *htmlPath=[[NSBundle mainBundle] resourcePath];
htmlPath=[htmlPath stringByAppendingPathComponent:@"html/index.html"];
NSURL *localURL=[[NSURL alloc]initFileURLWithPath:htmlPath];
[self.webview loadRequest:[NSURLRequest requestWithURL:localURL]];
[self addSubview:self.webview]; JSContext *context = [self.webview valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
context[@"log"] = ^() { NSLog(@"+++++++Begin Log+++++++");
NSArray *args = [JSContext currentArguments]; for (JSValue *jsVal in args) {
NSLog(@"%@", jsVal);
} JSValue *this = [JSContext currentThis];
NSLog(@"this: %@",this);
NSLog(@"-------End Log-------"); }; // [context evaluateScript:@"log('ider', [7, 21], { hello:'world', js:100 });"]; }
return self;
} @end</javascriptcore>

(1)在上述代码中,使用javascriptCore.framework,首先使用UIWebview加载一个静态网页,并

使用

JSContext *context = [self.webview valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

获取该UIWebview的javascript执行环境。

(2)在该javascript执行环境中,定义一个js函数,注意关键点来了

这个函数的执行体完全是 objective-c代码写的,也就是下面:

 context[@"jakilllog"] = ^() {

         NSLog(@"Begin Log");
NSArray *args = [JSContext currentArguments]; for (JSValue *jsVal in args) {
NSLog(@"%@", jsVal);
} JSValue *this = [JSContext currentThis];
NSLog(@"-------End Log-------"); };

(3)试想一下,在定义的webview中,如果使用js执行log这个函数,那么会不会调用上面oc中block段代码呢,答案是肯定的!

下面看看UIWebView 中所加载的 html及其js代码是如何写的

(4)index.html代码

<!--//  Created by wangdan on 15-3-19.-->
<!--// Copyright (c) 2014年 wangdan. All rights reserved.-->
<script type="text/javascript" src="index.js"></script>点击button

上面html定义了一个button,然后引用index.js,点击button的响应函数为buttonClick()

该函数在index.js中定义,如下

 function buttonClick()
{
jakilllog("hello world");
}

意思是点击这个button,就调用jakilllog()函数,jakilllog()函数显然是我们在oc中实现的一个block段,

就是上述绿色部分的block段。

点击button会执行么?答案是肯定的。

下面上图

下图是执行的结果

点击html中的button,能够执行oc中的代码

说明直接从js调用oc的意图达到。

转至:http://www.2cto.com/kf/201503/383795.html

这里还有几篇很详细的介绍:

iOS开发之Objective-C与JavaScript的交互

ios7 JavaScriptCore.framework

ios中javascript直接调用oc代码而非通过改变url回调方式(转)的更多相关文章

  1. C++中调用OC代码

    前言 最近项目中为了方便维护,底层统一使用C++编写.由于是项目是做屏幕共享sdk,所以只能底层的压缩.编解码使用C++,屏幕捕获部分Mac和win就自己实现了.那么问题就来了,因为是面向接口编程,所 ...

  2. 如何实现 javascript “同步”调用 app 代码

    在 App 混合开发中,app 层向 js 层提供接口有两种方式,一种是同步接口,一种一异步接口(不清楚什么是同步的请看这里的讨论).为了保证 web 流畅,大部分时候,我们应该使用异步接口,但是某些 ...

  3. iOS-JS调用OC代码

    监听时间点击 改变当前浏览器窗口地址 在js里调用OC代码,需要在网页上写一个协议,不是http协议 然后在OC的webView shouldStartloadWithRequest

  4. iOS中JavaScript和OC交互

    转载自:http://www.devzeng.com/blog/ios-uiwebview-interaction-with-javascript.html 还可参考的文章:http://blog.c ...

  5. iOS中JavaScript和OC交互 --by 胡 xu

    在iOS开发中很多时候我们会和UIWebView打交道,目前国内的很多应用都采用了UIWebView的混合编程技术,最常见的是微信公众号的内容页面.前段时间在做微信公众平台相关的开发,发现很多应用场景 ...

  6. 在 Swift 中调用 OC 代码

    前言 在 Swift 语言中,我们可以使用 Objective-C.C 语言编写代码,我们可以导入任意用 Objective-C 写的 Cocoa 平台框架.Objective-C 框架或 C 类库. ...

  7. ios--网页js调用oc代码+传递参数+避免中文参数乱码的解决方案(实例)

    此解决方案原理: 1.在ViewController.h中声明方法和成员变量,以及webView的委托: // //  ViewController.h //  JS_IOS_01 // //  Cr ...

  8. 1.JAVA中使用JNI调用C++代码学习笔记

    Java 之JNI编程1.什么是JNI? JNI:(Java Natibe Inetrface)缩写. 2.为什么要学习JNI?  Java 是跨平台的语言,但是在有些时候仍然是有需要调用本地代码 ( ...

  9. 03_Android NDK中C语言调用Java代码,javah的使用,javap的使用以及生成签名,Android.mk的编写,C代码的编写

     1  案例场景,通过C语言回调Java的代码,案例的最终界面: 2  案例的代码结构如下: 3 编写DataProvider的代码: package com.example.ndkcallbac ...

随机推荐

  1. 2016年11月25日 星期五 --出埃及记 Exodus 20:16

    2016年11月25日 星期五 --出埃及记 Exodus 20:16 "You shall not give false testimony against your neighbor.不 ...

  2. 解决discuz论坛搬家:“Table ‘common_syscache’ is read only”问题

    解决discuz论坛搬家:“Table ‘common_syscache’ is re http://www.zixuephp.com/wzht/discuz/20141203_11562.html ...

  3. mysql分库分表

    1.分库分表 很明显,一个主表(也就是很重要的表,例如用户表)无限制的增长势必严重影响性能,分库与分表是一个很不错的解决途径,也就是性能优化途径,现在的案例是我们有一个1000多万条记录的用户表mem ...

  4. Arduino中的setup()和loop()函数

    今天看arduino的源代码,对于arduino中的setup和loop有了新的理解,可能你以前对于这俩个函数就是知道arduino是初始化,而loop是死循环,但是托若你看了Arduino的主函数你 ...

  5. easyui DataGrid 的 Checkbox 选择多行

    这么一来在取得 DataGrid 的 Checkbox 有勾选的数据值就可以沿用方式一的程序, 1.$('#ButonGetCheck').click(function(){ 2.var checke ...

  6. mfc线程

    1.生成线程 方式1. HANDLE hthread; //线程句柄 hthread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)threadFunc,NU ...

  7. RS485模块(485与TTL信号的转换)

    1 综述 MAX3483, MAX3485, MAX3486, MAX3488, MAX3490以及MAX3491是用于RS-485与RS-422通信的3.3V,低功耗收发器,每个器件中都具有一个驱动 ...

  8. 如何使用同一个Action中的不同方法

    如何使用同一个Action中的不同方法 1.使用Action的DMI(Dynamic Method Invocation--动态方法调用) (1)动态方法调用: 表单元素的action不是直接为某个A ...

  9. H5网站借鉴

    http://www.rdinfo.com.cn/index.shtml http://www.winployee.com/ http://www.lkkdesign.com/ http://www. ...

  10. MVC开发模式

     关于mvc详情可参阅:http://www.w3school.com.cn/aspnet/mvc_intro.asp MVC (Modal View Controler)本来是存在于Desktop程 ...