现在的位置: 首页 > 综合 > 正文

TTNavigator和TTURLMap

2013年12月10日 ⁄ 综合 ⁄ 共 9185字 ⁄ 字号 评论关闭

平时阅读别人翻译的各类文章,感激之外,自己也想翻译一些技术类文章,主要的目的是用来提高自己的阅读能力。正在学习Three20,一个开源的Objective-C类库,用来开发iOS应用。官网上有篇文章讲TTNavigator,于是想翻译过来,动手后却发觉艰难的很。明明意思很清楚,表达出来却词不达意。所幸步子却迈出了,希望大伙阅读之余多提意见,我也会不断的重构这篇翻译。看得不爽,告个罪先。

========以下是正文========

URL-Based Navigation
基于URL的导航

Navigation in iPhone apps can be challenging – there is no single prescribed way to open a view and pass data into it. Most applications rely on each view having a particular API that the callers must know. This leads to a lot of boilerplate code to open
the same view from multiple locations in your application.
iPhone应用程序的导航很有挑战性——没有一个统一的规则来打开一个视图,并给其传递数据。大多数应用程序都由视图构成,这些视图有特定的API,调用者必须了解。这导致了你的应用程序多个地方使用公式化代码打开了相同的视图。

The URL-based navigation in TTNavigator provides a standard way to navigate the user from one view to another, with built-in understanding of some of the standard iPhone interfaces like UINavigationController, UITabBarController, and more.
TTNavigator这个基于URL的导航提供了一个标准的方法,将用户从一个视图中定位到另一个视图。TTNavigator内置了一些像UINavigationControllerUITabBarController等等我们都了解的标准的iPhone接口。

Introduction
简介
Persistence
持久化
URL mapping methods
URL映射方法
Native parameters
本机参数
Troubleshooting
故障排除

Introduction
简介

The concept behind TTNavigator is similar to Ruby on Rails’ routing in that you link URL patterns to code in a url map. Callers simply request a url, and TTNavigator will find the appropriate code to run. This means that the url map makes a semantic distinction
between what you want to display, and how you want to display it. The most common pattern is to have a single, shared navigator used across your whole application.
TTNavigator背后隐藏的概念类似Ruby on Rails(ROR)的路由:通过一个URL映射把URL模式和代码联系起来。呼叫者只需请求一个URL,TTNavigator会找到合适的代码运行。【这意味着URL映射为你要显示什么,和你如何要显示它之间做一个语义上的区别。】最常见的模式是有一个在你的整个应用程序中使用的单一的,共享的navigator。

Here’s an example to get started. Typically this appears in your Application Delegate’s applicationDidFinishLaunching: selector.
咱们通过一个例子开始。下面代码通常出现在你的应用程序Delegate的applicationDidFinishLaunching:中。

1
2
3
4
5
TTNavigator* navigator = [TTNavigator navigator];
navigator.window = window;
 
TTURLMap* map = navigator.URLMap;
[map from:@"tt://restaurant/(initWithName:)" toViewController:[RestaurantController class]];

The above refers to a class, RestaurantController, with a selector, initWithName:
上面的代码引用类RestaurantController的一个方法:initWithName:

1
2
3
-(void) initWithName: (NSString*)name {
  //...
}

This establishes a simple map which recognizes one url. Imagine that you wanted to open the restaurant controller for a given restaurant. For instance, Chotchkie’s.
这将建立一个简单的映射,它标记一个URL。试想一下,你想打开一个给定餐厅的控制器。例如,Chotchkie的。

Typically you’d do it this way, if you were embedded in a UINavigationController:
通常情况下,控制器内嵌到UINavigationController时,你会做这样:

1
2
3
RestaurantController* controller = [[RestaurantController alloc] initWithName:@"Chotchkie's"];
[navigationController pushViewController:controller animated:YES];
[controller release];

This is a lot of boilerplate. The only reason to keep controller around is to add it to the UINavigationController, and release it. Really, you just want to “open this view in the current context” and be done with it.
这个太公式化了。仅仅是生成一个控制器,将它添加到UINavigationController,最后释放它。实际上,你只是想“在当前上下文中打开这个视图”,仅此而已。

