Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift委托和SocketScan scanApi.setDelegate()_Swift_Delegates_Socketscan - Fatal编程技术网

Swift委托和SocketScan scanApi.setDelegate()

Swift委托和SocketScan scanApi.setDelegate(),swift,delegates,socketscan,Swift,Delegates,Socketscan,iOS的SocketScan API是用Objective-C编写的,旨在将CHS模式下的SocketMobile扫描仪集成到本机应用程序中 启动ScanApi时,需要将ViewController设置为ScanApiHelperDelegate,这需要在viewDidLoad上进行一些设置,以及从扫描仪接收操作的一些函数 变量设置为: var scanApi = ScanApiHelper() var scanApiConsumer = NSTimer() 然后在viewDidLoad中,实

iOS的SocketScan API是用Objective-C编写的,旨在将CHS模式下的SocketMobile扫描仪集成到本机应用程序中

启动ScanApi时,需要将ViewController设置为ScanApiHelperDelegate,这需要在viewDidLoad上进行一些设置,以及从扫描仪接收操作的一些函数

变量设置为:

var scanApi = ScanApiHelper()
var scanApiConsumer = NSTimer()
然后在viewDidLoad中,实现以下代码:

scanApi.setDelegate(self)
scanApi.open()
scanApiConsumer = NSTimer.scheduledTimerWithTimeInterval(0.2, target: self, selector:Selector("onTimer"), userInfo: nil, repeats: true)
然后,scanApiConsumer调用以下函数以侦听来自扫描仪的通知:

func onTimer () -> Void{
    scanApi.doScanApiReceive()
    scanApi.getDevicesList()
}
扫描条形码时,它执行以下操作:

func onDecodedData(device: DeviceInfo, decodedData: ISktScanDecodedData) {
    //code to execute here
}
如果需要,用户将被路由到另一个视图,在该视图中扫描条形码会执行不同的代码。scanApi.setDelegate的设置如下:

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "manifestToRepackContainer" {
        let vc = (segue.destinationViewController as RepackContainer)
        scanApi.setDelegate(vc)
        vc.containerBarcode = GlobalVars.barcodeData
    }
}
这也很有效。到达后,扫描仪将正确执行指定的功能。而且,在ViewDid出现在原始查看器上时,我有此设置,它也可以按预期工作:

override func viewDidAppear(animated: Bool) {
    scanApi.setDelegate(self)
}
当用户需要在情节提要的一个完全不同的区域(“远程”视图)中扫描功能时,就会出现问题,其中prepareForSegue方法无法触发scanApi.setDelegate()

我最初的想法是,通过在“远程”视图中执行scanApi.setDelegate(self),在“远程”视图中定义scanApi委托。当然,此视图也被指定为scanApiHelperDelegate,并包含所有需要的函数。但是,它不起作用。原始viewController仍然是代理,扫描条形码将继续触发原始viewController中列出的功能,而不是当前功能。编译器不返回任何错误

我怀疑可能是a)与Swift与Objective-C API交互的方式有关,或者b)我使用“self”错误地声明了什么应该是新的scanApi委托


那么,在这种情况下,声明新的scanApi委托的正确方法是什么?这是API的问题吗?

当前版本的scanApi Helper不支持多个委托视图,但未来版本将支持多个委托视图。如果您想将其添加到项目中的ScanApiHelper,以下是我们所做的修改

注意:这些更改是向后兼容的,因此即使您不需要支持多个代理视图,也可以在ScanApiHelper发布时安全地应用这些更改或升级到最新版本

ScanApiHelper.h

Index: ScanApiHelper.h
===================================================================
--- ScanApiHelper.h (revision 12778)
+++ ScanApiHelper.h (revision 12779)
@@ -65,6 +65,7 @@
 @end

 @protocol ScanApiHelperDelegate <NSObject>
+@optional
 /**
  * called each time a device connects to the host
  * @param result contains the result of the connection
@@ -103,7 +104,6 @@
  */
 -(void) onErrorRetrievingScanObject:(SKTRESULT) result;

