iOS iOS与html进行交互

实现的

效果就是上边那样:首先通过webview 进行网络请求 然后进行显示。

         然后点击下一页的按钮 通过js的响应显示另一个网页

         最后通过下一页的按钮可以返回到首页。

    本文仅仅是h5跟ios 的交互的入门 所以没有做细致的描述。

首先先说一下思路:我的项目中是那样的:首先h5从后台拿到数据,然后我请求h5的界面,然后通过h5的按钮进行选择,通过ios控制按钮到那个界面。

这个小demo不涉及数据传输,只是界面的交互。

1 我自己写了两个小网页。

代码如下

首页的indexPage.html

<!DOCTYPE html>
<html>
 <head>
 <meta charset="UTF-8">
 <title></title>
 </head>
 <body>
 <button onclick="next()">nextPage(下一页)</button>
 </body>
 <script>
 alert("123");
 function next(){
 WOSS.goForward("下一页","http://127.0.0.1:8020/HelloHBuilder/index2.html");
 }
 </script>
</html>

第二个界面的html index2.html

<!DOCTYPE html>
<html>
 <head>
 <meta charset="UTF-8">
 <title></title>
 <br />
 <label>这是第二个网页,欢迎你跳转成功了</label>
 <button onclick="returnFirst()">返回首页</button>
 </head>
 <body>
 </body>
 <script>
 function returnFirst(){
  WOSS.goHome("返回","http://127.0.0.1:8020/HelloHBuilder/index1.html#");
 }
 </script>
</html>

2 进行ios代码的编写

  (1)创建Navigation.h

#import <UIKit/UIKit.h>

@interface LSNavigation : UINavigationController

@end

   Navigation.m

#import "LSNavigation.h"

@implementation LSNavigation

@end

 (2)appDelegate的设置

appDelegate.h

#import <UIKit/UIKit.h>
#import "LSNavigation.h"
@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@property (strong, nonatomic) LSNavigation  *baseNavigationController;
@end

 appdelagete.m

#import "AppDelegate.h"
#import "LSNavigation.h"
#import "LSWebVC.h"
@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.baseNavigationController = [[LSNavigation alloc] init];
    self.window.rootViewController  = self.baseNavigationController;
    LSWebVC *vc = [[LSWebVC alloc]init];
    [self.baseNavigationController pushViewController:vc animated:YES];
    return YES;
}

(3)创建:LSwebViewVC用来显示加载webView

webVIewVC.h

#import <UIKit/UIKit.h>
#import <JavaScriptCore/JavaScriptCore.h>
@interface LSWebVC : UIViewController
@property (nonatomic,strong) UIWebView *webView;
//@property (nonatomic,assign) BOOL needRefresh;
@property (nonatomic,copy) NSString *webTitle;
@property (nonatomic,copy) NSString *webUrl;
@end

webViewVC.m

#import "LSWebVC.h"
#import "LSInterActive.h"
@interface LSWebVC()<UIWebViewDelegate>
@property (nonatomic,strong) JSContext *context;

@end
@implementation LSWebVC
-(void)viewDidLoad
{
    _webView = [[UIWebView alloc]initWithFrame:CGRectMake(0, 0,([UIScreen mainScreen].bounds.size.width ) , ([UIScreen mainScreen].bounds.size.height))];
    self.view.backgroundColor = [UIColor yellowColor];
    
       self.title = self.webTitle;
   
    
    self.webView.delegate = self;
    [self.view addSubview:self.webView];
    if(!self.webUrl)
    {
        self.webUrl=@"http://127.0.0.1:8020/HelloHBuilder/indexPage.html";

    }else{
        
        self.webUrl = [self.webUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    }
    NSURL *url = [NSURL URLWithString:self.webUrl];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20];
    [self.webView loadRequest:request];
}
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
    self.context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    self.context.exceptionHandler = ^(JSContext *con, JSValue *exception) {
        NSLog(@"exception==========================================================:%@", exception);
        con.exception = exception;
    };
    //设置对象别名
    
     LSInterActive *interactive = [[LSInterActive alloc] init];
    self.context[@"WOSS"] = interactive;

}
@end

(4)创建进行点击交互的类(用于存放一些点击事件交互用)

 LSINterActive.h

