Cognex Mobile Barcode SDK for iOS
概述
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的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IBM V7000错误代码及解决
- 下一篇: 设计模式(八)装饰模式