문제

iOS7 새로운 기능 중 하나 인 JavaScriptcore 프레임 워크 중 하나를 사용하려고합니다.JavaScript에서 HelloWorld 문자열을 성공적으로 출력 할 수 있지만 JavaScript에서 HTTP 게시물을 수행 한 다음 객체 -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";
};
.

여기에 내 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:@[]];
}
.

JavaScriptCore 프레임 워크에서 HTTP 요청 기능이 제공되지 않습니까?그렇다면 UIWebView-stringByEvaluatingJavaScriptFromString:를 사용 하여이 작업을 극복 할 수 있습니까?내 프로젝트에 컴파일하여 포함 된 다른 JavaScript 엔진 (예 : v8)?

도움이 되었습니까?

해결책

HTTP 요청은 JavaScript 언어가 아닌 브라우저의 일부가 아니라 JavaScript 코어의 일부가 아니라는 것입니다. JavaScript 코어는 ECMAScript 정의에있는 항목 만 포함한다고 가정합니다.

AJAX를 원한다면 WebView는 이동하는 방법입니다.

다른 팁

XMLHttpRequest는 JavaScript의 일부가 아니라 전 마찬가지로 IOS UrlRequest를 여전히 래핑 할 수 있으므로 JS에서 사용할 수 있습니다.

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에 바인딩

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