将变量从目标c返回到javascript

Lan*_*don 3 javascript objective-c cordova

我有一个phonegap应用程序,我想在Documents文件夹中运行一个非常简单的"存在文件"命令.我得到它主要工作.在js中,我有:

fileDownloadMgr.fileexists("logo.png");
......
PixFileDownload.prototype.fileexists = function(filename) {   
    PhoneGap.exec("PixFileDownload.fileExists", filename);
};
Run Code Online (Sandbox Code Playgroud)

然后在目标C中,我有:

-(BOOL) fileExists:(NSMutableArray*)paramArray withDict:(NSMutableDictionary*)options;{
  NSString * fileName = [paramArray objectAtIndex:0];

  NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  NSString *documentsDirectory = [paths objectAtIndex:0];   
  NSString *newFilePath = [documentsDirectory stringByAppendingString:[NSString stringWithFormat: @"/%@", fileName]];

  BOOL isMyFileThere = [[NSFileManager defaultManager] fileExistsAtPath:newFilePath];

  //i'm stuck here  
}
Run Code Online (Sandbox Code Playgroud)

我可以使用NSLog将其打印到控制台,以查看逻辑是否正常并且BOOL设置正确.但我需要在javascript世界中使用该变量.我知道stringByEvaluatingJavaScriptFromString,但这只会执行javascript,即调用回调函数.这不是我需要的,我需要(在javascript中):

var bool = fileDownloadMgr.fileexists("logo.png");
if(bool) alert('The file is there!!!!!!');
Run Code Online (Sandbox Code Playgroud)

我需要做什么才能将目标c中的bool返回到javascript中?

out*_*tis 6

由于调用PhoneGap.exec是异步的,因此需要传递一个在被调用的Objective-C方法成功时调用的函数.使成功处理程序成为一个参数fileexists(之后解释的原因):

PixFileDownload.prototype.fileexists = function(filename, success) {   
    PhoneGap.exec(success, null, "PixFileDownload", "fileExists", filename);
};
Run Code Online (Sandbox Code Playgroud)

第二个参数PhoneGap.exec是一个错误处理程序,在这里未使用.

在Obj-C方法中,使用a PluginResult通过方法将结果传递给success函数-resultWithStatus:messageAsInt:.

-(BOOL) fileExists:(NSMutableArray*)paramArray withDict:(NSMutableDictionary*)options;{
    ...
    //i'm stuck here
    /* Create the result */
    PluginResult* pluginResult = [PluginResult resultWithStatus:PGCommandStatus_OK 
                                                messageAsInt:isMyFileThere];
    /* Create JS to call the success function with the result */
    NSString *successScript = [pluginResult toSuccessCallbackString:self.callbackID];
    /* Output the script */
    [self writeJavascript:successScript];

    /* The last two lines can be combined; they were separated to illustrate each
     * step.
     */
    //[self writeJavascript: [pluginResult toSuccessCallbackString:self.callbackID]];
}
Run Code Online (Sandbox Code Playgroud)

如果Obj-C方法可能导致错误条件,请使用PluginResult's' toErrorCallbackString:创建一个调用错误函数的脚本.确保您还将错误处理程序作为第二个参数传递给PhoneGap.exec.

协调和延续

现在,承诺添加success参数的解释fileexists."协调"是计算的一个特征,意味着代码在其依赖的任何计算完成之前不会运行.同步调用为您提供免费协调,因为函数在计算完成之前不会返回.使用异步调用,您需要注意协调.你可以通过将依赖代码捆绑在一个名为" continuation " 的函数中(这意味着"从给定的点向前的其余计算")并将此继续传递给异步函数.这被称为(不出所料)延续传递风格(CPS).请注意,您可以将CPS与同步调用一起使用,但这并不常见.

PhoneGap.exec是异步的,因此它接受延续,一个在成功时调用,一个在失败时调用.fileexists取决于异步函数,因此它本身是异步的,需要传递一个延续.之后的代码fileDownloadMgr.fileexists("logo.png");应该包含在传递给的函数中fileexists.例如,如果您最初有:

if (fileDownloadMgr.fileexists("logo.png")) {
    ...
} else {
    ...
}
Run Code Online (Sandbox Code Playgroud)

创建一个延续很简单,但是当你有多个延续时它会变得有点毛茸茸.将if语句重写为函数,用变量替换对异步函数的调用:

function (x) {
    if (x) {
        ...
    } else {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

然后将此延续传递给fileexists:

fileDownloadMgr.fileexists("logo.png", function (exists) {
    if (exists) {
        ...
    } else {
        ...
    }
});
Run Code Online (Sandbox Code Playgroud)

进一步阅读

我找不到PluginResult-resultWithStatus:messageAsInt:,但展示了如何从一个OBJ-C法'返回值回JS一个例子如何创建一个PhoneGap的插件适用于iOS ’.对于文档PhoneGap.exec的API文档是目前比较差.既然两者都是维基页面,也许我或其他人会找到时间来改进它们.还有标题实现文件PluginResult.