TTNavigator和TTURLMap

平時閱讀別人翻譯的各類文章,感激之外,自己也想翻譯一些技術類文章,主要的目的是用來提高自己的閱讀能力。正在學習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表述。

發佈了0 篇原創文章 · 獲贊 2 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章