ios中javascript直接调用oc代码而非通过改变url回调方式(转)
之前一个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的交互
ios中javascript直接调用oc代码而非通过改变url回调方式(转)的更多相关文章
- C++中调用OC代码
前言 最近项目中为了方便维护,底层统一使用C++编写.由于是项目是做屏幕共享sdk,所以只能底层的压缩.编解码使用C++,屏幕捕获部分Mac和win就自己实现了.那么问题就来了,因为是面向接口编程,所 ...
- 如何实现 javascript “同步”调用 app 代码
在 App 混合开发中,app 层向 js 层提供接口有两种方式,一种是同步接口,一种一异步接口(不清楚什么是同步的请看这里的讨论).为了保证 web 流畅,大部分时候,我们应该使用异步接口,但是某些 ...
- iOS-JS调用OC代码
监听时间点击 改变当前浏览器窗口地址 在js里调用OC代码,需要在网页上写一个协议,不是http协议 然后在OC的webView shouldStartloadWithRequest
- iOS中JavaScript和OC交互
转载自:http://www.devzeng.com/blog/ios-uiwebview-interaction-with-javascript.html 还可参考的文章:http://blog.c ...
- iOS中JavaScript和OC交互 --by 胡 xu
在iOS开发中很多时候我们会和UIWebView打交道,目前国内的很多应用都采用了UIWebView的混合编程技术,最常见的是微信公众号的内容页面.前段时间在做微信公众平台相关的开发,发现很多应用场景 ...
- 在 Swift 中调用 OC 代码
前言 在 Swift 语言中,我们可以使用 Objective-C.C 语言编写代码,我们可以导入任意用 Objective-C 写的 Cocoa 平台框架.Objective-C 框架或 C 类库. ...
- ios--网页js调用oc代码+传递参数+避免中文参数乱码的解决方案(实例)
此解决方案原理: 1.在ViewController.h中声明方法和成员变量,以及webView的委托: // // ViewController.h // JS_IOS_01 // // Cr ...
- 1.JAVA中使用JNI调用C++代码学习笔记
Java 之JNI编程1.什么是JNI? JNI:(Java Natibe Inetrface)缩写. 2.为什么要学习JNI? Java 是跨平台的语言,但是在有些时候仍然是有需要调用本地代码 ( ...
- 03_Android NDK中C语言调用Java代码,javah的使用,javap的使用以及生成签名,Android.mk的编写,C代码的编写
1 案例场景,通过C语言回调Java的代码,案例的最终界面: 2 案例的代码结构如下: 3 编写DataProvider的代码: package com.example.ndkcallbac ...
随机推荐
- Cimg代码初探
Cimg代码初探 程序设计最为激动人心的地方,在于丰富的并且容易被查阅到资料.比如对于图像处理,固然有Opencv等较为丰富.被广泛知晓的类库:也有其他很多具有一定特色的类库.在这段时间里面, ...
- Resilio(BtSync)搭建
Resilio(原名:BtSync)介绍 同步是使用PC和Mac,NAS,甚至服务器之间传输文件的最好方法.创建自己的私有云.连接设备和同步文件安全,不发送他们在第三方服务器.我们不限制你的速度和存储 ...
- Python 中对文件的输入输出
#! /usr/bin/python # Filename:using_file.py poem = '''\ Programming is fun When the work is done if ...
- CSS之盒子模型
CSS核心内容 源文件目录: D:\Users\ylf\Workspaces\MyEclipse 10 标准流 盒子模型 浮动 定位 标准流/非标准流: 标准流:就是普通的 非标准流:实际工作中要打破 ...
- Datagrid扩展方法InitEditGrid{支持单元格编辑}
//-----------------------------------------------------------------/******************************** ...
- 2016年11月20日 星期日 --出埃及记 Exodus 20:11
2016年11月20日 星期日 --出埃及记 Exodus 20:11 For in six days the LORD made the heavens and the earth, the sea ...
- merge into的用法
merge into 是英文的一个短语,意思是汇入,合并.顾名思义,merge into是合并了insert和update操作,其执行效率要高于分别单独执行insert和update语句. //创建表 ...
- MySQL(三) —— 约束以及修改数据表
约束: 1. 约束保证数据的完整性和一致性: 2. 约束分为表级约束和列级约束: 3. 约束类型包括:NOT NULL, PRIMARY KEY, UNIQUE KEY, DEFAULT, FOREI ...
- Have You Ever Wondered About the Difference Between NOT NULL and DEFAULT?
https://blog.jooq.org/2014/11/11/have-you-ever-wondered-about-the-difference-between-not-null-and-de ...
- Codeforces Round #249 (Div. 2)B(贪心法)
B. Pasha Maximizes time limit per test 1 second memory limit per test 256 megabytes input standard i ...