当前位置: 首页 > news >正文

H5(WebView)跳Native(UIView)

做网络ios应用难免要用到UIWebViewController,直接嵌入一个html页面。这种native+web的方式再很多app中都有应用,app store就是一个,另外如淘宝iPhone客户端的支付,口碑网iPhone客户端的团购内容,等等。这种实现方式,某种程度上牺牲了一些体验,但大大提高了开发效率,而且降低了升级成本。这种方式非常适合实现一个仍处在发展初期的功能。

但使用native+web的方式有一个最大的问题,就是从WebView向NativeView的跳转。由于进入WebView后,页面中的链接都是web控制,所有点击都将在web框架内进行,无法返回到NativeView,给WebView的使用造成很大局限。这里介绍一下如何实现从WebView向NativeView的跳转。

实现原理很简单,在内嵌的页面里写一个规定格式的超链接,在WebViewController里抓载入状态,判断URL是否为约定的,按照约定跳转到相应的NativeView。

具体实现,先看WebViewDelegate里的几个方法:

- (BOOL)webView:(UIWebView *)webView
   shouldStartLoadWithRequest:(NSURLRequest *)request
   navigationType:(UIWebViewNavigationType)navigationType;
 
- (void)webViewDidStartLoad:(UIWebView *)webView;
 
- (void)webViewDidFinishLoad:(UIWebView *)webView;
 
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error;

这四个方法分别在不同时机被调用。第一个方法在页面请求发出之前被调用,第二个和第三个方法分别再页面内容开始载入和载入完成时被调用,最后一个是载入失败时被调用。

要抓请求状态需要在第一个方法中。因为页面中所写的URL是应用开发者约定的格式,而不是HTTP请求,因此这个请求无法成功发送,那么也就不会调用到第二和第三个方法,第四个方法用于异常处理,所以只能在第一个方法中抓请求状态。通过第一个方法的request参数,拿到request.URL,这个URL就是我们写在WebView上的,那么WebViewController就可以根据约定,判断出要跳转的NativeView,通过NavigationController跳转,或是实现其他逻辑。

在约定URL的时候还要注意,这个URL一定不要定义成一个HTTP请求。WebViewController就会自动处理HTTP请求,把请求发出去,页面也会发生重新载入,而这个请求是指向NativeView的,也就是不存在与Internet上,所以页面将出现404状态。

另外,如果WebView上指向NativeView的不是一个超链接,通过javascript方式也可以实现这个功能。只要通过JS把页面跳转到之前提到过的约定格式的URL就可以了。通过JS的方式,还可以实现WebView到NativeView的自动跳转。

 

 

附送把URL拆解的代码一份

 

ExtString.h

 

 
#define PROTOCOL	@"PROTOCOL"
#define HOST		@"HOST"
#define PARAMS		@"PARAMS"
#define URI			@"URI"
 
@interface ExtNSString : NSString {
}
 
@end
 
@interface NSString (ExtNSString)
 
/**
 *  @param NSString *URL 需要解析的URL,格式如:http://host.name/testpage/?keyA=valueA&keyB=valueB
 *  @return NSDictionary *params 从URL中解析出的参数表
 *    PROTOCOL 如 http
 *    HOST     如 host.name
 *    PARAMS   如 {keyA:valueA, keyB:valueB}
 *    URI      如 /testpage
 */
- (NSDictionary *)paramsFromURL;
 
@end

 

ExtString.m

 

#import "ExtNSString.h"
 
@implementation NSString (ExtNSString)
 
