Подтвердить что ты не робот

Приложение Lauching с URL (через UIApplicationDelegate handleOpenURL), работающее под iOS 4, но не под iOS 3.2

Я внедрил UIApplicationDelegate

application:didFinishLaunchingWithOptions:

и

application:handleOpenURL:

согласно спецификации, то есть

application:didFinishLaunchingWithOptions:
returns YES 

и

application:handleOpenURL: opens the URL. 

Код работает под iOS 4 (в обоих случаях, то есть при запуске приложения и при его активации из приостановленного состояния). Тем не менее, код не работает в iOS 3.2.

4b9b3361

Ответ 1

Я даю ответ на свой вопрос. Выяснение решения заняло у меня некоторое время и было довольно неприятным. Если вы выполняете поиск в Интернете, вы найдете некоторые частичные ответы, но мне все же понадобилось некоторое время, чтобы выработать следующее решение, и я надеюсь, что это добавит некоторую ясность.

Итак, рекомендуемое поведение вашего приложения выглядит следующим образом (см. Открытие поддерживаемых типов файлов в iOS Ref Lib):

  • Не используйте applicationDidFinishLaunching: (см. примечание в UIApplicationDelegate).
  • Внесите application:didFinishLaunchingWithOptions: и проверьте URL-адрес, верните YES, если вы можете его открыть, иначе НЕТ, но не открывайте его.
  • Внесите application:handleOpenURL: и откройте URL-адрес, верните YES в случае успеха, иначе NO.

В iOS 4 передача URL-адреса в приложение приводит к одному из следующих двух способов:

  • Если приложение запущено, вызывается application:didFinishLaunchingWithOptions: и вызывается application:handleOpenURL:, если и application:didFinishLaunchingWithOptions: возвращается YES.
  • Если приложение становится активным из приостановленного состояния, тогда application:didFinishLaunchingWithOptions: не вызывается, а вызывается application:handleOpenURL:.

Однако в iOS 3.2 кажется, что application:handleOpenURL: никогда не вызывается! Подсказка о том, что поведение отличается от iOS 3.2, можно найти в Обработка запросов URL. Там вы обнаружите, что application:handleOpenURL: вызывается, если application:didFinishLaunchingWithOptions: не реализовано, но applicationDidFinishLaunching: реализовано. Но application:handleOpenURL: не вызывается, если выполняется application:didFinishLaunchingWithOptions:.

Следовательно, одним из решений для работы кода под 3.2 и 4.0 является:

  • Откройте URL-адрес в application:didFinishLaunchingWithOptions:, но затем верните NO, чтобы предотвратить вызов application:handleOpenURL:.
  • Откройте URL-адрес в application:handleOpenURL:, если вам меньше 4.0, и приложение находится в состоянии приостановлено.

Я нашел это решение в другом посте, но я был в замешательстве, потому что это противоречило рекомендации в документации iOS Ref Lib (а именно, что мы должны вернуть ДА в application:didFinishLaunchingWithOptions:). (В этот момент я не понимал, что документация противоречит ему).

Я считаю, что текущее поведение iOS 4.0 будет будущим поведением, я предпочитаю следующее решение:

  • Не используйте applicationDidFinishLaunching:.
  • Внесите application:didFinishLaunchingWithOptions: и проверьте URL-адрес, верните YES, если вы можете его открыть, иначе НЕТ, но не открывайте его. Если мы находимся на 3.2, откройте URL.
  • Внесите application:handleOpenURL: и откройте URL-адрес, верните YES в случае успеха, иначе NO.

Итак, вкратце, я реализую поведение iOS 4 и добавил следующую строку в application:didFinishLaunchingWithOptions:


    if([[[UIDevice currentDevice] systemVersion] hasPrefix:@"3.2"]) {
        [self application:application handleOpenURL:url];
    }

которые делают код работать под 3.2.

Ответ 3

Я начал писать приложение, которое использовало Dropbox api. Чтобы понять концепцию, я запустил пример приложения, используя мой ключ/секрет, упомянутый в документации Dropbox/Developer . Когда образец приложения начал работать, я использовал те же ключевые/секретные значения для моего приложения.

Для примера приложения реализация handleOpenURL (или openURL на iOS 4.2) выполняется, как и ожидалось. По какой-то странной причине это было не для моего приложения. Мое приложение появилось в фоновом режиме, чтобы отобразить страницу входа в систему и страницу проверки подлинности dropbox. После успешного входа в систему и проверки подлинности мое приложение никогда не выходило на передний план. Это было верно и для платформы Simulator, и для устройства (iPad).

Я попробовал почти все, перечисленные в интернете, включая этот пост. Благодарю. Однако успеха не было.

Наконец, он НАЧАЛО работает для моего приложения, когда я делал следующее:

  • В симуляторе выберите "iOS Simulator → Reset" Содержание и настройки "и reset.
  • На устройстве я удалил пример исполняемого приложения, связанного с приложением, и который, в свою очередь, связал с ним кеш.

Ответ 4

Добавьте в конец application:DidFinishLaunchingWithOptions следующее:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    ...    

    NSURL *url = (NSURL *)[launchOptions valueForKey:UIApplicationLaunchOptionsURLKey];
    if (url != nil && [url isFileURL]) {
        return YES;
    }  else return NO;
} // End of application:didFinishLaunchingWithOptions:

// New method starts 
-(BOOL) application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
    mvc = [nc.viewControllers objectAtIndex:0];
    if (url != nil && [url isFileURL]) {
        [mvc handleOpenURL:url];
    }
    return YES;
}

где mvc - мой основной ViewController, и nc мой навигационный контроллер.

Затем в MainViewController сделайте следующее:

- (void)handleOpenURL:(NSURL *)url {
    [self.navigationController popToRootViewControllerAnimated:YES];

    // Next bit not relevant just left in as part of the example
    NSData *jsonData = [NSData dataWithContentsOfURL:url];        
    NSError *error;
    NSDictionary *dictionary = [[NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error] objectAtIndex:0];
    [self managedObjectFromStructure:dictionary withManagedObjectContext:self.context];
    ...
}

после объявления handleOpenURL в .h, конечно.

Спасибо Кристиану за то, что он прилагал усилия для этого.