2016-03-21 16 views
4

In Crash-Berichten sehe ich NSInternalInconsistencyException bekommen von den WKWebView Delegierten Methoden zum Aufrufen von JavaScript-Warnungen, dh. "Der Abschluss-Handler wurde an - [MyClass webView: runJavaScriptAlertPanelWithMessage: initiatedByFrame: completionHandler:] wurde nicht aufgerufen".Was kann dazu führen, dass UIAlertController-Aktionen nie aufgerufen werden?

Alle UIAlertAction ruft die WKWebView Abschlussbehandlungsroutine von seinem Handler. Die einzige Erklärung ist, dass die Warnung abgebrochen wird, ohne eine Aktion aufzurufen. UIAlertView hatte Delegate-Methoden für solche Fälle, aber UIAlertController bietet diese Ebene der Kontrolle nicht.

Hat jemand eine Lösung dafür entwickelt?

Ich habe überlegt, die gleiche Technik zu verwenden, die Apple in CompletionHandlerCallChecker (in WebKit) verwendet, um den Aufruf meines eigenen Rückrufs zu erfassen, und den WKWebView-Handler aufzurufen, um die falsche Ausnahme zu verhindern. Es scheint schrecklich kludgy, und ich bin mir noch nicht sicher, es würde funktionieren. Ich würde eher verhindern, dass dies überhaupt geschieht.

Bearbeiten: Ich weiß, dass das programmatische Verwerfen des Alert-Controllers dieses Verhalten erzeugt, was bedauerlich ist, aber ich kenne nicht den Zustand, in dem iOS entscheidet, den Controller ohne Benutzerinteraktion zu entlassen.

Edit 2: Für den Code anfordert, es ist wirklich die minimale Umsetzung:

- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler { 
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message message:nil preferredStyle:UIAlertControllerStyleAlert]; 
    [alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { 
    completionHandler(); 
    }]]; 
    [self presentViewController:alertController animated:YES completion:nil]; 
} 
+0

Geben Sie den entsprechenden Code in Ihre Frage ein. – rmaddy

+0

Haben Sie eine UIAlertAction für die Schaltfläche Abbrechen? – matt

+0

Sie haben jemals die Lösung dafür gefunden? Wenn nicht, wie würden Sie CompletionHandlerCallChecker, das Sie erwähnt haben, tun? Ich habe genau das gleiche Problem, bei dem eine andere Benutzeroberfläche auftreten kann und dazu führen kann, dass die Warnung abgewiesen wird und nicht gesagt wird, dass sie nur diese Ausnahme verursacht. – danchik

Antwort

0

Hier ist meine kludgy aber Arbeitslösung:

class CompletionHandlerCallCheckerDefeater: NSObject { 
    private var calledCompletionHandler: Bool = false 
    private var fallbackHandler:() -> Void 

    init(fallbackHandler:() -> Void) { 
    self.fallbackHandler = fallbackHandler 
    } 

    deinit { 
    if (!calledCompletionHandler) { 
     fallbackHandler() 
    } 
    } 

    func didCallCompletionHandler() { 
    calledCompletionHandler = true 
    } 
} 

In Ihrem Delegat Rückruf, nutzen es wie folgt :

Weisen Sie dem FallbackHandler alles zu, was notwendig ist, es muss nicht b sein Sperre übergeben, es muss nur die CompletionHandler mit entsprechenden Parametern aufrufen. Der "Defeater" wird zerstört, wenn alle Referenzen freigegeben sind, das heißt, wenn der Alarm zerstört wird, und er ruft den FallbackHandler (der completionHandler aufruft) auf, wenn didCallCompletionHandler nie aufgerufen wurde, wodurch die Ausnahme vermieden wird.