RN開發(fā)填坑之旅

大概是2017年底接觸的RN宾茂,當時項目開發(fā)中遇到很多問題瓷马,都是自己一步一個坑走過來的】缜纾看了下當時的筆記欧聘,覺得還是在這里記錄下,防丟失坟奥。

React-native APP 開始

  1. App Store下載Xcode并安裝(about one hour)

  2. 下載并安裝Android studio:https://developer.android.com/studio/index.html(需翻墻树瞭,take too long)

  3. npm install -g react-native-cli

  4. react-native init MyApp(最新版可能下載失敗導致無法成功run ios,所以用下面的version)

    react-native init MyApp --version 0.44.3

iOS模擬器調(diào)試

  1. cd 進入MyApp目錄下(你的項目目錄)

  2. react-native run-ios

  3. 若報錯:xcrun: error: unable to find utility "instruments", not a developer tool or in PATH

    解決:sudo xcode-select -s /Applications/Xcode.app/Contents/Developer/

  4. 若模擬器爆紅:No bundle URL present

    解決1:在模擬器運行期間 項目目錄下執(zhí)行npm install

    解決2:檢查翻墻的代理爱谁,由全局模式改為自動模式即可

  5. ?

iOS真機調(diào)試

  1. 打開Xcode

  2. 綁定Apple ID:Xcode 》preferences 》accounts

  3. 選中左側(cè)project根目錄,點擊右側(cè)General配置

  4. identity 》Bundle identifier 輸入唯一標識(保證唯一即可)

  5. Signing 》Team 選中剛剛綁定的Apple ID對應的team

  6. 點擊左上角run 按鈕右側(cè)運行設備選項孝偎,選中USB已連接的你的設備

  7. run

  8. 過程中出問題按照提示對設備進行授權(quán)配置

  9. 若build時就出錯访敌,嘗試重啟Xcode,再run

  10. 若connect server error:查看手機電腦wiffi是否一致衣盾,若不一致寺旺,停掉服務重新run

  11. 若報錯The application does not have a valid signature.clean下重跑

android調(diào)試

  1. cd進入MyApp目錄

  2. react-native run-android

  3. 若報錯:Error watching file for changes: EMFILE

    解決辦法:watchman出錯,卸載并重裝

    brew uninstall --force watchman

    rm -rf/usr/local/var/run/watchman/

    brew install watchman

  4. 錯誤信息不明時可打開android studio查看詳情

  5. 若gradle的問題:可能因為android studio 的gradle沒加載成功势决,修改gradle-wrapper.properties文件內(nèi)url為其他版本,例:

    https://services.gradle.org/distributions/gradle-3.3-all.zip

    或改成本地地址在setting內(nèi)加以配置

  6. 可通過http://localhost:8081/index.android.bundle?platform=android去驗證服務是否成功開啟

  7. 報錯could not connect development server:(坑W杷堋)

    (1). android studio debug運行模式,

    (2). 打開命令行果复,cd到當前目錄陈莽,react-native start

    (3). 真機或模擬器reload,成功與否

    (4). 若失敗:adb reverse tcp:8081 tcp:8081走搁,reload(5). 若command adb not found:"adb"不是內(nèi)部命令和sudo: adb: command not found

  1. 真機adb無響應:(可能因為其他應用占用adb的5037端口)

    解決:netstat -aon|findstr “5037” 找到占用端口的進程PID独柑,? 打開任務管理器,殺掉對應進程私植。? 重新run

  2. ?

react-native學習指南

參考:給所有開發(fā)者的React Native詳細入門指南

引用antd-mobile的坑

  1. 對于莫名其妙的問題忌栅,確保自己antd-mobile的版本不要太低,坑

  2. 對于找不到module的問題曲稼,請用yarn安裝索绪,cnpm安裝可能會漏掉一些依賴

  3. 對于antd-mobile not defined 的錯誤,確保安裝了react-dom贫悄,antd-mobile者春,babel-plugin-import,并且修改.babelrc 文件清女,例:

{  
 "plugins": [["import", { "libraryName": "antd-mobile" }]],    "presets": ["react-native"]
}