#import <Foundation/Foundation.h>
#import <JavaScriptCore/JavaScriptCore.h>
@protocol FCInteractiveProtocol <JSExport>
//1.1前进         //goForward(title,forwardUrl)
- (void)go:(NSString *)title forward:(NSString *)url;

- (void)go:(NSString *)title home:(NSString *)url;
@end

@interface LSInterActive : NSObject<FCInteractiveProtocol>

@end

 LSInterActive.m

#import "LSInterActive.h"
#import "LSWebVC.h"
#import "LSNavigation.h"
#import "AppDelegate.h"

@implementation LSInterActive

//下一页
-(void)go:(NSString *)title forward:(NSString *)url
{
    NSLog(@"FCInteractive-------goForward:%@,%@",title,url);
    
    //当前是异步线程
    dispatch_async(dispatch_get_main_queue(), ^{
        AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
        LSNavigation *navi = delegate.baseNavigationController;
        LSWebVC *nextVc = [[LSWebVC alloc] init];
        nextVc.webTitle = title;
        nextVc.webUrl = url;
        [navi pushViewController:nextVc animated:YES];
    });
}

//返回主页
- (void)go:(NSString *)title home:(NSString *)url{
    NSLog(@"FCInteractive-------goHome:%@,%@",title,url);
    //当前是异步线程
    dispatch_async(dispatch_get_main_queue(), ^{
        AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
        LSNavigation *navi = delegate.baseNavigationController;
        
        UIViewController *vc = navi.viewControllers[0];
        if ([vc isKindOfClass:[LSWebVC class]]) {
            LSWebVC *firstVc = (LSWebVC *)vc;
           // firstVc.needRefresh = YES;
        }
        [navi popToRootViewControllerAnimated:YES];
    });
}

@end

这样的话就可以了。简单的实现了交互。如有不足,欢迎指出 本人邮箱673658917@qq.com

------------------------补充分界线-------------------------------------------------------------------------

最近又在看oc与h5交互,所以又补充一点,就是 例如你在原生的界面登录成功之后怎么给html界面把值传过去?

我这边采用的方式是:通知传值的方式

思路: 在webviewVC的界面初始化的时候就要把通知加上 然后 登录成功之后  发送通知 将值传给h5

//添加一个通知 等着需要传值给html的时候就用这个通知
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(receiveNoti:) name:@"sendMyUserID" object:nil];

通知方法实现

//利用通知的方法 给h5传值
- (void)receiveNoti:(NSNotification*)noti{
    NSString *jsString = [NSString stringWithFormat:@"sendUserPhone(\"%@\")",@"55586"];
    //    NSLog(@"登录成功js-------%@",jsString);
    [self.context evaluateScript:jsString];
}

发送通知

-(void)btnClicked:(UIButton*)sender{
    [[NSNotificationCenter defaultCenter]postNotificationName:@"sendMyUserID" object:nil];
    
}

这样的话就可以了哦,oc跟h5 相互船传值就是这么简单。

想要demo的加我 qq   673658917@qq.com

 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------以上是第一种方法,也是利用原生的 uiwebview进行实现的,步骤简单,我现在项目中使用的方法就是方法1.  但是ios8之后  苹果推出了 wkWebview 比uiwebview 占用内存更小,运行速度更快,现在献上  wkwebview的使用方法,供大家参考。---------------------------------------------------------------------------------------

以前的时候并没有深入研究过webview,最近正好失恋了,就研究一下吧。

以前的时候一直在用uiwebview  老是感觉占很多的内存,但是没有时间处理,所以就一直拖着。

最近发现了wkwebview  这个是ios8之后出来的,就在#import <WebKit/WebKit.h>这个类里边就包含了这个wkwebview这个类,wkwebview继承于uiview 特点:占用内存更少了,速度更快了。

看一下wkwebview的特性:

1.性能 稳定性 功能方面有很大的提高(最直观的就是体现在占用的内存上边)。

2.允许js的Nitro库加载并使用(uivieqview中限制)

3.支持更多的html5特性

4.高达60fps的滚动刷新频率以及内置手势

