IOSでは、UIWebView
内のJavascriptからObjective-Cメソッドを呼び出して、Javascriptにデータを返送する方法を教えてください。これはWebkitライブラリを使用してOS Xで実行できることを知っていますが、これはiOSでも可能ですか? PhoneGapはこれをどのように達成しますか?
Objective-CからJavaScriptを直接呼び出すAPIがありますが、JavascriptからObjective-Cを直接呼び出すことはできません。
Javascriptアクションを特別なURLにシリアル化し、UIWebViewのデリゲートのshouldStartLoadWithRequest
メソッドでそのURLをインターセプトする必要があります。
- (BOOL)webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType;
そこで、その特別なURLをデシリアライズし、Objective-C側で必要なことを行うためにそれを解釈できます。 (上記のNO
メソッドでshouldStartLoadWithRequest
メソッドを返す必要があります。これにより、UIWebViewは偽のURLを使用してWebページをロードするためのHTTPリクエストを実際に作成しません。)
次に、Webビューでこのメソッドを呼び出すことにより、Objective-CからJavascriptを実行できます。
- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;
偽のURLスキームを使用することをお勧めします。そうすれば、アクションURLと正当なリクエストの違いを簡単に判断できます。次の行に沿ってJavascriptでこのリクエストを行うことができます。
// JavaScript to send an action to your Objective-C code
var myAppName = 'myfakeappname';
var myActionType = 'myJavascriptActionType';
var myActionParameters = {}; // put extra info into a dict if you need it
// (separating the actionType from parameters makes it easier to parse in ObjC.)
var jsonString = (JSON.stringify(myActionParameters));
var escapedJsonParameters = escape(jsonString);
var url = myAppName + '://' + myActionType + "#" + escapedJsonParameters;
document.location.href = url;
次に、UIWebView.delegate
のshouldStartLoadWithRequest
メソッドでは、URLスキームとフラグメントを調べて、それが通常のリクエストであるか、特別なアクションの1つであるかを確認できます。 (URLのフラグメントは、#
。)
- (BOOL)webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType {
// these need to match the values defined in your JavaScript
NSString *myAppScheme = @"myfakeappname";
NSString *myActionType = @"myJavascriptActionType";
// ignore legit webview requests so they load normally
if (![request.URL.scheme isEqualToString:myAppScheme]) {
return YES;
}
// get the action from the path
NSString *actionType = request.URL.Host;
// deserialize the request JSON
NSString *jsonDictString = [request.URL.fragment stringByReplacingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
// look at the actionType and do whatever you want here
if ([actionType isEqualToString:myActionType]) {
// do something in response to your javascript action
// if you used an action parameters dict, deserialize and inspect it here
}
// make sure to return NO so that your webview doesn't try to load your made-up URL
return NO;
}
(json文字列をNSDictionaryにデシリアライズするのに助けが必要な場合は この回答 を読んでください。)
ページの場所を変更すると、複数の 問題 が発生する可能性があります。
here で提供されるソリューションは次のとおりです。
同じURLテクニック(jsとObjective-C)を使用して、iframeで場所を変更するだけです:
var iframe = document.createElement("IFRAME");
iframe.setAttribute("src", "js-frame:myObjectiveCFunction";
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
iframe = null;
役立つことを願っています
Objective-Cから:文字列のjavascript関数をUIWebViewに渡すことができます。 Webページはそれを実行し、結果を返します。これにより、変数を渡し、Javascriptからデータを取得できます。
- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script
例:
NSString *script = @"document.getElementById('myTextField').value";
NSString *output = [myWebView stringByEvaluatingJavaScriptFromString:script];
JavaScriptから:URL内にデータを渡します。 UIWebViewDelegateでURLリクエストをインターセプトします。データを取得し、NOを返すことでURL要求を中止します。
<script>window.location = "url://key1/value1"; </script>
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType