質問

JavaScriptCoreフレームワークのiOS7新機能の1つを使用しようとしています。私はJavaScriptからHelloWorld文字列を正常に出力できますが、私が興味があるのはJavaScriptでHTTP投稿をしてから、その応答をObjective-Cに渡します。残念ながら、JavaScriptでXMLHttpRequestオブジェクトを作成しているときは、EXC_BAD_ACCESS (code=1, address=....)を取得します。

これはJavaScriptコード(hello.js)です:

var sendSamplePost = function () {
    // when the following line is commented, everything works,
    // if not, I get EXC_BAD_ACCESS (code=1, address=....)
    var xmlHttp = new XMLHttpRequest();
};

var sayHello = function (name) {
    return "Hello " + name + " from Javascript";
};
.

これは、My ViewControllerの内部のObjective-Cコードです。

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    JSContext *context = [[JSContext alloc] initWithVirtualMachine:[[JSVirtualMachine alloc] init]];

    NSString *scriptPath = [[NSBundle mainBundle] pathForResource:@"hello" ofType:@"js"];
    NSLog(@"scriptPath: %@", scriptPath);
    NSString *script = [NSString stringWithContentsOfFile:scriptPath encoding:NSUTF8StringEncoding error:nil];
    NSLog(@"script: %@", script);

    [context evaluateScript:script];

    JSValue *sayHelloFunction = context[@"sayHello"];
    JSValue *returnedValue = [sayHelloFunction callWithArguments:@[@"iOS"]];

    // this works!
    self.label.text = [returnedValue toString];


    JSValue *sendSamplePostFunction = context[@"sendSamplePost"];

    // this doesn't work :(
    [sendSamplePostFunction callWithArguments:@[]];
}
.

HTTPリクエスト機能はJavaScriptCoreフレームワークで提供されていませんか。もしそうなら、UIWebView-stringByEvaluatingJavaScriptFromString:を使用してこれを克服できますか?私がコンパイルして私のプロジェクトに含まれている場合は、別のJavaScriptエンジン(例えば、v8)?

役に立ちましたか?

解決

私の推測は、JavaScript言語ではなく、ブラウザの一部であるため、HTTPリクエストはJavaScriptコアの一部ではないということでしょう。
JavaScriptコアでは、ECMAScript定義内のものだけが含まれていると仮定します。

ajaxが欲しいのなら、WebViewは行く方法です。

他のヒント

XMLHTTPRequestは、前述のように、JavaScriptの一部ではなく、あなたはそれがあなたのJSで利用可能であるようにiOS URLRequestをラップすることができるようにまだ描くことができます。 jsutils.h

   @protocol UtilsExport;

   @interface JSUtils : NSObject <UtilsExport>
   @end

   @protocol UtilsExport <JSExport>
   - (void)get:(NSString *)url then:(JSValue *)jsCallback;
   @end
.

jsutils.m

#import "JSUtils.h"

- (void)get:(NSString *)url then:(JSValue *)callback {
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]
                                                           cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
                                                       timeoutInterval:10];
    [request setHTTPMethod:@"GET"];
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
        if ([data length] > 0 && error == nil) {
            [callback callWithArguments:@[[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding], @YES]];
        } 
    }];
}
.

次に、コード内のjscontextにインスタンスを

にバインドします。
JSContext *context = [[JSContext alloc] init];
context[@"utils"] = [[JSUtils alloc] init];
.

あなたのJSファイルから、

を呼び出すことができます
utils.getThen('http://localhost/api/dashboard', function(resultString){
  console.log(resultString)
}
.

ブロックを使用してJScontextにまっすぐにバインドして同じ結果を得ます。

JSContext *context = [[JSContext alloc] init];

context[@"request"] = ^(NSString *url) {
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]
                                                       cachePolicy:NSURLRequestReloadIgnoringCacheData
                                                   timeoutInterval:10];

    NSURLResponse *response = nil;

    [request setHTTPMethod:@"GET"];
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
    NSString *body = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    return body;
};
.

JS:

var body = request(url);
.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top