在react-native使用Icon

  1. 使用antd-mobile的Icon

    RN 版本由于 Icon 無法做純 UI钱烟,需要 native 支持

    • 下載 https://at.alicdn.com/t/font_r5u29ls31bgldi.ttf 重命名為 anticon.ttf

    • 打開 iOS 項目 info.plist 文件,添加 Fonts provided by application嫡丙,指定一個 item 的值為 anticon.ttf拴袭, 將 anticon.ttf 拖進項目;

    • Android 項目將 anticon.ttf 放在 android/app/src/main/assets/fonts/ 目錄下;

    使用方式:

內(nèi)置的幾個圖標: <Icon type="check" size="md" color="red" />
自定義圖標:<Icon type={'\ue601'} size={55} /> (具體參看 demo)

自定義圖標:<Icon type={'\ue601'} size={55} /> (具體參看 demo)</pre>

  1. 使用react-native-vector-icons

    參考react-native-vector-icons的簡單使用

    Icon選用參考:http://fontawesome.io/icons/

  2. ?

若出現(xiàn)搜不到的問題曙博,嘗試卸載APP重啟

native-echarts

  1. React Native使用百度Echarts顯示圖表的示例代碼

  2. Android 上圖表有時不顯示問題

    原因:圖形渲染支持的不好拥刻?

    解決:隱藏包含echart的div,數(shù)據(jù)填充渲染結(jié)束后顯示div父泳,中間要有一定時間的延遲般哼,比如100ms

  3. ?

android打包

  1. 根據(jù)RN官網(wǎng)推薦方式打包

  2. 若類似錯:Could not find com.android.tools.build:gradle:3.0.0.

    可能:自己android studio版本不是3.0.0,換成對應版本

    或者:android/build.gradle下

buildscript {
    repositories {
        ...
        google()
    }
}
  1. 若報錯:Could not get unknown property 'MYAPP_RELEASE_STORE_FILE'

    原因:將如下代碼加入到android/gradle.properties, **改為密鑰

MYAPP_RELEASE_STORE_FILE=my-release-key.keystore
MYAPP_RELEASE_KEY_ALIAS=my-key-alias
MYAPP_RELEASE_STORE_PASSWORD=****
MYAPP_RELEASE_KEY_PASSWORD=****
  1. 項目中用到react-native-echarts惠窄,在android打包后無法顯示圖表:

    原因:release版本只能使用uri加載資源(蒸眠??杆融?)

    解決:

    1. 把node_modules/native-echarts/src/components/Echarts/tpl.html文件復制一份到android/app/src/main/assets文件里

    2. 修改node_modules/native-echarts/src/components/Echarts/index.js:source={require('./tpl.html')}改為source={{uri:'file:///android_asset/tpl.html'}}

    3. 打包后記得改回來楞卡,不然ios無法正常顯示圖表

  2. 修改版本信息:

    android在android/app/build.gradle文件下修改

    其中versionCode一般是整數(shù),上傳appstore時脾歇,每次都需比上次數(shù)字要大蒋腮,否則不予覆蓋上一版本

    versionName用于在app上顯示版本信息,供自己或用戶查看

defaultConfig{
  versionCode 1
  versionName "1.0"
}
  1. ?

IOS打包

  1. 在Xcode中選擇Product -> Scheme -> Edit Scheme (cmd + <)藕各,然后選擇Run選項卡池摧,將Build Configuration設置為release

  2. 在ios中用http請求需做配置,參照讓iOS項目允許使用http協(xié)議請求

  3. run激况,若想調(diào)試作彤,將Build Configuration重新設置為debug

  4. 一鍵打包:React-Native中iOS一鍵打包發(fā)布腳本

  5. 設置應用圖標和閃屏圖片react native ios打包到真機

  6. 若出現(xiàn)其他手機無法run release版本膘魄,報錯:

can't link with a main executable file '/Users/liujinling/Library/Developer/Xcode/DerivedData/gngcApp-glzeunbnyelbpmcrehcygunmtjfq/Build/Products/Release-iphoneos/gngcApp.app/gngcApp' for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)

解決:
product ->schema-> edit ->schema-> run 選擇release buildxxxTests 只勾選Testbuild中xxx 勾選全部

  1. 賬號下手機連接數(shù)量達上限宦棺,無法使用其他手機調(diào)試或安裝:

    原因:免費的賬號連接設備數(shù)應該是3個左右瓣距,想連接更多的測試機,升級到收費賬號代咸,可連100個設備

    解決:1. 申請企業(yè)收費開發(fā)者賬號

    ? 2. General/signing/Team:添加一個新的account

  2. 安裝release版時報錯:Could not write to the device,或A valid provisioning profile for this executable was not found.:

    原因:我這里因為切換team(開發(fā)者賬號)導致

    解決:Xcode上方導航欄product下clean操作蹈丸,重新run

  3. ?

