## Scheme

业务在某些时候需要自己拼接 Scheme 用于让去哪儿旅行打开相应的 url，其规则如下：

### Protocol - phoneScheme

不用的 App 对应不同的名称，同时这个名称，也存在于 App 内置 WebView 的 UserAgent 内。常用的如下：

* Android 大客户端: `qunaraphone`
* iPhone 大客户端 Free 版: `qunariphone`
* iPhone 大客户端 Pro 版: `qunariphonepro`

独立客户端，应该有各自的名称，可以问对应业务线的 App 的开发。

### Path

Hy 方案提供的 path 为 `hy`。

### Params

提供的参数有：

* `url`: 目标页面url，需 encodeURIComponent
* `type`: WebView 形态。
 * 默认（navibar-normal）: 存在 native 导航条
 * navibar-none: 不存在 native 导航条（全屏 WebView）
 * browser: 给第三方页面提供的 WebView
* `name`: 页面名称，应具有唯一性，用于路由定位
* `navigation`: 当 type 为 navibar-normal 时，native 导航条的配置。需将配置 data， JSON.stringify 后 encodeURIComponent。(具体配置可见下文)
* `method`: 请求方式。 默认为 0（GET），可选 1（POST）

### 拼接

拼接规则规则为: `protocol + '://' + path + paramQuery`

例如: `qunariphone://hy?url=http%3A%2F%2Fued.qunar.com%2Fhy2%2Fhysdk%2Fdemo%2F&name=hysdk-demo&type=navibar-none`

## 导航参数
### normal导航栏选项
当webView的type类型为navibar-normal时，`navigation` 参数各字段详细解释如下：

```js
navigation: {
    color: colorOptions     // 颜色属性
    title: titleOptions,    // 导航栏标题位置配置
    left: leftOptions,      // 导航栏左侧按钮配置
    right: rightOptions,    // 导航栏右侧按钮配置
}
```
#### 颜色属性
`color` 字段用于设定导航栏以及导航栏上按钮的颜色, 所有的color都是可选的，不设置则使用的是默认值

```js
color: {
    backgroundColor: '#000000', //背景颜色
    textColor: {
        normal: '#FF0000', //文字普通颜色
        selected: '#8464E3' //文字选中颜色
    }
}
```

`title`、`left`、`right`字段都可以设置color属性，背景颜色和文字颜色设置优先级为：元素内部color结构>外部默认color结构>框架默认颜色。 left和right可以为数组，数组的每一项都支持 color:{} 参数设置的结构。这个结构为默认统一的结构。如下：

```js
color: {
    backgroundColor: '#xxxxxx', //背景颜色 (因为iOS中按钮不存在背景颜色，所以在iOS中不起作用)
    textColor: {
        normal: '#xxxxxx', //文字普通颜色
        selected: '#xxxxxxx' //文字选中颜色
    }
}
```

当title里面的style为segment时，title里面的color结构比较特殊。为导航条特别设置的color结构。如下：

```js
color: {
    backgroundColor: {
        normal: '#xxxxxx', //背景普通颜色
        selected: '#xxxxxx' //背景选中颜色
    },
    textColor: {
        normal: '#xxxxxx', //文字普通颜色
        selected: '#xxxxxx' //文字选中颜色 (iOS中不能设置,iOS中segment选中按钮的文字为透明，显示的颜色为navigationBar的颜色)
    }
}
```

#### title字段
`title` 字段用于定义导航栏标题区域。可以有以下几种取值：

- 文字标题  
![](./images/navtitle1.png)

```js
title: {
    style: 'text',
    text: '标题',
    color: { //和外层color相同，优先级高于外层，图中是没有设置color，使用的默认颜色
        backgroundColor: '#xxxxxx', //背景普通颜色
        textColor: {
            normal: '#xxxxxx', //文字普通颜色
            selected: '#xxxxxx' //文字选中颜色
        }
    }
}
```

- 位置类标题  
![](./images/navtitle2.png)

```js
title: {
    style: 'location',
    text: '北京',
    color: { //和外层color相同，优先级高于外层，图中是没有设置color，使用的默认颜色
        backgroundColor: '#xxxxxx', //背景普通颜色
        textColor: {
            normal: '#xxxxxx', //文字普通颜色
            selected: '#xxxxxx' //文字选中颜色
        }
    }
}
```

- 分段选择按钮  
![](./images/navSegmentTitle.png)

