0%

关于React Native的详细介绍我就不叙述了,他是使用js构建原生app的开发框架。一次编码多平台运行,非常强大。但是个人不喜欢js的过于灵活(弱类型)的语法。强大的强类型语言Typescript(简称TS)是我的首选,他可以编译成JavaScript,编译成的JavaScript代码可读性很好,但是这不是关键,关键是TS开发和调试效率极高。
但是React Native官方是使用js的开发的,如果如果使用TS开发React Native的关键是transformer
eact-native结合的关键是使用转换器

初始化项目

1
2
3
react-native init YahuiApp
cd YahuiApp
yarn add --dev react-native-typescript-transformer typescript @types/react @types/react-native

用vscode打开 添加配置文件

配置Typescript

新建文件 tsconfig.json内容为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
"compilerOptions": {
"module": "es2015",
"target": "es2015",
"moduleResolution": "node",
"jsx": "react-native",
"noImplicitAny": true,
"experimentalDecorators": true,
"preserveConstEnums": true,
"sourceMap": true,
"watch": true,
"allowSyntheticDefaultImports": true
},
"filesGlob": [
"src/**/*.ts",
"src/**/*.tsx"
],
"exclude": [
"index.android.js",
"index.ios.js",
"build",
"node_modules"
]
}

新建文件 tslint.json 内容为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
{
"rules": {
"class-name": false,
"comment-format": [
true,
"check-space"
],
"indent": [
true,
"spaces"
],
"no-duplicate-variable": true,
"no-eval": true,
"no-internal-module": true,
"no-trailing-whitespace": true,
"no-unsafe-finally": true,
"no-var-keyword": true,
"one-line": [
true,
"check-open-brace",
"check-whitespace"
],
"quotemark": [
true,
"double"
],
"semicolon": [
true,
"always"
],
"triple-equals": [
true,
"allow-null-check"
],
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
}
],
"variable-name": [
true,
"ban-keywords"
],
"whitespace": [
true,
"check-branch",
"check-decl",
"check-operator",
"check-separator",
"check-type"
]
}
}

配置React Native Packager

根目录新建rn-cli.config.js文件 内容为:

1
2
3
4
5
6
7
8
9
10
11
12
13
    module.exports = {
getTransformModulePath() {
return require.resolve('react-native-typescript-transformer');
},
getSourceExts() {
return [ 'ts', 'tsx' ]
}
};
<!-- 修改package.json 文件 的scripts start
"scripts": {
"start": "react-native start --transformer node_modules/react-native-typescript-transformer/index.js --sourceExts ts,tsx",
"test": "jest"
}, -->

编写代码

在 src文件夹里新建main.tsc文件
代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
    import React, { Component } from "react";
import {
StyleSheet,
Text,
View
} from "react-native";

interface Props {

}

interface State {

}

export default class App extends Component<Props, State> {
render() {
return (
<View style={styles.container}>
<Text style={styles.text}>
Welcome to React Native!
</Text>
</View>
);
}
}

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#F5FCFF",
} as React.ViewStyle,

text: {
fontSize: 20,
textAlign: "center",
margin: 10,
} as React.TextStyle,
});
AppRegistry
import {
AppRegistry,
} from 'react-native';
import App from "./src/main";

AppRegistry.registerComponent('YahuiApp', () => App);

至此 您的使用TS开发React Native的项目环境搭建好了

最终代码在:https://github.com/YahuiWong/react-native-typescript 如果觉得有用,请Star

转载请注明出处:https://blog.yahui.wang/2017/08/26/react-native-typescript-init-debug/

查询端口映射情况

netsh interface portproxy show v4tov4
查询这个IP所有的端口映射。
netsh interface portproxy show v4tov4|find “192.168.1.1”

增加一个端口映射

netsh interface portproxy add v4tov4 listenport=外网端口 listenaddress=主IP connectaddress=私网IP connectport=私网IP端口
例如:
netsh interface portproxy add v4tov4 listenport=8888 listenaddress=118.123.13.180 connectaddress=192.168.1.10 connectport=2222

删除一个端口映射

netsh interface portproxy delete v4tov4 listenaddress=主IP listenport=外网端口
例如:
netsh interface portproxy delete v4tov4 listenaddress=118.123.13.180 listenport=8888

ios审核被拒

ios app上线的时候应为检测到app里面含有私有api被拒了,头疼,代码这么多怎么快速定位是哪里的代码出的问题呢

解决办法

