2012-05-27 9 views
7

WebViewインスタンスのJavaScriptとWebViewDelegateの間で通信する場合、JavaScriptタイプとObjective-Cタイプは前後に変換されます。たとえば、JavaScriptからObjective-C関数を呼び出すと、文字列はNSString、数字はNSNumber、オブジェクトはWebScriptObjectになります。WebScriptObjectのプロパティを安全に読み取る方法は?

他はかなり扱いが簡単ですが、WebScriptObjectは奇妙なようです。

{"foo": 1, "bar": 2}のような辞書を渡すとき、私は、このような[[arg valueForKey:@"foo"] intValue] == 1

のようvalueForKeyを使用して抽出物の特性、しかし、あなたは、プロパティが存在するかどうかわからない場合について、参照コードのほとんど?キーがオプションの場合はどうなりますか? [arg valueForKey:@"baz"]は例外をスローします。私にできること

ことの一つは、

@try { 
    foo = [[arg valueForKey:@"baz"] intValue]; 
} 
@catch (NSException* e) { 
    foo = 0; 
} 

のようなものですが、私はObjective-Cの中の例外が安全ではないし、フロー制御のために使用すべきではないと聞きました。

私は考えることができる唯一の他の方法は、ここで使用される方法のいくつかのバリエーションである。言い換えればhttp://edotprintstacktrace.blogspot.com/2011/10/sample-webscriptobject-javascript.html

:あなたのWebScriptObjectに機能しObject.keys 2.コールを実装するJavaScript関数を定義するには1.使用evaluateWebScript 3.返されたキーの配列を反復処理し、一致するものが見つかるとvalueForKeyを呼び出します。

これは私にとって非常に非効率的です。もっと良い方法があるはずです...そこにはありますか?

答えて

3

私はうまくいくものを見つけたと思います.WebScriptObjectをJSObjectRefに変換することができ、JSObjectRefsで動作するCメソッドがたくさんありますが、ドキュメントが少し欠けているので難しいです何をすべきかを理解する。ここで

は、プロパティが存在するかどうかをチェックすることができます方法は次のとおりです。

id getProperty(WebScriptObject *obj, NSString *prop) { 
    JSStringRef jsProp = JSStringCreateWithCFString((__bridge CFStringRef) prop); 

    if (JSObjectHasProperty(self.frame.globalContext, [obj JSObject], jsProp)) { 
     return [options valueForKey:prop]; 
    } else { 
     return nil; 
    } 

    JSStringRelease(jsString); 
} 

あなたは(そのキーを事前に知られていない)すべてのプロパティを一覧表示したい場合、あなたはいくつかのより多くの機能を使用する必要があります:

JSPropertyNameArrayRef properties = 
    JSObjectCopyPropertyNames(self.frame.context, [obj JSObject]); 

size_t count = JSPropertyNameArrayGetCount(properties); 

for (NSInteger i = 0; i < count; i++) { 
    JSStringRef property = JSPropertyNameArrayGetNameAtIndex(properties, i); 
    // ... etc. as above 
} 
+0

:Appleは定期的にObjCオブジェクトにJavaScriptオブジェクトを橋渡しするために使用することができJSValueウィッヒという名前のクラスを導入しましたか?オプションは何ですか? –

+0

これは –

+0

のサブクラスです。申し訳ありませんが、それは確かに不明でした...この場合、 'options'は私が物を抽出したい' WebScriptObject'です。 'properties'は辞書にチェックインするキーを事前に知っていれば、興味のあるフィールドの配列です。 キーがあらかじめわからない任意のオブジェクトを読み取る場合は、 'JSObjectCopyPropertyNames'を使用して' JSObject'からキーのリストを取得し、 'JSPropertyNameArrayGetCount'と' JSPropertyNameArrayGetNameAtIndex'を使用してその配列を処理できます。 –

4

OS X 10.9とiOS 7には、これを行うためのより簡単な方法があります。あなたはから `properties`配列を得るのですか

// WebScriptObject *options; obtained from a callback in ObjC 
id objCObject = [[options JSValue] toObject]; 

if ([objCObject isKindOfClass:[NSArray class]]) { 
    for (id object in objCObject) { 
     NSLog(@"object: %@", object); 
    } 
} 
else if ([objCObject isKindOfClass:[NSDictionary class]]) { 
    for (id<NSCopying> key in [objCObj allKeys]) { 
     NSLog(@"object for key %@: %@", key, [objCObject objectForKey:key]); 
    } 
} 
関連する問題