zoukankan      html  css  js  c++  java
  • 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/
  • 相关阅读:
    Mat
    分治法-最近点对问题
    动态规划作业-最长公共子序列问题
    动态规划作业-多段图的最短路径问题
    OpenCV+VisualStudion2017配置
    R入门(二)-对象以及它们的模式和属性
    Big number
    R入门(一)
    Spring-aop
    Spring-ioc
  • 原文地址:https://www.cnblogs.com/ranger-jlu/p/3883837.html
Copyright © 2011-2022 走看看