Есть ли способ зарегистрировать URL с параметрами запроса в Three20? - PullRequest
0 голосов
/ 31 января 2011

У меня есть URL с различным количеством параметров запроса:

myapp://profile?username=1&status=2&title=3

Я хотел бы зарегистрировать что-то подобное в TTUrlMap

[map from:@"myapp://profile*" toViewController:[ProfileController class]];

И я бы хотел, чтобы Three20 распознал «остальную часть URL» и вызвал что-то вроде:

initWithOriginalUrl:(NSString*) originalUrl

где я могу затем проанализировать параметры запроса или:

initWithQueryParams(NSDictionary*) queryParams 

где TTNavigator распознал мой URL, проанализировал параметры в карте и затем вызвал мой контроллер, передав параметры запроса?

Это поддерживается? Я бы предпочел не передавать закодированный URL как параметр, как было предложено здесь: Pass URL Question

Ответы [ 2 ]

3 голосов
/ 02 февраля 2011

Да, есть способ сделать это.Если целевой класс URL-адреса, например, ProfileController, зарегистрируйте URL-адрес следующим образом:

[map from:@"myapp://profile?originalURL=(initWithOriginalURL:)"
  toViewController:[ProfileController class]];

Как видите, будет передано значение параметра запроса с именем originalURLв качестве первого аргумента функции с именем initWithOriginalURL:.Поэтому в ProfilerController объявите эту функцию:

- (id)initWithOriginalURL:(NSString*)originalURL {
    // Initialize your controller.  For example, you might do this:
    if (self = [self initWithNibName:nil bundle:nil]) {
        self.variableHeightRows = YES;

        self.dataSource =
            [TTListDataSource dataSourceWithObjects:
             [TTTableLongTextItem itemWithText:[NSString stringWithFormat:@"Original URL is %@", originalURL]],
             nil];
    }

    return self;
}

Таким образом, URL-адреса, которые вы можете открыть, будут выглядеть как myapp://profile?originalURL=URL_GOES_HERE.Обратите внимание, что, как и в случае с URL-адресами в Интернете, важно кодировать URL-адреса любых параметров запроса.Итак, вот пример кода, который откроет вышеуказанный ProfileController:

// any URL goes here -- this is the query parameter we are going to
// pass as the "originalURL=..." parameter.
NSString* url = @"http://www.google.com/search?hl=en&q=stack+overflow";

// URL-encode it: turn most non-alphanumerics into %XX
NSString * encodedURL = (NSString *)CFURLCreateStringByAddingPercentEscapes(
    NULL,
    (CFStringRef)url,
    NULL,
    (CFStringRef)@"!*'\"();:@&=+$,/?%#[] ",
    kCFStringEncodingUTF8 );

// Open the URL
TTOpenURL([NSString stringWithFormat:@"myapp://profile?originalURL=%@", encodedURL]);

В этом случае encodedURL в итоге будет:

myapp://profile?originalURL=http%3A%2F%2Fwww.google.com%2Fsearch%3Fhl%3Den%26q%3Dstack%2Boverflow
1 голос
/ 10 февраля 2011

Я собираюсь ответить на это сам - хитрость заключается в знании initWithNavigatorURL - Three20 проанализирует параметры вашего запроса, вызовет этот метод и передаст ему проанализированные параметры, если вы явно не задали метод на своей карте.Поэтому решение состоит в том, чтобы добавить это к вашей карте:

[map from:@"myapp://profile" toViewController:[ProfileController class]];

и реализовать магический метод initWithNavigatorUrl на вашем toViewController

@implementation ProfileController

- (id)initWithNavigatorURL:(NSURL*)URL query:(NSDictionary*)query {
    NSLog(@"ProfileController initWithNavigatorUrl %@, %@", URL, query);  
    ....
...