文字列連結が使えない(色んな意味で)

最近ObjcのコードをSwiftに書き換えてます

JavaScriptCoreを使ったコードの書き換え時に気になったことを。

まず、C言語で使用されている文字列リテラルの連結がSwiftでは使用できません。

JSContext *context = [frame javaScriptContext];
context.exceptionHandler = handler;
[context evaluateScript:
    @"var emb = document.getElementById('flashWrap');" // この辺から
    @"var rect = emb.getBoundingClientRect();"
    @"var atop = rect.top;"
    @"var aleft = rect.left;"  // この辺まで
];

こういうの。

この文字列リテラル連結を使うとJavaScriptを改行付きで書けるため読みやすいです。

が、これがSwiftでは使えません。

代案として使用したのが、以下のコード。

let context = frame.javaScriptContext
context.exceptionHandler = handler
context.evaluateScript(
    "var emb = document.getElementById('flashWrap');" +
    "var rect = emb.getBoundingClientRect();" + 
    "var atop = rect.top;" + 
    "var aleft = rect.left;"
)

うん。見やすさはそれほど変わらない。いける。

と思ったのもつかの間、SourceKitServiceが暴走とクラッシュを繰り返し始めた。

さらに、コンパイル時間もとんでもなく掛かる。

実用に堪えない。


いろいろ試してみた結果、以下のコードを用いることでSourceKitServiceの暴走、クラッシュ、コンパイル時間の短縮が確認できた。

let context = frame.javaScriptContext
context.exceptionHandler = handler
let lines = [
    "var emb = document.getElementById('flashWrap');",
    "var rect = emb.getBoundingClientRect();",
    "var atop = rect.top;",
    "var aleft = rect.left;"
]
context.evaluateScript("".join(lines))

[String]を作って、joinで連結する。回りくどい。


ただし、実行時に連結されるため実行時間は掛かる模様。