Avvio App con l'URL (via UIApplicationDelegate handleOpenURL) che lavorano sotto iOS 4, ma non sotto iOS 3.2

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

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.

È stato utile?

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 chiama application:handleOpenURL: se e application:didFinishLaunchingWithOptions: restituito YES.
  • Se l'applicazione è sempre attiva da allora stato sospeso application:didFinishLaunchingWithOptions: non si chiama, ma application: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 che application: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:

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

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top