这里介绍一个网易游戏开源的检测项目中是否含有私有api的项目 iOS-private-api-checker
整个开源项目是用python写的,虽然项目里面有readme.md介绍说明文件,但是对于没有接触过python项目的人可能还是有点陌生的。这里就详细介绍些如何使用此项目检测

clone项目到本地

git clone https://github.com/NetEaseGame/iOS-private-api-checker
cd iOS-private-api-checker

安装依赖python包`

请确认你的mac上已经安装好了,pip 如果没有的话 运行 sudo easy_install pip

pip install flask
pip install macholib

生成IOS项目SDK版本的私有api库

修改 config.py文件

现在的版本默认是 'sdk': '8.1'修改 sdks_config.append的参数为你的sdk版本
比如说我是10.3的版本
修改成了

sdks_config.append({
    'sdk': '10.3',
    'framework': '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator10.3.sdk/System/Library/Frameworks/',
    'private_framework': '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator10.3.sdk/System/Library/PrivateFrameworks/',
    'docset': '/Applications/Xcode.app/Contents/Developer/Documentation/DocSets/com.apple.adc.documentation.docset/Contents/Resources/docSet.dsidx'
})

开始重新生成api数据库

过程稍慢,生成时间由电脑配置高低决定,耐心等待下

python build_api_db.py

运行项目

在根目录创建一个 tmp 目录,并设置 777 权限

mkdir tmp
chmod -R 777 tmp/

之后运行

python run_web.py

上传ipa文件

根据上个页面的提示打开 http://0.0.0.0:9527
托转你的api文件到网页提示的区域 等待一下就可以在Private API in APP得到检测结果

检测检测并导出结果excel

修改目录下的 iOS_private.py文件

修改 ipa_folder的值为你的ipa文件所在的目录的路径

批量生成

python iOS_private.py

在tmp文件夹里可以找到生成好的xlsx文件

react native简介和安装

React Native使你能够在Javascript和React的基础上获得完全一致的开发体验,构建世界一流的原生APP。

React Native着力于提高多平台开发的开发效率 —— 仅需学习一次,编写任何平台。(Learn once, write anywhere)

Facebook已经在多项产品中使用了React Native,并且将持续地投入建设React Native。

关于react native的详细简介和安装教程可以在 官方入门教程 或者中文版安装介绍教程 查看学习,这里不做过多介绍了

react-native弹性布局

react-native 的生命周期

react-native View&Text

react-native 组件之间的通讯

react-native Navigator

nodejs

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。 Nodejs的包管理器 npm,是全球最大的开源库生态系统。

nodejs各平台安装

http-server

安装

打开命令终端 执行 npm install http-server -g 等待安装完毕即可

使用

在您想快速搭建静态文件访问的文件夹里 执行 http-server 就可以看到打印出来的可以访问的http地址和端口号 打开浏览器访问试试吧

nodejs

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。 Nodejs的包管理器 npm,是全球最大的开源库生态系统。

安装

windows下安装

window下安装是最简单的

1. 打开 nodejs官网

2. 下载适合您电脑的安装程序

current版本为例,打开 https://nodejs.org/en/download/current/ 点击Windows Installer 下载安装程序

3. 打开安装程序开始安装

默认ndoejs 就会 add to path 所以不需要手动添加path路径了,选择安装路径,之后下一步… 安装即可

4. 检查安装是否成功

按 Win+R 输入cmd 打开命令行工具
输入

node --version

查看安装好的nodejs的版本

v7.10.0

mac下安装

1. 先安装mac下的开发包管理工具brewhome(已经装过的跳过此步骤)

打开brew官网
拷贝安装命令

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

打开 应用程序=>实用工具=>终端 把刚刚拷贝的命令粘贴到终端 回车 根据提示输入管理员密码 等待安装完毕

2.执行 brew install nodejs 安装nodejs

linux 下安装

1. 打开下载地址

  1. 找到和您电脑适配的linux版本 点击下载,或者复制下载地址 在命令终端 使用wget 下载那个编译好的tar.xz文件

解压文件终端执行 tar xvJf node-v7.10.0-linux-x64.tar.xz
2. 把解压好的文件夹拷贝到你想放置的位置
sudo cp -PRv node-v7.10.0-linux-x64 /usr/local/nodejs
3. 添加PATH
export PATH=$PATH:/usr/local/nodejs添加到你的path中

flex布局方式又称弹性布局,主要要用到的属性有flexDirection,justifyContent,alignItems,alignSelf,flexWrap,flex,position,margin,padding

flexDirection

该属性确定了子组件主轴排序方向,枚举值。

row(默认)         主轴方向为水平,起点在左端。
row- reverse      主轴方向为水平,起点在右端
column    主轴方向为垂直,起点在上端
column-reverse        主轴方向为垂直,起点在下端

justifyContent

该属性确定了组件在主轴方向上的对齐方式,枚举值。

flex-start(默认)   组件沿着主轴方向的起始位置靠齐。如:假如主轴方向是row的话就是左对齐,是row- reverse的话就是右对齐,是column的话就是上对齐,是 column-reverse的话就是下对齐。
flex-end            组件沿着主轴方向的结束位置靠齐,和flex-start相反。
space-between  组件在主轴方向上两端对齐,其中的间隔相等。
space-around   组件会平均分配在主轴方向上,两端保留一定的位置空间。

alignItems

组件在侧轴方向上的对齐方式。
flex-start 组件沿着侧轴上的起点对齐
flex-end 组件沿着侧轴上的终点对齐
center     组价在侧轴方向上居中对齐
stretch(默认)  组件在侧轴方向上占满

flexWrap

是否换行 默认情况下,项目都排列在一条线上,放不下的部分则不放置,flexWap就是定义是否换行的。

nowrap(默认)   不换行
wrap            换行,第一行在上方
wrap-reverse    换行,第一行在下方

flex

有三个参数,默认参数为 0 1 auto。 第一个参数为flex-grow,第二,第三个为:flex-shrink和flex-basis。

alignSelf

定义单个组件自己的对齐方式,默认为auto。枚举值:auto|flex-start|flex-end|center|baseline|stretch

position

枚举值,absolute绝对定位,relative相对定位

margin

内边距

padding

外边距

为什么会有redux

react-native中的state

state 组建的属性,主要是用来储存组件自身需要的属性,每次修改都会修改state的值,react 内部会坚挺state属性的变化,一旦发生变化,就会主动触发组件的render方法

redux带来了什么

我们都知道 react的思维是组件化来构建我们的页面。在项目中单个组件通过修改state的方式重新渲染页面是没什么问题的,但是当页面繁多,功能复杂,组件之间交互频繁的时候还去重新渲染界面的话,单个操作就可能导致前端卡到爆炸!!!

所以 FaceBook在14年提出了Flux架构的概念,紧随其后 redux在15年就应景而生。完美解决了react搭建大型复杂项目所有到的问题。

redux重要的三点

应用中素有的state都以一个对象树的形式存储在一个单一的store中。

唯一改变state的方法是触发action

通过reducers描述action如何改变state树

redux状态管理的流程

为了便于理解我们可以看下图

redux各模块之间的联系

action

用户触发或者程序触发

reducer

根据action操作来租出不同的数据相应,更新state

store

store最终的值来自reducer,reducer修改store对象的某些值,然后改变UI

状态改变的流程

状态改变的流程

action=>reducer=>更新之后的store=>UI更新

建议入门项目

1.example-react-native-redux

参考资料:

1. Redux 中文文档

2. Redux 官方文档

3. ReactNative 架构Redux研究

4. React-Native项目为什么要使用redux

开发环境搭建Hello World

  1. 安装Xcode

  2. File => New => Playground

     import UIKit
     var str = "Hello World,yahue"
    

在Playground 就可以看到Hello World,yahue

数据类型

内置类型:

swift内置类型非常丰富,列举几个

int:整型

  1. 长度和运行平台对应

    32位平台=>Init32
    64位平台=>Init64

  2. 长度范围:-2,147,483,648~2,147,483,647

UInt 无符号整型

浮点数

Double

表示64位浮点数。当你需要存储很大或者很高精度的浮点数时请使用此类型。

Float

表示32位浮点数。精度要求不高的话可以使用此类型。

Double精确度很高,至少有15位数字,而Float最少只有6位数字。选择哪个类型取决于你的代码需要处理的值的范围。

布尔值

Boolean 值有true和false

… 不一一介绍内置类型了

类型别名

对当前类型定义一个别名
如:
import Cocoa

typealias meter = Int
var distance: meter = 10086
print(distance)

playground 执行以上程序,输出结果为:

10086

类型安全

swift是个强类型的语言,声明之后不能修改类别
如以下代码:
import Cocoa

var a = 10010
a = "10086"
print(a)

在xcode中会直接提示错误

error: cannot assign value of type 'String' to type 'Int'
a = "10086"

类型申明

类型声明的方式有多重
###var 声明一变量

变量是一种使用方便的占位符,用于引用计算机内存地址。

如代码:

import Cocoa

var var1 = 421
print(var1)

var var2:Float

var2 = 3.1415926
print(var2)

输出:
421
3.1415926
###let 声明一个常量

申明方式和var一样,但是意义不一样
常量一旦设定,在程序运行时就无法改变其值。

可选类型的申明

可选(Optional)类型,用于处理值缺失(值为null)的情况。

申明方式:

var optionalInteger: Int?
var optionalInteger: Optional<Int>

代码示例:
import Cocoa

var vars1:String? = nil

if vars1 != nil {
    print(vars1)
}else{
    print("字符串为 nil")
}

运行结果:

字符串为 nil

强制获取值:

import Cocoa

var vars1:String? = nil
vars1="hello http://blog.yahui.wang"
  print(vars1)
if vars1 != nil {
    print(vars1!) //强制获取值
}else{
    print("字符串为 nil")
}

执行结果:

Optional("hello http://blog.yahui.wang")
hello http://blog.yahui.wang

自动解析值

!?

?

上面我们说到 这两种声明方式是一样的
var optionalInteger: Int?
var optionalInteger: Optional
查看Optional的文档可以知道Optional只是一个枚举
enum Optional : LogicValue, Reflectable
也就是说当你使用var varS: String?的时候 你是“申明了一个Optional类型值,它可能包含一个String值,也可能什么都不包含”
不要以为是 “我声明了一个Optional的String值”

!

一下代码意义一样
var optionalInteger: Int! //!相当于下面这种写法的语法糖
var optionalInteger: ImplicitlyUnwrappedOptional

Implicitly Unwrapped Optionals, 直译就是隐式拆包的Optional,也就是说每次使用这个值的时候都会自动在变量后面加上个!拆包,当值为nil的时候 肯定会报错

那么!大概也有两种使用场景
1.强制对Optional值进行拆包(unwrap)
2.声明Implicitly Unwrapped Optionals值,一般用于类中的属性

执行流控制

条件语句

if … else

switch

循环

for

for in

while

repeat while

循环控制

continue

break

fallthough

字符串和字符

数组

字典

函数

函数

闭包

枚举

结构体和类

共同点

  1. 定义属性用于存储值
  2. 定义方法用于提供功能
  3. 定义附属脚本用于访问值
  4. 定义构造器用于生成初始化值
  5. 通过扩展以增加默认实现的功能
  6. 符合协议以对某类提供标准功能

类还有如下的附加功能:

  1. 继承允许一个类继承另一个类的特征
  2. 类型转换允许在运行时检查和解释一个类实例的类型
  3. 解构器允许一个类实例释放任何其所被分配的资源
  4. 引用计数允许对一个类的多次引用

属性

存储属性

延迟存储属性

实例化变量

计算属性和只读计算属性

只有 getter 没有 setter 的计算属性就是只读计算属性。

属性观察器

全局变量和局部变量

类型属性

获取和设置类型属性的值

方法

下标脚本

继承

构造过程和拆构过程

构造过程是类初始化
拆构过程是类被释放时执行

可选链

ARC 自动引用计数

类型转换

扩展

协议

访问控制

泛型

golang中如果你定了一个struct T,有个可以定义一个接收者为T的函数来使T更强大

但是T作为receiver有两种形式:

一种是T本身,另一种是*T,即T的指针形式

但作为T本身是 方法里的操作 相当于把 T 复制了一份出来

如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package main

import (
"fmt"
)
func main() {
var persion=Persion{Name:"Tom",Age:10}
fmt.Println(persion)
persion.Say("hello yahui")
fmt.Println(persion)
}
type Persion struct
{
Name string
Age int
}
func (p Persion) Say(word string) {
p.Name="Jack"
fmt.Println(p.Name,"Say",word)
}

输出:

1
2
3
4
5

{Tom 10}
Jack Say hello yahui
{Tom 10}

但作为*T是方法里的操作是真正的正在引用T

如以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package main

import (
"fmt"
)
func main() {
var persion=Persion{Name:"Tom",Age:10}
fmt.Println(persion)
persion.Say("hello yahui")
fmt.Println(persion)
}
type Persion struct
{
Name string
Age int
}
func (p *Persion) Say(word string) {
p.Name="Jack"
fmt.Println(p.Name,"Say",word)
}

输出:

1
2
3
{Tom 10}
Jack Say hello yahui
{Jack 10}