Приложение для запуска с URL (через handleOpenURL UIApplicationDelegate), работающее под iOS 4, но не под iOS 3.2 - PullRequest
11 голосов
/ 31 августа 2010

Я реализовал UIApplicationDelegate's

application:didFinishLaunchingWithOptions:

и

application:handleOpenURL:

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

application:didFinishLaunchingWithOptions:
returns YES 

и

application:handleOpenURL: opens the URL. 

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

Ответы [ 4 ]

33 голосов
/ 31 августа 2010

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

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

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

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

  • Если приложение запускается, тогда application:didFinishLaunchingWithOptions: вызывается и application:handleOpenURL: вызывается, если application:didFinishLaunchingWithOptions: возвращает ДА.
  • Если приложение становится активным из приостановленного состояния, то 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 (а именно, что мы должны вернуть YES в application:didFinishLaunchingWithOptions:).(В тот момент я не осознавал, что документация сама по себе противоречит).

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

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

Итак, в целом, я реализую iOS4 и добавили следующую строку в application:didFinishLaunchingWithOptions:

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

, что заставляет код работать под 3.2.

7 голосов
/ 15 марта 2012

application:handleOpenURL: теперь УСТАРЕЛО.

Начиная с iOS 4.2, вы можете использовать это для открытия URL:

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url 
        sourceApplication:(NSString *)sourceApplication annotation:(id)annotation

Документация:

https://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UIApplicationDelegate_Protocol/Reference/Reference.html

2 голосов
/ 06 марта 2012

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

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

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

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

  • В симуляторе выберите «Симулятор iOS -> Сбросить содержимое и настройки» и выполните сброс.
  • На устройстве я удалил пример исполняемого файла, связанного с приложением, и, в свою очередь, удалил связанный с ним кеш.
0 голосов
/ 04 октября 2012

Добавьте следующее в конец 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, конечно.

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

...