This project is a React Native implementation of Hyphenate, a Mobile Instant Messaging as a Service.
- Start
- Content structure
- Redux State
- Features coming soon
- Hyphenate Web SDK
- Version Support
- Version log
Set up React Native environment
- Clone the repo
$ git clone https://github.com/HyphenateInc/hyphenate-react-native.git
$ cd hyphenate-react-native
- Install dependencies
$ npm install
Note:
- Install the latest vesion of npm by running
$ npm install npm@latest -g
- Install yarn by running command
$ npm install -g yarnpkg@0.15.1
- Run
$ npm run newclear
if encountering library dependency (node_modules) errors, which triggers commands `rm -rf $TMPDIR/react-* && watchman watch-del-all && rm -rf ios/build/ModuleCache/* && rm -rf node_modules/ && npm cache clean && npm i'. - Clean the buffer after installation**
-
npm run clean
-
Open Xcode: select product -> clean
-
Please close the terminal if open there's one currently open
-
Compile debug version of the app if no signature in place, release version require signature to run
- Add project: File -> New -> Project -> select "React Native" -> select project file location -> pop up "Create Project" The directory {file path} is not empty. Would you like to create a project from existing sources instead? -> select "Yes"
- Open the app "Terminal" -> Run
$ npm install
to install dependencies - Add simulator: select "Run" tab -> "Edit Configurations" -> click "+" sign -> select "React Native" -> select "Target platform", either Android or iOS -> click "OK"
- select "Run" tab -> click "Run"
- Basic installation environment iOS and Android https://facebook.github.io/react-native/docs/getting-started.html
$ brew install android-sdk
// zshrc depending on your dependencies
export ANDROID_HOME=~/Library/Android/sdk
export PATH=${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/
// remember this!
source .zshrc
-
Emulator and SDK installation https://developer.android.com/studio/run/managing-avds.html
- react-native support api minimal 16
- Recommend use
$ android
for API and image management- Install API and Image based on your platform dependencies
- Create image after install
AVD Mannger
successfully - Install Android xx (API xx)
- SDK Platform
- Google APIS Intel x86 Atom System Image
- Recommend use
Android studio
for image management and operation (or use$ android avd
)- Open any item -> Tools -> Android -> AVD Manager / SDK Manager
-
Emulator testing
- run any Image
emulator -avd <avd name>
- root diretory
$ npm start
and run the server - root diretory
$ react-native run-android
will install app to Image(will install to physical device if connected)- use
sudo
for authentication errors - There's no need to recompile the app everytime once the app is running normally on the device, because contect is loaded via
main.jsbundle
.
- use
- after running
ctr + m
orcmd + m
to turn on controller- if button failed, then try: emulator -> settings -> send keyboards shortcuts to -> Emulator controls(default)
- Emulator production testing environment:
$ react-native run-android --variant=release
- run any Image
-
Formal signed version https://facebook.github.io/react-native/docs/signed-apk-android.html
- Please follow the steps above to sign the app
build.gradle
located in android/app directory- compile to
$ cd android && ./gradlew assembleRelease
-
4 different methods to install to device
$ react-native run-android --variant=release
$ npm run android:install
- Remove the installed package from physical device
$ npm run android:build
- Go to
android/app/build/outpus/apk
and runadb install xx.apk
. Make sure there's one device is running - Download
Android File Transfer
, will automatically popup if connected(unlock device, allow USB testing, connect to device)
- Go to
$ cd android && ./gradlew assembleRelease
-
log
$ npm run android:logcat
- Check the log for abnormal app termination. Device must be under the same network as computer.
$ npm start
$ android
$ android avd
$ emulator -avd n4-768
$ react-native run-android
$ react-native run-android --variant=release
$ npm run android:install
$ npm run android:build
$ npm run android:logcat
$ ./gradlew assembleRelease
$ ./gradlew installRelease
$ cd android/app/build/outpus/apk && adb install app-release.apk
Note: see shortcuts in root directory package.json
scripts content
A: Remove image file, rebuild it, then run it again
A: Try remove the installed app first, the reinstall
A: ctrl+m
to open controller, the select Debug JS Remotely
-
Basic installation environment iOS and Android https://facebook.github.io/react-native/docs/getting-started.html
-
iOS simulator installation
- Xcode -> Preferences-> Components -> iOS x.x Simulator
-
Simulator testing
react-native run-ios --simulator "iPhone 7"
cmd + d
to open controllercmd + r
reload
-
Physical device testing
- Xcode config
- Targets -> app -> General -> Signing -> add an iCloud account
- Add team and unique Bundle Identifier. ex. org.reactjs.native.example.app.lwz
- Targets -> app -> General -> Signing -> Team
- Targets -> app -> General -> Signing -> Signing Certificate
- Targets -> app -> General -> Identity -> Bundle Identifier -> update unique id indicator
- Targets -> appTests -> General -> Signing -> Team
- Targets -> appTests -> General -> Signing -> Signing Certificate
Product -> Scheme -> Edit Scheme (cmd + <), make sure you're in the Run tab from the side
update to debug or releaseProject -> app -> Configurations -> use 'debug' for command-line builds
update to debug or release
- Xcode to ensure the usability of app/main.jsbundle, do not add customized index
- main.jsbundle packaging
- Packaging using cURL facebook/react-native#5747
react-native bundle --dev false --platform ios --entry-file ./index.ios.js --bundle-output ./ios/app/main.jsbundle
- this method does not support
npm link
, need tonpm unlink hyphenate-web
- this method does not support
- main.jsbundle packaging
- Debug and release are sharing the same controller, just update the build setting to debug or release on Xcode
- Run app on physical device via Xcode
- will automatically open a packager if there's no packager initiated, then build a release version package
- Note: No relation with local file main.jsbundle. packaging will not update the local version of the file.
- Xcode -> select device -> run
- Trust certification: iOS device -> General -> Device Management -> persion Certificate -> trust it
- You can turn on controller by shaking the phone under debug mode if the app is running successfully.
- Xcode config
- [Signing for requires a development team](https://github.com/CocoaPods/CocoaPo ds/issues/5531)
- Running On Device
$ npm start
$ react-native run-ios --simulator "iPhone 7"
$ react-native run-ios
$ react-native bundle --dev false --platform ios --entry-file ./index.ios.js --bundle-output ./ios/app/main.jsbundle
- Close controller between switch to debug or release
react-native run-ios --simulator "iPhone 7"
. Make sure no physical device is connected to computer, able to compile multiple devices, but will not be able to run them.
A: Try cleaning, turn off package controller, then run the app
A: facebook/react-native#11454
A: fix curl -0 -L http://npmjs.org/install.sh | sudo sh
Include the NativeAnimation module on iOS in the starter projec
A: facebook/react-native#10638
A:
react-native run-ios
do not usesudo
, that will cause app compilation issue for simulator- compiling error
NSLocalizedDescription = "Permission denied";
if not usingsudo
sudo chmod 777 /Users/username/.babel.json
- if still receiving
Permission denied
related problems- make sure the components and files are under the current user's directory not in root
sudo chown -R user:user_group directory_name
Go to File -> Project settings
Click the Advanced button
Select "Custom" and select "Relative to Workspace" in the pull down
click done, done
- App
- Containers | Page | Routing
- App.js main entry point
- Redux/ initialization
- I18n/ initialization
- Config/index.js system initialization
- RootContainer.js root container
- Navigation/NavigationRouter.js initial routing
- /Config/ReduxPersist persistent initialization
- App.js main entry point
- Common components
- I18n multi-languages support
- Images resources
- Lib Web IM initialization
- Navigation routing
- Redux actions / reducers
- Hyphenate web SDK
- Containers | Page | Routing
Redux is a predictable state container for JavaScript apps. Learn more
{
// UI related
ui: [
// ex. UI loading
common: {
fetching:false
},
login: {
username: '',
password: '',
isSigned: false,
},
register: { },
contactInfo: { },
],
im: [],
// data entities
entities: {
roster: {
byName: {
{
jid, name, subscription, groups?
}
},
names: ['lwz2'...],
// friend list is based on roster
friends: [],
},
// subscribe notified
subscribe: {
byFrom: {}
},
room: {},
group: {
byId: {},
names: []
},
members: {
byName: [],
byGroupId: []
}
blacklist: {},
message: {
byId: {}
chat: {
[chatId]: [messageId1, messageId2]
},
groupChat: {
[chatId]: {}
},
}
}
}
- https issue
- splash screen
- hot reloading
- local storage
- Chat optimization, limit the queue length and message pagination
- full loading
React Native SDK is modified due to different browser environment from Hyphenate web SDK. Hyphenate web SDK is not suitable for direct use under react-native environment, please refer the following steps for React Native SDK integration.
- Copy
App/Lib/WebIM.js
andApp/Lib/WebIMConfig.js
WebIM.js
// copy the modified strophe
import '../Sdk/dist/strophe-1.2.8.js'
// modified sdk directory
import websdk from '../Sdk'
// react-native has window object, but not standard browser. Rely on xmldom module for window and document object.
import xmldom from 'xmldom'
// modification of basic messaging: remove some browser dependencies
import config from './WebIMConfig'
// you can modify http components for http request
import Api from '../Services/Api'
let WebIM = window.WebIM = websdk
window.WebIM.config = config
// strophe dependency
window.DOMParser = xmldom.DOMParser
// parse document object
let document = window.document = new DOMParser().parseFromString("<?xml version='1.0'?>\n", 'text/xml')
// establish connection
WebIM.conn = new WebIM.connection({
isMultiLoginSessions: WebIM.config.isMultiLoginSessions,
https: WebIM.config.https,
url: WebIM.config.xmppURL,
isAutoLogin: false,
heartBeatWait: WebIM.config.heartBeatWait,
autoReconnectNumMax: WebIM.config.autoReconnectNumMax,
autoReconnectInterval: WebIM.config.autoReconnectInterval
})
- copy App/Sdk directory
- install dependencies for xmldom
$ npm install --save xmldom
- replace with customized http module
- Demo example: App/Containers/App.js, listen to XMPP event(currently using Redux, you can customize it depending on the framework and method of data processing)
WebIM.conn.listen({
// xmpp connected successfully
onOpened: (msg) => {
// push message after presence
WebIM.conn.setPresence();
// get contacts
store.dispatch(RosterActions.getContacts())
// login successful
store.dispatch(LoginActions.loginSuccess(msg))
// get blacklist
store.dispatch(BlacklistActions.getBlacklist())
// get group list
store.dispatch(GroupActions.getGroups())
NavigationActions.contacts()
},
...
iOS >= 9.0 Android >= 4.1 (API 16)
Note: Development and testing environment is base on Mac.
Current version v0.2.0 @ 2017-01-03