react-native入門,編寫靜態頁面,集成原生項目

React-Native技術調研

0.前提:

搭建環境:https://reactnative.cn/docs/getting-started/,
分mac/win/linux,平臺分android/ios。node

1.建立一個新項目

使用rn建立一個項目和把rn技術集成到一個現有的原生項目是有差異的。react

//建立和運行一個rn項目:
react-native init AwesomeProject
cd AwesomeProject
react-native run-ios

編譯和運行須要一段時間...耐心等待..根據rn版本的不一樣,ios虛擬機也不不一樣,好比最新的0.57版本的是iphoneX,低版本的rn默認創造的ios虛擬機就老一點。linux

注意官網中特別提到:android

!!!注意!!!:init 命令默認會建立最新的版本,而目前最新的 0.45 及以上版本須要下載 boost
等幾個第三方庫編譯。這些庫在國內即使FQ也很難下載成功,致使不少人沒法運行iOS項目!!!中文網在論壇中提供了這些庫的國內下載連接。若是你嫌麻煩,又沒有對新版本的需求,那麼能夠暫時建立0.44.3的版本。webpack

我在rn版本0.57.5,react-cli版本2.0.1直接init建立項目沒有遇到以上問題。ios

幾個經常使用操做

  1. cmd+r 刷新,可配置熱更新,調出菜單enable liveload
  2. cmd+d 調出菜單

2.試着用RN寫一個靜態頁面

https://github.com/ZhangMingZhao1/react-native-pratice/tree/master/earphone_guidegit

3.集成到一個原生項目

這裏以一個rn集成到ios object-c爲例,現實中這種狀況可能也更多一些。github

a.

用xcode新建一個單頁面應用,語言選擇object-c,名字爲ReactNativeDemo,在項目根目錄下,新建ReactNative文件夾,用於存放跟reactnative相關文件。(後面簡稱rn)web

b.

在rn文件夾中新建一個package.json,內容爲:npm

{
  "name": "ReactNativeDemo",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start"
  },
  "dependencies": {
    "react": "16.0.0",
    "react-native": "0.51.0"
  }
}

注意版本嚴格規定

c.

進入rn文件夾,npm install,在rn文件夾新建index.js,之前版本是inex.ios.js。
內容爲:

import React, { Component } from 'react';
import {
    AppRegistry,
    StyleSheet,
    Text,
    View
} from 'react-native';

class ScoresView extends React.Component {
    render() {
      var contents = this.props['scores'].map((score) => (
        <Text key={score.name}>
          {score.name}:{score.value}
          {'\n'}
        </Text>
      ));
      return (
        <View style={styles.container}>
          <Text style={styles.highScoresTitle}>2048 High Scores!</Text>
          <Text style={styles.scores}>{contents}</Text>
        </View>
      );
    }
  }
  
  const styles = StyleSheet.create({
    container: {
      flex: 1,
      justifyContent: 'center',
      alignItems: 'center',
      backgroundColor: '#FFFFFF',
    },
    highScoresTitle: {
      fontSize: 20,
      textAlign: 'center',
      margin: 10,
    },
    scores: {
      textAlign: 'center',
      color: '#333333',
      marginBottom: 5,
    },
  });
  
// 註冊組件,程序入口
// 第一個參數:註冊模塊名稱,這裏親測不和項目名一致也能夠,可是好多資料說名字要和項目名一致
// 第二個參數:函數,此函數返回組件類名,程序啓動就會自動去加載這個組件
AppRegistry.registerComponent('App', () => ScoresView);

d.

進入項目根目錄,安裝cocoapods,

brew install cocoapods

個人mac下會報個錯,在一個文件下沒有權限寫入,而homebrew如今禁止使用sudo執行,根據提示的指令能夠收回那個文件的權限,複製粘貼執行就好。

安裝好後,在根目錄使用pod init,在生成的Podfile中內容改成:

source 'https://github.com/CocoaPods/Specs.git'
react_native_path = './ReactNative/node_modules/react-native'
platform :ios, ‘9.0’
use_frameworks!