-@optional
 /**
  * called each time ScanAPI receives decoded data from scanner
  * @param result is ESKT_NOERROR when decodedData contains actual
@@ -179,9 +179,15 @@
     id<ISktScanApi>_scanApi;
     id<ISktScanObject>_scanObjectReceived;
     NSObject* _commandContextsLock;
+    BOOL _shared;// to indicate when ScanApiHelper is shared across multiple views
+    NSMutableArray* _delegateStack;
 }

++(ScanApiHelper*)sharedScanApiHelper;

+-(void)pushDelegate:(id<ScanApiHelperDelegate>)delegate;
+-(void)popDelegate:(id<ScanApiHelperDelegate>)delegate;
+
 /**
  * register for notifications in order to receive notifications such as
  * "Device Arrival", "Device Removal", "Decoded Data"...etc...
索引:ScanApiHelper.h
===================================================================
---ScanApiHelper.h(12778版)
+++ScanApiHelper.h(12779版)
@@ -65,6 +65,7 @@
@结束
@协议ScanApiHelperDelegate
+@可选的
/**
*每次设备连接到主机时调用
*@param result包含连接的结果
@@ -103,7 +104,6 @@
*/
-(void)onErrorRetrievingScanObject:(SKTRESULT)结果;
-@可选的
/**
*每次ScanAPI从扫描仪接收解码数据时调用
*当decodedData包含实际值时,@param结果为ESKT_NOERROR
@@ -179,9 +179,15 @@
id_scanApi;
已收到的身份证;
NSObject*_commandContextsLock;
+BOOL_shared;//指示何时跨多个视图共享ScanApiHelper的步骤
+NSMutableArray*_delegateStack;
}
++(ScanApiHelper*)共享的ScanApiHelper;
+-(无效)代理:(id)代理;
+-(void)popDelegate:(id)delegate;
+
/**
*注册通知以接收通知,例如
*“设备到达”、“设备移除”、“解码数据”等。。。
ScanApiHelper.mm

Index: ScanApiHelper.mm
===================================================================
--- ScanApiHelper.mm    (revision 12778)
+++ ScanApiHelper.mm    (revision 12779)
@@ -105,12 +105,16 @@
 @implementation ScanApiHelper

 -(id)init{
+    static ScanApiHelper* sharedScanApiHelper=nil;
     self=[super init];
     if(self!=nil){
+        sharedScanApiHelper=self;
         _commandContextsLock=[[NSObject alloc]init];
         _deviceInfoList=[[NSMutableDictionary alloc]init];
         _scanApiOpen=FALSE;
         _scanApiTerminated=TRUE;// by default ScanApi is not started
+        _shared=NO;
+        _delegateStack=[[NSMutableArray alloc]init];
     }
     return self;
 }
@@ -130,6 +134,7 @@
     _commandContextsLock=nil;

     _deviceInfoList=nil;
+    _delegateStack=nil;
 }
 #else
 -(void)dealloc{
@@ -151,10 +156,54 @@

     [_deviceInfoList release];
     _deviceInfoList=nil;
+    
+    [_delegateStack release];
+    _delegateStack=nil;
+    
     [super dealloc];
 }
 #endif

++(ScanApiHelper*)sharedScanApiHelper{
+    static ScanApiHelper* scanApiHelper=nil;
+    if(scanApiHelper==nil){
+        scanApiHelper=[[ScanApiHelper alloc]init];
+        scanApiHelper->_shared=YES;
+    }
+    return scanApiHelper;
+}
+
+-(void)pushDelegate:(id<ScanApiHelperDelegate>)delegate{
+    if(_delegate != delegate){
+        if(_delegate!=nil){
+            [_delegateStack addObject:_delegate];
+        }
+        _delegate=delegate;
+        [self generateDeviceArrivals];
+    }
+}
+
+-(void)popDelegate:(id<ScanApiHelperDelegate>)delegate{
+    if(_delegate ==delegate){
+        if(_delegateStack.count>0){
+            id<ScanApiHelperDelegate> newDelegate=[_delegateStack objectAtIndex:_delegateStack.count-1];
+            [_delegateStack removeLastObject];
+            _delegate = newDelegate;
+            // generate a device Arrival for each scanner we've already receive
+            // so that the new view can be aware of the connected scanners
+            if(_delegate!=nil){
+                for (NSString* key in _deviceInfoList) {
+                    DeviceInfo* device=[_deviceInfoList objectForKey:key];
+                    [_delegate onDeviceArrival:ESKT_NOERROR device:device];
+                }
+            }
+        }
+        else{
+            _delegate=nil;
+        }
+    }
+}
+
 /**
  * register for notifications in order to receive notifications such as
  * "Device Arrival", "Device Removal", "Decoded Data"...etc...
@@ -1519,14 +1568,15 @@
 #endif    
     // release the previous ScanAPI object instance if
     // it exists
-    if(_scanApi!=nil){
-        [_scanApi close];
-        [SktClassFactory releaseScanApiInstance:_scanApi];
-    }
     _scanApi=[SktClassFactory createScanApiInstance];
     SKTRESULT result=[_scanApi open:nil];
-    if(_delegate!=nil)
-        [_delegate onScanApiInitializeComplete:result];
+    if((_delegate!=nil)&&([_delegate respondsToSelector:@selector(onScanApiInitializeComplete:)])){
+        [_delegate onScanApiInitializeComplete:result];
+    }
     _scanApiTerminated=FALSE;

 #if __has_feature(objc_arc)
@@ -1576,8 +1626,9 @@
             }
         }
         else{
-            if(_delegate!=nil)
+            if((_delegate!=nil)&&([_delegate respondsToSelector:@selector(onErrorRetrievingScanObject:)])){
                 [_delegate onErrorRetrievingScanObject:result];
+            }
         }
     }
     return result;
@@ -1600,8 +1651,9 @@
             result=[self handleDeviceRemoval:scanObj];
             break;
         case kSktScanMsgIdTerminate:
-            if(_delegate!=nil)
+            if((_delegate!=nil)&&([_delegate respondsToSelector:@selector(onScanApiTerminated)])){
                 [_delegate onScanApiTerminated];
+            }
             closeScanApi=TRUE;
             break;
         case kSktScanMsgSetComplete:
@@ -1619,8 +1671,9 @@

     // if there is an error then report it to the ScanAPIHelper user
     if(!SKTSUCCESS(result)){
-        if(_delegate!=nil)
+        if((_delegate!=nil)&&([_delegate respondsToSelector:@selector(onError:)])){
             [_delegate onError:result];
+        }
     }
     return closeScanApi;
 }
@@ -1657,8 +1710,9 @@
     }

     // notify the ScanApiHelper user a scanner has connected to this host
-    if(_delegate!=nil)
+    if((_delegate!=nil)&&([_delegate respondsToSelector:@selector(onDeviceArrival:device:)])){
         [_delegate onDeviceArrival:result device:deviceInfo];
+    }

 #if __has_feature(objc_arc)
 #else 
@@ -1702,8 +1756,9 @@
     [SktClassFactory releaseDeviceInstance:scanDevice];

     // notify the ScanApiHelper user a scanner has connected to this host
-    if(_delegate!=nil)
+    if((_delegate!=nil)&&([_delegate respondsToSelector:@selector(onDeviceRemoval:)])){
         [_delegate onDeviceRemoval:deviceInfo];
+    }

     return result;
 }
@@ -1766,7 +1821,7 @@
             result=[self handleDecodedData:scanObj];
             break;
         case kSktScanEventError:
-            if(_delegate!=nil)
+            if((_delegate!=nil)&&([_delegate respondsToSelector:@selector(onError:)]))
                 [_delegate onError:[[scanObj Msg]Result]];
             break;

@@ -1809,6 +1864,7 @@
     return result;
 }

 /**
  * sendNextCommand
  *
@@ -1855,4 +1911,25 @@
     return result;
 }

+/**
+ *  generateDeviceArrivals
+ *
+ *  internal function to generate device
+ *  arrival notifications when the delegate
+ *  change to a new delegate.
+ *  This is used in a multi views application
+ *  that has more than one view to receive the
+ *  decoded data
+ */
+-(void)generateDeviceArrivals{
+    // generate a device Arrival for each scanner we've already receive
+    // so that the new view can be aware of the connected scanners
+    if(_delegate!=nil){
+        for (NSString* key in _deviceInfoList) {
+            DeviceInfo* device=[_deviceInfoList objectForKey:key];
+            [_delegate onDeviceArrival:ESKT_NOERROR device:device];
+        }
+    }
+}
+
 @end
