MasterpassQRScanSDK 2.0.1

MasterpassQRScanSDK 2.0.1

测试已测试
语言语言 Obj-CObjective C
许可 自定义
发布最后发布2021年5月

Muhammad AzeemMastercard LabsMani Tiwaree维护。



  • Mastercard

Masterpass QR Scan SDK

此 SDK 提供了 QR 扫描的 UI 组件,允许修改视图的简单属性或使用自定义视图进行显示。

此 SDK 使用 Objective-C 开发,并与 Swift 一起工作。

此 SDK 基于 QRCodeReaderViewController

要求

  1. Xcode 9.0.0+
  2. iOS 8.0+

特点

  1. 简单的 QR 扫描 UI 定制界面
  2. 通过使用自定义 UI 容易扩展
  3. 支持纵向和横向模式下的扫描功能

安装

Cocoapods

  • 在您的 Podfile 中编写以下内容

    use_frameworks!
    pod 'MasterpassQRScanSDK'
    
  • 执行 pod install

  • 所有设置已完成

手册

Swift
  • 下载 Masterpass QR Scan SDK 的最新版本。

  • 解压文件。

  • 转到您的 Xcode 项目的“通用”设置。将 MasterpassQRScanSDK.framework 拖到“嵌入的二进制文件”部分。确保选中“如果需要则复制项”并单击完成。

  • 在您的应用程序目标的“构建阶段”中创建一个新的“运行脚本阶段”,并在脚本文本字段中粘贴以下片段

    bash "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/MasterpassQRScanSDK.framework/strip-frameworks.sh"

    此步骤是为了解决在归档通用二进制文件时的 App Store 提交错误的问题。

Objc
  • 遵循与 Swift 相同的说明

使用方法

在 iOS10+ 中,您需要首先提供有关相机使用的理由。为此,您需要将 隐私 - 相机使用描述 (NSCameraUsageDescription) 字段添加到您的 Info.plist 中。

简单

  1. 检查相机权限。确保已授权使用相机。
  2. 创建并配置 QRReaderViewControllerBuilder 实例。
  3. 使用 QRReaderViewControllerBuilder 实例创建一个 QRReaderViewController
  4. 设置 QRReaderViewController 实例的代理。
  5. 数据也可以通过块/闭包读取
  6. 呈现控制器。

请注意,您应该使用 QRCodeReader.isAvailable()QRCodeReader.supportsQRCode() 方法检查设备是否支持读取库。

Swift

import MasterpassQRScanSDK
import AVFoundation

@IBAction func scanWithOriginalTheme(_ sender: Any) {
    guard QRCodeReader.isAvailable() && QRCodeReader.supportsQRCode() else {
        return
    }
    // Presents the readerVC
    checkCameraPermission { [weak self] in
        guard let strongSelf = self else {
            return
        }

        var reader:QRCodeReader?

        let qrVC = QRCodeReaderViewController(builder: QRCodeReaderViewControllerBuilder {
            $0.startScanningAtLoad = false
            reader = $0.reader
        })

        //block to read the result
        reader?.setCompletionWith({ result in
            reader?.stopScanning()
            self?.scanResult.text = result;
            self?.dismiss(animated: true, completion: nil)
        })

        //block when cancel is pressed
        qrVC.setCompletionWith({ result in
            reader?.stopScanning()
            self?.dismiss(animated: true, completion: nil)
        })

        // Retrieve the QRCode content via delegate
        qrVC.delegate = self

        strongSelf.present(qrVC, animated: true, completion: {
            qrVC.startScanning()
        })
    }
}

// Check camera permissions
func checkCameraPermission(completion: @escaping () -> Void) {
    let cameraMediaType = AVMediaType.video
    let cameraAuthorizationStatus = AVCaptureDevice.authorizationStatus(for: cameraMediaType)

    switch cameraAuthorizationStatus {
    case .denied:
        showAlert(title: "Error", message: "Camera permissions are required for scanning QR. Please turn on Settings -> MasterpassQR Demo -> Camera")
        break
    case .restricted:
        showAlert(title: "Error", message: "Camera permissions are restricted for scanning QR")
        break
    case .authorized:
        completion()
    case .notDetermined:
        // Prompting user for the permission to use the camera.
        AVCaptureDevice.requestAccess(for: cameraMediaType) { [weak self] granted in
            guard let strongSelf = self else { return }

            DispatchQueue.main.async {
                if granted {
                    completion()
                } else {
                    strongSelf.showAlert(title: "Error", message: "Camera permissions are required for scanning QR. Please turn on Settings -> MasterpassQR Demo -> Camera")
                }
            }
        }
    }
}

func showAlert(title: String, message: String) {
    let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: "Ok", style: .cancel, handler: nil))
    present(alert, animated: true, completion: nil)
}

