Lancement App avec l'URL (via UIApplicationDelegate handleOpenURL) travaillant sous iOS 4, mais pas sous iOS 3.2
-
26-09-2019 - |
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.
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é etapplication:handleOpenURL:
est appelé si etapplication:didFinishLaunchingWithOptions:
est retourné OUI. - Si l'application devient actif d'un état suspendu alors
application:didFinishLaunchingWithOptions:
n'est pas appelé maisapplication: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 queapplication: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:
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.