RScanView.m 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. //
  2. // RScanView.m
  3. // r_scan
  4. //
  5. // Created by 李鹏辉 on 2019/11/23.
  6. //
  7. #import "RScanView.h"
  8. #import <AVFoundation/AVFoundation.h>
  9. #import "RScanResult.h"
  10. @interface RScanView()<AVCaptureMetadataOutputObjectsDelegate>
  11. @property(nonatomic , strong)AVCaptureSession * session;
  12. @property(nonatomic , strong)FlutterMethodChannel * _channel;
  13. @property(nonatomic , strong)FlutterRScanViewEventChannel * _event;
  14. @property(nonatomic , strong)AVCaptureVideoPreviewLayer * captureLayer;
  15. @property(nonatomic , strong)AVCaptureDevice * _device;
  16. - (void)onMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result;
  17. @end
  18. @implementation RScanView
  19. - (AVCaptureSession *)session{
  20. if(!_session){
  21. _session=[[AVCaptureSession alloc]init];
  22. }
  23. return _session;
  24. }
  25. - (instancetype)initWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id)args binaryMessenger:(NSObject<FlutterBinaryMessenger> *)messenger{
  26. if(self = [super initWithFrame:frame]){
  27. NSString * channelName=[NSString stringWithFormat:@"com.rhyme_lph/r_scan_view_%lld/method",viewId];
  28. self._channel=[FlutterMethodChannel methodChannelWithName:channelName binaryMessenger:messenger];
  29. __weak __typeof__(self) weakSelf = self;
  30. [weakSelf._channel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
  31. [weakSelf onMethodCall:call result:result];
  32. }];
  33. NSString * eventChannelName=[NSString stringWithFormat:@"com.rhyme_lph/r_scan_view_%lld/event",viewId];
  34. FlutterEventChannel * _evenChannel = [FlutterEventChannel eventChannelWithName:eventChannelName binaryMessenger:messenger];
  35. self._event=[FlutterRScanViewEventChannel new];
  36. // [self._event setRsView:self];
  37. [_evenChannel setStreamHandler:self._event];
  38. AVCaptureVideoPreviewLayer * layer=[AVCaptureVideoPreviewLayer layerWithSession:self.session];
  39. self.captureLayer=layer;
  40. layer.backgroundColor=[UIColor blackColor].CGColor;
  41. [self.layer addSublayer:layer];
  42. layer.videoGravity=AVLayerVideoGravityResizeAspectFill;
  43. self._device=[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
  44. AVCaptureDeviceInput * input=[[AVCaptureDeviceInput alloc] initWithDevice:self._device error:nil];
  45. AVCaptureMetadataOutput * output=[[AVCaptureMetadataOutput alloc]init];
  46. [self.session addInput:input];
  47. [self.session addOutput:output];
  48. self.session.sessionPreset=AVCaptureSessionPresetHigh;
  49. output.metadataObjectTypes=output.availableMetadataObjectTypes;
  50. [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
  51. [output setMetadataObjectTypes:@[AVMetadataObjectTypeAztecCode,AVMetadataObjectTypeCode39Code,
  52. AVMetadataObjectTypeCode93Code,AVMetadataObjectTypeCode128Code, AVMetadataObjectTypeDataMatrixCode,AVMetadataObjectTypeEAN8Code,AVMetadataObjectTypeEAN13Code,AVMetadataObjectTypeITF14Code,AVMetadataObjectTypePDF417Code,AVMetadataObjectTypeQRCode,AVMetadataObjectTypeUPCECode]];
  53. [self.session startRunning];
  54. }
  55. return self;
  56. }
  57. - (void)layoutSubviews{
  58. [super layoutSubviews];
  59. self.captureLayer.frame=self.bounds;
  60. }
  61. -(void)onMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
  62. if ([call.method isEqualToString:@"startScan"]) {
  63. [self resume];
  64. result(nil);
  65. }else if([call.method isEqualToString:@"stopScan"]){
  66. [self pause];
  67. result(nil);
  68. }else if ([call.method isEqualToString:@"setFlashMode"]){
  69. NSNumber * isOpen = [call.arguments valueForKey:@"isOpen"];
  70. result([NSNumber numberWithBool:[self setFlashMode:[isOpen boolValue]]]);
  71. }else if ([call.method isEqualToString:@"getFlashMode"]){
  72. result([NSNumber numberWithBool:[self getFlashMode]]);
  73. }else {
  74. result(FlutterMethodNotImplemented);
  75. }
  76. }
  77. -(void)resume{
  78. if(![self.session isRunning]){
  79. [self.session startRunning];
  80. }
  81. }
  82. -(void)pause{
  83. if ([self.session isRunning]) {
  84. [self.session stopRunning];
  85. }
  86. }
  87. -(BOOL)setFlashMode:(BOOL) isOpen{
  88. [self._device lockForConfiguration:nil];
  89. BOOL isSuccess = YES;
  90. if ([self._device hasFlash]) {
  91. if (isOpen) {
  92. self._device.flashMode=AVCaptureFlashModeOn;
  93. self._device.torchMode=AVCaptureTorchModeOn;
  94. }else{
  95. self._device.flashMode = AVCaptureFlashModeOff;
  96. self._device.torchMode = AVCaptureTorchModeOff;
  97. }
  98. }else{
  99. isSuccess=NO;
  100. }
  101. [self._device unlockForConfiguration];
  102. return isSuccess;
  103. }
  104. -(BOOL)getFlashMode{
  105. [self._device lockForConfiguration:nil];
  106. BOOL isSuccess = self._device.flashMode==AVCaptureFlashModeOn&&
  107. self._device.torchMode==AVCaptureTorchModeOn;
  108. [self._device unlockForConfiguration];
  109. return isSuccess;
  110. }
  111. - (void)captureOutput:(AVCaptureOutput *)output didOutputMetadataObjects:(NSArray<__kindof AVMetadataObject *> *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
  112. if (metadataObjects.count>0) {
  113. AVMetadataMachineReadableCodeObject * metaObject=metadataObjects[0];
  114. NSString * value=metaObject.stringValue;
  115. if(value.length&&self._event){
  116. [self._event getResult:[RScanResult toMap:metaObject]];
  117. }
  118. }
  119. }
  120. @end
  121. @implementation FlutterRScanViewEventChannel
  122. - (FlutterError *)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)events{
  123. self.events = events;
  124. if(self.rsView){
  125. NSNumber * isPlay=[arguments valueForKey:@"isPlay"];
  126. if(isPlay){
  127. if (isPlay.boolValue) {
  128. [self.rsView resume];
  129. }else{
  130. [self.rsView pause];
  131. }
  132. }
  133. }
  134. return nil;
  135. }
  136. - (FlutterError * _Nullable)onCancelWithArguments:(id _Nullable)arguments {
  137. if(self.rsView){
  138. [self.rsView pause];
  139. }
  140. return nil;
  141. }
  142. - (void)getResult:(NSDictionary *)msg{
  143. if(self.events){
  144. self.events(msg);
  145. }
  146. }
  147. @end