```js
title: { // 指定标题
    style: 'segment',
    segments: [{
        title: 'A',
        name: 'a'
    }, {
        title: 'B',
        name: 'b'
    }],
    color: { //和外层color相同，优先级高于外层，图中是没有设置color，使用的默认颜色
        backgroundColor: {
            normal: '#xxxxxx', //背景普通颜色
            selected: '#xxxxxx' //背景选中颜色
        },
        textColor: {
            normal: '#xxxxxx', //文字普通颜色
            selected: '#xxxxxxx' //文字选中颜色
        }
    }
}
```

#### left字段
`left`字段用于定义导航栏左侧区域。可以有以下几种取值：

- native返回  
![](./images/navbutton1.png)  
不写left字段即可
- 文字按钮

**left和right的文字的长度限制：ios最多显示四个汉字，adr最多显示两个汉字。如果想显示更多的文字，可以考虑不使用native的header。**

![](./images/navbutton2.png)  

``` js
left: {
    style: 'text',
    text: '按钮',
    name: 'leftButton', // 可选，不设置则默认为left
    color: { //和外层color相同，优先级高于外层，图中是没有设置color，使用的默认颜色
        backgroundColor: {      // iOS中按钮无背景，故设置无效
            normal: '#xxxxxx',  //背景普通颜色
            selected: '#xxxxxx' //背景选中颜色
        },
        textColor: {
            normal: '#xxxxxx', //文字普通颜色
            selected: '#xxxxxx' //文字选中颜色
        }
    }
}
```

- 图标按钮  
![](./images/navbutton3.png)  

``` js
left:{
    style: 'icon',
    icon: '\uF067',
    //icon类型 设置color无效
}
```  

