Pregunta

Estoy intentando utilizar una de las nuevas funciones de iOS7, JavaScriptCore Framework.Puedo generar con éxito una cadena helloWorld desde Javascript, pero lo que me interesa es hacer POST HTTP en Javascript y luego pasar la respuesta a Objective-C.Desafortunadamente, cuando estoy creando un XMLHttpRequest objeto en Javascript, obtengo EXC_BAD_ACCESS (code=1, address=....).

Aquí está el código 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";
};

Aquí está el código Objective-C dentro de mi ViewController:

- (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:@[]];
}

¿Podría ser que la funcionalidad de solicitudes HTTP no se proporcione en JavaScriptCore Framework?En caso afirmativo, ¿podría superar esto usando UIWebView's -stringByEvaluatingJavaScriptFromString:?¿Qué pasa si compilé e incluí en mi proyecto otro motor Javascript (p. ej.V8)?

¿Fue útil?

Solución

Supongo que las solicitudes HTTP no son parte de JavaScript Core, ya que en realidad son parte del navegador, no del lenguaje JavaScript.
Supongo que el núcleo de JavaScript solo incluye lo que está en la definición de ECMAScript.

Si desea AJAX, entonces WebView es el camino a seguir.

Otros consejos

XMLHttpRequest, como se indicó anteriormente, no forma parte de JavaScript, pero aún puede empaquetar la URLRequest de iOS para que esté disponible en su JS.

en JSUtils.h

   @protocol UtilsExport;

   @interface JSUtils : NSObject <UtilsExport>
   @end

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

en 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]];
        } 
    }];
}

A continuación, vincule la instancia al JSContext en algún lugar de su código.

JSContext *context = [[JSContext alloc] init];
context[@"utils"] = [[JSUtils alloc] init];

desde su archivo JS, ahora puede llamar

utils.getThen('http://localhost/api/dashboard', function(resultString){
  console.log(resultString)
}

También puedes usar un bloque y vincularlo directamente al JSContext para obtener el mismo resultado.

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;
};

En JS:

var body = request(url);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top