2016年11月3日 星期四

Netinfo in React Native

20161103 Netinfo in React Native

React Native 判斷 NetInfo 這部份的 API 在兩個平台上不大相容

變得有點奇怪

參考這裡面的作法

src/actions/network.js

setIsConnected: (isConnected: boolean): Action => ({
type: 'setIsConnected',
isConnected,
}),
setConnectType: (connectType: string): Action => ({
type: 'setConnectType',
connectType,
}),

src/reducer/network.js

add corresponding reducer

src/entry.js

constructor(props) {
super(props);
// force reset otherwise could be a problem in persist storage
this.props.actions.setIsConnected(false);
this.props.actions.setConnectType(undefined);
}
componentDidMount() {
NetInfo.addEventListener('change', this.dispatchConnected);
// iOS doesn't have to do this
NetInfo.fetch().done(
connectType => this.dispatchConnected(connectType)
);
}
componentWillUnmount() {
NetInfo.removeEventListener('change', this.dispatchConnected);
}
dispatchConnected = (connectType) => {
let isConnected = false;
if (connectType.toLowerCase() !== 'none' && connectType.toLowerCase() !== 'unknown') {
isConnected = true;
}
this.props.actions.setIsConnected(isConnected);
this.props.actions.setConnectType(connectType);
};

Usage

store.network.isConnect boolean
store.network.connectType string

it could be undefined

2016年7月22日 星期五

build iphone app by command line

20160722 build iphone app by commandline

如果沒使用 CocoaPods 的話, -workspace 可以不用指定

假設 project 名字是 hello

$ cd ios && xcodebuild -workspace hello.xcworkspace -scheme hello -destination generic/platform=iOS -configuration Release -derivedDataPath build
$ ios-deploy -b build/Build/Products/Release-iphoneos/hello.app

然後安裝 ios-deploy

這邊要注意的是 build 成 Release才能獨立執行
如果是 Debug 版需要
修改路徑 Release-iphoneos 成 Debug-iphoneos
而且要使用 --debug 去執行

$ ios-deploy --debug -b build/Build/Products/Debug-iphoneos/hello.app

2016年5月8日 星期日

React Native 的 50 道陰影

Intro.

因為最近開始要開發 React Native app
我以前就很想往網頁那塊學
只是人懶沒救
所以 Web 相關的技術我一律都不懂 T__T
寫一下 4/12 到現在的心得


安裝

因為我想要跟 master 的 UIExplorer
所以很多東西是純開發可能不會用到的

因為 MacOS 實在是太方便了, 所以安裝時幾乎沒踩到什麼雷
除了

  1. ndk 要 r10e, 一開始官方教學文件
  2. boost 老是抓不下來
  3. 裝 Nuclide 時沒搞清楚 Hack 幹嘛用,硬是去裝...花了一堆 CPU power 在編 source code...
  4. 因為 flow 實在太吃記憶體了, 對我的 4GB MBA 是種傷害...
    目前還沒有辦法限制他

npm 以前根本沒用到
一開始還不知道 npm 的管理邏輯
把一些該 local module 裝成 global 的
其實要真正裝成 global 的很少
目前只有

npm list -depth 0 -g
/usr/local/lib
├── babel-cli@6.7.7
├── babel-eslint@6.0.4
├── eslint@2.9.0
├── npm@3.8.9
├── react-native-cli@0.2.0
└── rnpm@1.6.5

自己的事處理完了, 開始要管到別人的開發環境
Linux 是第一個坑

  1. 剛安裝後缺少的大大小小的 library / command line tool
  2. Android SDK build tool 要裝 23.0.1
  3. Python 只能 2.7
  4. Node.js 6.0 有遇到奇怪問題,不過忘了是啥 → 改用 4.4.3
  5. break point 無法 resolve (TBD)