Mac 下gradle配置

android studio 下載gradle極慢,所以下載到本地自己配置

  1. 下載所需版本:http://services.gradle.org/distributions/ (例:gradle-4.1-all)

  2. 命令open .gradle 打開finder呐芥,

  3. 進入wrapper/dists/gradle-4.1-all/(njsjdscn),刪掉目錄下所有

  4. 將下載的gradle-4.1-all.zip拉進來逻杖,重啟android studio

記一次重大填坑現(xiàn)場

在android和ios真機+模擬器run成功n次,雙機打包均跑成功后思瘟,再次android真機調(diào)試時荸百,突然的gradle構(gòu)建失敗1豕ァ9换啊!WTF

詭異1:android打包時按照react-native官網(wǎng)配置了一些文件光绕,今天打開代碼女嘲,發(fā)現(xiàn)一會這里多了個‘g’,一會那里classpath被刪掉诞帐,還有其他的屬性名缺了一半欣尼,連gradle.zip后面緊跟了個’android‘……細思極恐

詭異2:react-native-linear-gradient庫突然無法正確引入?錯誤提示:com.facebook.react:react-native:+

詭異3:android/app/build.gradle文件找不到com.facebook.react:react-native:+

解決

  1. 在android studio 報錯處跟蹤進react-native-linear-gradient停蕉,添加一塊代碼愕鼓,既然gradle找不到com.facebook.react:react-native:+,我們就告訴他怎么找
repositories {
    jcenter()
}
  1. 在android/app/build.gradle添加如下代碼