5.将uiviewviewdelegate与uiwenview重构成了14个类和3个协议 (查看苹果官方文档https://developer.apple.com/reference/webkit

下边开始讲使用了哦

准备工作:

1.设置oc代码

2.设置html代码

3.运行

  oc代码:

//
//  ViewController.m
//  OC与JS交互之WKWebView
//
//  Created by user on 16/8/18.
//  Copyright © 2016年 rrcc. All rights reserved.
//

#import "ViewController.h"
#import <WebKit/WebKit.h>

@interface ViewController () <WKScriptMessageHandler>

@property (nonatomic, strong) WKWebView *wkWebView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //1.
    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    config.preferences.minimumFontSize = 18;
    
    
    //2.
    self.wkWebView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height/2) configuration:config];
    [self.view addSubview:self.wkWebView];
    
    
    //3.
//    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
//    NSURL *baseURL = [[NSBundle mainBundle] bundleURL];
//    [self.wkWebView loadHTMLString:[NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil] baseURL:baseURL];
    NSURL *url = [[NSURL alloc]initWithString:@"http://127.0.0.1:8020/h5AndOCTest/myIndex.html"];
    NSURLRequest *request  = [[NSURLRequest alloc]initWithURL:url];
    [self.wkWebView loadRequest:request];
    
    
    
    //4.
    WKUserContentController *userCC = config.userContentController;
    //JS调用OC 添加处理脚本
    [userCC addScriptMessageHandler:self name:@"showMobile"];
    [userCC addScriptMessageHandler:self name:@"showName"];
    [userCC addScriptMessageHandler:self name:@"showSendMsg"];
    
}



//网页加载完成之后调用JS代码才会执行,因为这个时候html页面已经注入到webView中并且可以响应到对应方法
//oc调用h5,通过按钮的点击事件进行响应
- (IBAction)btnClick:(UIButton *)sender {
    if (!self.wkWebView.loading) {
        if (sender.tag == 123) {//电话
            [self.wkWebView evaluateJavaScript:@"alertMobile()" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
                //TODO
                NSLog(@"%@ %@",response,error);
            }];
        }
        
        if (sender.tag == 234) {//名字
            
            [self.wkWebView evaluateJavaScript:@"alertName('小红')" completionHandler:nil];
        }
        
        if (sender.tag == 345) {//信息
            [self.wkWebView evaluateJavaScript:@"alertSendMsg('18870707070','周末爬山真是件愉快的事情')" completionHandler:nil];
        }

    } else {
        NSLog(@"the view is currently loading content");
    }
}


#pragma mark - WKScriptMessageHandler
//h5调用oc 根据h5那边传递过来的数据进行响应的弹框显示
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    NSLog(@"%@",NSStringFromSelector(_cmd));
    NSLog(@"%@",message.body);

    if ([message.name isEqualToString:@"showMobile"]) {
        [self showMsg:@"我是下面的小红 手机号是:18870707070"];
    }
    
    if ([message.name isEqualToString:@"showName"]) {
        NSString *info = [NSString stringWithFormat:@"你好 %@, 很高兴见到你",message.body];
        [self showMsg:info];
    }
    
    if ([message.name isEqualToString:@"showSendMsg"]) {
        NSArray *array = message.body;
        NSString *info = [NSString stringWithFormat:@"这是我的手机号: %@, %@ !!",array.firstObject,array.lastObject];
        [self showMsg:info];
    }
}

- (void)showMsg:(NSString *)msg {
    [[[UIAlertView alloc] initWithTitle:nil message:msg delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil] show];
}




@end

html代码:

<html>
    <!--描述网页信息-->
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>小黄</title>
         <style>
            *{
                font-size: 50px;
            }
        
            .btn{height:80px; width:80%; padding: 0px 30px; background-color: #0071E7; border: solid 1px #0071E7; border-radius:5px; font-size: 1em; color: white}
         </style>
        
        <script>
            function clear() {
                document.getElementById('mobile').innerHTML = ''
                document.getElementById('name').innerHTML = ''
                document.getElementById('msg').innerHTML = ''
            }
        
            //OC调用JS的方法列表
            function alertMobile() {
                //这里已经调用过来了 但是搞不明白为什么alert方法没有响应
                //alert('我是上面的小黄 手机号是:13300001111')
                document.getElementById('mobile').innerHTML = '我是上面的小黄 手机号是:13300001111'
            }

            function alertName(msg) {
                //alert('你好 ' + msg + ', 我也很高兴见到你')
                document.getElementById('name').innerHTML = '你好 ' + msg + ', 我也很高兴见到你'
            }

            function alertSendMsg(num,msg) {
                //window.alert('这是我的手机号:' + num + ',' + msg + '!!')
                document.getElementById('msg').innerHTML = '这是我的手机号:' + num + ',' + msg + '!!'
            }
        
            //JS响应方法列表
            function btnClick1() {
                window.webkit.messageHandlers.showMobile.postMessage(null)
            }

            function btnClick2() {
                window.webkit.messageHandlers.showName.postMessage('xiao黄')
            }

            function btnClick3() {
                window.webkit.messageHandlers.showSendMsg.postMessage(['13300001111', 'Go Climbing This Weekend !!!'])
            }

        </script>
        
        
    </head>

    <!--网页具体内容-->
    <body>
        <br/>

        <div>
            <label>小黄:13300001111</label>
        </div>
        <br/>

        <div id="mobile"></div>
        <div>
            <button class="btn" type="button" onclick="btnClick1()">小红的手机号</button>
        </div>
        <br/>
        
        <div id="name"></div>
        <div>
            <button class="btn" type="button" onclick="btnClick2()">打电话给小红</button>
        </div>
        <br/>
        
        <div id="msg"></div>
        <div>
            <button class="btn" type="button" onclick="btnClick3()">发短信给小红</button>
        </div>


    </body>
</html>

oc代码中 的文件路径 根据实际情况定 ,如果是在项目中本地的就用我注释的方法,如果是在电脑桌面上就可以用没有注释的路径,根据实际情况来。

就这样就完成了。

想要源码的 联系我邮箱  673658917@qq.com

或者是加我qq   673658917

与君共勉

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏青玉伏案

iOS开发之抽屉效果实现

  说道抽屉效果在iOS中比较有名的第三方类库就是PPRevealSideViewController。一说到第三方类库就自然而然的想到我们的CocoaPods...

2406
来自专栏一个爱瞎折腾的程序猿

个人项目框架搭建 -- Autofac简单使用记录

832
来自专栏移动端开发

Telegram学习解析系列(二):这我怎么给后台传输数据?

写在前面:          在iOS开发的过程中,有很多时候我们都在和数据打交道,最基本的就是数据的下载和上传了,估计很多很多的小伙伴都在用AFNetwork...

41810
来自专栏一“技”之长

SDWebImage源码分析 原

     SDWebImage是iOS开发中非常流行的一个网络图片加载库,如果你观察其源码,会发现其中的文件非常多,虽然文件数很多,但是作者的代码结构和条理却是...

2093
来自专栏Alice

iOS afnetworking最新版报错 没有AFHTTPRequestOperationManager类了

今天开了一个小项目   用的是pod   然后  安装好 Afnetworking之后   发现 AFHTTPRequestOperationManager  ...

4379
来自专栏一“技”之长

iOS事件响应控制 原

    以前遇到一个项目,一个UIImageView对象上面有一个UIButton对象,然而项目的需求需要在点击 button的同时,UIImageView也接...

834
来自专栏陈满iOS

iOS开发·UIWindow与视图层级调整技巧(makeKeyWindow,resignKeyWindow,makeKeyAndVisible,keyWindow,windowLevel,UIWind

例如,很多人习惯在keyWindow上添加一个自定义浮层视图,但是,当自己或者其它第三方框架曾经调高过其它自定义UIWindow属性windowLevel,或者...

4401
来自专栏QQ音乐技术团队的专栏

React-Native 分包实践

对于很多在使用react-native开发应用的小伙伴们肯定都会遇到一个问题,功能越来越复杂,生成的jsbundle文件越来越大,无论是打包在app内发布还是走...

1.2K6
来自专栏coding...

Objective-c 多线程操作 自定义NSOperation 模拟下载写在前面效果分析代码DEMO地址

使用多线程下载图片,使用内存缓存和磁盘缓存。 这里只为理解NSOperation及其派生类 真要应用到APP中 请下载成熟的第三方库

1196
来自专栏coding...

iOS开发实战-时光记账Demo 网络版效果分析客户端部分服务端部分Demo地址简书主页

user表 相反Tally与Users的关系就是:一对多

922

扫码关注云+社区