icon按钮需要事先向应用中嵌入相应的web font字体文件。[icon编码查看](http://iconfont.corp.qunar.com/projects/473)

#### right字段
`right`字段用于定义导航栏右侧区域。除去不具备native返回功能之外，与`left`字段相同。

**left和right的文字的长度限制：ios最多显示四个汉字，adr最多显示两个汉字。如果想显示更多的文字，可以考虑不使用native的header。**

除此之外，对于左右按钮可以通过action指定其完成特定的native功能：

```js
{
    style: 'icon',
    icon: '\uf0cc',
    action: 'share'
}
```

right字段也支持数组来设置多个按钮

```js
right: [{
    style: 'icon',
    icon: '\uf0cc',
    action: 'share'
}, {
    style: 'text',
    text: '第二个按钮',
    name: 'button2', // 可选，不设置则默认为right，通过调用 QunarAPI.hy.onNavClick 可以监听到按钮的点击，根据按钮的名字就可以定位到被点击的按钮
}]
```

目前支持的action取值： `share`，弹出分享界面。

### transparent导航栏选项
当webView的type类型为navibar-transparent时，`navigation`参数各字段详细解释如下：

```js
navigation: {
    left: [{
        //第一个按钮默认为返回键
        icon: '\uf066',
        name: 'leftButton1',

    }, {
        icon: '\uf078',
        name: 'leftButton1',
    }],
    right: [{
        icon: '\uf067',
        name: 'rightButton1',
    }, {
        icon: '\uf068',
        name: 'rightButton2',
    }],
}
```

使用默认的按钮颜色如下：  
![](./images/nav-trans-default.png)

#### left字段
`left`字段为数组，用于定义导航栏左侧区域的多个按钮，第一个按钮默认为返回键 对按钮的颜色的设置均为选填（PS：android的颜色设置在开发中～）

```js
// 指定左侧按钮
 left: [{
            icon: '\uf066',             // 按钮样式，应用此字段作为图标
            name:'leftButton1',         // 按钮名称，用于区分点击的按钮
            foregroundColor:'#0000FF',  // 图标色，可选
            backgroundColor:'#00FF00',  // 图标填充色，可选
            borderColor:'#FF0000',      // 图标边框颜色，可选
        },{

            icon: '\uf078',
            name:'leftButton2',         
            foregroundColor:'#0000FF',
            backgroundColor:'#00FF00',
            borderColor:'#FF0000',
            action:'share'              // 点击时的native功能，目前只支持'share'，可选
        }],
```

使用上面的颜色设置的按钮结果为：  
![](./images/nav-trans.jpg)  

#### right字段
`right`字段定义和`left`一致，不过第一个按钮并不是返回键

## 错误码
### 错误码规则
每次调用接口时，可能获得正确或者错误的返回码，开发者可以根据返回码信息调试接口，排查错误。

<p><font color="#ff0000">优先从各插件返回码中找，如果没有符合的，再到通用错误码中找</font></p>

错误码规则说明：

<p><font color="#ff0000"><b><ins>1</ins></b></font><font color="#000000"><b> </b></font><font color="#ff0000"><b><ins>00</ins></b></font><font color="#000000"><b>  </b></font><font color="#ff0000"><b><ins>01</ins></b></font></p>

错误码由三部分组成：

第一部分：1、代表通用，2、代表qunarapi，3、代表业务插件
第二部分：插件编码，由两位组成
第三部分：错误编码

### 全局返回码
#### 通用返回码
<table style="text-align:center">
	<tr>
		<th> 返回码 </th>
		<th> 说明 </th>
	</tr>
	<tr>
		<td> 10001</td>
		<td> api不存在</td>
	</tr>
	<tr>
		<td> 10002</td>
		<td> 参数类型不合法</td>
	</tr>
	<tr>
		<td> 10003</td>
		<td> 参数不能为空</td>
	</tr>
	<tr>
		<td> 10004 </td>
		<td> 参数错误 </td>
	</tr>
	<tr>
		<td> 10005</td>
		<td> 数据获取失败</td>
	</tr>
	<tr>
		<td> 10006</td>
		<td> 功能不支持</td>
	</tr>
	<tr>
		<td> 10007</td>
		<td> 日期格式错误</td>
	</tr>
	<tr>
		<td> 10008 </td>
		<td> 日期范围错误</td>
	</tr>
	<tr>
		<td> 10009 </td>
		<td> 远端服务不可用</td>
	</tr>
	<tr>
		<td> 10010  </td>
		<td> 超时</td>
	</tr>
	<tr>
		<td> 10011 </td>
		<td> 发生异常 </td>
	</tr>
</table>

#### HySDK
**1 checkJsApi**
<table style="text-align:center">
    <tr>
        <th>返回码</th>
        <th>说明</th>
        <th>平台</th>
        <th>备注</th>
    </tr>
    <tr>
        <td>10003</td>
        <td>参数不能为空</td>
        <td>iOS(80011101)</td>
        <td>jsApiList数组以及<br/>数组中的每一项都不为空</td>
    </tr>
    <tr>
        <td>10011</td>
        <td>发生异常</td>
        <td>Android(Browser:27)</td>
        <td></td>
    </tr>
</table>

**2 分享**
<table style="text-align:center">
	<tr>
		<th>返回码</th>
		<th>说明</th>
		<th>平台</th>
		<th>备注</th>
	</tr>
	<tr>
		<td>20101</td>
		<td>当前微信的版本不支持</td>
		<td>iOS(80011101)</td>
		<td>版本太低</td>
	</tr>
	<tr>
		<td>20102</td>
		<td>未安装微信</td>
		<td>iOS(80011101)</td>
		<td></td>
	</tr>
	<tr>
		<td>20103</td>
		<td>分享失败</td>
		<td>iOS(80011101)，Android(Browser:27)</td>
		<td></td>
	</tr>
</table>

**3 定位**
<table style="text-align:center">
    <tr>
        <th>返回码</th>
        <th>说明</th>
        <th>平台</th>
        <th>备注</th>
    </tr>
    <tr>
        <td>20201</td>
        <td>定位超时</td>
        <td>iOS(80011101)，Android(Browser:27)</td>
        <td></td>
    </tr>
    <tr>
        <td>20202</td>
        <td>定位出现错误</td>
        <td>iOS(80011101)</td>
        <td>超时，没有权限，定位不可用的错误码都为20202(以后可以扩展开)</td>
    </tr>
</table>

**4 登录**
<table style="text-align:center">
    <tr>
        <th>返回码</th>
        <th>说明</th>
        <th>平台</th>
        <th>备注</th>
    </tr>
    <tr>
        <td>20301</td>
        <td>登录失败</td>
        <td>iOS(80011101)，Android(Browser:27)</td>
        <td></td>
    </tr>
    <tr>
        <td>20302</td>
        <td>同步登录态失败</td>
        <td>iOS(80011101)，Android(Browser:27)</td>
        <td></td>
    </tr>
    <tr>
        <td>20303</td>
        <td>网络错误</td>
        <td>Android(Browser:27)</td>
        <td></td>
    </tr>
        <tr>
        <td>10005</td>
        <td>数据获取失败</td>
        <td>Android(Browser:27)</td>
        <td></td>
    </tr>
</table>

**5 UI相关**
<table style="text-align:center">
    <tr>
        <th>返回码</th>
        <th>说明</th>
        <th>平台</th>
        <th>备注</th>
    </tr>
    <tr>
        <td>10003</td>
        <td>参数不能为空</td>
        <td>Android(Browser:27)</td>
        <td></td>
    </tr>
    <tr>
        <td>10004</td>
        <td>参数错误</td>
        <td>iOS(80011101)，Android(Browser:27)</td>
        <td>1、不合法的URL，比如非字符串<br/>2、URL为空</td>
    </tr>
    <tr>
        <td>10005</td>
        <td>数据获取失败</td>
        <td>Android(Browser:27)</td>
        <td></td>
    </tr>
    <tr>
        <td>20401</td>
        <td>页面不存在</td>
        <td>iOS(80011101)，Android(Browser:27)</td>
        <td>没有对应name的webview</td>
    </tr>
    <tr>
        <td>20402</td>
        <td>新开页面异常</td>
        <td>iOS(80011101)</td>
        <td></td>
    </tr>
    <tr>
        <td>20403</td>
        <td>刷新导航条异常</td>
        <td>iOS(80011101)，Android(Browser:27)</td>
        <td></td>
    </tr>
</table>

**6 图片上传**
<table style="text-align:center">
	<tr>
	<th > 返回码 </th>
		<th>说明 </th>
		<th>平台 </th>
		<th>备注 </th>
	</tr>
	<tr>
		<td>10005</td>
		<td>数据获取失败</td>
		<td>iOS(80011101) </td>
		<td>获取ServerId失败 </td>
	</tr>
	<tr>
		<td>10004 </td>
		<td>参数错误</td>
		<td>Android(Browser:27)</td>
		<td>参数count不合法，count最大值是9，最多选择9张图片  </td>
	</tr>
	<tr>
		<td>20501 </td>
		<td>用户取消 </td>
		<td>iOS(80011101)</td>
		<td></td>
	</tr>
	<tr>
		<td> 20502 </td>
		<td> 已达到选择图片数上限 </td>
		<td> iOS(80011101)，Android(Browser:27) </td>
		<td></td>
	</tr>
	<tr>
		<td> 20503 </td>
		<td> 相机拍照失败  </td>
		<td> iOS(80011101)，Android(Browser:27) </td>
		<td></td>
	</tr>
	<tr>
		<td> 20504 </td>
		<td> 图片上传失败 </td>
		<td> iOS(80011101)，Android(Browser:27) </td>
		<td></td>
	</tr>
	<tr>
		<td> 20505 </td>
		<td> 图片服务器不合法 </td>
		<td> iOS(80011101) </td>
		<td> 非Qunar域的url都算不合法 </td>
	</tr>
	<tr>
		<td> 20506  </td>
		<td> 参数错误1  </td>
		<td> iOS(80011101) </td>
		<td> localId不在已选图片内  </td>
	</tr>
	<tr>
		<td> 20507  </td>
		<td> 参数错误2  </td>
		<td> iOS(80011101) </td>
		<td> localId参数错误  </td>
	</tr>
	<tr>
		<td> 20508 </td>
		<td> 保存图片失败  </td>
		<td> Android(Browser:27), iOS(80011101)  </td>
		<td></td>
	</tr>
	<tr>
		<td> 20509 </td>
		<td> 预览图片失败  </td>
		<td> Android(Browser:27)  </td>
		<td></td>
	</tr>
	<tr>
		<td> 20510 </td>
		<td> 下载图片失败  </td>
		<td> Android(Browser:27)  </td>
		<td></td>
	</tr>
	<tr>
		<td> 20512 </td>
		<td> 选择相册图片失败  </td>
		<td> Android(Browser:27), iOS(80011101)  </td>
		<td></td>
	</tr>
</table>

### 业务错误码
#### 忘记密码
<table style="text-align:center">
	<tr>
		<th> 返回码 </th>
		<th> 说明 </th>
		<th> 平台 </th>
		<th> 备注 </th>
	</tr>
	<tr>
		<td> 30601 </td>
		<td> 用户取消重置密码 </td>
		<td> iOS(80011101)</td>
		<td></td>
	</tr>
	<tr>
		<td> 30602 </td>
		<td> 选择国别码错误</td>
		<td> Android(Browser:27) </td>
		<td></td>
	</tr>
	<tr>
		<td> 30603 </td>
		<td> 绑定银行卡错误</td>
		<td> Android(Browser:27), iOS(80011101)</td>
		<td></td>
	</tr>
	<tr>
		<td> 30604 </td>
		<td> 重置密码错误</td>
		<td> Android(Browser:27)</td>
		<td></td>
	</tr>
	<tr>
		<td> 10011 </td>
		<td> 发生异常 </td>
		<td> Android(Browser:27)</td>
		<td></td>
	</tr>
</table>

## 苹果设备映射表
### iPhone
| model | 型号 |
| :-----: | :-----: |
|iPhone1,1| iPhone 2G (A1203)|
|iPhone1,2| iPhone 3G (A1241/A1324)|
|iPhone2,1| iPhone 3GS (A1303/A1325)|
|iPhone3,1| iPhone 4 (A1332)|
|iPhone3,2| iPhone 4 (A1332)|
|iPhone3,3| iPhone 4 (A1349)|
|iPhone4,1| iPhone 4S (A1387/A1431)|
|iPhone5,1| iPhone 5 (A1428)|
|iPhone5,2| iPhone 5 (A1429/A1442)|
|iPhone5,3| iPhone 5c (A1456/A1532)|
|iPhone5,4| iPhone 5c (A1507/A1516/A1526/A1529)|
|iPhone6,1| iPhone 5s (A1453/A1533)|
|iPhone6,2| iPhone 5s (A1457/A1518/A1528/A1530)|
|iPhone7,1| iPhone 6 Plus (A1522/A1524)|
|iPhone7,2| iPhone 6 (A1549/A1586)|
|iPhone8,1| iPhone 6s (A1633/A1688/A1691/A1700)|
|iPhone8,2| iPhone 6s Plus (A1634/A1687/A1690/A1699)|
|iPhone9,1| iPhone 7|
|iPhone9,3| iPhone 7|
|iPhone9,2| iPhone 7 Plus|
|iPhone9,4| iPhone 7 Plus|

### iPod
| model | 型号 |
| :-----: | :-----: |
| iPod1,1| iPod Touch (A1213)|
| iPod2,1| iPod Touch 2G (A1288)|
| iPod3,1| iPod Touch 3G (A1318)|
| iPod4,1| iPod Touch 4G (A1367)|
| iPod5,1| iPod Touch 5G (A1421/A1509)|
| iPod7,1| iPod Touch 6G (A1574)|

### iPad
| model | 型号 |
| :-----: | :-----: |
|iPad1,1| iPad (A1219/A1337)|
|iPad2,1| iPad 2 (A1395)|
|iPad2,2| iPad 2 (A1396)|
|iPad2,3| iPad 2 (A1397)|
|iPad2,4| iPad 2 (A1395+New Chip)|
|iPad3,1| iPad 3 (A1416)|
|iPad3,2| iPad 3 (A1403)|
|iPad3,3| iPad 3 (A1430)|
|iPad3,4| iPad 4 (A1458)|
|iPad3,5| iPad 4 (A1459)|
|iPad3,6| iPad 4 (A1460)|
|iPad4,1| iPad Air (A1474)|
|iPad4,2| iPad Air (A1475)|
|iPad4,3| iPad Air (A1476)|
|iPad5,3| iPad Air 2 (A1566)|
|iPad5,4| iPad Air 2 (A1567)|
|iPad2,5| iPad mini 1G (A1432)|
|iPad2,6| iPad mini 1G (A1454)|
|iPad2,7| iPad mini 1G (A1455)|
|iPad4,4| iPad mini 2 (A1489)|
|iPad4,5| iPad mini 2 (A1490)|
|iPad4,6| iPad mini 2 (A1491)|
|iPad4,7| iPad mini 3 (A1599)|
|iPad4,8| iPad mini 3 (A1600)|
|iPad4,9| iPad mini 3 (A1601)|
|iPad5,1| iPad mini 4 (A1538)|
|iPad5,2| iPad mini 4 (A1550)|

### 模拟器
| model | 型号 |
| :-----: | :-----: |
| i386 | iPhone Simulator |
| x86_64 | iPhone Simulator |
