mirror of
https://github.com/simplezhli/flutter_barcode_reader.git
synced 2024-12-23 07:19:20 +08:00
Rewrote iOS scanner in ObjC to avoid swift plugin conflicts with use_frameworks!
This commit is contained in:
parent
3cea973135
commit
80b5c6f3eb
@ -6,7 +6,6 @@ if ENV['FLUTTER_FRAMEWORK_DIR'] == nil
|
||||
end
|
||||
|
||||
target 'Runner' do
|
||||
use_frameworks!
|
||||
|
||||
# Pods for Runner
|
||||
|
||||
|
@ -20,6 +20,6 @@ SPEC CHECKSUMS:
|
||||
Flutter: d674e78c937094a75ac71dd77e921e840bea3dbf
|
||||
MTBBarcodeScanner: 66c75f40cbac5986c97634a0775bfe7f92243e7c
|
||||
|
||||
PODFILE CHECKSUM: cc70c01bca487bebd110b87397f017f3b76a89f1
|
||||
PODFILE CHECKSUM: 407db753d18e8726329521f96a8fa0bebaef3f42
|
||||
|
||||
COCOAPODS: 1.3.1
|
||||
|
@ -11,6 +11,7 @@
|
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||
3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
|
||||
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
5CB758D7343A0FB9D27CC91C /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C8072F22B7B32BA6730C5387 /* libPods-Runner.a */; };
|
||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
|
||||
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
|
||||
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
@ -20,7 +21,6 @@
|
||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
||||
A969C0372EF8436F14E8E3DB /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 178DF4CC418BA343104EED78 /* Pods_Runner.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
@ -41,7 +41,6 @@
|
||||
/* Begin PBXFileReference section */
|
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
||||
178DF4CC418BA343104EED78 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
||||
3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
|
||||
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
@ -56,6 +55,7 @@
|
||||
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
C8072F22B7B32BA6730C5387 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -65,7 +65,7 @@
|
||||
files = (
|
||||
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
|
||||
3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
|
||||
A969C0372EF8436F14E8E3DB /* Pods_Runner.framework in Frameworks */,
|
||||
5CB758D7343A0FB9D27CC91C /* libPods-Runner.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -75,7 +75,7 @@
|
||||
3C7717B73810891D4425A279 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
178DF4CC418BA343104EED78 /* Pods_Runner.framework */,
|
||||
C8072F22B7B32BA6730C5387 /* libPods-Runner.a */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
@ -227,9 +227,12 @@
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-resources.sh",
|
||||
"${PODS_ROOT}/GoogleMaps/Maps/Frameworks/GoogleMaps.framework/Versions/A/Resources/GoogleMaps.bundle",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
@ -290,14 +293,10 @@
|
||||
inputPaths = (
|
||||
"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
|
||||
"${PODS_ROOT}/../../../../../../flutter/bin/cache/artifacts/engine/ios/Flutter.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/MTBBarcodeScanner/MTBBarcodeScanner.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/barcode_scan/barcode_scan.framework",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MTBBarcodeScanner.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/barcode_scan.framework",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:barcode_scan/barcode_scanner.dart';
|
||||
import 'package:barcode_scan/barcode_scan.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
void main() {
|
||||
|
@ -1,4 +1,9 @@
|
||||
#import <Flutter/Flutter.h>
|
||||
#import "BarcodeScannerViewControllerDelegate.h"
|
||||
|
||||
@interface BarcodeScanPlugin : NSObject<FlutterPlugin>
|
||||
|
||||
@interface BarcodeScanPlugin : NSObject<FlutterPlugin, BarcodeScannerViewControllerDelegate>
|
||||
|
||||
@property(nonatomic, retain) FlutterResult result;
|
||||
@property (nonatomic, assign) UIViewController *hostViewController;
|
||||
@end
|
||||
|
@ -1,8 +1,35 @@
|
||||
#import "BarcodeScanPlugin.h"
|
||||
#import <barcode_scan/barcode_scan-Swift.h>
|
||||
#import "BarcodeScannerViewController.h"
|
||||
|
||||
@implementation BarcodeScanPlugin
|
||||
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
|
||||
[SwiftBarcodeScanPlugin registerWithRegistrar:registrar];
|
||||
FlutterMethodChannel *channel = [FlutterMethodChannel methodChannelWithName:@"com.apptreesoftware.barcode_scan"
|
||||
binaryMessenger:registrar.messenger];
|
||||
BarcodeScanPlugin *instance = [BarcodeScanPlugin new];
|
||||
instance.hostViewController = [UIApplication sharedApplication].delegate.window.rootViewController;
|
||||
[registrar addMethodCallDelegate:instance channel:channel];
|
||||
}
|
||||
|
||||
- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
|
||||
if ([@"scan" isEqualToString:call.method]) {
|
||||
self.result = result;
|
||||
[self showBarcodeView];
|
||||
} else {
|
||||
result(FlutterMethodNotImplemented);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)showBarcodeView {
|
||||
BarcodeScannerViewController *scannerViewController = [[BarcodeScannerViewController alloc] init];
|
||||
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:scannerViewController];
|
||||
scannerViewController.delegate = self;
|
||||
[self.hostViewController presentViewController:navigationController animated:NO completion:nil];
|
||||
}
|
||||
|
||||
- (void)barcodeScannerViewController:(BarcodeScannerViewController *)controller didScanBarcodeWithResult:(NSString *)result {
|
||||
if (self.result) {
|
||||
self.result(result);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -1,213 +0,0 @@
|
||||
//
|
||||
// BarcodeScannerViewController.swift
|
||||
// AppTreeRevolution
|
||||
//
|
||||
// Created by Matthew Smith on 2/18/15.
|
||||
// Copyright (c) 2015 AppTree Software. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import MTBBarcodeScanner
|
||||
|
||||
protocol BarcodeScannerViewControllerDelegate : class {
|
||||
func barcodeScannerViewController(_ controller : BarcodeScannerViewController, didScanBarcodeWithResult result: String)
|
||||
}
|
||||
|
||||
struct BarcodeScanContext {
|
||||
var attributeIndex : Int?
|
||||
}
|
||||
|
||||
protocol TorchSupport {
|
||||
var flashOn: Bool { get }
|
||||
var hasTorch: Bool { get }
|
||||
func toggleFlash(to flashOn: Bool)
|
||||
}
|
||||
|
||||
extension TorchSupport {
|
||||
var flashOn: Bool {
|
||||
if let device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo) {
|
||||
return device.torchMode == AVCaptureTorchMode.on && device.flashMode == AVCaptureFlashMode.on
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var hasTorch: Bool {
|
||||
let device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
|
||||
return device?.hasTorch ?? false
|
||||
}
|
||||
|
||||
func toggleFlash(to flashOn: Bool) {
|
||||
let device : AVCaptureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)
|
||||
do {
|
||||
if device.hasFlash && device.hasTorch {
|
||||
try device.lockForConfiguration()
|
||||
if flashOn {
|
||||
device.flashMode = AVCaptureFlashMode.on
|
||||
device.torchMode = AVCaptureTorchMode.on
|
||||
} else {
|
||||
device.flashMode = AVCaptureFlashMode.off
|
||||
device.torchMode = AVCaptureTorchMode.off
|
||||
}
|
||||
device.unlockForConfiguration()
|
||||
}
|
||||
} catch {
|
||||
print("Could not lock the camera configuration")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BarcodeScannerOverlayView : UIView, TorchSupport {
|
||||
|
||||
var turnLightOnLabel : UILabel!
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
_init()
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
_init()
|
||||
}
|
||||
|
||||
override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
}
|
||||
|
||||
func _init() {
|
||||
turnLightOnLabel = UILabel()
|
||||
turnLightOnLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||
turnLightOnLabel.textColor = UIColor.white
|
||||
turnLightOnLabel.layer.cornerRadius = 8.0
|
||||
turnLightOnLabel.clipsToBounds = true
|
||||
turnLightOnLabel.alpha = 0.8
|
||||
turnLightOnLabel.text = "Tap to toggle flash"
|
||||
self.addSubview(turnLightOnLabel)
|
||||
self.addConstraints(NSLayoutConstraint
|
||||
.constraints(withVisualFormat: "V:|[turnLightOnLabel(20)]-20-|",
|
||||
options: NSLayoutFormatOptions.alignAllBottom,
|
||||
metrics: nil,
|
||||
views: ["turnLightOnLabel" : turnLightOnLabel]))
|
||||
}
|
||||
|
||||
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||
UIView.animate(withDuration: 0.35, animations: {
|
||||
self.turnLightOnLabel.alpha = 0.0
|
||||
})
|
||||
self.toggleFlash(to: true)
|
||||
}
|
||||
|
||||
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||
UIView.animate(withDuration: 0.35, animations: {
|
||||
self.turnLightOnLabel.alpha = 0.8
|
||||
})
|
||||
self.toggleFlash(to: false)
|
||||
}
|
||||
}
|
||||
|
||||
class BarcodeScannerViewController: UIViewController, TorchSupport {
|
||||
|
||||
var overlayView: BarcodeScannerOverlayView!
|
||||
var previewView: UIView!
|
||||
|
||||
var scanner : MTBBarcodeScanner!
|
||||
var context : BarcodeScanContext = BarcodeScanContext()
|
||||
|
||||
weak var delegate : BarcodeScannerViewControllerDelegate?
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
self.previewView = UIView(frame: self.view.bounds)
|
||||
self.previewView.translatesAutoresizingMaskIntoConstraints = false
|
||||
self.overlayView = BarcodeScannerOverlayView(frame: self.view.bounds)
|
||||
self.overlayView.translatesAutoresizingMaskIntoConstraints = false
|
||||
self.view.addSubview(previewView)
|
||||
self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:[previewView]", options: NSLayoutFormatOptions.alignAllBottom, metrics: nil, views: ["previewView" : previewView]))
|
||||
self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:[previewView]", options: NSLayoutFormatOptions.alignAllBottom, metrics: nil, views: ["previewView" : previewView]))
|
||||
|
||||
|
||||
// self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:[overlayView]", options: NSLayoutFormatOptions.alignAllBottom, metrics: nil, views: ["overlayView" : overlayView]))
|
||||
// self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:[overlayView]", options: NSLayoutFormatOptions.alignAllBottom, metrics: nil, views: ["overlayView" : overlayView]))
|
||||
scanner = MTBBarcodeScanner(previewView: previewView)
|
||||
self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(BarcodeScannerViewController.cancel))
|
||||
updateFlashButton()
|
||||
}
|
||||
|
||||
private func updateFlashButton() {
|
||||
if !self.hasTorch {
|
||||
return
|
||||
}
|
||||
if self.flashOn {
|
||||
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Flash Off", style: .plain, target: self, action: #selector(BarcodeScannerViewController.toggle))
|
||||
} else {
|
||||
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Flash On", style: .plain, target: self, action: #selector(BarcodeScannerViewController.toggle))
|
||||
}
|
||||
}
|
||||
|
||||
func toggle() {
|
||||
self.toggleFlash(to: !flashOn)
|
||||
self.updateFlashButton()
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
if self.scanner.isScanning() {
|
||||
self.scanner.stopScanning()
|
||||
}
|
||||
MTBBarcodeScanner.requestCameraPermission { (success : Bool) -> Void in
|
||||
if success {
|
||||
self.startScan()
|
||||
} else {
|
||||
self.showNoCameraAccessAlert()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func cancel() {
|
||||
self.dismiss(animated: true, completion: nil)
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
}
|
||||
|
||||
override func viewWillDisappear(_ animated: Bool) {
|
||||
super.viewWillDisappear(animated)
|
||||
self.scanner.stopScanning()
|
||||
}
|
||||
|
||||
override func viewDidDisappear(_ animated: Bool) {
|
||||
super.viewDidDisappear(animated)
|
||||
if self.flashOn {
|
||||
self.toggleFlash(to: false)
|
||||
}
|
||||
}
|
||||
|
||||
override func didReceiveMemoryWarning() {
|
||||
super.didReceiveMemoryWarning()
|
||||
}
|
||||
|
||||
fileprivate func startScan() {
|
||||
do {
|
||||
try self.scanner.startScanning(resultBlock: {[weak self] results in
|
||||
if let code = results?.first {
|
||||
self?.scanner.stopScanning()
|
||||
if let strongSelf = self {
|
||||
self?.delegate?.barcodeScannerViewController(strongSelf, didScanBarcodeWithResult: code.stringValue)
|
||||
self?.dismiss(animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
})
|
||||
} catch {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func showNoCameraAccessAlert() {
|
||||
let alertController = UIAlertController(title: "Camera access denied", message: "Camera access has been disabled for this application. To turn camera access back on, please go to the iOS settings application.", preferredStyle: .alert);
|
||||
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in
|
||||
_ = self.navigationController?.popViewController(animated: true)
|
||||
}))
|
||||
self.present(alertController, animated: true, completion: nil)
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
import Flutter
|
||||
import UIKit
|
||||
import MTBBarcodeScanner
|
||||
|
||||
public class SwiftBarcodeScanPlugin: NSObject, FlutterPlugin, BarcodeScannerViewControllerDelegate {
|
||||
|
||||
private var result : FlutterResult?
|
||||
private var hostViewController : UIViewController?
|
||||
|
||||
public static func register(with registrar: FlutterPluginRegistrar) {
|
||||
let channel = FlutterMethodChannel(name: "com.apptreesoftware.barcode_scan", binaryMessenger: registrar.messenger());
|
||||
let instance = SwiftBarcodeScanPlugin();
|
||||
instance.hostViewController = UIApplication.shared.delegate?.window!?.rootViewController
|
||||
registrar.addMethodCallDelegate(instance, channel: channel);
|
||||
}
|
||||
|
||||
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
||||
switch call.method {
|
||||
case "scan":
|
||||
self.result = result;
|
||||
showBarcodeView();
|
||||
break;
|
||||
default:
|
||||
result(FlutterMethodNotImplemented);
|
||||
}
|
||||
}
|
||||
|
||||
private func showBarcodeView() {
|
||||
let viewController = BarcodeScannerViewController()
|
||||
let navController = UINavigationController(rootViewController: viewController)
|
||||
viewController.delegate = self
|
||||
self.hostViewController?.present(navController, animated: true, completion: nil);
|
||||
}
|
||||
|
||||
func barcodeScannerViewController(_ controller : BarcodeScannerViewController, didScanBarcodeWithResult result: String) {
|
||||
if let callback = self.result {
|
||||
callback(result)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user