André Lima
André Lima

Reputation: 661

Three20 URL routing with objects as parameters

We just added Three20 to our existing project and are having some trouble to get along with its routing system.

What we have right now is a transition from a view controller A to a view controller B, having A as the delegate of view controller B, to allow me to trigger an action on A when a specific action occurs on B.

Let's say I have a button on A that calls B like the following:

- (IBAction)buttonAction:(id)sender {
    id bvc = [[[BViewController alloc] initWithDelegate:self] autorelease];
    [self.navigationController pushViewController:bvc animated:YES];
}

Now, instead of the button, we want to use a link in a TTStyledText for the same purpose. The problem is we don't know how to pass the A view controller instance to B's initWithDelegate: method. We discovered how to pass strings as parameters for the TTURLMap, but that won't work for us.

Maybe we need a more thorough design change here. Any thoughts?

Upvotes: 3

Views: 456

Answers (1)

Yosi Taguri
Yosi Taguri

Reputation: 1388

Here are 2 options:

  1. you set all your object in a kind an object container and put it in a global cache where you can get an id for that container which you encode into a string in the url. This would add a bit of overhead in managing the lifecycle of these object :(

  2. There is another useful way to invoke three 20 controller using urls which involves a bit different way of coupling the paramters:

Your target controller would have another init method like this:

-(id)initWithNavigatorURL:(NSURL *)URL query:(NSDictionary *)query {
    self = [super initWithNavigatorURL:URL query:query];
    if (self) {
        self.parameter = [query objectForKey:@"[YOUR PARAMETER NAME]"];
    }
    return self;
}

you invoke it by calling the controller like this:

TTURLAction *action = [[[TTURLAction actionWithURLPath:@"yourapp://yourViewController"] 
                        applyAnimated:YES] 
                       applyQuery:[NSDictionary dictionaryWithObject:[YOUR OBJECT] forKey:@"[YOUR PARAMETER NAME]"]];
[[TTNavigator navigator] openURLAction:action];

Now all you are left with is mapping the links inside the label to somehow invoke that fancy TTURLAction.

You do this by changing the TTURLMap in your controller that hosts the styled label. three20 has the following way to add a mapping to a specific class and selector:

- (void)from:(NSString*)URL toObject:(id)object selector:(SEL)selector;

so in that view controller that hosts the label add this:

TTNavigator* navigator = [TTNavigator navigator];
TTURLMap* map = navigator.URLMap;
[map from:@"yourapp://someaction" toObject:self selector:@selector(userpressedlink)];

inside that userpressedlink method call the fancy TTURLAction

A few thing to remember:

  1. you need to remove that mapping ( I suggest viewWillAppear to add the mapping and viewWillDisappear to remove them)
  2. each link should have it's own mapping so you can distinguish the links and map them to differen selectors.

Upvotes: 3

Related Questions