大概是2017年底接觸的RN宾茂,當時項目開發(fā)中遇到很多問題瓷马,都是自己一步一個坑走過來的】缜纾看了下當時的筆記欧聘,覺得還是在這里記錄下,防丟失坟奥。
React-native APP 開始
App Store下載Xcode并安裝(about one hour)
下載并安裝Android studio:https://developer.android.com/studio/index.html(需翻墻树瞭,take too long)
npm install -g react-native-cli
-
react-native init MyApp(最新版可能下載失敗導致無法成功run ios,所以用下面的version)
react-native init MyApp --version 0.44.3
iOS模擬器調(diào)試
cd 進入MyApp目錄下(你的項目目錄)
react-native run-ios
-
若報錯:
xcrun: error: unable to find utility "instruments", not a developer tool or in PATH
解決:
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer/
-
若模擬器爆紅:No bundle URL present
解決1:在模擬器運行期間 項目目錄下執(zhí)行npm install
解決2:檢查翻墻的代理爱谁,由全局模式改為自動模式即可
?
iOS真機調(diào)試
打開Xcode
綁定Apple ID:Xcode 》preferences 》accounts
選中左側(cè)project根目錄,點擊右側(cè)General配置
identity 》Bundle identifier 輸入唯一標識(保證唯一即可)
Signing 》Team 選中剛剛綁定的Apple ID對應的team
點擊左上角run 按鈕右側(cè)運行設備選項孝偎,選中USB已連接的你的設備
run
過程中出問題按照提示對設備進行授權(quán)配置
若build時就出錯访敌,嘗試重啟Xcode,再run
若connect server error:查看手機電腦wiffi是否一致衣盾,若不一致寺旺,停掉服務重新run
若報錯
The application does not have a valid signature.
clean下重跑
android調(diào)試
cd進入MyApp目錄
react-native run-android
-
若報錯:Error watching file for changes: EMFILE
解決辦法:watchman出錯,卸載并重裝
brew uninstall --force watchman
rm -rf/usr/local/var/run/watchman/
brew install watchman
錯誤信息不明時可打開android studio查看詳情
-
若gradle的問題:可能因為android studio 的gradle沒加載成功势决,修改gradle-wrapper.properties文件內(nèi)url為其他版本,例:
https://services.gradle.org/distributions/gradle-3.3-all.zip
或改成本地地址在setting內(nèi)加以配置
可通過http://localhost:8081/index.android.bundle?platform=android去驗證服務是否成功開啟
-
報錯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
-
真機adb無響應:(可能因為其他應用占用adb的5037端口)
解決:netstat -aon|findstr “5037” 找到占用端口的進程PID独柑,? 打開任務管理器,殺掉對應進程私植。? 重新run
?
react-native學習指南
參考:給所有開發(fā)者的React Native詳細入門指南
引用antd-mobile的坑
對于莫名其妙的問題忌栅,確保自己antd-mobile的版本不要太低,坑
對于找不到module的問題曲稼,請用yarn安裝索绪,cnpm安裝可能會漏掉一些依賴
對于antd-mobile not defined 的錯誤,確保安裝了react-dom贫悄,antd-mobile者春,babel-plugin-import,并且修改.babelrc 文件清女,例:
{
"plugins": [["import", { "libraryName": "antd-mobile" }]], "presets": ["react-native"]
}
在react-native使用Icon
-
使用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>
-
使用react-native-vector-icons
參考react-native-vector-icons的簡單使用
Icon選用參考:http://fontawesome.io/icons/
?
若出現(xiàn)搜不到的問題曙博,嘗試卸載APP重啟
native-echarts
-
Android 上圖表有時不顯示問題
原因:圖形渲染支持的不好拥刻?
解決:隱藏包含echart的div,數(shù)據(jù)填充渲染結(jié)束后顯示div父泳,中間要有一定時間的延遲般哼,比如100ms
?
android打包
根據(jù)RN官網(wǎng)推薦方式打包
-
若類似錯:
Could not find com.android.tools.build:gradle:3.0.0.
可能:自己android studio版本不是3.0.0,換成對應版本
或者:android/build.gradle下
buildscript {
repositories {
...
google()
}
}
-
若報錯:
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=****
-
項目中用到react-native-echarts惠窄,在android打包后無法顯示圖表:
原因:release版本只能使用uri加載資源(蒸眠??杆融?)
解決:
把node_modules/native-echarts/src/components/Echarts/tpl.html文件復制一份到android/app/src/main/assets文件里
修改node_modules/native-echarts/src/components/Echarts/index.js:
source={require('./tpl.html')}
改為source={{uri:'file:///android_asset/tpl.html'}}
打包后記得改回來楞卡,不然ios無法正常顯示圖表
-
修改版本信息:
android在android/app/build.gradle文件下修改
其中versionCode一般是整數(shù),上傳appstore時脾歇,每次都需比上次數(shù)字要大蒋腮,否則不予覆蓋上一版本
versionName用于在app上顯示版本信息,供自己或用戶查看
defaultConfig{
versionCode 1
versionName "1.0"
}
- ?
IOS打包
在Xcode中選擇Product -> Scheme -> Edit Scheme (cmd + <)藕各,然后選擇Run選項卡池摧,將Build Configuration設置為release
在ios中用http請求需做配置,參照讓iOS項目允許使用http協(xié)議請求
run激况,若想調(diào)試作彤,將Build Configuration重新設置為debug
設置應用圖標和閃屏圖片react native ios打包到真機
若出現(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 build
中xxxTests
只勾選Test
, build
中xxx 勾選全部
-
賬號下手機連接數(shù)量達上限宦棺,無法使用其他手機調(diào)試或安裝:
原因:免費的賬號連接設備數(shù)應該是3個左右瓣距,想連接更多的測試機,升級到收費賬號代咸,可連100個設備
解決:1. 申請企業(yè)收費開發(fā)者賬號
? 2. General/signing/Team:添加一個新的account
-
安裝release版時報錯:
Could not write to the device
,或A valid provisioning profile for this executable was not found.
:原因:我這里因為切換team(開發(fā)者賬號)導致
解決:Xcode上方導航欄product下clean操作蹈丸,重新run
?
Mac 下gradle配置
android studio 下載gradle極慢,所以下載到本地自己配置
下載所需版本:http://services.gradle.org/distributions/ (例:gradle-4.1-all)
命令open .gradle 打開finder呐芥,
進入wrapper/dists/gradle-4.1-all/(njsjdscn),刪掉目錄下所有
將下載的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:+
解決:
- 在android studio 報錯處跟蹤進react-native-linear-gradient停蕉,添加一塊代碼愕鼓,既然gradle找不到
com.facebook.react:react-native:+
,我們就告訴他怎么找
repositories {
jcenter()
}
- 在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 文件預覽
-
利用
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, '成功')
}
})
}
}
- 輔助
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')
})
-
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 證書設置指南
-
若報錯:
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)建證書時的不一致
解決:
修改info.plist文件中的bundle ID保持一致
把Build Settings中Package分欄下的Product Bundle Identifier改成新的bundle ID
?
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的圖標一定要上傳
推送通知圖標:極光推送默認選取應用圖標
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晕城,所以新建相應路徑嘗試泞坦。不行的話,重啟手機砖顷,此為坑贰锁。再不行,換個手機試試滤蝠,可能當前手機有緩存豌熄。