Avvio App con l'URL (via UIApplicationDelegate handleOpenURL) che lavorano sotto iOS 4, ma non sotto iOS 3.2
-
26-09-2019 - |
Domanda
Ho implementato di UIApplicationDelegate
application:didFinishLaunchingWithOptions:
e
application:handleOpenURL:
secondo la specifica, cioè
application:didFinishLaunchingWithOptions:
returns YES
e
application:handleOpenURL: opens the URL.
I lavori di codice sotto IOS 4 (in entrambi i casi, cioè, quando l'applicazione viene avviata e quando diventa attiva da stato sospeso). Tuttavia, il codice non funziona sotto iOS 3.2.
Soluzione
I dare una risposta alla mia domanda. Trovare la soluzione mi ha messo un po 'ed era piuttosto frustrante. Se fate un internet la ricerca a trovare alcune risposte parziali, ma ancora mi c'è voluto un po 'per capire la seguente soluzione e spero che aggiunge un po' di chiarezza.
Quindi, prima, il comportamento consigliato della vostra applicazione sembra essere la seguente (vedi di apertura Tipi di file supportati in iOS Rif Lib):
- non implementano
applicationDidFinishLaunching:
(vedi la nota alla UIApplicationDelegate ) - Implementare
application:didFinishLaunchingWithOptions:
e controllare l'URL, YES di ritorno, se è possibile aprire, altrimenti no, ma non aprirlo. - Implementare
application:handleOpenURL:
e aprire l'URL, ritorno YES in caso di successo, altrimenti no.
In iOS 4, il superamento di un URL di un risultato app in uno dei due comportamenti seguenti:
- Se l'applicazione viene avviata quindi
application:didFinishLaunchingWithOptions:
si chiama e si chiamaapplication:handleOpenURL:
se eapplication:didFinishLaunchingWithOptions:
restituito YES. - Se l'applicazione è sempre attiva da allora stato sospeso
application:didFinishLaunchingWithOptions:
non si chiama, maapplication:handleOpenURL:
si chiama.
Tuttavia, in iOS 3.2 sembra come se application:handleOpenURL:
non viene mai chiamato! Un suggerimento che il comportamento è diverso sotto iOS 3.2 possono essere trovate in la gestione delle richieste di URL . Ci si scopre che application:handleOpenURL:
viene chiamato se application:didFinishLaunchingWithOptions:
non è implementata, ma applicationDidFinishLaunching:
è implementato. Ma application:handleOpenURL:
non viene chiamato se application:didFinishLaunchingWithOptions:
è implementato.
Quindi, una soluzione per far funzionare il codice sotto 3.2 e 4.0 è:
- Apri l'URL nel
application:didFinishLaunchingWithOptions:
, ma poi tornare NO per impedire cheapplication:handleOpenURL:
si chiama. - Apri l'URL nel
application:handleOpenURL:
, nel caso in cui si è sotto 4.0 e l'applicazione era in stato di sospensione.
Ho trovato questa soluzione in un altro post, ma ero confuso, perché contraddiceva la raccomandazione nella documentazione iOS Rif Lib (vale a dire che dovremmo tornare SI in application:didFinishLaunchingWithOptions:
). (A quel punto non mi rendevo conto che la documentazione contraddice sé).
Credo che l'attuale comportamento iOS 4.0 sarà il comportamento futuro preferisco la seguente soluzione:
- non implementano
applicationDidFinishLaunching:
. - Implementare
application:didFinishLaunchingWithOptions:
e controllare l'URL, YES di ritorno, se è possibile aprire, altrimenti no, ma non aprirlo. Se siamo sulla 3.2, aprire l'URL. - Implementare
application:handleOpenURL:
e aprire l'URL, ritorno YES in caso di successo, altrimenti no.
Quindi, in sintesi, a implementare il comportamento iOS 4 e aggiunta la seguente riga alla application:didFinishLaunchingWithOptions:
if([[[UIDevice currentDevice] systemVersion] hasPrefix:@"3.2"]) {
[self application:application handleOpenURL:url];
}
che rendono il codice di lavoro sotto 3.2.
Altri suggerimenti
application:handleOpenURL:
è ormai deprecato.
A partire da iOS 4.2, è possibile utilizzare questo per gli URL di apertura:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
Documentazione:
Ho iniziato a scrivere applicazioni che ha usato Dropbox api. Per capire il concetto, ho eseguito un'applicazione di esempio utilizzando la mia chiave / segreto menzionato dropbox / sviluppatore documentazione . Una volta app campione ha iniziato a lavorare, ho usato stessi valori chiave / secret per la mia applicazione.
Per applicazione del campione, messa handleOpenURL (o openURL su iOS 4.2) viene eseguito come previsto. Per qualche strana ragione, non è stato il caso per la mia app. La mia app è entrata sfondo al fine di mostrare la schermata di login e pagina di autenticazione del set. Dopo il login e l'autenticazione, la mia app non è mai entrato in primo piano. Era vero sia per la piattaforma Simulator e il dispositivo (iPad)
Ho provato quasi tutto quotata Internet compreso questo post. Grazie. Non c'era il successo, però.
Infine, è INIZIARE a lavorare per la mia applicazione, quando ho seguito:
- Il simulatore, selezionare "iOS Simulator -> Content Reset e impostazioni", e ripristinare
- Il dispositivo, ho cancellato applicazione di esempio legato eseguibile e che a sua volta la cache di eliminazione associato ad esso.
Aggiungere il seguente alla fine del 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;
}
dove MVC è il mio principale ViewController, e NC il mio controller di navigazione.
Poi nel MainViewController, fare qualcosa di simile:
- (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];
...
}
dopo aver dichiarato handleOpenURL nel .h naturalmente.
Grazie va a Christian per mettere nello sforzo per questo.