target 'ReactNativeDemo' do
# 'node_modules'目錄通常位於根目錄中
# 可是若是你的結構不一樣,那你就要根據實際路徑修改下面的`:path`
pod 'React', :path => react_native_path, :subspecs => [
'Core',
#'BatchedBridge', # 0.45 版本之後須要添加
'CxxBridge',
'DevSupport', # 若是RN版本 >= 0.43,則須要加入此行才能開啓開發者菜單
'RCTText',
'RCTImage',
'RCTNetwork',
'RCTWebSocket', # 這個模塊是用於調試功能的
# 在這裏繼續添加你所須要的模塊
]
# 若是你的RN版本 >= 0.42.0,則加入下面這行
pod 'yoga', :path => react_native_path + '/ReactCommon/yoga'
# Third party deps
pod 'DoubleConversion', :podspec => react_native_path + '/third-party-podspecs/DoubleConversion.podspec'
pod 'GLog', :podspec => react_native_path + '/third-party-podspecs/GLog.podspec'
pod 'Folly', :podspec => react_native_path + '/third-party-podspecs/Folly.podspec'

end

這個文件相似npm的package.json,記錄了所需文件的依賴,因此下一步就是

pod install

e.

在總ios項目中修改http的安全策略,在info.plist加上:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>localhost</key>
        <dict>
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>

f.

用xcode打開項目,在Main.storyboard拖入一個按鈕,在ViewController.m中加入頭文件:

#import <React/RCTRootView.h>

再增長一個按鈕的跳轉方法:

- (IBAction)pushToReactNativeView:(id)sender {
    NSURL *jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.bundle?platform=ios"];
    
    RCTRootView *rootView =
    [[RCTRootView alloc] initWithBundleURL: jsCodeLocation
                                moduleName: @"App"
                         initialProperties:
     @{
       @"scores" : @[
               @{
                   @"name" : @"Alex",
                   @"value": @"42"
                   },
               @{
                   @"name" : @"Joel",
                   @"value": @"10"
                   }
               ]
       }
                             launchOptions: nil];
    UIViewController *vc = [[UIViewController alloc] init];
    vc.view = rootView;
    [self presentViewController:vc animated:YES completion:nil];
}

可能會出現加載出錯,這是由於pod install安裝的文件沒有加載進來,重啓xcode項目,從新打開項目便可。
而後把ViewController.m文件中的#import <fishhook/fishhook.h> 改成 #import "fishhook.h",否則後面運行可能會報錯。

g.

給這個按鈕和這個方法綁定起來,進入keyboard,按住 ctrl,點擊按鈕會出現一個箭頭,指向左上角的ViewContrller,可出現一個框,選擇剛纔寫的pushToReactNativeView方法,會在右下角看到關聯了。
這部可詳見iOS學習之基礎控件添加和事件綁定,推薦一個連接:https://www.jianshu.com/p/6eb302a62956

h.

進入到rn文件夾,npm start 啓動node服務器,這時會進入dev狀態,動態打包。回到xcode,運行項目,點擊按鈕,就會看到跳轉到rn寫的頁面。

4.RN打包給原生項目使用

a.

在rn項目根目錄中建立release_ios 文件夾,(打包必須建立文件夾)具體能夠本身命名,做爲資源目標的輸出文件目錄。
在根目錄下執行打包命令:

react-native bundle --entry-file index.js --platform ios --dev false --bundle-output release_ios/main.jsbundle --assets-dest release_ios/

會看到release_ios下多出assets文件夾(若是有圖片),和兩個jsbindle文件.

b.

將main.jsbundle和assets拖入Xcode的項目導航面板中,選擇默認導入便可(位置和裏面的文件夾同級)
在這裏插入圖片描述

修改上面的ViewController,m,
在這裏插入圖片描述

將端口動態引入改成本地,讓React Native去使用咱們剛纔導入的jsbundle,這樣以來咱們就擺脫了對本地nodejs服務器的依賴。固然也能夠將jsbundle 放到本身的遠程服務器中,更換遠程的服務器文件就能夠加載jsbundle,爲了提升性能咱們能夠在本地作一次緩存。@後面是本身打包文件的名字不加後綴。

c.

ios app的打包就能夠看官網了:https://developer.apple.com/support/app-store-connect/

5.留下的疑問,待繼續研究

  1. npm start後打包的文件是在哪裏放着的,找了一下沒找到,難道和webpack dev同樣使用了memory-fs-js,把臨時打包文件動態寫進了內存裏嗎?
  2. 你們能夠補充..etc
相關文章
相關標籤/搜索