Since the call to PhoneGap.exec is asynchronous, you need to pass a function that is invoked when the called Objective-C method succeeds. Make the success handler an argument to fileexists (the reason why is explained later):
PixFileDownload.prototype.fileexists = function(filename, success) {
PhoneGap.exec(success, null, "PixFileDownload", "fileExists", filename);
};
The second argument to PhoneGap.exec is an error handler, unused here.
Within the Obj-C method, use a PluginResult to pass the result to the success function via the -resultWithStatus:messageAsInt: method.
-(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]];
}
If the Obj-C method may result in error conditions, use PluginResult's toErrorCallbackString: to create a script that calls the error function. Make sure you also pass an error handler as the second argument to PhoneGap.exec.
Coordination & Continuations
Now, the promised explanation for adding the success parameter to fileexists. "Coordination" is a feature of computation meaning that code doesn't run until any computation it relies on has completed. Synchronous calls give you coordination for free because functions don't return until their computation completes. With asynchronous calls, you need to take care of coordination. You do this by bundling the dependent code in a function called a "continuation" (which means "the rest of the computation from a given point forward") and passing this continuation to the asynchronous function. This is called (unsurprisingly) continuation passing style (CPS). Note that you can use CPS with synchronous calls, it's just not quite as common.
PhoneGap.exec is asynchronous, so it accepts continuations, one to invoke on success and one on failure. fileexists depends on an asynchronous function so it is itself asynchronous and needs to be passed a continuation. The code after fileDownloadMgr.fileexists("logo.png"); should be wrapped in a function passed to fileexists. For example, if you originally had:
if (fileDownloadMgr.fileexists("logo.png")) {
...
} else {
...
}
Creating a continuation is straightforward, though it can get a bit hairy when you have multiple continuations. Rewrite the if statement as a function, replacing the call to the asynchronous function with a variable:
function (x) {
if (x) {
...
} else {
...
}
}
Then pass this continuation to fileexists:
fileDownloadMgr.fileexists("logo.png", function (exists) {
if (exists) {
...
} else {
...
}
});
Further Reading
I couldn't find PluginResult's -resultWithStatus:messageAsInt:, but there is an example that shows how to return a value from an Obj-C method back to JS in "How to Create a PhoneGap Plugin for iOS". The documentation for PhoneGap.exec in the API docs is currently rather poor. Since both are Wiki pages, perhaps I or someone else will find the time to improve them. There are also the header and implementation files for PluginResult.