2013-04-25 10 views
12

Questa è la versione di cacao di questa domanda:cacao utilizzando NSAppleEventManager e kInternetEventClass/kAEGetURL

AEInstallEventHandler handler not being called on startup

Ecco la mia registrazione protocollo Info.plist:

... 
    <key>CFBundleURLTypes</key> 
    <array> 
     <dict> 
      <key>CFBundleURLName</key> 
      <string>My Protocol</string> 
      <key>CFBundleURLIconFile</key> 
      <string>myicon</string> 
      <key>CFBundleTypeRole</key> 
      <string>Viewer</string> 
      <key>CFBundleURLSchemes</key> 
      <array> 
       <string>myapp</string> 
      </array> 
     </dict> 
    </array> 

Ecco dove ho impostato la metodo per ascoltare l'evento kInternetEventClass/kAEGetURL quando si fa clic su un collegamento browser con il link "myapp: // unused /? a = 123 & b = 456":

- (void)applicationDidFinishLaunching:(NSNotification *)notification 
{ 
    [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(getURL:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL]; 
    ... 
} 

Ecco il metodo del gestore:

- (void)getURL:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)reply 
{ 
    [[[event paramDescriptorForKeyword:keyDirectObject] stringValue] writeToFile:@"/testbed/complete_url.txt" atomically:YES]; 
} 

ecco il link web di prova:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> 
<html lang="en"> 
<head> 
</head> 
<body> 
    <a href="myapp://open/?a=123&b=456">Open My App</a> 
</body> 
</html> 

Tutto questo funziona alla grande se l'applicazione è già in esecuzione.

Il metodo del gestore viene chiamato e l'URL completo viene acquisito.

Tuttavia, se l'app non è ancora in esecuzione, lo stesso link avvierà l'app, ma il gestore non verrà richiamato, il che ha senso dal momento che il gestore non era ancora stato associato all'evento.

Questi argomenti nell'URL sono importanti per la nostra applicazione da coordinare con l'applicazione web. Sebbene la maggior parte delle volte la nostra applicazione sarà già in esecuzione quando si verifica questo clic, è ragionevole aspettarsi che in alcuni casi non lo sia.

Ho provato a controllare l'ambiente e ad elaborare gli argomenti di chiamata e non vedo l'URL in nessuno di essi.

Qualcuno sa come possiamo catturare questo URL in modo affidabile, anche quando la nostra applicazione non è già in esecuzione quando avviene il clic del browser?

+0

Lo hai mai capito? – canhazbits

+0

@canhazbits: registrazione del gestore in '-applicationWillFinishLaunching:' funziona nei miei test. C'è qualcosa di insolito nel modo in cui questa app è configurata o configurata? Ad esempio, è possibile che il delegato dell'app non sia impostato o meno nella classe che si ritiene essere? O potrebbe essere impostato dopo che l'app ha finito di lanciare? Stai provando a fare un'app NIB-less? Se metti le istruzioni di registro in '-applicationWillFinishLaunching:' e '-applicationDidFinishLaunching:', vengono entrambi eseguiti? –

+0

Sì, sono entrambi eseguiti.Ma no, mettere la registrazione in 'applicationWillFinishLaunching' non funziona per me. – canhazbits

risposta

1

Ho appena affrontato questo problema esatto. Non so se è la soluzione giusta ma puoi registrare il gestore di eventi nel metodo init del delegato dell'app.

// in AppDelegate.m 

- (id)init 
{ 
    self = [super init]; 

    if (self) { 
    [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(handleURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL]; 
    } 

    return self; 
} 

Una cosa da notare è però che handleURLEvent:withReplyEvent di chiamata primaapplicationDidFinishLaunching: se l'applicazione viene avviata da un regime di URL get.

+0

Ho provato in applicationWillFinishLaunching, applicationDidFinishLaunching e il metodo init, ma non ha funzionato. c'è un'altra soluzione? Sarà molto utile per me. Grazie in anticipo. – boopathy

3

SimpleScriptingPlugin campione di Apple registra il gestore in applicationWillFinishLaunching:, che è probabilmente più pulito rispetto all'utilizzo init. (E come mi ha detto il mikker, il gestore viene chiamato prima dello applicationDidFinishLaunching:.)

+0

Ho provato in applicationWillFinishLaunching, applicationDidFinishLaunching e il metodo init, ma non ha funzionato. c'è un'altra soluzione? Sarà molto utile per me. Grazie in anticipo. – boopathy