2013-04-25 16 views
12

Jest to wersja Cocoa tego pytania:Cocoa obsługi protokołu używając NSAppleEventManager i kInternetEventClass/kAEGetURL

AEInstallEventHandler handler not being called on startup

Oto moja rejestracja protokół 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> 

Oto gdzie ustawić metoda nasłuchiwania zdarzenia kInternetEventClass/kAEGetURL po kliknięciu łącza przeglądarki z linkiem "myapp: // unused /? a = 123 & b = 456":

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

Oto metoda obsługi:

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

Oto test web link:

<!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> 

To wszystko działa świetnie, jeśli aplikacja jest już uruchomiona.

Metoda obsługi jest wywoływana, a pełny adres URL jest przechwytywany.

Jeśli jednak aplikacja nie jest jeszcze uruchomiona, ten sam link uruchomi aplikację, ale obsługa nie zostanie wywołana - co ma sens, ponieważ przewodnik nie był jeszcze związany z wydarzeniem.

Te argumenty w adresie URL są ważne dla naszej aplikacji do koordynacji z aplikacją webową. Chociaż większość czasu nasza aplikacja będzie już działać po kliknięciu, można oczekiwać, że w niektórych przypadkach tak się nie stanie.

Próbowałem sprawdzać środowisko i przetwarzać argumenty wywołania, ale nie widzę adresu URL w żadnym z nich.

Ktoś wie, w jaki sposób możemy niezawodnie przechwycić ten adres URL, nawet jeśli nasza aplikacja nie jest już uruchomiona po kliknięciu przeglądarki?

+0

Czy kiedykolwiek to rozgryzłeś? – canhazbits

+0

@canhazbits: Rejestrowanie programu obsługi w '-aplikacjiWillFinishLaunching:' działa w moich testach. Czy jest coś niezwykłego w konfiguracji lub konfiguracji tej aplikacji? Na przykład, czy delegat aplikacji nie jest ustawiony, czy nie jest klasą, którą uważasz za? Czy może to być ustawione po uruchomieniu aplikacji? Czy próbujesz zrobić aplikację bez NIB? Jeśli umieścisz instrukcje dziennika w "-applicationWillFinishLaunching:" i "-applicationDidFinishLaunching:", czy oba są wykonywane? –

+0

Tak, oba są wykonywane.Ale nie, umieszczenie rejestracji w 'applicationWillFinishLaunching' nie działa dla mnie. – canhazbits

Odpowiedz

1

Właśnie napotkałem ten dokładny problem. Nie wiem, czy to właściwe rozwiązanie, ale można zarejestrować procedurę obsługi zdarzenia w metodzie delegata aplikacji init -metoda.

// in AppDelegate.m 

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

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

    return self; 
} 

Należy pamiętać jednak, że handleURLEvent:withReplyEvent get nazywane przedapplicationDidFinishLaunching: jeśli aplikacja jest uruchomiona przez schemat URL.

+0

Próbowałem w applicationWillFinishLaunching, applicationDidFinishLaunching i init metoda, ale nic nie działało. Czy jest jakieś inne rozwiązanie? To będzie dla mnie bardzo pomocne. Z góry dziękuję. – boopathy

3

Apple SimpleScriptingPlugin próbka rejestruje obsługi w applicationWillFinishLaunching:, który jest prawdopodobnie czystsze niż przy użyciu init. (I jak mikker powiedział, handler zostaje wywołany przed applicationDidFinishLaunching:.)

+0

Próbowałem w applicationWillFinishLaunching, applicationDidFinishLaunching i init metoda, ale nic nie działało. Czy jest jakieś inne rozwiązanie? To będzie dla mnie bardzo pomocne. Z góry dziękuję. – boopathy