// MARK: - QRCodeReaderViewController Delegate Methods
func reader(_ reader: QRCodeReaderViewController, didScanResult result: String) {
    reader.stopScanning()
    self.scanResult.text = result;
    dismiss(animated: true, completion: nil)
}

func readerDidCancel(_ reader: QRCodeReaderViewController) {
    reader.stopScanning()
    dismiss(animated: false, completion: nil)
}

Objective-C

@import MasterpassQRScanSDK;
@import AVFoundation;

- (IBAction)scanAction:(id)sender {
  if (![QRCodeReader isAvailable] || ![QRCodeReader supportsQRCode]) {
      return;
  }
  __weak typeof(self) weakSelf = self;
  [self checkCameraPermission: ^{

      __block __weak QRCodeReader* reader;
      QRCodeReaderViewController* qrVC = [QRCodeReaderViewController readerWithBuilderBlock:^(QRCodeReaderViewControllerBuilder *builder){
          reader = builder.reader;
      }];

      //block to read the result
      [reader setCompletionWithBlock:^(NSString *result) {
          [reader stopScanning];
          [self dismissViewControllerAnimated:YES completion: nil];
          self.scanResult.text = result;
      }];

      //block when cancel is pressed
      [qrVC setCompletionWithBlock:^(NSString *result) {
          [reader stopScanning];
          [self dismissViewControllerAnimated:YES completion: nil];
      }];

      // Retrieve the QRCode content via delegate
      qrVC.delegate = weakSelf;

      [weakSelf presentViewController:qrVC animated:true completion:nil];
  }];
}

// Check camera permissions
- (void)checkCameraPermission:(void (^)(void))completion {
    AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    if (status == AVAuthorizationStatusDenied) {
        [self showAlertWithTitle:@"Error" message: @"Camera permissions are required for scanning QR. Please turn on Settings -> MasterpassQR Demo -> Camera"];
        return;
    } else if (status == AVAuthorizationStatusRestricted) {
        [self showAlertWithTitle:@"Error" message: @"Camera permissions are restricted for scanning QR"];
        return;
    } else if (status == AVAuthorizationStatusAuthorized) {
        completion();
    } else if (status == AVAuthorizationStatusNotDetermined) {
        __weak __typeof(self) weakSelf = self;
        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (granted) {
                    completion();
                } else {
                    [weakSelf showAlertWithTitle:@"Error" message: @"Camera permissions are required for scanning QR. Please turn on Settings -> MasterpassQR Demo -> Camera"];
                }
            });
        }];
    }
}

- (void)showAlertWithTitle:(NSString *)title message:(NSString *)message {
    UIAlertController *controller = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
    [controller addAction:[UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleCancel handler:nil]];
    [self presentViewController:controller animated:true completion:nil];
}

# pragma mark - QRCodeReaderViewControllerDelegate Methods
- (void)reader:(QRCodeReaderViewController *)reader didScanResult:(NSString *)result {
    [reader stopScanning];
    [self dismissViewControllerAnimated:YES completion: nil];
    self.scanResult.text = result;
}

- (void)readerDidCancel:(QRCodeReaderViewController *)reader {
    [reader stopScanning];
    [self dismissViewControllerAnimated:YES completion: nil];
}

高级

自定义视图控制器

使用嵌入为子视图控制器 的 QRReaderViewController 的自定义视图控制器。

Swift

import MasterpassQRScanSDK

class CustomViewController : UIViewController, QRCodeReaderDelegate {

  lazy var reader: QRCodeReaderViewController = {
    return QRCodeReaderViewController(builder: QRCodeReaderViewControllerBuilder {
        let readerView = $0.readerView

        // Setup overlay view
        let overlayView = readerView.getOverlay()
        overlayView.cornerColor = UIColor.purple
        overlayView.cornerWidth = 6
        overlayView.cornerLength = 75
        overlayView.indicatorSize = CGSize(width: 250, height: 250)

        // Setup scanning region
        $0.scanRegionSize = CGSize(width: 250, height: 250)

        // Hide torch button provided by the default view
        $0.showTorchButton = false

        // Hide cancel button provided by the default view
        $0.showCancelButton = false

        // Don't start scanning when this view is loaded i.e initialized
        $0.startScanningAtLoad = false

        $0.showSwitchCameraButton = false;

    })
  }()

  override func viewDidLoad() {
      super.viewDidLoad()

      reader.delegate = self

      self.addChildViewController(reader)
      self.view.insertSubview(reader.view, at: 0)

      let viewDict = ["reader" : reader.view as Any]
      self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[reader]|", options: [], metrics: nil, views: viewDict))
      self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[reader]|", options: [], metrics: nil, views: viewDict))

      reader.didMove(toParentViewController: self)
  }

  override func viewDidAppear(_ animated: Bool) {
      super.viewDidAppear(animated)
      reader.startScanning()
  }

  override func viewWillDisappear(_ animated: Bool) {
      super.viewWillDisappear(animated)
      reader.stopScanning()
  }

