从 iOS cordova 中的委托方法发送 pluginResult

Posted

技术标签:

【中文标题】从 iOS cordova 中的委托方法发送 pluginResult【英文标题】:Sending pluginResult from delegate method in iOS cordova 【发布时间】:2014-01-24 00:30:19 【问题描述】:

我有一个问题似乎尚未得到解答。我是cordova的新手,所以我不确定这是否是框架中的调用。我有一个使用 Zbar libaray 扫描条形码的插件。扫描结果由委托管理,并在 imagePickerController:didFinishPickingMediaWithInfo: 方法中返回。我的插件调用了 scan 方法,但在我的 scan 方法结束后返回。我需要它将日期返回到我请求它的网站。我需要知道如何让我的扫描方法等待我的 zbar 委托完成,然后再发送对我的 webview 的响应。如果您能为我解决这个问题,请提前感谢您。并且没有调用 [super writejavascript:jsCallback] 不起作用,我使用的是cordova而不是phonegap。

#import "Camera.h"
#import <Cordova/CDV.h>
#import "AppDelegate.h"


@implementation Camera


@synthesize resultStr, command, hasPendingOperation;

//Override
- (void)pluginInitialize

    NSLog(@"%@", @"init Camera");



- (void)scan:(CDVInvokedUrlCommand*)mycommand
    NSLog(@"%@", @"Camera.scan");

    self.command = mycommand;

    ZBarReaderViewController *reader = [ZBarReaderViewController new];
    reader.readerDelegate = self;

    reader.supportedOrientationsMask = ZBarOrientationMaskAll;

    ZBarImageScanner *scanner = reader.scanner;
    // TODO: (optional) additional reader configuration here

    // EXAMPLE: disable rarely used I2/5 to improve performance
    [scanner setSymbology: ZBAR_I25
                   config: ZBAR_CFG_ENABLE
                       to: 0];



    // present and release the controller
    [self.viewController presentViewController:reader animated:YES completion:nil];

    NSLog(@"%@", @"finsihed plugin");


- (void) imagePickerController: (UIImagePickerController*) reader
 didFinishPickingMediaWithInfo: (NSDictionary*) info

    // ADD: get the decode results
    id<NSFastEnumeration> results =
    [info objectForKey: ZBarReaderControllerResults];
    ZBarSymbol *symbol = nil;
    for(symbol in results)
        // EXAMPLE: just grab the first barcode
        break;

    self.resultStr = symbol.data;

    // ADD: dismiss the controller (NB dismiss from the *reader*!)
    [reader dismissViewControllerAnimated:YES completion:nil];

    CDVPluginResult* pluginResult = nil;
    if (self.resultStr != nil && [self.resultStr length] > 0) 
        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:self.resultStr];
     else 
        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Failed to scan barcode!"];
    
    NSLog(@"%@", self.resultStr); //<----- this is the date I need to return to my //webview this issue is scan: has already completed and returned
    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];


@end

【问题讨论】:

【参考方案1】:

当您从 javascript 调用插件时,您会提供成功和失败的回调。此回调是插件将值传回 Web 层的唯一方式。

具体来说,你的 javascript 看起来像这样。

    cordova.exec(
                 function (result) 
                     // do stuff with plugin result! Hurray!
                 ,
                 function (error) 
                     self.alert("Things went downhill, sorry... :\r\r" + error);
                 ,
                 "PluginName", "MethodName", [parameters]
    );

由于插件结果已经通过回调传递,因此它是由委托提供的这一事实应该是无关紧要的。

更新

您的问题询问有关在 Objective-C 端等待的问题。 不要等待。这不是 Cordova 的设计方式,如果您没有立即从调用中返回,您甚至会看到控制台中弹出警告。

Cordova 插件调用旨在调用异步回调,您必须围绕这些回调设计 Web 界面。

一种常见的方法是在执行调用时显示微调器或占位符文本

    显示微调器或占位符文本(“检索数据”) 调用插件

在回调中:

    移除微调器/占位符。 显示结果。

【讨论】:

我同意这一点,因此这就是我的 JS 方面的工作方式。然而问题是被调用的“MethodName”,在这种情况下是 scan: 将在方法运行后返回。因此,当显示扫描仪视图时,插件已经返回到我的 JS 端。我需要找到一种方法让它等待我的代表返回日期。【参考方案2】:

我发现了这个问题,它与UIImagePickerController 的范围有关。当委托方法运行时,这个对象是唯一仍在范围内的东西。我错误地将回调 ID 保存为类属性,我以为在调用 imagePickerController:didFinishPickingMediaWithInfo: 方法时可以检索它。

解决方法只是扩展 ZBAR 阅读器类并添加一个属性,以便我可以存储回调 ID。所有 Cordova 插件都需要正确的回调 ID 才能返回 JS 端属性。

【讨论】:

你是如何调用目标 C 方法扫描的:来自 javascript?我在使用自定义插件时遇到问题

以上是关于从 iOS cordova 中的委托方法发送 pluginResult的主要内容,如果未能解决你的问题,请参考以下文章

使用委托从iOS中的ViewModel传递数据到UI的任何替代方法?

向 Cordova AppDelegate iOS 添加额外的委托

分支 io 推荐兑换奖励发送十进制值

将值从 iOS 本机代码传递给 cordova

如何使用cordova将电话铃声静音?

iOS - 如何使用 phoneGap / Cordova 中的参数调用 writeJavascript