With TTNavigator, just open this url with:
使用TTNavigator,只需要打开这个URL:

1
2
[navigator openURLAction:[TTURLAction actionWithURLPath:@"http://github.com/jverkoey"]];
[[TTNavigator navigator] openURLAction:  [[TTURLAction actionWithURLPath:@"tt://restaurant/Chotchkie's"] applyAnimated:YES]]

When openURLAction: is called, an instance of RestaurantController will be allocated, and then the initWithName: selector will be invoked with @”Chotchkie’s” as the value of the first parameter.
当调用openURLAction:时,初始化一个RestaurantController实例,然后调用initWithName:,并将”Chotchkie’s“作为参数传入。

Persistence
持久化

One huge advantage of using TTNavigator is the fact that the user’s entire navigation state can be persisted automatically based on these URLs. This means that if you have a tab bar with navigation controllers, TTNavigator will remember the “stack” of urls
that the user has navigated using openURLAction:. The next time the application is launched, the user will be shown exactly the navigation state as the last time they launched the application.
使用TTNavigator的一个巨大的优势是,基于这些URL,用户的整个导航状态可以自动保持下来。这意味着,如果你有一个标签栏导航控制器,用户浏览使用openURLAction:导航时,TTNavigator会记得这些URL的“堆栈”。下一次启动应用程序,用户看到的恰恰正是他们最后一次运行应用程序的导航状态。

TTNavigator is smart enough to only persist the URLs, and avoid re-instantiating a whole stack of views on startup. So if the user is 10 levels deep into a UINavigationController, only the most recent view will be instantated at startup. The user will, however,
be able to navigate backwards using UINavigationController’s “back” button, and the views will be instantiated on demand.
TTNavigator很聪明的,它只持久URL,避免启动时重新实例化整个视图堆栈。因此,如果用户跑到了UINavigationController的第10层,只有最后使用的视图会在启动时实例化。可是,用户仍能够使用UINavigationController的“后退”按钮向后导航,视图将会按照需求进行实例化。

Be careful with this though, because it is easy to accidentally write code where a view is dependent on state that has been initialized in a previous view.
不过,我们仍需小心,因为容易意外地编写出这样的代码:一个视图依赖于前一个视图初始化后的状态。

Enabling persistence
启用持久化

The default persistence mode of TTNavigator is TTNavigatorPersistenceModeNone. To enable persistence you will need to choose one of the other two persistence modes before you call restoreViewControllers. Within your applicationDidFinishLaunching: method
(or wherever you initialize the navigator) you can set one of three persistence modes.
TTNavigator默认的持久模式是TTNavigatorPersistenceModeNone。要启用持久化,在调用restoreViewControllers之前,需要选择其他两种持久模式中的一种。在applicationDidFinishLaunching:(或任何初始化navigator的地方)中,你可以设置三种持久模式中的一种。

TTNavigatorPersistenceModeNone – No persistence.
TTNavigatorPersistenceModeNone – 不启用持久化。
TTNavigatorPersistenceModeTop – Persist only the first URL in the history.
TTNavigatorPersistenceModeTop – 只持久历史中的第一个URL。
TTNavigatorPersistenceModeAll – Persist the entire history.
TTNavigatorPersistenceModeAll – 持久整个历史。

To set the persistence mode, set the persistenceMode property of TTNavigator.
通过设置TTNavigator的persistenceMode属性来设置持久化。

1
2
TTNavigator* navigator = [TTNavigator navigator];
navigator.persistenceMode = TTNavigatorPersistenceModeAll;

URL mapping methods
URL映射方法

There are two methods of mapping that you should be aware of. Mapping from URLs to Controllers, and mapping from NSObjects to URLs (which are generally then mapped to controllers). We’ll start with the simpler case.
你需要了解2种映射方法。一种是从URLs到控制的映射,一种是从NSObjects到URLs(这些URL通常也映射到控制器)的映射。我们从简单的例子开始。

URLs to Controllers
URLs到控制

The first form is when you have a url, say “tt://menu/1″, and this is being mapped to a Controller. Let’s say we have the following map (from TTNavigatorDemo):
第一种形式,你有一个URL:“tt://menu/1”,映射到一个控制器。比如,我们有以下映射(来自例子TTNavigatorDemo):

