возвращая переменные из цели c в JavaScript - PullRequest
3 голосов
/ 27 августа 2011

У меня есть приложение phonegap, и я хочу выполнить очень простую команду «существует ли файл» в папке «Документы». И у меня это в основном работает. В JS у меня есть:

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

Тогда в Задаче 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  
}

Я могу использовать NSLog, чтобы распечатать это на консоли, чтобы увидеть, что логика работает и BOOL настроен правильно. Но мне нужна эта переменная обратно в мир JavaScript. Мне известно о stringByEvaluatingJavaScriptFromString, но он просто выполнит javascript, т.е. вызовет функцию обратного вызова. Это не то, что мне нужно здесь, мне нужно (в JavaScript):

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

Что мне нужно сделать, чтобы вернуть это bool из цели c обратно в javascript?

1 Ответ

6 голосов
/ 27 августа 2011

Поскольку вызов PhoneGap.exec является асинхронным, необходимо передать функцию, которая вызывается при успешном выполнении вызываемого метода Objective-C.Сделайте обработчик успеха аргументом fileexists (причина, по которой это объяснено позже):

PixFileDownload.prototype.fileexists = function(filename, success) {   
    PhoneGap.exec(success, null, "PixFileDownload", "fileExists", filename);
};

Второй аргумент PhoneGap.exec - это обработчик ошибок, здесь он не используется.

В пределахметод Obj-C, используйте PluginResult для передачи результата в функцию успеха с помощью метода -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]];
}

Если метод Obj-C может привести к ошибочным условиям, используйте PluginResult 's toErrorCallbackString:, чтобы создать скрипт, который вызывает функцию ошибки.Убедитесь, что вы также передаете обработчик ошибок в качестве второго аргумента PhoneGap.exec.

Координация и продолжение

Теперь обещаемое объяснение добавления параметра success в fileexists.«Координация» - это особенность вычислений, означающая, что код не запускается до тех пор, пока не завершатся какие-либо вычисления, на которые он полагается.Синхронные вызовы дают вам координацию бесплатно, потому что функции не возвращаются, пока их вычисления не завершатся.При асинхронных вызовах вам необходимо позаботиться о координации.Вы делаете это, связывая зависимый код в функцию, называемую « продолжение » (что означает «остаток вычисления от заданной точки вперед») и передавая это продолжение в асинхронную функцию.Это называется (неудивительно) стиль передачи продолжения (CPS).Обратите внимание, что вы можете использовать CPS с синхронными вызовами, это просто не так часто.

PhoneGap.exec является асинхронным, поэтому он принимает продолжения, одно для вызова в случае успеха, а другое для сбоя.fileexists зависит от асинхронной функции, поэтому она сама асинхронна и должна быть передана как продолжение.Код после fileDownloadMgr.fileexists("logo.png"); должен быть заключен в функцию, переданную в fileexists.Например, если у вас изначально было:

if (fileDownloadMgr.fileexists("logo.png")) {
    ...
} else {
    ...
}

Создание продолжения является простым, хотя оно может стать немного затруднительным, если у вас есть несколько продолжений.Перепишите оператор if как функцию, заменив вызов асинхронной функции переменной:

function (x) {
    if (x) {
        ...
    } else {
        ...
    }
}

Затем передайте это продолжение в fileexists:

fileDownloadMgr.fileexists("logo.png", function (exists) {
    if (exists) {
        ...
    } else {
        ...
    }
});

Дальнейшее чтение

Я не смог найти PluginResult -resultWithStatus:messageAsInt:, но есть пример, который показывает, как вернуть значение из метода Obj-C обратно в JS в " Как создатьПлагин PhoneGap для iOS".Документация для PhoneGap.exec в документации по API в настоящее время довольно скудная.Поскольку обе страницы являются вики-страницами, возможно, я или кто-то еще найду время, чтобы улучшить их.Также есть файлы header и реализация для PluginResult.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...