Windows 是第二個坑

  • 沒有 Shell → cygwin
  • 沒有 VCBuild MSBuild C++ 開發環境之類的 → VS2013 community
  • ANDROID_HOME 在 cygwin 下的環境設定是原來 windows style
    ex: d:\android\sdk 而不是 /cygdrive/d/android/sdk
  • npm start 不能用 → react-native start
  • packager 起來十分之慢, 如果在他完全 init 完之前就 get index
    js reload 再也沒有用
    → 參考別人的 解法
  • Nuclide 說不支援 Windows, 目前因為沒有用這個在開發, 不知道會遇到啥問題

Nuclide

Atom 裝好 Nuclide 後
預設他不會去安裝 recommend dependency
可能因為每次開啟都會去檢查
所以造成 Atom 啟動很慢
所以安裝完 Nuclide 第一件事先去把第一個選項打開
重開 Atom 讓他安裝
裝完再重開


Javascript

其實我蠻喜歡寫 script language 的
可是 JavaScript 的版本太雜亂其實蠻痛苦的
一開始先花了點時間看 w3schools 的 js 教學
因為大部份很簡單,可以很快速的看範例就看完

Atom 有一個套件叫 script
可以一邊寫純 js 一邊執行
不過他使用的是 babel-node
所以還要另外安裝

React Native 採用 BabelJS 的 transpiler
可是又不是全部都採用
所以看一下官方 文件
學一下需要學到的語法

有時候會看到奇怪的語法
可以到 BabelJS 官網去看他轉成存 JavaScript 的結果
不然這鬼東西一開始誰看得懂啊

var f = store => next => action =>
  Array.isArray(action)
    ? action.map(next)
    : next(action);

Coding style

Style guide