1
[map from:@"tt://menu/(initWithMenu:)" toSharedViewController:[MenuController class]];

Opening “tt://menu/1″ will call
打开URL“tt://menu/1”将调用

1
[[MenuController alloc] initWithMenu:1]

This extends for multiple parameters, also. Let’s say we want to display a specific page in MenuController.
这个例子处理多参数。比如我们想显示MenuController中的制定页。

1
[map from:@"tt://menu/(initWithMenu:)/(page:)" toSharedViewController:[MenuController class]];

Opening “tt://menu/1/5″ will call
打开URL“tt://menu/1/5”将调用

1
[[MenuController alloc] initWithMenu:1 page:5]

Other data types
其他数据类型

Parameters will automatically map to the method’s data types. In the above examples we’ve assumed that initWithMenu: has this signature
参数会自动映射到方法的数据类型。上述例子中,我们假设initWithMenu:有如下声明

1
- (id)initWithMenu:(MenuPage)page

Where MenuPage is an enum (effectively an int).
We could also map parameters to strings if we wanted.
此处的MenuPage是一个枚举(实际上是一个int)。
如你所愿,我们也可以把参数映射为字符串。

1
- (id)initWithMenuName:(NSString*)name

The map:
映射:

1
[map from:@"tt://menu/(initWithMenuName:)" toSharedViewController:[MenuController class]];

Opening “tt://menu/lunch” will call
打开URL“tt://menu/lunch”将调用

1
[[MenuController alloc] initWithMenuName:@"lunch"]

NSObjects to URLs
NSObjects到URLs

NSObjects in three20 have the ability to be mapped to URLs via the URLValueWithName addition in UINSObjectAdditions.h.
three20中,NSObjects通过UINSObjectAdditions.hURLValueWithName方法来映射到URL。

This is an incredibly useful feature when populating a table with items. So how does it work?
将数据填充到表时,这是一个令人难以置信的有用的功能。那么它是如何工作的?

First off, let’s consider a basic NSObject:
首先,有一个基本的NSObject的:

1
@interface Contact : NSObject {

}

@property (nonatomic, retain) NSNumber* uid;
@property (nonatomic, retain) NSString* firstName;
@property (nonatomic, retain) NSString* lastName;

@end

We want to populate a table controller with a list of Contacts. Upon tapping any contact in the list, you should be taken to a view that shows the Contact details. Using TTTableItem we can set a URL for each table item, but how do we generate this URL?
我们想把一个联系人列表填充到一个表中。点击其中任意一个联系人,将会有一个视图来显示联系人详细信息。通过TTTableItem我们可以给表的每个项目一个URL,但是这个URL是怎么生成的?

Introducing the NSObject TTURL map:
NSObject TTURL映射简介:

1
[map from:[Contact class] name:@"view" toURL:@"tt://contact/view/(uid)"];

Calling [aContact URLValueWithName:@"view"] will generate a URL specifically for aContact.
调用 [aContact URLValueWithName:@"view"] 将生成一个URL并分配给aContact。

1
2
3
Contact* aContact = [[Contact alloc] initWithFirstName:@"Johnny" lastName:@"Appleseed" uid:1];
NSString* url = [aContact URLValueWithName:@"view"];
// url = @"tt://contact/view/1"

This can then be mapped through a URL to Controller map as discussed above.
综上所述,就会生成一个URL到控制器的映射。

Parameter substitution
参数替换

You may have noticed from the example above that mapping an object to a URL allows you to use properties from the NSObject to create the URL. Simply include the parameter name, surrounded by (parenthesis), and URLValueWithName will automatically substitute
it. Any property of the NSObject can be used to generate the URL, allowing you to break the object down into a unique URL representation.
您可能已经从上面的例子中注意到了,映射对象到URL允许你使用NSObject的属性来创建URL。只需包含用(括号)包围的参数名,URLValueWithName会自动替换它。 任何NSObject参数都能用来生成URL,让你把对象分解成一个唯一URL表述。

抱歉!评论已关闭.