Lancement App avec l'URL (via UIApplicationDelegate handleOpenURL) travaillant sous iOS 4, mais pas sous iOS 3.2

StackOverflow https://stackoverflow.com/questions/3612460

Question

Je l'ai mis en œuvre de UIApplicationDelegate

application:didFinishLaunchingWithOptions:

et

application:handleOpenURL:

selon la spécification, à savoir

application:didFinishLaunchingWithOptions:
returns YES 

et

application:handleOpenURL: opens the URL. 

Le code fonctionne sous iOS 4 (dans les deux cas, à savoir lorsque l'application est lancée et quand il est activé à partir de l'état suspendu). Cependant, le code ne fonctionne pas sous iOS 3.2.

Était-ce utile?

La solution

Je donne une réponse à ma propre question. Trouver la solution m'a pris un certain temps et était assez frustrant. Si vous faites une recherche sur Internet vous trouverez des réponses partielles, mais il me reste pris un certain temps pour élaborer la solution suivante et j'espère qu'il ajoute un peu de clarté.

Alors d'abord, le comportement recommandé de votre application semble être la suivante (voir ouverture pris en charge Types de fichiers dans iOS Ref Lib):

  • Ne pas mettre en œuvre applicationDidFinishLaunching: (voir la note à UIApplicationDelegate )
  • Mettre en œuvre application:didFinishLaunchingWithOptions: et vérifiez l'URL, le retour OUI si vous pouvez l'ouvrir, sinon NON, mais ne l'ouvrez pas.
  • Mettre en œuvre application:handleOpenURL: et ouvrir l'URL, le retour OUI en cas de succès, sinon NO.

Dans iOS 4, en passant une URL à un résultat d'application dans l'un des deux comportements suivants:

  • Si l'application est lancée alors application:didFinishLaunchingWithOptions: est appelé et application:handleOpenURL: est appelé si et application:didFinishLaunchingWithOptions: est retourné OUI.
  • Si l'application devient actif d'un état suspendu alors application:didFinishLaunchingWithOptions: n'est pas appelé mais application:handleOpenURL: est appelé.

Cependant, dans iOS 3.2, il apparaît comme si application:handleOpenURL: est jamais appelé! Une allusion au fait que le comportement est différent sous iOS 3.2 se trouve dans Traitement des demandes d'URL . Vous y trouverez que application:handleOpenURL: est appelée si application:didFinishLaunchingWithOptions: n'est pas mis en œuvre, mais applicationDidFinishLaunching: est mis en œuvre. Mais application:handleOpenURL: n'est pas appelé si application:didFinishLaunchingWithOptions: est mis en œuvre.

Par conséquent, une solution pour faire fonctionner le code sous 3.2 et 4.0 est:

  • Ouvrir l'URL dans application:didFinishLaunchingWithOptions:, mais revenir NO pour éviter que application:handleOpenURL: est appelé.
  • Ouvrir l'URL dans application:handleOpenURL:, au cas où vous êtes sous 4.0 et l'application était en état suspendu.

J'ai trouvé cette solution dans un autre poste, mais je ne comprenais pas, car elle contredit la recommandation dans la documentation iOS Ref Lib (à savoir que nous devrions revenir OUI dans application:didFinishLaunchingWithOptions:). (À ce moment-là, je ne savais pas que la documentation qu'elle contredit l'auto).

Je crois que le comportement actuel iOS 4.0 sera le comportement futur Je préfère la solution suivante:

  • Ne pas mettre en œuvre applicationDidFinishLaunching:.
  • Mettre en œuvre application:didFinishLaunchingWithOptions: et vérifiez l'URL, le retour OUI si vous pouvez l'ouvrir, sinon NON, mais ne l'ouvrez pas. Si nous sommes sur 3.2, ouvrez l'URL.
  • Mettre en œuvre application:handleOpenURL: et ouvrir l'URL, le retour OUI en cas de succès, sinon NO.

Donc, en résumé, je mets en œuvre le comportement iOS 4 et ajouté la ligne suivante à application:didFinishLaunchingWithOptions:

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

qui font le travail de code sous 3.2.

Autres conseils

application:handleOpenURL: est maintenant dépréciée.

d'iOS 4.2, vous pouvez l'utiliser pour ouvrir les URL:

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

Documentation:

https://developer.apple .com / bibliothèque / ios / # DOCUMENTATION / UIKit / Référence / UIApplicationDelegate_Protocol / Référence / Reference.html

J'ai commencé à écrire l'application qui a utilisé Dropbox api. Pour comprendre le concept, je courais un exemple d'application utilisant ma clé / secrète mentionné à dropbox / développeur . Une fois que l'application de l'échantillon a commencé à travailler, je mêmes valeurs clés / secrets pour mon application.

Pour exemple d'application, la mise en œuvre de handleOpenURL (ou openURL sur iOS 4.2) est exécuté comme prévu. Pour une raison étrange, il n'a pas été le cas pour mon application. Mon application est entrée arrière-plan pour afficher l'écran de connexion et la page d'authentification de dropbox. Après connexion réussie et l'authentification, mon application n'est jamais entré au premier plan. Il était vrai pour les deux plate-forme simulateur et périphérique (iPad)

J'ai essayé presque tout sur Internet, y compris la liste ce poste. Merci. Il n'y avait pas de succès, cependant.

Enfin, il COMMENCÉ travailler pour ma demande quand je ne suit:

  • Sur simulateur, sélectionnez "iOS Simulator -> Réinitialiser contenu et réglages", et remis à zéro
  • .
  • Sur l'appareil, j'ai supprimé exemple d'application concernant exécutable et qui à son tour supprimer le cache associé.

Ajoutez ce qui suit à la fin de 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;
}

où est ma principale mvc ViewController et nc mon contrôleur de navigation.

Ensuite, dans le MainViewController, faire quelque chose comme ceci:

- (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];
    ...
}

après avoir déclaré handleOpenURL dans le .h bien sûr.

Merci à Christian va pour mettre dans l'effort pour cela.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top