概述

Cognex Mobile Barcode SDK (cmbSDK) 是用于开发移动条码扫描应用程序的SDK。

SDK是付费的,但功能很强大。

Cognex Mobile Barcode SDK for iOS : https://cmbdn.cognex.com/download#Platforms

iOS技术文档地址:https://cmbdn.cognex.com/knowledge/-cognex-mobile-barcode-sdk-for-ios

SDK

  • CMBReaderDevice

这个类提供了,连接,扫码,扫码结果回调,断开连接等系列操作。

  • CMBReadResult

这个类是扫描结果的抽象类,将扫描结果打包成CMBReadResult,提供了扫描的内容readResult.readString 和 readResult.image,是否是有效的goodRead。

goodRead (BOOL):判断读取是否成功
readString (NSString): 解码后的条码字符串
图像(UIImage):解码器处理过的图像/帧
imageGraphics (NSData):条码的边界路径作为SVG数据
XML (NSData):解码器返回的原始 XML
符号(CMBSymbology):条码的符号类型。该枚举在CMBReaderDevice.h 中定义。

  • CMBReadResults

这个类有两个数组,readResults 和 subReadResults ,将一帧(或者更短时间)内的所有扫描结果CMBReadResult都“入队”到两个数组中。

读取扫描结果的时候,我们只需取第一个元素作为最终的扫描结果即可。

  • CDMDataManSystem

这个类提供了连接远程服务的API,通过用户名和密码连接远程,可以发送命令和接收命令。

  • CDMResponse

远程连接的回调类。

  • MWOverlay

以下两种模式的UI是不一样的,如果需要自定义UI的话,可以选择第一种模式,在previewView添加自定义试图。

// 这种模式适用于自己设置一个previewView,在规定的previewView范围内扫描

[MWOverlay setOverlayMode:OM_CMB];

// 这种模式在SDK的较低版本中是全屏进行扫描,在高一点的版本中(如2.6.1)如果设置previewView,则在previewView范围内扫描,不设置的话默认全屏扫描。低版本中设置previewView是无效的。

[MWOverlay setOverlayMode:OM_LEGACY];

还有一些设置边框颜色什么的属性,可以试试看。

  • CDMEADiscoverer

SDK使用

下载官方提供的SDK,文档以及Demo,例 cmbSDK_iOS_v2.6.1 -> samples -> SampleApp

Demo中已经引用好了SDK,官方给我的SDK支持 arm64和armv7的真机和x86_64的模拟器。

WScanViewController

