objc側:
JS側:- (void)updateWithHTML:(NSString *)html {html = [html stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];NSData *data = [html dataUsingEncoding:NSUTF8StringEncodingallowLossyConversion:NO];NSString *base64String = [data base64EncodedStringWithOptions:0];NSString *jsString = [NSString stringWithFormat:@"updateWithHTML('%@');", base64String];NSString *result = [self.webView stringByEvaluatingJavaScriptFromString:jsString];NSLog(@"result:%@", result);}
function updateWithHTML(base64html) {var html = decodeURIComponent(window.atob(base64html));// do some stuffreturn 'OK';}
Base64エンコードを使う理由:
文字列に含まれる括弧やシングルクォートのせいか、JSを実行できていないようでした。
(objcコード中の引数htmlは特定ページを表現するための完全なHTML文字列で、JSコードも含んでいます)
JSON化も試してみたのですが、いまいち期待通り動かなかったためBase64化して渡すことにしました。
うまく使えばJSONでも解決できそうなのですが…必要があればまた検討します。
URLエンコードを使う理由:
URLエンコード無しの場合、JS側でBase64デコード後の日本語が文字化けしてしまいました。
window.btoa - Web API インターフェイス | MDNによると、Unicodeに対してatob()を使うと例外が出るようでした。
私の書いたJSコードをSafariで動かしてみても特に例外は出ていないようでしたが、
上記サイトの通りURLエンコードも行うようにしたところ、期待通り日本語文字列を取得できるようになりました。
なお、ios - How do I URL encode a string - Stack Overflowによると、[NSString stringByAddingPercentEscapesUsingEncoding:]は不完全らしいので、さらに改善が必要かもしれません。