索引:ScanApiHelper.mm
===================================================================
---ScanApiHelper.mm(版本12778)
+++ScanApiHelper.mm(版本12779)
@@ -105,12 +105,16 @@
@ScanApiHelper的实现
-(id)init{
+静态ScanApiHelper*sharedScanApiHelper=nil;
self=[super init];
if(self!=nil){
+sharedScanApiHelper=self;
_commandContextsLock=[[NSObject alloc]init];
_DeviceInfo列表=[[NSMutableDictionary alloc]init];
_scanApiOpen=FALSE;
_scanApiTerminated=TRUE;//默认情况下,未启动ScanApi
+_shared=否;
+_delegateStack=[[NSMutableArray alloc]init];
}
回归自我;
}
@@ -130,6 +134,7 @@
_commandContextsLock=nil;
_DeviceInfo列表=零;
+_delegateStack=nil;
}
#否则
-(无效)解除锁定{
@@ -151,10 +156,54 @@
[_设备信息列表发布];
_DeviceInfo列表=零;
+    
+[_delegatestackrelease];
+_delegateStack=nil;
+    
[super dealoc];
}
#恩迪夫
++(ScanApiHelper*)共享的ScanApiHelper{
+静态ScanApiHelper*ScanApiHelper=nil;
+if(scanApiHelper==nil){
+scanApiHelper=[[scanApiHelper alloc]init];
+scanApiHelper->_shared=YES;
+    }
+返回帮助者;
+}
+
+-(无效)pushDelegate:(id)delegate{
+如果(_delegate!=委托){
+如果(_delegate!=nil){
+[_delegatestackaddobject:_delegate];
+        }
+_delegate=代表;
+[自生副产品];
+    }
+}
+
+-(void)popDelegate:(id)delegate{
+如果(_delegate==委托){
+如果(_delegateStack.count>0){
+id newDelegate=[\u delegateStack objectAtIndex:\u delegateStack.count-1];
+[_delegatestackremovelastobject];
+_delegate=newDelegate;
+//为我们已经收到的每个扫描仪生成设备到达
+//以便新视图能够识别已连接的扫描仪
+如果(_delegate!=nil){
+用于(NSString*输入设备信息列表){
+DeviceInfo*设备=[\u DeviceInfo列表对象forkey:key];
+[_delegateondevicearrival:ESKT_NOERROR device:device];
+                }
+            }
+        }
+否则{
+_delegate=nil;
+        }
+    }
+}
+
/**
*注册通知以接收通知,例如
*“设备到达”、“设备移除”