美文网首页程序员iOS开发心得
简单的天气查询Demo(iOS和RN混合开发)

简单的天气查询Demo(iOS和RN混合开发)

作者: 运气不够技术凑 | 来源:发表于2018-07-04 15:51 被阅读41次

         第一步是利用Xcode新建一个iOS原生项目,然后利用cocoapods将react-native集成进来,具体操作可以看官方文档:https://reactnative.cn/docs/0.50/integration-with-existing-apps.html

        然后就是开发了:

        在原生项目中,很简单,一个UITextField和一个UIButton

    #import "ViewController.h"

    #import "RNViewController.h"

    @interface ViewController ()

    @property(strong,nonatomic)UIButton *btn;

    @property(strong, nonatomic)UITextField *textFiled;

    @end

    @implementation ViewController

    - (void)viewDidLoad {

        [super viewDidLoad];

        // Do any additional setup after loading the view, typically from a nib.

        CGPoint center = self.view.center;

        self.btn= [[UIButtonalloc]initWithFrame:CGRectMake(50, center.y,200,50)];

        self.btn.backgroundColor = [UIColor redColor];

        [self.btn setTitle:@"查询天气" forState:UIControlStateNormal];

        [self.btn addTarget:self action:@selector(goView:) forControlEvents:UIControlEventTouchDown];

        [self.viewaddSubview:self.btn];

        self.textFiled= [[UITextFieldalloc]initWithFrame:CGRectMake(50, center.y-100,200,50)];

        self.textFiled.backgroundColor = [UIColor grayColor];

        [self.viewaddSubview:self.textFiled];

    }

        在button的点击事件里面,是跳转到RN的视图,在这里用 push 是为了可以在之后的 既可以从原生到RN视图,也可以从RN视图返回原生视图,但是这里还需要在AppDelegate.m里面初始化一个根控制器 UINavigationController *nav;

    AppDelegate.m

    #import "AppDelegate.h"

    #import "ViewController.h"

    @interface AppDelegate ()

    @end

    @implementation AppDelegate

    - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {

        self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];

        self.window.backgroundColor = [UIColor whiteColor];

        ViewController *view = [[ViewController alloc]init];

        // 初始化Nav

        _nav = [[UINavigationController alloc]initWithRootViewController:view];

        // 将Nav设置为根视图

        self.window.rootViewController = _nav;

         [self.window makeKeyAndVisible];

        return YES;

    }

    ViewController.m的点击方法:

    - (void)goView:(UIButton*)btn

    {

        RNViewController *RNView = [RNViewController new];

        NSDictionary *dic = @{@"cityName":self.textFiled.text};

        RNView.props= dic;

        [self.navigationController pushViewController:RNView animated:YES];

    }

        接下来就是编写RN代码,我这里用的是WebStorm 2018.2 EAP版本,EAP版本是免费使用的。

       打开index.ios.js文件,我RN的代码是放在这个文件里面的,这里需要根据你自己取名字的情况。

        RN的构造函数:

    this.state = {

    isLoading:true, //网络请求状态

        error:false,

        errorInfo:"",

        weatherTitle:this.props.cityName,

        weatherContent: [],

    }

       RN里面,render渲染的执行分为三种情况:

    render() {

    //第一次加载等待的view

        if (this.state.isLoading && !this.state.error) {

    return this.renderLoadingView();

        }

    //请求失败view

    else if (this.state.error) {

            return this.renderErrorView();

        }

    //请求成功

        return this.renderData();

    }

    1、在renderLoadingView()渲染完成后,会执行一个方法componentDidMount(),这个方法是在界面渲染完后执行的。  

    2、网络请求我用的fetchData()。

    3、需要注意的是,如果使用了this.setState()方法的话,将会重新执行一次render渲染。然后根据判断条件执行需要渲染方法。

    componentDidMount() {

    //请求数据

        this.fetchData(this.state.weatherTitle);

    }

    //网络请求

    fetchData(cityName) {

    //这个是js的访问网络的方法

        fetch(REQUEST_URL+'location='+cityName)

    .then((response) => response.json())

    .then((responseData) => {

    console.log("sucess",responseData.HeWeather6[0])

    this.setState({

    //复制数据源

                    weatherTitle: responseData.HeWeather6[0].basic.location,

                    weatherContent: responseData.HeWeather6[0].now,

                    isLoading:false,

                    isRefreshing:false,

                });

                console.log("sucess",this.state.weatherContent)

    })

    .catch((error) => {

    this.setState({

    error:true,

                    errorInfo: error

    })

    })

    .done();

    }

    然后来说说从原生传递数据给RN界面,也就是把需要查询的地址传到RN的过程。

        RCTRootView是一个UIView容器,承载着React Native应用。同时它也提供了一个联通原生端和被托管端的接口。通过RCTRootView的初始化函数你可以将任意属性传递给React Native应用。参数initialProperties必须是NSDictionary的一个实例。这一字典参数会在内部被转化为一个可供JS组件调用的JSON对象。

    具体过程:

    在原生界面里面:

     在ViewController.m里的button的点击事件,我们通过获取textFiled的内容,然后初始化了一个字典,然后传入到RNViewController.m里。

    ViewController.m的点击事件:

    - (void)goView:(UIButton*)btn

    {

        RNViewController *RNView = [RNViewController new];

        NSDictionary *dic = @{@"cityName":self.textFiled.text};

        RNView.props= dic;

       // [self presentViewController:RNView animated:YES completion:nil];

        [self.navigationController pushViewController:RNView animated:YES];

    }

    RNViewController.h:

    @interfaceRNViewController :UIViewController

    @property(nonatomic) NSDictionary *props;

    @end

    RNViewController.m:

    [[RCTRootViewalloc]initWithBundleURL:jsCodeLocation

                                                             moduleName:@"RNDemo"

                                                      initialProperties:self.props

                                                          launchOptions:nil];

    这个初始化RN界面的方法,里面的  initialProperties:self.props 这个就是初始化传入参数

    @implementationRNViewController

    - (void)viewDidLoad {

        [super viewDidLoad];

        // Do any additional setup after loading the view.

        NSString * strUrl = @"http://localhost:8081/index.ios.bundle?platform=ios&dev=true";

        NSURL* jsCodeLocation = [NSURLURLWithString:strUrl];

        RCTRootView* rootView = [[RCTRootViewalloc]initWithBundleURL:jsCodeLocation

                                                             moduleName:@"RNDemo"

                                                      initialProperties:self.props

                                                          launchOptions:nil];

        self.view= rootView;

    }

    在RN界面里面:

    cityName就是字典的key值,然后直接使用就可以了。

    demo地址:https://github.com/bbbbprefect/iOSRNWeather.git

    使用前记得pod install以及npm install噢~

    相关文章

      网友评论

        本文标题:简单的天气查询Demo(iOS和RN混合开发)

        本文链接:https://www.haomeiwen.com/subject/rcyeuftx.html