question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

IOS App crash with Null Reference Exception at SetupCaptureSession()

See original GitHub issue

I am in the process of updating a native xamarin ios app to a Microsoft.IOS .Net 6 app. I am using the ZXing.Net6.Mobile nuget which I used to replace the older ZXing.Net.Mobile .

The code being used was seamless as far as building but I am getting a null reference exception when calling the .Scan method. It’s crashing all the way back to the Main application file. Just before the crash the camera does try to open.

This is the stack trace I am getting object reference not set to instance of an object at ZXing.Mobile.ZXingScannerView.SetupCaptureSession() at ZXing.Mobile.ZXingScannerView.<StartScanning>b__42_0() at Foundation.NSActionDispatcher.Apply() at Foundation.NSObject.InvokeOnMainThread(Action ) at ZXing.Mobile.ZXingScannerView.StartScanning(Action`1 scanResultHandler, MobileBarcodeScanningOptions options) at ZXing.Mobile.ZXingScannerViewController.<ViewDidAppear>b__33_1() at Foundation.NSAsyncActionDispatcher.Apply() at UIKit.UIApplication.UIApplicationMain(Int32 , String[] , IntPtr , IntPtr ) at UIKit.UIApplication.Main(String[] , Type , Type ) at DSDRouteManager.iOS.Application.Main(String[] args) in /Users/jamespridgen/Desktop/DSDRouteManager/DSDRouteManager.IOS/Main.cs:line

These are the keys I have in Info.plist <key>NSCameraUsageDescription</key> <string>Can we use your camera</string> <key>Privacy - Camera Usage Description</key> <string>Taking picture barcode</string> <key>Privacy - Photo Library Usage Description</key> <string>Taking picture barcode</string>

This is the code I am using to call the camera

          var auth = AVCaptureDevice.GetAuthorizationStatus(AVAuthorizationMediaType.Video);
          if (auth == AVAuthorizationStatus.NotDetermined)
          {
              if (AVCaptureDevice.RequestAccessForMediaTypeAsync(AVAuthorizationMediaType.Video).Result)
              {
                  auth = AVCaptureDevice.GetAuthorizationStatus(AVAuthorizationMediaType.Video);
              }
          }

       // camera access has been granted at this point
          var cameraScanner = new MobileBarcodeScanner(this); // "this" is the UIViewController
          var options = Util.GetMobileBarcodeScanningOptions();
          var result = await cameraScanner.Scan(options,true); // crash happens here

          
          Scanning options
          
 return new MobileBarcodeScanningOptions()
   {
       AutoRotate = true,
       PossibleFormats = new List<BarcodeFormat>()
       {
           BarcodeFormat.All_1D,
           BarcodeFormat.QR_CODE,
           BarcodeFormat.CODE_39,
           BarcodeFormat.CODE_128,
           BarcodeFormat.UPC_A,
           BarcodeFormat.UPC_E
       }
   };
   
   Do I need some kind of initialization that the older nuget didn't require.
   
   Any help would be much appreciated
   James

Issue Analytics

  • State:open
  • Created 3 months ago
  • Comments:6

github_iconTop GitHub Comments

1reaction
jamesingreersccommented, Jul 5, 2023

@spinspin Thanks for this. It helped a bunch!

0reactions
spinspincommented, Jul 2, 2023

@jamesingreersc this should be enough to get going , I’m using MvvmCross but the core functionality to create a barcode scanner is in here

public class BarcodeScannerViewController : MvxViewController<BarcodeScannerViewModel> { AVCaptureSession captureSession; AVCaptureVideoPreviewLayer previewLayer; public Action<string> BarcodeScanned { get; set; }

    public BarcodeScannerViewController(IntPtr handle) : base(handle) { }

    public BarcodeScannerViewController(){}

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();
        SetUI();
        StartScanning();
    }

    private void SetUI()
    {        
        View.BackgroundColor = UIColor.White;

        NavigationController.NavigationBar.TitleTextAttributes = new UIStringAttributes
        {
            Font = UIFont.FromName("Gill Sans", 20),
            ForegroundColor = UIColor.Black
        };

        NavigationItem.BackButtonTitle = "";
        NavigationItem.Title = "Barcode Scanning";

        var closeImage = UIImage.FromBundle("Close36pt").ImageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate);

        if (DeviceInfo.Version.Major >= 13)
        {
            closeImage.ApplyTintColor(UIColor.Black);
        }

        var closeButton = new UIButton();
        closeButton.SetImage(closeImage, UIControlState.Normal);
        closeButton.TintColor = UIColor.Black;
        NavigationItem.SetRightBarButtonItem(new UIBarButtonItem(closeButton),true);

        closeButton.TouchUpInside += (sender, args) =>
        {
            ViewModel.OnBarcodeScanCancel();
        };
    }


    void StartScanning()
    {
        try
        {
            captureSession = new AVCaptureSession();
            var videoCaptureDevice = AVCaptureDevice.GetDefaultDevice(AVMediaTypes.Video);
            // Create an input from the video capture device
            var videoInput = AVCaptureDeviceInput.FromDevice(videoCaptureDevice, out NSError error);

            if (error != null)
            {
                ViewModel.OnBarcodeScanError();
                return;
            }
            else
            {
                captureSession.AddInput(videoInput);
            }

            // Create a metadata output and set its delegate
            var metadataOutput = new AVCaptureMetadataOutput
            {
                RectOfInterest = UIScreen.MainScreen.Bounds
            };

            metadataOutput.SetDelegate(new OutputDelegate(DidScanBarcode), DispatchQueue.MainQueue);
            captureSession.AddOutput(metadataOutput);
            metadataOutput.MetadataObjectTypes = AVMetadataObjectType.EAN13Code
                                   | AVMetadataObjectType.QRCode
                                   | AVMetadataObjectType.EAN8Code
                                   | AVMetadataObjectType.Code128Code;

            // Create a preview layer to show the view from the camera
            previewLayer = new AVCaptureVideoPreviewLayer(captureSession)
            {
                Frame = new CGRect(View.Bounds.X, View.Bounds.Y +50 , View.Bounds.Width, View.Bounds.Height-50)
            };


            View.Layer.AddSublayer(previewLayer);

            // Create a new UIView with the desired dimensions.
            var redLineView = new UIView
            {
                BackgroundColor = UIColor.Red,
                Frame = new CGRect(0, previewLayer.Frame.GetMidY(), View.Bounds.Width, 2) // This line is 2 points thick and centered in the preview layer.
            };

            // Add the view to the parent view.
            View.AddSubview(redLineView);

            // Start the capture session
            captureSession.StartRunning();
        }

        catch (Exception)
        {
            ViewModel.OnBarcodeScanError();
        }
    }

    private void DidScanBarcode(string barcode)
    {
        // Stop the capture session and notify the delegate
        captureSession.StopRunning();
        captureSession.Dispose(); // release the capture session
        captureSession = null; // set it to null

        // Remove the preview layer
        previewLayer.RemoveFromSuperLayer();
        previewLayer.Dispose(); // Dispose the preview layer
        previewLayer = null; // set it to null

        ViewModel.OnBarcodeScanSuccess(barcode);
    }


    public override void ViewWillDisappear(bool animated)
    {
        base.ViewWillDisappear(animated);

        if (IsBeingDismissed || IsMovingFromParentViewController)
        {
            Cleanup();
        }
    }

    void Cleanup()
    {
        // Stop the capture session and release resources
        captureSession.StopRunning();
        captureSession.Dispose();
        captureSession = null;

        previewLayer.RemoveFromSuperLayer();
        previewLayer.Dispose();
        previewLayer = null;
    }
}

class OutputDelegate : AVCaptureMetadataOutputObjectsDelegate
{
    Action<string> barcodeHandler;

    public OutputDelegate(Action<string> barcodeHandler)
    {
        this.barcodeHandler = barcodeHandler;
    }

    public override void DidOutputMetadataObjects(AVCaptureMetadataOutput captureOutput, AVMetadataObject[] metadataObjects, AVCaptureConnection connection)
    {
        if (metadataObjects != null && metadataObjects.Length > 0)
        {
            var readableObject = metadataObjects[0] as AVMetadataMachineReadableCodeObject;

            if (readableObject != null)
            {
                var barcode = readableObject.StringValue;
                barcodeHandler?.Invoke(barcode);
            }
        }
    }
}

public interface IBarcodeScanningServiceDelegate
{
    void DidFinishScanning(string barcode);
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

App crash due to NullReferenceException in ...
We have installed Xamarin.iOS 13.20.2.2 in Visual Studio for Mac. The app is a Xamarin Forms App and we use the System.Net.Http.HttpClient class ......
Read more >
Xamarin.Forms application throws NullReferenceException ...
I'm creating a Xamarin.Forms Portable application that runs fine in Android but always crashes in iOS. I get this error: System.
Read more >
Strange iOS Crash Only on iOS 13.X…
Hello,. The app is in production/testfilght and I have seen this crash in Xcode Organizer. The highest percentage of such crashes.
Read more >
App crashes with error "Fatal Exception
From IOS 16 onwards my app which uses UITextView in iOS for editing, started crashing for a number of users with error.
Read more >
Fatal Exception: NSInvalidArgument…
the device tries to access the private key reference, it returns nil and our app crashes only on iOS 15. Passing nil to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found