allprojects {
    repositories {
        jcenter()
        mavenCentral()
        mavenLocal()
        maven {
            // All of React Native (JS, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
    }
}

url "$rootDir/../node_modules/react-native/android"報錯,將其改為url "$rootDir/node_modules/react-native/android"慧起。應該是通過yarn安裝的react-native使用前者菇晃,通過npm安裝的使用后者

莫名其妙的坑,踩了一下午完慧,燥

又一次重重大填坑現(xiàn)場

RN Android 文件預覽

  1. 利用react-native-doc-viewer

    *注意注釋部分

const handlePress = (name,id) => {
  const nameArr = name.split('.');
  const type = nameArr[nameArr.length - 1];
  //Interface.downloadUrl + id是文件的下載地址
  const downloadUrl = Interface.downloadUrl + id + '.' + type;
  if (Platform.OS === 'ios') {
    //IOS(成功預覽)
    OpenFile.openDoc([{
      url: downloadUrl,
      //此處url后綴必須帶文件type(例:.doc)
      //原因:ios配置沒有fileType谋旦,需靠url后綴識別文件類型
      fileNameOptional: name
      //ios的fileNameOptional取值中文是ok的
    }], (error, url) => {
      if (error) {
        console.error(error);
      } else {
        console.log(url, '成功')
      }
    })
  } else {
    //Android(除圖片外,其他無效屈尼,打不開文件)
    OpenFile.openDoc([{
      url: Interface.downloadUrl + id,
      //此處url直接為下載地址,無需特意加類型后綴
      fileName: name,
      //Android的fileName取值中文報錯
      cache:false,
      fileType:type
    }], (error, url) => {
      if (error) {
        console.error(error);
      } else {
        console.log(url, '成功')
      }
    })
    }
  }
  1. 輔助react-native-fs
//Android
const SavePath = RNFS.DocumentDirectoryPath;
//const SavePath = RNFS.ExternalDirectoryPath;
//const SavePath = RNFS.ExternalStorageDirectoryPath;

//當配合react-native-doc-viewer拴孤,以上三個路徑均測試脾歧,無法打開文件
//當配合原生模塊,使用第二個

//const SavePath = RNFS.MainBundlePath //ios的存儲路徑
const options = {
  fromUrl: downloadUrl,
  //加不加類型后綴都ok
  toFile: `${SavePath}/${name}`,
};

RNFS.downloadFile(options).promise.then(res => {
  console.log(res, 'res')
  //配合react-native-doc-viewer(無效)
  OpenFile.openDoc([{
      url: `file://${SavePath}/${name}`,
      //此處url為系統(tǒng)內(nèi)部路徑演熟,前面需加‘file://’
      fileName: name,
      //Android的fileName取值中文報錯
      cache:false,
      fileType:type
    }], (error, url) => {
      if (error) {
        console.error(error);
      } else {
        console.log(url, '成功')
      }
    })
  //配合原生模塊(成功)
  NativeModules.OpenFileModule.show(`${SavePath}/${name}`)
        
}).catch(err => {
  console.log(err, 'err')
})
  1. react-native-fs加原生模塊實現(xiàn)
//任意位置新建一個類(java文件)
package com.reactNativeModules;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.webkit.MimeTypeMap;
import android.widget.Toast;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

import java.io.File;
import java.util.Locale;
public OpenFileModule(ReactApplicationContext reactContext){
   super(reactContext);
 }

 @Override
 public String getName(){
   return "OpenFileModule";
 }
 //getName為必需

 @ReactMethod
 private void show(final String filePath)
 {
   String ext = filePath.substring(filePath.lastIndexOf('.')).toLowerCase(Locale.US);
   try
     {
       MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
       String temp = ext.substring(1);
       String mime = mimeTypeMap.getMimeTypeFromExtension(temp);
       Intent intent = new Intent();
                  intent.setAction(android.content.Intent.ACTION_VIEW);
       File file = new File(filePath);
       intent.setDataAndType(Uri.fromFile(file), mime);
//這里原本:startActivity(intent); 
//但由于react調(diào)原生方法鞭执,不存在原生activity司顿,報錯,使用下面兩句代替
       Activity currentActivity = getCurrentActivity();              currentActivity.startActivity(intent);
     }
   catch (Exception e)
     {
       e.printStackTrace();
       Toast.makeText(getReactApplicationContext(), "無法打開后綴名為." + ext + "的文件兄纺!",
       Toast.LENGTH_LONG).show();
     }
   }
//任意位置定義一個包(java文件)
   package com.reactNativeModules;

   import com.facebook.react.ReactPackage;
   import com.facebook.react.bridge.JavaScriptModule;
   import com.facebook.react.bridge.NativeModule;
   import com.facebook.react.bridge.ReactApplicationContext;
   import com.facebook.react.uimanager.ViewManager;

   import java.util.ArrayList;
   import java.util.Collections;
   import java.util.List;

   /**
    * Created by liujinling on 2018/1/23.
    */

   public class OpenFilePackage implements ReactPackage{
       @Override
       public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
           return Collections.emptyList();
       }

       @Override
       public List<NativeModule> createNativeModules(
               ReactApplicationContext reactContext) {
           List<NativeModule> modules = new ArrayList<>();
         
        //OpenFileModule為上文新建的類名
           modules.add(new OpenFileModule(reactContext));
           return modules;
       }

     //此處為必需
       @Override
       public List<Class<? extends JavaScriptModule>> createJSModules() {
           return Collections.emptyList();
       }
   }
//在mainactivity.java內(nèi)注冊模塊(必需)
   protected List<ReactPackage> getPackages() {  
       return Arrays.<ReactPackage>asList(  
         //OpenFilePackage為上文新建的包名
               new MainReactPackage(),new OpenFilePackage());  
   } 
//js中使用
   import {NativeModules} from 'react-native';

   //注意這里的path需帶文件類型后綴
   //且前面不要加‘file://’
   //直接取RNFS.ExternalDirectoryPath存儲的地址
   const path = '/data/file/test.doc'
   NativeModules.OpenFileModule.show(path)

android中TextInput頂起TabBar問題

目錄:android/app/src/main/AndroidManifest.xml中的<activity>標簽中大溜,添加android:windowSoftInputMode="stateAlwaysHidden|adjustPan|adjustResize"

gngcApp極光推送

蘋果開發(fā)者平臺:蘋果開發(fā)者平臺

證書配置:iOS 證書申請和使用詳解

官方描述證書配置:iOS 證書設置指南

  1. 若報錯:The provisioning profile specified in your build settings ("test") has an AppID of "com.baidu.test" which does not match your bundle identifier "com.apple.test"

    原因:info.plist文件中的bundle ID與創(chuàng)建證書時的不一致

    解決

    1. 修改info.plist文件中的bundle ID保持一致

    2. 把Build Settings中Package分欄下的Product Bundle Identifier改成新的bundle ID

  2. ?

