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 ...
随机推荐
- SQL-PIVOT 数据透视 行列转换
-- 数据透视 -- PIVOT: 行转列 SELECT * FROM ( SELECT N'张三' AS 姓名, N'语文' AS 课程,70 AS 分数 UNION SELECT ...
- hdu1074 Doing Homework
这题比较有意思,暴力搜索必然tle,可以用状态压缩dp解决. 我们先不考虑完成所有作业的扣分,而考虑其一个子集的情况. 假设我们得到了完成某子集S对应的作业最少扣分,我们试着向该子集中增加一个元素a, ...
- U3D刚体测试2(ForceMode,AddForce,RelativeAddForce)
摘自圣典的一段翻译: ForceAdd a continuous force to the rigidbody, using its mass.添加一个可持续力到刚体,使用它的质量.Accelerat ...
- 更新yum源
见地址: http://www.cnblogs.com/lightnear/archive/2012/10/03/2710952.html 163的不好用,执行失败,用alibaba的没有问题,如下: ...
- Git合并开发代码分支到测试代码分支
——转载请注明出自天外归云的博客园 用TortoiseGit下载代码到本地 首先需要在本机安装好TortoiseGit.然后在随便哪个路径下比如D盘,右键“Git Clone”: 然后URL处选择项目 ...
- androidactivity与webview结合
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android=" ...
- mysql更改已有数据表的字符集,保留原有数据内容
mysql更改已有数据表的字符集,保留原有数据内容 原文网址:http://blog.csdn.net/learn_2/article/details/6460370 环境:在应用开始阶段没有 ...
- HTTP和FTP的区别
原文地址: http://blog.csdn.net/xiaoxiangzhu660810/article/details/8291656 一.字面上来看 HTTP是Hyper Text Tr ...
- shutdown命令
其实不需要使用软件,就可以实现自动关机或重启等功能的:Windows XP的关机是由Shutdown.exe程序来控制的,位于Windows\System32文件夹中.如 果想让Windows 200 ...
- [Gym]2008-2009 ACM-ICPC, NEERC, Moscow Subregional Contest
比赛链接:http://codeforces.com/gym/100861 A模拟,注意两个特殊的缩写. #include <bits/stdc++.h> using namespace ...