另外學一個新語言去參考別人的 style guide 是蠻重要的
Airbnb 有放出他們的 style guide
有點長... 然後我看完才發現他有中文版 (默

Flow

JavaScript 的動態型別是個大問題
所以早早用 flow 拘束起來是必要的

  • 安裝 flow-bin
  • 每個檔案開頭要有 /* @flow */
  • project 目前下要有 .flowconfig 不然 nuclide 不會理你
  • 指定的 flow 版本不對也不行
    所以開別人專案來參考你可以把版本改掉(少吃記憶體很重要!!!)

Eslint

Atom 套件裝 linter-eslint
這邊是參考一下官方的設定檔
react-native repo 下面的

  • .eslintrc
  • .eslintignore
  • npm 安裝
    • eslint-plugin-react
    • eslint-plugin-flow-vars

重開 Nuclide 才會生效


Localization

目前其實沒有找到喜歡的套件
react-native-localization 將就用吧

iOS 的 locale 字串不一樣
根據設定有時會有這種 zh-Hant-US 字串
iOS9 之後又改了不少
所以為了不讓他 fallback 抓到錯誤的語系
可能要在字串裡加了好幾組重複的
zh-Hant / zh-TW / zh
之類的

另外 npm 上的版本對 android 相容是有問題的
他只會傳回 zh 完全沒辦法使用 region code
而且預設是 zh_TW 這種字串, 跟 iOS 的 zh-TW 打架了
送了一個 PR 解決這問題
merge 了, 不過在沒有新版本前,只能跟 git master

npm install --save github:stefalda/ReactNativeLocalization

rnpm

如果要使用別人跨平台的 module
一個一個手動加設定會加到吐血

npm install -g rnpm

使用範例

rnpm link react-native-localization

source control

因為該死的 Xcode 每次改設定都會亂改一堆不必要段落
所以像使用 rnpm 之前之後盡量只 commit 最小改動


升級

因為 react-native 每兩個星期就發一個 stable 版
改動的幅度都不小
建議跟好 master branch 的 commit, 沒事就看一下
每次 release 新版都要看一下哪些 API changes

像 0.25 版把 React 跟 Component 從 'react-native' 拿掉
改回原來的 'react'
0.25 只會 warning, 0.26 就會正式拿掉了

升級時

$ npm install --save react-native@version
$ react-native upgrade

基本上我都會讓 upgrade 蓋掉所有的 template file
再用 diff 加回去


預設的 package name

react-native cli 好像都沒有處理 package name 這部份
init 時也不會問, upgrade 也不會問
所以像 android 預設的 package name 會變成 com.< project > 這種

因為 android 預設的 package name 其實沒差
最終 play store 只會看 application Id
其實可以不用改路徑

修改的部份

  • android/app/BUCK
  • android/app/build.gradle
    ApplicationId 還有版號
  • android/app/src/main/java/com/< project >/MainActivity.java
    這個路徑改了後,以後 react-native 一樣會產生
    覺得是 optional

執行

React native 開發分成幾個

  • IDE
  • Packager
  • Debugger
  • App @ Device or Emulator

IDE

目前我用了一下 Visual Studio Code
他也是從 Atom 改過來的
不知道是不是我少裝套件還是怎樣
我還是用不大順手

  • IntelliJ IDEA 太肥
    小廟養不起大佛
  • Sublime Text 一直覺得難上手
  • vim? 瘋了嗎?

最後還是決定跟官方的腳步使用 Nuclide

Packager

開發時必要平台相關程式碼已經被打包進 emulator 或機器了
只要改動 js, reload 後 Packager 就會把 bundle 重新丟進 app 裡
Nuclide → react-native → start packager 可以直接在 IDE 開一個 tab 跑起來

另外 live reload 是好東西
js 一存檔,app 上就會把結果顯示出來
不過他如果沒有載入完又存檔一次
就爛惹~~
強制關閉 app 再打開就好了

Debugger

目前還沒開發到大型程度,很少用
主要是用 Nuclide → iOS simulator logs 來看 console.log

app 裡開啟 debug 會直接開 Chrome 出來
所以要先 Nuclide → react-native → Start debugger

打包

如果要 daily use 當然要讓程式直接吃手機上的檔案
所以要把 bundle 丟進去 build
Android 是丟進去當 asset, iOS 是要 main.jsbundle

在新版的 template 這些都被處理好了
Android 只要 build release 版
iOS uncomment AppDelegate.m 到 Option 2

不過像 UIExplorer 裡還沒更新
要手動把 main.jsbundle 加進 project

curl 'http://localhost:8081/Examples/UIExplorer/UIExplorerApp.ios.bundle?platform=ios' -o main.jsbundle

2016年4月6日 星期三

default git email

這次建新的 repository 又忘了改 email... ~/.gitconfig 裡的 user email 是預設值 查了一下可以用

[user]
 name = Elvis Chiang
# email = email@default.one
 useConfigOnly = true

這樣每次使用新的 repository 時就會提醒你設定新的 email

git config user.email hello@github.com

Github 上已經上傳的 commit 可以使用官方提供的 script

Changing author info

原來的 repository 只要重新 git pull --rebase 就好

2016年4月2日 星期六

Telegram Bot

最近有在玩 Walkr, 覺得查詢資訊有點麻煩

就跑去玩了一下 Telegram Bot

寫一下心得

API document

API Document

有蠻詳細的步驟

One bot rules them all

所以要跟官方的 @BotFather 註冊

/newbot

取得 token

Bot 的運作

  • 基本上就是執行程式, bot 會去跟 server 註冊,然後 looping 等使用者下指令
  • 更改了 bot 設定, 好像要結束對話才行, 不太知道怎重啟

找東西來抄

官網上就有列了一下列表

因為我打算練習一下 Golang, 所以有人已經串好 API 可以用了

Telegram Bot API for Golang

go get bitbucket.org/mrd0ll4r/tbotapi

範例在

$(GOROOT)/src/bitbucket.org/mrd0ll4r/tbotapi/examples

基本上看 echo.go 還有 photo.go 就可以寫出簡單的功能了

送 Photo 的部份,他 API 裡預設是沒有設定標題

api.NewOutgoingPhoto(tbotapi.NewRecipientFromChat(msg.Chat), "example.png", file).Send()

可以改用

photo := api.NewOutgoingPhoto(tbotapi.NewRecipientFromChat(msg.Chat), "example.png", file)
photo.setCaptain("blah")
photo.Send()