Skip to content

Commit

Permalink
Update README_EN.md
Browse files Browse the repository at this point in the history
  • Loading branch information
lincode committed Oct 17, 2016
1 parent 424b5c1 commit e360565
Show file tree
Hide file tree
Showing 3 changed files with 236 additions and 190 deletions.
27 changes: 14 additions & 13 deletions README.md
Expand Up @@ -5,6 +5,8 @@
[![iOS](https://img.shields.io/badge/iOS-7.0-green.svg)]()
[![Language](https://img.shields.io/badge/language-ObjC-blue.svg)](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html)

**[README in English](https://github.com/douban/rexxar-ios/blob/master/README_EN.md)**

**Rexxar** 是一个针对移动端的混合开发框架。现在支持 Android 和 iOS 平台。`Rexxar-iOS` 是 Rexxar 在 iOS 系统上的客户端实现。

通过 Rexxar,你可以使用包括 javascript,css,html 在内的传统前端技术开发移动应用。Rexxar 的客户端实现 Rexxar Container 对于 Web 端使用何种技术并无要求。我们现在的 Rexxar 的前端实现 Rexxar Web,以及 Rexxar Container 在两个平台的实现 Rexxar-iOS 和 Rexxar-Android 项目中所带的 Demo 都使用了 [React](https://facebook.github.io/react/)。但你完全可以选择自己的前端框架在 Rexxar Container 中进行开发。
Expand All @@ -19,9 +21,7 @@ Rexxar-iOS 现在支持 iOS 7 及以上版本。
Rexxar 包含三个库:

- Rexxar Web :[https://github.com/douban/rexxar-web](https://github.com/douban/rexxar-web)

- Rexxar Android:[https://github.com/douban/rexxar-android](https://github.com/douban/rexxar-android)

- Rexxar iOS:[https://github.com/douban/rexxar-ios](https://github.com/douban/rexxar-ios)

## 安装
Expand All @@ -38,7 +38,7 @@ $ gem install cocoapods

```ruby
target 'TargetName' do
pod 'Rexxar', :git => 'https://github.com/douban/rexxar-ios.git', :commit => '0.2.0'
pod 'Rexxar', :git => 'https://github.com/douban/rexxar-ios.git', :commit => '0.2.1'
end
```

Expand Down Expand Up @@ -97,9 +97,9 @@ Rexxar 使用 url 来标识页面。提供一个正确的 url 就可以创建对
RXRConfig.setRoutesCachePath("com.douban.RexxarDemo.rexxar")
```

以上配置设置了缓存路径缓存文件夹存在的目的也是减少资源文件的下载次数,加快打开页面的速度使得用户可以得到近似原生页面的页面加载体验
缓存文件夹存在的目的也是减少资源文件的下载次数,加快打开页面的速度使得用户可以得到近似原生页面的页面加载体验

缓存资源文件一般会出现在 Rexxar 部署了一次路由表的更新之后这也是 Rexxar 支持`热部署`的方法:由路由表控制资源文件的更新一般可以让应用定期访问路由表比如,在开启应用时,或者关闭应用时更新路由表更新路由表的方法如下:
缓存资源文件一般会出现在 Rexxar 部署了一次路由表的更新之后这也是 Rexxar 支持`热部署`的方法:路由表控制资源文件的更新一般可以让应用定期访问路由表比如,在开启应用时,或者关闭应用时更新路由表更新路由表的方法如下:

```Swift
RXRViewController.updateRouteFiles(completion: nil)
Expand Down Expand Up @@ -142,7 +142,7 @@ Rexxar 使用 url 来标识页面。提供一个正确的 url 就可以创建对

首先,可以继承 `RXRViewController`,在 `RXRViewController` 基础上以实现你自己客户端容器

我们暴露了三类接口供开发者更方便地扩展属于自己的特定功能实现
然后,可以使用 Rexxar 提供的三个接口下面会介绍如何使用这三个接口,更方便地扩展属于自己的特定功能

### 定制 RXRWidget

Expand Down Expand Up @@ -227,6 +227,14 @@ deinit {

在 Demo 中的 `FullRXRViewController` 可以看到如何注册和取消注册 RXRContainerAPI 和 RXRDecorator


## Partial RXRViewController

如果,你发现一个页面无法全部使用 Rexxar 实现你可以在一个原生页面内内嵌一个 RXRViewController,部分功能使用原生实现,另一部分功能使用 Rexxar 实现

Demo 中的 PartialRexxarViewController 给出了一个示例


## Rexxar 的公开接口

* Rexxar Container
Expand Down Expand Up @@ -254,13 +262,6 @@ deinit {
- `NSDictionary+RXRMultipleItem`


## Partial RXRViewController

如果,你发现一个页面无法全部使用 Rexxar 实现你可以在一个原生页面内内嵌一个 RXRViewController,部分功能使用原生实现,另一部分功能使用 Rexxar 实现

Demo 中的 PartialRexxarViewController 给出了一个示例


## 未来可能的改进

使用 WKWebView 替代 UIWebView 是一个长远的目标WKWebView 在速度和内存消耗上都优于 UIWebView但是,WKWebView 并不完善对于 Rexxar iOS Container 而言,最重要的缺陷是不支持使用 NSURLProtocol 截获 WKWebView 中发出的网络请求所以在现有的 Rexxar 的实现中,并没有使用 WKWebView但是,我们会持续努力,以寻找切换至 WKWebView 的可能性
Expand Down
222 changes: 222 additions & 0 deletions README_EN.md
@@ -0,0 +1,222 @@
# Rexxar iOS

[![Test Status](https://travis-ci.org/douban/rexxar-ios.svg?branch=master)](https://travis-ci.org/douban/rexxar-ios)
[![IDE](https://img.shields.io/badge/XCode-8-blue.svg)]()
[![iOS](https://img.shields.io/badge/iOS-7.0-green.svg)]()
[![Language](https://img.shields.io/badge/language-ObjC-blue.svg)](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html)

**Rexxar** is a cross-platform library for hybrid mobile application. It supports both iOS and Android. `Rexxar iOS` is Rexxar's Container in iOS.

Rexxar brings the ease of web technologies, including HTML, JavaScript and CSS, into mobile application development. We have used [React](https://facebook.github.io/react/) for the web front demo, but a Rexxar Container does not confine your choice of web front end framework. You can use your own web front side framework to develop the application in Rexxar Container.

Rexxar iOS supports iOS 7.0 and above.


## Rexxar

About Rexxar's integral introduction, please check this article: [豆瓣的混合开发框架 -- Rexxar](http://lincode.github.io/Rexxar-OpenSource). In order to bring its full power, Rexxar iOS or Android need a Web implementation to offer the routes map api and the Web resources including HTML, JavaScript, CSS.

Rexxar includes threes libraries:

- Rexxar Web:[https://github.com/douban/rexxar-web](https://github.com/douban/rexxar-web)
- Rexxar Android:[https://github.com/douban/rexxar-android](https://github.com/douban/rexxar-android)
- Rexxar iOS:[https://github.com/douban/rexxar-ios](https://github.com/douban/rexxar-ios)


## Installation

### Install Cocoapods

[CocoaPods](http://cocoapods.org) is a dependency manager for Objective-C and Swift. You can install it with the following command:

```bash
$ gem install cocoapods
```

### Podfile

```ruby
target 'TargetName' do
pod 'Rexxar', :git => 'https://github.com/douban/rexxar-ios.git', :commit => '0.2.1'
end
```

Then, run the following command:

```bash
$ pod install
```


## Usage

Please check out RexxarDemo for demo usage. We have used Github raw file as the routes map api. You would want to dynamically generate the routes map via an api endpoint, and need a real server to serve HTML, Javascript, and CSS in production.

It's possible to change this endpoint with RXRConfig, see below for details.

### Configure routes map api address

```Swift
RXRConfig.setRoutesMapURL(NSURL(string:"https://raw.githubusercontent.com/douban/rexxar-web/master/example/dist/routes.json)!)
```
Rexxar use url to identify the page in mobile application. With a valid url, we can create a RXRViewController. There is the map from url to HTML resources in the routes map api file. In the Demo, you can see a routes map api file like this:
```json
{
"items": [{
"remote_file": "https://raw.githubusercontent.com/douban/rexxar-web/master/example/dist/rexxar/demo-252452ae58.html",
"deploy_time": "Sun, 09 Oct 2016 07:43:47 GMT",
"uri": "douban://douban.com/rexxar_demo[/]?.*"
}],
"partial_items": [{
"remote_file": "https://raw.githubusercontent.com/douban/rexxar-web/master/example/dist/rexxar/demo-252452ae58.html",
"deploy_time": "Sun, 09 Oct 2016 07:43:47 GMT",
"uri": "douban://partial.douban.com/rexxar_demo/_.*"
}],
"deploy_time": "Sun, 09 Oct 2016 07:43:47 GMT",
}
```

### Configure the resource path

```Swift
RXRConfig.setRoutesResourcePath("rexxar")
```

We usually ship a copy of HTML resource files with the application's release package, in order to boost the initial load of the hybrid page. You can set the local path to the folder that contains the resource files with this API. Please be reminded that the folder type in Xcode must be set as `folder reference`, with a blue folder icon; instead of the `group` type with a yellow icon.

### Configure the cache path

```Swift
RXRConfig.setRoutesCachePath("com.douban.RexxarDemo.rexxar")
```

Cache is also used to improve performance over routing. Rexxar can be set to check the routes map periodically and save the latest version in the cache. By deploying different path with the routes, it's possible to do a `hot deployment`, with which you can update the page just by replacing the resource file, and no need to go through the tedious process of asking a new release via App Store.

This is the way to call to update routes map file:

```Swift
RXRViewController.updateRouteFiles(completion: nil)
```

### Use `RXRViewController`

You can use `RXRViewController` directly as your hybrid container. Or you can inherit `RXRViewController` to implement your own Rexxar Container. In RexxarDemo, we implement `FullRXRViewController` inheriting from `RXRViewController`.

To initialize a RXRViewController, you just need a valid url. This url should exist in the routes map file. Every url represents a page in app. Rexxar Container search the page's resource files via the url in the routes map file.

```Swift
let controller = RXRViewController(URI: uri)
let titleWidget = RXRNavTitleWidget()
let alertDialogWidget = RXRAlertDialogWidget()
controller.activities = [titleWidget, alertDialogWidget]
navigationController?.pushViewController(controller, animated: true)
```


## Customize Rexxar Container

First, you inherit `RXRViewController` to implement your own Rexxar Container.

Then, you use the three interfaces provided by Rexxar to make your customization easier.

### Create your own RXRWidget

The `RXRWidget` protocol provides threes three methods: `canPerformWithURL:`, `prepareWithURL:`, `performWithContoller:`. Override these three methods to conform the `RXRWidget` protocol to implement a native UI, for example displaying a toast or adding pull to refresh UI widget etc.

You can find an example `RXRNavTitleWidget` in Rexxar.

```Objective-C
@interface RXRNavTitleWidget ()

@property (nonatomic, copy) NSString *title;

@end


@implementation RXRNavTitleWidget

- (BOOL)canPerformWithURL:(NSURL *)URL
{
NSString *path = URL.path;
if (path && [path isEqualToString:@"/widget/nav_title"]) {
return true;
}
return false;
}

- (void)prepareWithURL:(NSURL *)URL
{
self.title = [[URL rxr_queryDictionary] rxr_itemForKey:@"title"];
}

- (void)performWithController:(RXRViewController *)controller
{
if (controller) {
controller.title = self.title;
}
}

@end
```

### Create your own RXRContainerAPI

In order to offer information computed by native but consumed by web, for example, getting the device's GPS location information, you can create a class conforming to `RXRContainerAPI` protocol and implement the three methods: `shouldInterceptRequest:`, `responseWithRequest:`, `responseData`.

You can find an example `RXRLocContainerAPI` in RexxarDemo. In this example, `RXRLocContainerAPI` returns the city information. To reduce Demo's complexity, we create it as a mock with false and always the same city information. You can implement your own loc information service on the base of this example.

### Create your own RXRDecorator

If the modification of request from Rexxar Container is needed, for example, adding the authentication information in http header, you can inherit `RXRDecorator` and implementing two methods `shouldInterceptRequest:`, `prepareWithRequest:`.

In RexxarDemo, you will find an example of usage of `RXRRequestDecorator` in `FullRXRViewController` to add the authentication information in http request.


## Partial RXRViewcontroller

If a page cannot be fully implemented in HTML, you still have a choice to render the page partially with Rexxar. A partial RXRViewController allows you to write part of a page in HTML, and the reset of it in native code.

Check out class `PartialRexxarViewController` in RexxarDemo for example.


## Rexxar's public interfaces

* Rexxar Container
- `RXRConfig`
- `RXRViewController`

* Widget
- `RXRWidget`
- `RXRNavTitleWidget`
- `RXRAlertDialogWidget`
- `RXRPullRefreshWidget`

* ContainerAPI
- `RXRNSURLProtocol`
- `RXRContainerInterceptor`
- `RXRContainerAPI`

* Decorator
- `RXRRequestInterceptor`
- `RXRDecorator`
- `RXRRequestDecorator`

* Util
- `NSURL+Rexxar`
- `NSDictionary+RXRMultipleItem`


## Optimisation in future

Replacing UIWebView by WKWebView is our long-term goal. WKWebView is better on speed and memory than UIWebView. But WKWebView doesn't support all features of UIWebView. The most import absence for Rexxar is the support of NSURLProtocol. We can not intercept the request from Rexxar Container with WKWebView. Anyway we will do our best to bring WKWebView to Rexxar in future.


## Unit Test

Rexxar iOS includes a suite of unit tests within the RexxarTests subdirectory.

## License

The MIT License.

0 comments on commit e360565

Please sign in to comment.