JavaScriptからObjective-Cに渡したArrayでの注意その2
11/7追記:WebKit DOM Programming TopicsのCalling Objective-C Methods From JavaScriptに書いてあった。WebKit側の資料しか見てなかったから気づかなかったorz
Other JavaScript objects are wrapped as WebScriptObject instances. As an exception, JavaScript arrays cannot be cleanly mapped to NSArray objects because they are a hybrid between a numerically-indexed array and an associative array. To avoid loss of data during the mapping, you must instead use the webScriptValueAtIndex: and setWebScriptValueAtIndex:value: methods.
webScriptValueAtIndex:とsetWebScriptValueAtIndex:value:ね。
NSArrayとしてそのまま扱うのは駄目な感じでした。
Objective-Cの世界でNSArrayとして普通に使うには、JS側から配列のサイズも一緒に渡すなり、文字列とかの配列ならjoinで結合しちゃって文字列として渡して、Objective-C側でNSArrayを作るなどする必要がある。
JSとObjective-Cでのやり取りに必要な下準備は省略するので、そこの部分であれっとなった場合はこちらを。
http://d.hatena.ne.jp/yuichi_katahira/20121007/1349577340
単純にJavaScript→Objective-CとArrayを渡してみる。
function testMethod() { window.objC.callFromJSObjCMethod_(["a","b","c"]); }
- (void)callFromJSObjCMethod:(NSArray *)fromJSArray { //WebScriptObject count呼んで unrecognized selector sent to instance xxxxx とエラーでます。 NSLog(@"%ld",[fromJSArray count]); //count使えないので、forループができません。なので、for-inとかも当然エラー //↓NG for (NSString *s in fromeJSArray) { NSLog(@"%@",s); } }
配列のサイズも渡す版
function testMethod() { var array = ["a","b","c"]; window.objC.callFromJSObjCMethod_withCount_(array,array.length); }
- (void)callFromJSObjCMethod:(NSArray *)fromJSArray withCount:(NSNumber *)jsArrayCount { NSMutableArray *workArray = [NSMutableArray array]; int targetLength = [jsArrayCount intValue]; int i; for (i = 0; i<targetLength; i++) { [workArray addObject:[fromJSArray objectAtIndex:i]]; } //workArrayを使ってなにか処理 }
Array.join()を使って文字列として渡してしまう版
function testMethod() { window.objC.callFromJSObjCMethod_(["a","b","c"].join()); }
- (void)callFromJSObjCMethod:(NSString *)fromJSArrayStrings { NSArray *workArray = [fromJSArrayStrings componentsSeparatedByString:@","]; //workArrayを使ってなにか処理 }
以上。