- (NSDictionary *)paramsFromURL {
 
	NSString *protocolString = [self substringToIndex:([self rangeOfString:@"://"].location)];
 
	NSString *tmpString = [self substringFromIndex:([self rangeOfString:@"://"].location + 3)];
	NSString *hostString = nil;
 
	if (0 < [tmpString rangeOfString:@"/"].length) {
		hostString = [tmpString substringToIndex:([tmpString rangeOfString:@"/"].location)];
	}
	else if (0 < [tmpString rangeOfString:@"?"].length) {
		hostString = [tmpString substringToIndex:([tmpString rangeOfString:@"?"].location)];
	}
	else {
		hostString = tmpString;
	}
 
	tmpString = [self substringFromIndex:([self rangeOfString:hostString].location + [self rangeOfString:hostString].length)];
	NSString *uriString = @"/";
	if (0 < [tmpString rangeOfString:@"/"].length) {
		if (0 < [tmpString rangeOfString:@"?"].length) {
			uriString = [tmpString substringToIndex:[tmpString rangeOfString:@"?"].location];
		}
		else {
			uriString = tmpString;
		}
	}
 
	NSMutableDictionary* pairs = [NSMutableDictionary dictionary];
	if (0 < [self rangeOfString:@"?"].length) {
		NSString *paramString = [self substringFromIndex:([self rangeOfString:@"?"].location + 1)];
		NSCharacterSet* delimiterSet = [NSCharacterSet characterSetWithCharactersInString:@"&;"];
		NSScanner* scanner = [[[NSScanner alloc] initWithString:paramString] autorelease];
		while (![scanner isAtEnd]) {
			NSString* pairString = nil;
			[scanner scanUpToCharactersFromSet:delimiterSet intoString:&pairString];
			[scanner scanCharactersFromSet:delimiterSet intoString:NULL];
			NSArray* kvPair = [pairString componentsSeparatedByString:@"="];
			if (kvPair.count == 2) {
				NSString* key = [[kvPair objectAtIndex:0]
								 stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
				NSString* value = [[kvPair objectAtIndex:1]
								   stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
				[pairs setObject:value forKey:key];
			}
		}
	}
 
	return [NSDictionary dictionaryWithObjectsAndKeys:
			pairs, PARAMS,
			protocolString, PROTOCOL,
			hostString, HOST,
			uriString, URI, nil];
}
 
@end
 
@implementation ExtNSString
@end

 

原文链接:http://pingguohe.net/2011/06/25/webview_to_nativeview/

转载于:https://www.cnblogs.com/ranger-jlu/p/3883837.html

相关文章:

  • poj 2888 Magic Bracelet
  • 导入【 http://ip.qq.com/js/geo.js】外部省市县三级地区到Mysql数据库
  • 前端代码风格自动化系列(二)之Commitlint
  • SharePoint 2013 Designer 入门教程
  • SparkStreaming的实战案例
  • const let
  • 冷启动问题:如何构建你的机器学习组合?
  • hive报错 Another instance of Derby may have already booted the database
  • iOS应用审核的通关秘籍【转】
  • QTP常用功能
  • TCP三次握手
  • (原創) X61用戶,小心你的上蓋!! (NB) (ThinkPad) (X61)
  • Windows和Linux环境下Memcached安装与配置(转)
  • 如何给wordpress首页自动显示文章内容的第一个图片
  • Azure Automation (3) 定期将某个Azure订阅下的所有虚拟机开关机
  • Apache Spark Streaming 使用实例
  • Java反射-动态类加载和重新加载
  • 工作手记之html2canvas使用概述
  • 和 || 运算
  • 基于 Babel 的 npm 包最小化设置
  • 基于MaxCompute打造轻盈的人人车移动端数据平台
  • 那些被忽略的 JavaScript 数组方法细节
  • Nginx惊现漏洞 百万网站面临“拖库”风险
  • ​queue --- 一个同步的队列类​
  • ( 10 )MySQL中的外键
  • (3)(3.5) 遥测无线电区域条例
  • (3)Dubbo启动时qos-server can not bind localhost22222错误解决
  • (android 地图实战开发)3 在地图上显示当前位置和自定义银行位置
  • (html转换)StringEscapeUtils类的转义与反转义方法
  • (ZT)一个美国文科博士的YardLife
  • (保姆级教程)Mysql中索引、触发器、存储过程、存储函数的概念、作用,以及如何使用索引、存储过程,代码操作演示
  • (二)什么是Vite——Vite 和 Webpack 区别(冷启动)
  • (附源码)ssm高校运动会管理系统 毕业设计 020419
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • *1 计算机基础和操作系统基础及几大协议
  • .bat批处理(一):@echo off
  • .cn根服务器被攻击之后
  • .NET 4 并行(多核)“.NET研究”编程系列之二 从Task开始
  • .Net 代码性能 - (1)
  • .Net语言中的StringBuilder:入门到精通
  • .so文件(linux系统)
  • ?php echo $logosrc[0];?,如何在一行中显示logo和标题?
  • [2008][note]腔内级联拉曼发射的,二极管泵浦多频调Q laser——
  • [2023-年度总结]凡是过往,皆为序章
  • [AX]AX2012 SSRS报表Drill through action
  • [bbk5179]第66集 第7章 - 数据库的维护 03
  • [BZOJ 3680]吊打XXX(模拟退火)
  • [CQOI 2010]扑克牌
  • [Erlang 0129] Erlang 杂记 VI 2014年10月28日
  • [IDF]啥?
  • [Java、Android面试]_05_内存泄漏和内存溢出
  • [JS入门到进阶] 前端开发不能写undefined?这是误区!
  • [Luogu 3958] NOIP2017 D2T1 奶酪
  • [PHP] 算法-顺时针打印矩阵的PHP实现
  • [pytest] 运行方式、常用参数、前后置条件