App設置應用名字、圖標估脆、啟動頁

生成應用圖標:圖標工廠

只需上傳一張1024*1024的應用圖標钦奋,該網(wǎng)站會自動為你生成各種適配版本的icon,包括ios和android

ios

應用名稱:Xcode內(nèi)target/info/Custom iOS Target Propperties下的Bundle display name修改為應用名稱

應用圖標:項目目錄下Images.xcassets/AppIcon內(nèi)疙赠,將需要適配的圖標拖進去付材,注意:若要上傳到App Store,1024*1024的圖標一定要上傳

啟動頁關(guān)于iOS APP設置啟動圖片

推送通知圖標:極光推送默認選取應用圖標

android

應用名稱:android/app/src/main/res/values/strings.xml內(nèi)圃阳,修改應用名稱

應用圖標:android/app/src/main/res/文件夾下圖標文件替換為圖標工場下載下來的文件們

啟動頁

推送通知圖標:極光推送默認選取應用圖標厌衔,但在anfroid上可能行不通,android/app/src/main/res目錄下說明:若沒有res/drawable-xxxx/jpush_notification_icon這個資源默認使用應用圖標作為通知icon捍岳,在5.0以上系統(tǒng)將應用圖標作為默認推送圖標富寿,官網(wǎng)如是說。沒有可以新建一個锣夹,把圖標命名為相應名稱页徐。項目中res下圖標用的是mipmap,不是drawable晕城,所以新建相應路徑嘗試泞坦。不行的話,重啟手機砖顷,此為坑贰锁。再不行,換個手機試試滤蝠,可能當前手機有緩存豌熄。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市物咳,隨后出現(xiàn)的幾起案子锣险,更是在濱河造成了極大的恐慌,老刑警劉巖览闰,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芯肤,死亡現(xiàn)場離奇詭異,居然都是意外死亡压鉴,警方通過查閱死者的電腦和手機崖咨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來油吭,“玉大人击蹲,你說我怎么就攤上這事署拟。” “怎么了歌豺?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵推穷,是天一觀的道長。 經(jīng)常有香客問我类咧,道長馒铃,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任轮听,我火速辦了婚禮骗露,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘血巍。我一直安慰自己萧锉,他們只是感情好,可當我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布述寡。 她就那樣靜靜地躺著柿隙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鲫凶。 梳的紋絲不亂的頭發(fā)上禀崖,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天,我揣著相機與錄音螟炫,去河邊找鬼波附。 笑死,一個胖子當著我的面吹牛昼钻,可吹牛的內(nèi)容都是我干的掸屡。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼然评,長吁一口氣:“原來是場噩夢啊……” “哼仅财!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起碗淌,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤盏求,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后亿眠,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體碎罚,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年纳像,在試婚紗的時候發(fā)現(xiàn)自己被綠了魂莫。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡爹耗,死狀恐怖耙考,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情潭兽,我是刑警寧澤倦始,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站山卦,受9級特大地震影響鞋邑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜账蓉,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一枚碗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧铸本,春花似錦肮雨、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至锡足,卻和暖如春波丰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背舶得。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工掰烟, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人沐批。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓纫骑,卻偏偏與公主長得像,于是被迫代替她去往敵國和親珠插。 傳聞我的和親對象是個殘疾皇子惧磺,可洞房花燭夜當晚...
    茶點故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 曉靜是個二婚女,有一個女兒跟著前夫捻撑,前夫從來不讓曉靜見女兒磨隘。 現(xiàn)在的丈夫有個兒子,曉靜改嫁到這個家庭顾患,跟這個兒子相...
    依云70后閱讀 1,561評論 12 6
  • 交通類 1.航企迎戰(zhàn)票代公司抵抗"爬蟲"搶低價票 隨著機票代理手續(xù)費下調(diào)至零番捂,不少票代動起了歪腦筋。一些公司正利用...
    古月雁小青閱讀 233評論 0 0
  • 自從Captain走后根本不想回家江解,因為再也不會有人盼著我回去设预。房子只是一棟房子,并不是家犁河,重要的是房子里住的是誰...
    經(jīng)濟學家楊奶奶閱讀 185評論 0 1