  // MARK:- Actions
  @IBAction func toggleTorch(_ sender: Any) {
      reader.codeReader!.toggleTorch()
  }

  func reader(_ reader: QRCodeReaderViewController, didScanResult result: String) {
      reader.stopScanning()
  }

  func readerDidCancel(_ reader: QRCodeReaderViewController) {
      reader.stopScanning()
  }
}

Objective-C

@import MasterpassQRScanSDK;

@interface CustomViewController () <QRCodeReaderDelegate>

@property (nonatomic, strong) QRCodeReaderViewController *qrVC;

@end

@implementation CustomViewController

@implementation CustomViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    QRCodeReaderViewControllerBuilder *builder = [[QRCodeReaderViewControllerBuilder alloc] init];
    QRCodeReaderView *readerView = (QRCodeReaderView *) builder.readerView;

    // Setup overlay view
    QRCodeReaderViewOverlay *overlayView = (QRCodeReaderViewOverlay *)[readerView getOverlay];
    overlayView.cornerColor = UIColor.purpleColor;
    overlayView.cornerWidth = 6;
    overlayView.cornerLength = 75;
    overlayView.indicatorSize = CGSizeMake(250, 250);

    // Setup scanning region
    builder.scanRegionSize = CGSizeMake(250, 250);

    // Hide torch button provided by default view
    builder.showTorchButton = false;

    // Hide cancel button provided by default view
    builder.showCancelButton = false;

    // Don't start scanning when this view is loaded i.e initialized
    builder.startScanningAtLoad = false;

    builder.showSwitchCameraButton = false;

    self.qrVC = [[QRCodeReaderViewController alloc] initWithBuilder:builder];
    self.qrVC.delegate = self;

    // Add the reader as child view controller
    [self addChildViewController:self.qrVC];

    // Add reader view to the bottom
    [self.view insertSubview:self.qrVC.view atIndex: 0];

    NSDictionary *dictionary = @{@"qrVC": self.qrVC.view};
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[qrVC]|" options:0 metrics:nil views:dictionary]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[qrVC]|" options:0 metrics:nil views:dictionary]];

    [self.qrVC didMoveToParentViewController:self];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [self.qrVC startScanning];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    [self.qrVC stopScanning];
}

#pragma mark - Actions
- (IBAction)torchButtonPressed:(id)sender {
    [self.qrVC.codeReader toggleTorch];
}

#pragma mark - QRCodeReaderViewControllerDelegate methods
- (void)reader:(QRCodeReaderViewController *)reader didScanResult:(NSString *)result {
    [reader stopScanning];
}

- (void)readerDidCancel:(QRCodeReaderViewController *)reader {
    [reader stopScanning];
}
继承自 QRCodeReaderViewController

您可以通过继承 QRCodeReaderViewController 来创建自己的外观和感觉,以及类的组件位置。您可以修改以下组件

  • cameraView
  • 取消按钮
  • 切换摄像头按钮
  • 切换手电筒按钮

Swift

import UIKit
import MasterpassQRScanSDK

class QRCodeReaderViewControllerSubClass: QRCodeReaderViewController {

    //Mark: - Overriden
    override func setupUIComponents(withCancelButtonTitle cancelButtonTitle: String?, cameraView: QRCodeReaderView?) {
        if let cameraView = cameraView {
            self.cameraView = cameraView;
        }else
        {
            self.cameraView = QRCodeReaderView()
        }
        view.addSubview(self.cameraView!)
    }

    override func setupAutoLayoutConstraints() {
        let views = ["cameraView":self.cameraView!]
        view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-50-[cameraView]-50-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views))
        view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-50-[cameraView]-50-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views))

    }

}

Objective-C

#import <MasterpassQRScanSDK/MasterpassQRScanSDK.h>

@interface QRCodeReaderViewControllerSubClass : QRCodeReaderViewController
@end

@implementation QRCodeReaderViewControllerSubClass

#pragma mark - Overriden
- (void)setupUIComponentsWithCancelButtonTitle:(NSString *)cancelButtonTitle cameraView:(nullable QRCodeReaderView*) cameraView
{
    self.cameraView = cameraView;
    if (!self.cameraView) {
        self.cameraView                                       = [[QRCodeReaderView alloc] init];
        self.cameraView.translatesAutoresizingMaskIntoConstraints = NO;
        self.cameraView.clipsToBounds                             = YES;
    }
    [self.view addSubview:self.cameraView];

    //setup other components

}

- (void)setupAutoLayoutConstraints
{
    NSDictionary *views = @{ @"cameraView" : self.cameraView};
    [self.view addConstraints:
     [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-50-[cameraView]-50-|" options:0 metrics:nil views:views]];
    [self.view addConstraints:
     [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-50-[cameraView]-50-|" options:0 metrics:nil views:views]];

     //setup other components
}

@end