#import "WScanViewController.h"
#import <cmbSDK/cmbSDK.h> // 引用SDK头文件#define CognexRegistrationKey @"xxx"
#define CognexRegistrAuth @"xxx"     @interface WScanViewController ()<CMBReaderDeviceDelegate>@property (nonatomic, strong) UIImageView *previewView; // 扫描预览试图@property (nonatomic, strong) CMBReaderDevice *readerDevice; @property (nonatomic, weak) id<NSObject> applicationWillEnterForegroundObserver;
@property (nonatomic, weak) id<NSObject> applicationDidEnterBackgroundObserver;
@property (nonatomic, weak) id<NSObject> applicationWillResignActiveObserver;
@property (nonatomic, weak) id<NSObject> applicationDidBecomeActiveObserver;@property (nonatomic, assign) BOOL canAccessCamera;@end@implementation WScanViewController- (void)dealloc {}- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.// SDK 版本号NSLog(@"Version: %@",[CDMDataManSystem getVersion]);// 扫描预览试图self.previewView = [[UIImageView alloc] init];self.previewView.translatesAutoresizingMaskIntoConstraints = NO;[self.view addSubview:self.previewView];
}- (void)viewDidLayoutSubviews {[super viewDidLayoutSubviews];self.previewView.frame = CGRectMake(CGRectGetWidth(self.view.frame)*0.5-160, CGRectGetHeight(self.view.frame)*0.5-240, 320, 480);
}- (void)viewWillAppear:(BOOL)animated
{[super viewWillAppear:animated];// 检测相机授权AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];self.canAccessCamera = (authStatus != AVAuthorizationStatusDenied && authStatus != AVAuthorizationStatusRestricted);if (!self.canAccessCamera) {NSLog(@"没有权限访问相机");[self showAlert];return;}// 初始化扫描类self.readerDevice = [self createReaderDevice];[self addNotifications];
}- (void)viewWillDisappear:(BOOL)animated
{[super viewWillDisappear:animated];[self removeNotifications];if (self.readerDevice != nil &&self.readerDevice.connectionState == CMBConnectionStateConnected) {[self.readerDevice stopScanning];}
}-(void)viewDidDisappear:(BOOL)animated
{[super viewDidDisappear:animated];if (self.readerDevice != nil &&self.readerDevice.connectionState == CMBConnectionStateConnected) {[self.readerDevice disconnect];}
}- (void)addNotifications {void(^becomeActiveHandler)(NSNotification *) = ^(NSNotification *note){if (self.readerDevice.connectionState == CMBConnectionStateDisconnecting || self.readerDevice.connectionState == CMBConnectionStateDisconnected) {[self.readerDevice connectWithCompletion:^(NSError *error) {if (!error)[self.readerDevice startScanning];}];}};void(^becomeInactiveHandler)(NSNotification *) = ^(NSNotification *note){if (self.readerDevice.connectionState == CMBConnectionStateConnecting || self.readerDevice.connectionState == CMBConnectionStateConnected) {UIImage *screenShot = [WcanViewController getImageViewWithView:self.previewView];[self.readerDevice stopScanning];[self.readerDevice disconnect];self.previewView.image = screenShot;}};self.applicationDidBecomeActiveObserver = [NSNotificationCenter.defaultCenter addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue:NSOperationQueue.mainQueue usingBlock:becomeActiveHandler];self.applicationDidEnterBackgroundObserver = [NSNotificationCenter.defaultCenter addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil queue:NSOperationQueue.mainQueue usingBlock:becomeInactiveHandler];
}- (void)removeNotifications {[NSNotificationCenter.defaultCenter removeObserver:self.applicationDidBecomeActiveObserver];[NSNotificationCenter.defaultCenter removeObserver:self.applicationDidEnterBackgroundObserver];
}- (CMBReaderDevice *)createReaderDevice {if (self.readerDevice != nil) {[self.readerDevice disconnect];}// 这种模式指定在设置的previewView之内扫描以及预览。当设置为OM_LEGACY时,previewView的设置无效,会全屏预览扫描。[MWOverlay setOverlayMode:OM_CMB];// previewOptions 可以用 OR 语法传参。/**kCDMPreviewOptionDefaults:接受由CameraMode设置的所有默认值。kCDMPreviewOptionNoZoomBtn:隐藏直播预览上的缩放按钮。kCDMPreviewOptionNoIllumBtn:隐藏直播预览上的照明按钮。kCDMPreviewOptionHwTrigger:启用模拟硬件触发器(音量控制)以开始扫描。按下后,扫描开始。kCDMPreviewOptionPaused:当调用 startScanning()方法而不开始解码(即寻找条形码)时显示实时预览。按屏幕上的扫描按钮开始解码。kCDMPreviewOptionAlwaysShow:选择主动或被动瞄准模式时强制显示实时预览(例如CameraMode == kCDMCameraModePassiveAimer)kCDMPreviewOptionPessimisticCaching:仅在CameraMode ==     kCDMCameraModeActiveAimer时使用,这将在应用程序从后台恢复时从ActiveAimer读取设置,以防瞄准器设置从另一个应用程序更改。kCDMPreviewOptionHighResolution:使用更高分辨率的设备摄像头来帮助扫描小条码,但解码时间较慢。该选项在支持它的设备上将分辨率设置为 1920x1080,在不支持的设备上设置为默认分辨率。默认分辨率为 1280x720。  kCDMPreviewOptionHighFrameRate:将相机设置为 60 FPS 而不是默认的 30 FPS,以提供更流畅的相机预览。
kCDMPreviewOptionKeepPreviewInPausedState:在读取或超时后保持预览处于暂停状态。*/// 如果是扫描小条码的话,建议使用kCDMPreviewOptionHighResolution,会默认设置最大分辨率扫描。CMBReaderDevice *tmpDevice = [CMBReaderDevice readerOfDeviceCameraWithCameraMode:kCDMCameraModeNoAimerpreviewOptions:kCDMPreviewOptionDefaultspreviewView:self.previewViewregistrationKey:CognexRegistrationKeycustomData:CognexRegistrAuth];tmpDevice.delegate = self;if (tmpDevice.availability == CMBReaderAvailibilityAvailable && tmpDevice.connectionState == CMBConnectionStateDisconnected) {[tmpDevice connectWithCompletion:^(NSError *error) {if (error) {NSLog(@"%@", error.localizedDescription);}else {[tmpDevice startScanning];}}];}else {NSLog(@"不能打开摄像头扫描,请确保摄像头已允许访问");}return tmpDevice;
}- (void)showAlert {UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Permission denied" message:@"使用相机" preferredStyle:UIAlertControllerStyleAlert];[alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];[alertController addAction:[UIAlertAction actionWithTitle:@"Settings" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {NSURL * url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];if ([[UIApplication sharedApplication] canOpenURL:url]) {[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) {}];}}]];[self presentViewController:alertController animated:YES completion:nil];
}+ (UIImage *)getImageViewWithView:(UIView *)view
{CGRect screenRect = [UIScreen mainScreen].bounds;UIGraphicsBeginImageContext(screenRect.size);UIGraphicsGetCurrentContext();[view.layer renderInContext:UIGraphicsGetCurrentContext()];UIImage *image = UIGraphicsGetImageFromCurrentImageContext();UIGraphicsEndImageContext();return image;
}#pragma mark - CMBReaderDeviceDelegate
- (void)connectionStateDidChangeOfReader:(CMBReaderDevice *)reader
{if (self.readerDevice.connectionState == CMBConnectionStateConnected) {// https://cmbdn.cognex.com/v2.6.x/knowledge/-cognex-mobile-barcode-sdk-for-ios/using-cmbsdk/enabling-symbologies// 通过 -(void) setSymbology:(CMBSymbology)symbology
enabled:(bool)enabled
completion:(void (^)(NSError *error))completionBlock; 方法,启用符号系统// 此方法中用于符号系统参数的所有符号系统都可以在CMBReaderDevice.h 中找到。见枚举 CMBSymbology。// 以此来设置需要支持的扫码形式// Not find Codabar & Telepen[self.readerDevice setSymbology:CMBSymbologyDataMatrix enabled:YES completion:^(NSError *error){if (error){NSLog(@"FALIED TO ENABLE [CMBSymbologyDataMatrix], %@", error.description);}}];[self.readerDevice setSymbology:CMBSymbologyQR enabled:YES completion:^(NSError *error){if (error){NSLog(@"FALIED TO ENABLE [CMBSymbologyQR], %@", error.description);}}];[self.readerDevice setSymbology:CMBSymbologyMaxicode enabled:YES completion:^(NSError *error){if (error){NSLog(@"FALIED TO ENABLE [CMBSymbologyMaxicode], %@", error.description);}}];[self.readerDevice setSymbology:CMBSymbologyAzteccode enabled:YES completion:^(NSError *error){if (error){NSLog(@"FALIED TO ENABLE [CMBSymbologyAzteccode], %@", error.description);}}];[self.readerDevice setSymbology:CMBSymbologyDotcode enabled:YES completion:^(NSError *error){if (error){NSLog(@"FALIED TO ENABLE [CMBSymbologyDotcode], %@", error.description);}}];[self.readerDevice setSymbology:CMBSymbologyUpcEan enabled:YES completion:^(NSError *error){if (error){NSLog(@"FALIED TO ENABLE [CMBSymbologyUpcEan], %@", error.description);}}];[self.readerDevice setSymbology:CMBSymbologyC25 enabled:YES completion:^(NSError *error){if (error){NSLog(@"FALIED TO ENABLE [CMBSymbologyC25], %@", error.description);}}];[self.readerDevice setSymbology:CMBSymbologyC39 enabled:YES completion:^(NSError *error){if (error){NSLog(@"FALIED TO ENABLE [CMBSymbologyC39], %@", error.description);}}];[self.readerDevice setSymbology:CMBSymbologyC11 enabled:YES completion:^(NSError *error){if (error){NSLog(@"FALIED TO ENABLE [CMBSymbologyC11], %@", error.description);}}];[self.readerDevice setSymbology:CMBSymbologyC93 enabled:YES completion:^(NSError *error){if (error){NSLog(@"FALIED TO ENABLE [CMBSymbologyC93], %@", error.description);}}];[self.readerDevice setSymbology:CMBSymbologyC128 enabled:YES completion:^(NSError *error){if (error){NSLog(@"FALIED TO ENABLE [CMBSymbologyC128], %@", error.description);}}];[self.readerDevice setSymbology:CMBSymbologyC39ConvertToC32 enabled:YES completion:^(NSError *error){if (error){NSLog(@"FALIED TO ENABLE [CMBSymbologyC39ConvertToC32], %@", error.description);}}];[self.readerDevice setSymbology:CMBSymbologyMsi enabled:YES completion:^(NSError *error){if (error){NSLog(@"FALIED TO ENABLE [CMBSymbologyMsi], %@", error.description);}}];[self.readerDevice setSymbology:CMBSymbologyI2o5 enabled:YES completion:^(NSError *error){if (error){NSLog(@"FALIED TO ENABLE [CMBSymbologyI2o5], %@", error.description);}}];// 这里只扫条形码,结果不需要以图片或者图像的形式返回,所以设置为NO,在返回结果CMBReadResults里面,iamge就会为空。self.readerDevice.imageResultEnabled = NO;self.readerDevice.SVGResultEnabled = NO;// https://cmbdn.cognex.com/v2.6.x/knowledge/-cognex-mobile-barcode-sdk-for-ios/using-cmbsdk/advanced-configuration// 使用 DataMan 控制命令的高级配置 // 相机变焦设置 sendCommand("SET CAMERA.ZOOM 2");[self.readerDevice.dataManSystem sendCommand:@"SET DECODER.MAX-SCAN-TIMEOUT 120"];[self.readerDevice.dataManSystem sendCommand:@"SET FOCUS.FOCUSTIME 3"];}
}- (void)didReceiveReadResultFromReader:(CMBReaderDevice *)reader results:(CMBReadResults *)readResults
{NSMutableArray *results = [NSMutableArray array];if (readResults.readResults.count > 0) {[results addObjectsFromArray:readResults.readResults];}if (readResults.subReadResults.count > 0) {[results addObjectsFromArray:readResults.subReadResults];}NSPredicate *predicate = [NSPredicate predicateWithFormat:@"goodRead == TRUE"];[results filterUsingPredicate:predicate];if (results.count > 0) {CMBReadResult *result = results.firstObject;if (result.goodRead) {NSLog(@"++++++++++++%@+++++++++++++",result.readString);}[self dismissViewControllerAnimated:YES completion:nil];}
}@end
  • previewOptions

可以用 OR 语法传参。

kCDMPreviewOptionDefaults:接受由CameraMode设置的所有默认值。
kCDMPreviewOptionNoZoomBtn:隐藏直播预览上的缩放按钮。
kCDMPreviewOptionNoIllumBtn:隐藏直播预览上的照明按钮。
kCDMPreviewOptionHwTrigger:启用模拟硬件触发器(音量控制)以开始扫描。按下后,扫描开始。
kCDMPreviewOptionPaused:当调用 startScanning()方法而不开始解码(即寻找条形码)时显示实时预览。按屏幕上的扫描按钮开始解码。
kCDMPreviewOptionAlwaysShow:选择主动或被动瞄准模式时强制显示实时预览(例如CameraMode == kCDMCameraModePassiveAimer)
kCDMPreviewOptionPessimisticCaching:仅在CameraMode ==     kCDMCameraModeActiveAimer时使用,这将在应用程序从后台恢复时从ActiveAimer读取设置,以防瞄准器设置从另一个应用程序更改。
kCDMPreviewOptionHighResolution:使用更高分辨率的设备摄像头来帮助扫描小条码,但解码时间较慢。该选项在支持它的设备上将分辨率设置为 1920x1080,在不支持的设备上设置为默认分辨率。默认分辨率为 1280x720。  kCDMPreviewOptionHighFrameRate:将相机设置为 60 FPS 而不是默认的 30 FPS,以提供更流畅的相机预览。

kCDMPreviewOptionKeepPreviewInPausedState:在读取或超时后保持预览处于暂停状态。

  • previewOptions

如果是扫描小条码的话,建议使用kCDMPreviewOptionHighResolution,会默认设置最大分辨率扫描。

  • setSymbology

https://cmbdn.cognex.com/v2.6.x/knowledge/-cognex-mobile-barcode-sdk-for-ios/using-cmbsdk/enabling-symbologies

通过 -(void) setSymbology:(CMBSymbology)symbology
enabled:(bool)enabled
completion:(void (^)(NSError *error))completionBlock; 方法,启用符号系统

此方法中用于符号系统参数的所有符号系统都可以在CMBReaderDevice.h 中找到。见枚举 CMBSymbology。

以此来设置需要支持的扫码形式

问题

SDK不支持arm架构的模拟器设备,在M1 Xcode13上选择模拟器编译会报错:building for iOS Simulator-arm64 but attempting to link with file built for iOS Simulator-x86_64

解决办法:Build Settings -> Excluded Architectures -> arm 64

参考 ‘Xcode 12, building for iOS Simulator, but linking in an object file built for iOS, for architecture ‘arm64’’ :https://stackoverflow.com/questions/63607158/xcode-12-building-for-ios-simulator-but-linking-in-an-object-file-built-for-io

最后

如果只是简单的识别个二维码或者条形码就够了的话,使用系统提供的框封装一个QRCodeScaner完全满足需求。但是如果需要更加专业的扫描的话,Cognex还是挺专业的。

关于 Apple 的 MFi 产品计划以及上线要求之类的,建议仔细阅读一遍光放文档,文档中都有说明。

Cognex Mobile Barcode SDK for iOS相关推荐

  1. Use GraceNote SDK in iOS(二)获取音乐的完整信息

    在需求彻底明朗化,外加从MusicFans转到GraceNote,再从GraceNote的GNSDK转到iOS SDK后,最终完毕了在iOS上通过音乐的部分信息获取完整信息的功能了.(好吧,我承认是相 ...

  2. 中国移动灵犀云语音识别及合成SDK(iOS)使用指南

    随着智能家居概念的火热,语音交互这一新时代的人机交互方式再度掀起了热潮.移动互联网应用在设计开发时也纷纷考虑加入语音识别功能,带给用户除传统键盘或触控交互方式外的更便捷交互体验.中国移动近日推出的&q ...

  3. Windows Mobile 6 SDK 中的 GPS 工具

    Windows Mobile 6 SDK 中的 GPS 工具 GPS Intermediate Driver 自从 Windows Mobile 5.0 引进了 GPS Intermediate Dr ...

  4. untiy接入微信SDK实现iOS分享

    untiy接入微信SDK实现iOS分享功能 说明: 使用平台:mac电脑 Unity处理 进入微信开发者官网申请应用 2.下载微信的开发工具包sdk导入untiy的 Assest/Plugins/iO ...

  5. 基于声网 SDK 实现 iOS 端的一对一视频通话

    在很多产品,加入实时视频通话已经不是新鲜事情了,尤其是近几年的疫情影响,个人公司国家对于实时音视频的需求一直在快速的增长.例如视频会议.社交应用.实时游戏,甚至也可能出现在一些元宇宙的场景中. 本文将 ...

  6. 如何在React工程中使用JavaScript Barcode SDK创建Web条形码应用

    基于WebAssembly构建的Dynamsoft JavaScript Barcode SDK让Web开发者能够创建适用于浏览器的高性能条码应用.这篇文章分享下如何使用React快速创建一个简单的W ...

  7. ArcGIS Runtime SDK for iOS之符号和渲染

    本篇文章翻译自与点击打开链接,有不妥之处还请大家多多指正! 符号定义了图形外观的非地理方面.它包括了图形的颜色.线宽.透明度等等.ArcGIS Runtime SDK for iOS包含了许多符号类, ...

  8. uniapp离线打包升级SDK(iOS端)

    uniapp离线打包升级SDK(iOS端) 使用的工具 苹果账号 生成CertificateSigningRequest.certSigningRequest文件 创建Certificates 创建p ...

  9. Mobile APP(Apple IOS app store)特性分析

    Mobile APP(Apple IOS app store)特性分析 一.数据来源.分析目的和思路 1. 数据来源 IOS占据将近一半的智能手机市场,其App Store中有大量App,为了分析Ap ...

最新文章

  1. vip能ping通,但80不通的解决方法
  2. MIT无人车新突破:不需要地图也能在“乡野小道”上自动行驶
  3. Mac下Jekyll安装
  4. 一维行滤波提取俯视图下的车道线特征
  5. 中国高校计算机考研:计算机数据结构核心考点解析
  6. Java中带有JWebSocket的WebServerSocket
  7. android运行时状态,Android 如何保存Android 运行时状态
  8. [开发技巧3]不显示报表直接打印
  9. web系统数据库服务器,Web Gateway
  10. 新手产品经理的职业规划
  11. Ebooks C/C++
  12. activiti 工作流_activiti-boot快速开发工作流框架
  13. python中用来占位的语句是_MySQL / Python-gt;语句中占位符的语法错误?
  14. 经典机器学习系列(十)【变分推断】
  15. 像招程序员那样招司机,结果……
  16. Survivor空间溢出实例
  17. hmcl手机版下载_最新HMCL下载地址
  18. 思考的乐趣----matrix67数学笔记:最精妙的无字证明
  19. 全民奇迹修复云服务器跨服,穿过无数服务器来战你《全民奇迹MU》开启跨服PK时代...
  20. 怒怨与忧虑,微信的双重危机来临!

热门文章

  1. 两项大奖加持,浩鲸科技福利小店-WHALE SELECT
  2. ProxmoxVE添加新硬盘
  3. 入职一年的收获与体会
  4. iconfont彩色图标
  5. R7-2 sdut-九九乘法表分数 30作者 周雪芹单位 山东理工大学九九乘法表是数学学习的基础,今天我们就来看看乘法表的相关问题。《九九乘法歌诀》,又常称为“小九九”,如下图所示。你的任务是
  6. 拓扑排序三题(菜肴制作杂物最大食物链计数)
  7. 单片机 架构 程序 经验总结_avr单片机工作经验总结
  8. 蓝桥杯-黑色星期五(算法训练)
  9. 计算机等级考试准考证号规则,计算机等级考试(NCRE)准考证是根据什么规则编号的呢?...
  10. 2021-09-08 python基础知识学习:文件操作和os模块