2010-04-25 15 views
8

Ich versuche, Methodenaufrufe von JavaScript an Objective-C und umgekehrt zu senden. Alles funktioniert gut für window.location ausgelöste URLs, die von shouldStartLoadWithRequest abgefangen werden. Wenn ich stattdessen versuche, einen AJAX-Aufruf zu verwenden, wird sustainStartLoadWithRequest nicht aufgerufen. Gibt es eine Möglichkeit, dies zu tun? Hauptsächlich möchte ich nicht auf die maximale URL-Größe von Daten beschränkt sein, die von JavaScript an Objective-C übergeben werden können.shouldStartLoadWithRequest wird nicht aufgerufen, wenn AJAX/XMLHttpRequest verwendet

Mein UIWebViewDelegate implementiert:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { 
NSString *url = [[request URL] absoluteString]; 
NSRange urlrange = [url rangeOfString:@"myScheme://"]; 
if(urlrange.length > 0){ 
    NSLog(@"this is an objective-c call, do not load link: %@", [url substringWithRange:NSMakeRange(urlrange.location, [url length])]); 
    return NO; 
} else { 
    NSLog(@"not an objective-c call, load link: ", url); 
    return YES; 
} 
} 

Mein JavaScript-Aufrufe:

// works 
window.location.href = "myScheme://readyHref"; 

// fails 
var xmlHttpReq = false; 
if (window.XMLHttpRequest) { 
xmlHttpReq = new XMLHttpRequest(); 
} else if (window.ActiveXObject) { 
xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP"); 
} 
xmlHttpReq.open('GET', "myScheme://readyAJAX", false); 
xmlHttpReq.send(); 

Antwort

2

Obwohl ich nicht die Antwort, warum AJAX Anfragen abgefangen werden nicht von should fand ich zwei Lösungen gefunden. Ich nehme an, dass JavaScript-Anfragen nicht abgefangen werden, sondern nur HTML-assoziierte/-originierte Anfragen. Wenn jemand dies überprüfen oder korrigieren könnte, wäre ich glücklich.

Die beiden Problemumgehungen sind einfach. Auf der einen Seite scheint es, dass die Beschränkung von 256 Zeichen in der URL MobileSafari oder zumindest die URL in diesem Zustand nicht beeinflusst. Ich lese das Safari allows 80'000 charcters. Aber ich fühlte mich nicht wohl dabei. Die Problemumgehung # 2 besteht also darin, ein HTML-Formular zu verwenden, das die POST-Methode verwendet und die Aktion für Ihr Schema festlegt. Die Daten können in der Form als Wert eines Eingabefeldes oder dergleichen gespeichert werden. Nach dem Absenden des Formulars mit JavaScript wird shouldStartLoadWithRequest ausgelöst und die Daten können von HTTPBody abgerufen werden.

2

Ich bin mir nicht sicher, ob dies für Sie funktioniert, aber wenn Sie versuchen, die shouldStartLoadWithRequest verwenden, um auf native Telefonfunktionen von Javascript zuzugreifen, können Sie PhoneGap verwenden. Es ist ein praktisches und Open-Source-Ziel-c-Framework, das in der Lage ist, JavaScript und Ziel-c zu überbrücken.

Ich brauchte einen Weg, asynchron das Telefon zu verursachen, um von Javascript zu vibrieren, und ich schaute auf die PhoneGap-Quelle, um zu sehen, wie sie es tun. Nach einigen Tests stellte ich fest, dass $ .ajax nicht von sophotStartLoadWithRequest abgefangen werden würde und dass es sehr speziell war, wann es HTTP-Anfragen abfangen würde. Sie könnten jedoch alles in Ordnung bringen, indem Sie document.location anstelle von $ .ajax aufrufen und ein anderes Protokoll wie gap: // anstelle von http: // verwenden.

So ist der Javascript-Code wie folgt aussieht:
document.location = "gap://vibrate";

Und den Objective-C-Code:

- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType { 
    NSURL *url = request.URL; 
    NSString *urlString = url.relativeString; 

    if ([urlString isEqualToString:@"gap://vibrate"]) 
    { 
    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); 
    }; 

    return YES; 
}
10

Wenn Sie haben möchten eine saubere Art und Weise von Daten von JavaScript zu Objective Übertragung -C können Sie folgende Schritte ausführen:

  1. Sobald Sie JS Daten haben, die Sie zurück zu Objective-C dann innerhalb J senden möchten S speichere es in einer global zugänglichen Variable, z. var myTempData = ...
  2. Verwenden Sie die oben genannte Technik der document.location = 'myapp://fire-some-event'
  3. Nachdem Sie in Objective-C-Code ausführen [myWebView stringByEvaluatingJavaScriptFromString:@"myTempData"].
  4. Ich denke, Sie sind fertig, achten Sie auf Threading/Objekt-String-via-Json-Codierung.
Verwandte Themen