1

We have code in a Xamarin App using bar code scanning. It has been working successfully for 3 years. We have found an issue with the iPhone 11 pro and its three camera setup.

_captureSession = new AVCaptureSession();
CameraMetaDataDelegate del = null;
AVCaptureDevice captureDevice =
     AVCaptureDevice.GetDefaultDevice(AVMediaType.Video); 
if (captureDevice != null)
{
var videoInput = AVCaptureDeviceInput.FromDevice(captureDevice, out error);

if (videoInput != null) { _captureSession.AddInput(videoInput); }
else { iApp.Log.Error("Video capture error: " + error.LocalizedDescription); }

var metaDataOutput = new AVCaptureMetadataOutput();
_captureSession.AddOutput(metaDataOutput);

del = new CameraMetaDataDelegate(this, _layer);
metaDataOutput.SetDelegate(del, CoreFoundation.DispatchQueue.MainQueue);

metaDataOutput.MetadataObjectTypes = metaDataOutput.AvailableMetadataObjectTypes;


_videoPreviewLayer = new AVCaptureVideoPreviewLayer(_captureSession) { 
    Frame = View.Bounds,
    Orientation = (AVCaptureVideoOrientation)InterfaceOrientation,
};
View.Layer.AddSublayer(_videoPreviewLayer);

...

We have the the necessary entitlements in the info.plist

    <key>NSCameraUsageDescription</key>
<string>Scan Barcodes</string>

It seems to be crashing on the AVCaptureDeviceInput. The "Application would like access to the camera" popup remains on the screen after the crash. This works on older iPhones. We have not tried on an iPhone 11 non-pro.

Log looks like this

default 17:46:52.725211 -0500   tccd    PID[30] is checking access for target PID[933]
default 17:46:52.734801 -0500   mediaserverd    Updating configuration of monitor <RBSProcessMonitorConfiguration: 0x10cc25430; id: M30-27; qos: 25> {
    predicates = {
        <RBSProcessPredicate: 0x103735f30> {
            predicate = <RBSCompoundPredicate; <RBSCompoundPredicate; <RBSProcessEUIDPredicate; 501>; <RBSProcessBKSLegacyPredicate: 0x103104870>>; <RBSProcessBundleIdentifierPredicate; com.apple.InCallService>>;
        };
    }
    descriptor = <RBSProcessStateDescriptor: 0x10cc46300; values: 11> {
        namespaces = {
            com.apple.frontboard.visibility;
        }
    };
}
default 17:46:52.735816 -0500   mediaserverd    BKSApplicationStateMonitor updated with invalid process
default 17:46:52.736059 -0500   runningboardd   [daemon<com.apple.mediaserverd>:30] handle lookup could not find a matching process
default 17:46:52.736188 -0500   mediaserverd    <<<< FigCaptureClientSessionMonitor >>>> -[FigCaptureClientSessionMonitor _updateClientStateCondition:newValue:]: <private> Updating client with application state "Foregrounded" and layout state "None"
default 17:46:52.736343 -0500   mediaserverd    <<<< FigCaptureSession >>>> captureSession_updateRunningCondition: <0x102eddb90> (PID:933): ClientStartedSession:0 Cam/Audio:0/0 bg:0 prewarming:0 int:0 windowed:0 devStolen:0, pressured:0, active:0 shouldRun:0, start:0 stop:0 stopRecordingIfActive:0
default 17:46:52.746798 -0500   mediaserverd    Creating remote service object
default 17:46:52.748227 -0500   applecamerad    <private>
default 17:46:52.748255 -0500   applecamerad    <private>
default 17:46:52.748282 -0500   applecamerad    <private>
default 17:46:52.748314 -0500   applecamerad    <private>
default 17:46:52.748348 -0500   applecamerad    H10ISPFlickerDetectorCreate - HWType = 3; pContext = 0x104c0e830
default 17:46:52.748377 -0500   applecamerad    FlickerDetector: ArbiterClient resource access granted=1
default 17:46:52.749880 -0500   mediaserverd    2325: [volm/inpt/0] on device [ type: vhaw; id: 233; addr: 0x109a33d60; hidden: 0; VA strms: { i/238/0x109a34bc0,  }; agg dev: [ id: 203; addr: 0x10c38d800; uid: "VAD [vhaw] AggDev 6"; virt strms: {  }; phys devs: { [ id: 94; addr: 0x102e1af80; uid: "Hawking"; streams: { i/95/0x102e1b2d0,  } ] } ] ]: 1.000000.
default 17:46:52.749914 -0500   mediaserverd    161:   Setting Input Volume: 18.000000 dB, Final HW Volume: 18.000000 dB, Final SW Volume: 0.000000 dB
default 17:46:52.749945 -0500   mediaserverd    162:   PhysicalDevice UID = "Hawking"
default 17:46:52.750012 -0500   mediaserverd    163:   Scope = 1768845428 ("inpt")
default 17:46:52.750041 -0500   mediaserverd    164:   Element = 0 ("0")
default 17:46:52.750405 -0500   applecamerad    AURemoteIO.cpp:1546:Start: Starting AURemoteIO(0x107008c40)
output client:  1 ch,      0 Hz, Float32, output HW:  1 ch,      0 Hz, Float32
input client:   2 ch,  16000 Hz, Float32, inter, input HW:   2 ch,  16000 Hz, Float32, non-inter
default 17:46:52.750485 -0500   applecamerad    AURemoteIO.cpp:1556:Start: work interval port 0x607b
default 17:46:52.751151 -0500   mediaserverd    MEDeviceStreamClient.cpp:216:AddRunningClient: AQME device VirtualAudioDevice_Hawking: client starting: <RemoteIOClient@0x10500e600(@0x10500e658); input; CMSession(applecamerad[116])>; running count now 1
default 17:46:52.751186 -0500   mediaserverd    671: Client request to start IO proc ID 0x109a4abc0 on VAD 233.
default 17:46:52.751276 -0500   mediaserverd    <<<< FigCaptureSession >>>> captureSession_SetConfiguration: <0x102eddb90> (PID:933): New configuration: <private>
default 17:46:52.751375 -0500   mediaserverd    <<<< FigCaptureSession >>>> captureSession_updateRunningCondition: <0x102eddb90> (PID:933): ClientStartedSession:0 Cam/Audio:0/0 bg:0 prewarming:0 int:0 windowed:0 devStolen:0, pressured:0, active:0 shouldRun:0, start:0 stop:0 stopRecordingIfActive:0
default 17:46:52.751608 -0500   mediaserverd    599: Starting IO type 0 on AggregateDevice 203.
default 17:46:52.751655 -0500   mediaserverd     HALS_IOContext::StartIOProcID: 206 Hawking (VAD [vhaw] AggDev 6):
default 17:46:52.753329 -0500   mediaserverd                    starting ProcID 0x21 state: Prewarm: 0 Play: 0 State: Stopped IOProc 0x21: no
default 17:46:52.753407 -0500   mediaserverd     HALS_Device::_GetCombinedVolumeScalar: client 0 is not present and has a combined volume scalar is 1.000000
default 17:46:52.753633 -0500   mediaserverd    <<<< FigCaptureSession >>>> captureSession_SetConfiguration: <0x102eddb90> (PID:933): New configuration: <private>
default 17:46:52.753700 -0500   CommCenter  #I <private> request: <private>.
default 17:46:52.753812 -0500   mediaserverd    <<<< FigCaptureSession >>>> captureSession_updateRunningCondition: <0x102eddb90> (PID:933): ClientStartedSession:0 Cam/Audio:1/0 bg:0 prewarming:0 int:0 windowed:0 devStolen:0, pressured:0, active:0 shouldRun:0, start:0 stop:0 stopRecordingIfActive:0
default 17:46:52.753934 -0500   CommCenter  #I Received Audio State: <private>
default 17:46:52.753974 -0500   nfcd    00000001 57f02250 -[NFCameraStateMonitor _updateCameraStateValue:]:203  current=0, new=5
default 17:46:52.754014 -0500   mediaserverd    65: :413:: IOProc (AggregateDevice 203, IO type NonNullIOProc) running state is now running (2).
default 17:46:52.754047 -0500   nfcd    00000001 57f02250 -[NFCameraStateMonitor _updateCameraStateValue:]:203  current=5, new=7
default 17:46:52.754078 -0500   nfcd    00000001 57f02250 -[NFCameraStateMonitor _updateCameraStateValue:]:203  current=7, new=15
default 17:46:52.754405 -0500   backboardd  Connection removed: IOHIDEventSystemConnection uuid:07F3B331-86A0-445F-ABA7-DDDA546740A7 pid:933 process:MYAPP5 type:Passive entitlements:0x0 caller:BackBoardServices: <redacted> + 384 attributes:{
    HighFrequency = 1;
    bundleID = "com.MYCOMPANY.mobile.MYAPP.development";
    pid = 933;
} inactive:0 events:102 mask:0x800
default 17:46:52.754543 -0500   backboardd  HIDAnalytics Unregister Send event com.apple.hid.queueUsage
default 17:46:52.755359 -0500   SpringBoard Workspace connection invalidated for <FBWorkspaceServer: 0x2822ce040>
default 17:46:52.755514 -0500   SpringBoard [application<com.MYCOMPANY.mobile.MYAPP.development>:933] Now flagged as pending exit for reason: workspace client connection invalidated
default 17:46:52.755776 -0500   SpringBoard Updating configuration of monitor <RBSProcessMonitorConfiguration: 0x2823ed600; id: M57-6; qos: 25> {
    predicates = {
        <RBSProcessPredicate: 0x283a521b0> {
            predicate = <RBSCompoundPredicate; <RBSCompoundPredicate; <RBSProcessEUIDPredicate; 501>; <RBSProcessBKSLegacyPredicate: 0x283a40340>>; <RBSProcessBundleIdentifierPredicate; com.apple.springboard>>;
        };
        <RBSProcessPredicate: 0x283a5c2e0> {
            predicate = <RBSCompoundPredicate; <RBSCompoundPredicate; <RBSProcessEUIDPredicate; 501>; <RBSProcessBKSLegacyPredicate: 0x283a40340>>; <RBSProcessBundleIdentifierPredicate; com.apple.MailCompositionService>>;
        };
        <RBSProcessPredicate: 0x283a5c2d0> {
            predicate = <RBSCompoundPredicate; <RBSProcessBundleIdentifierPredicate; com.apple.ScreenshotServicesService>; <RBSCompoundPredicate; <RBSProcessEUIDPredicate; 501>; <RBSProcessBKSLegacyPredicate: 0x283a40340>>>;
        };
        <RBSProcessPredicate: 0x283a5d2e0> {
            predicate = <RBSCompoundPredicate; <RBSCompou<…>
default 17:46:52.755823 -0500   SpringBoard connection invalidated
default 17:46:52.755869 -0500   SpringBoard connection invalidated
default 17:46:52.756102 -0500   CommCenter  Client [<private>] disconnected (conn=0x101590a20), client list size 35
default 17:46:52.756159 -0500   locationd   #Spi, Connection invalidated for process <private>

Not sure if it is another permissions issue, or using the wrong AV API, or need another preliminary step. Perhaps a race condition that should delay until camera responds available?

Ben Butzer
  • 915
  • 10
  • 24
  • 1
    Hi , due to not having IPhone 11 to test , however you can have a check with [Verifying and Request Authorization for Capture](https://developer.apple.com/documentation/avfoundation/cameras_and_media_capture/requesting_authorization_for_media_capture_on_ios?language=objc) first . – Junior Jiang Sep 26 '19 at 06:27
  • Thanks Junior Jiang, I am getting status not determined for some reason. Digging deeper. – Ben Butzer Sep 26 '19 at 13:12
  • The status check is necessary to proceed to the next steps in iPhone 11 it appears. I have it narrowed down now to the set delegate line. metaDataOutput.MetadataObjectTypes = metaDataOutput.AvailableMetadataObjectTypes; – Ben Butzer Sep 26 '19 at 13:53
  • If I take that line out, I can actually proceed to the view screen and see the camera with the bar code line, but I am not actually capturing. – Ben Butzer Sep 26 '19 at 15:51
  • Okey , glad found the solution , this will be helpfu for other developers in iPhone 11. – Junior Jiang Sep 27 '19 at 02:05

1 Answers1

1

Junior Jiang's suggestion led me down the path to getting the iPhone 11 pro bar code scanning. First it really is necessary to check the authorization status, which used to fire on the first request before. Once this is established, then the camera will work. The second problem is that, at least in Xamarin C#, I could not assign the list of AvailableMetaDataObjectTypes. There is an earlier Stack Overflow which directs to use that list: Stack Overflow Xcode 9/Swift 4 AVCaptureMetadataOutput setMetadataObjectTypes use availableMetadataObjectTypes But now the solution was to explicitly state which ones to use.

_captureSession = new AVCaptureSession();
CameraMetaDataDelegate del = null;

var authStatus = AVCaptureDevice.GetAuthorizationStatus(AVMediaType.Video);
AVCaptureDevice captureDevice = null;

// check authorization status
if (authStatus == AVAuthorizationStatus.Authorized)
{
    captureDevice = AVCaptureDevice.GetDefaultDevice(AVMediaType.Video); // update for iOS 13
}
else if (authStatus == AVAuthorizationStatus.NotDetermined)
{
    AVCaptureDevice.RequestAccessForMediaType(AVMediaType.Video, (granted) =>
    {
        if (!granted)
        {
            Log.Error("ViewDidLoadBase ScanLayer RequestAccessForMediaType not granted!");
        }
        else
        {
            Log.Error("ViewDidLoadBase ScanLayer RequestAccessForMediaType granted!");
        }
    });
}
else
{
    Log.Error("Not Authorized! Status: " + authStatus.ToString());
}
if (captureDevice != null)
{
    var videoInput = AVCaptureDeviceInput.FromDevice(captureDevice, out error);
    if (videoInput != null)
    {
        _captureSession.AddInput(videoInput);
    }
    else
    {
        Log.Error("Video capture error: " + error.LocalizedDescription);
    }

    var metaDataOutput = new AVCaptureMetadataOutput();
    _captureSession.AddOutput(metaDataOutput);

    del = new CameraMetaDataDelegate(this, _layer);
    metaDataOutput.SetDelegate(del, CoreFoundation.DispatchQueue.MainQueue);

    //metaDataOutput.MetadataObjectTypes = metaDataOutput.AvailableMetadataObjectTypes;

    metaDataOutput.MetadataObjectTypes =  AVMetadataObjectType.QRCode | AVMetadataObjectType.Code128Code | AVMetadataObjectType.UPCECode | AVMetadataObjectType.EAN13Code ;   

    _videoPreviewLayer = new AVCaptureVideoPreviewLayer(_captureSession) { 
        Frame = View.Bounds,
        Orientation = (AVCaptureVideoOrientation)InterfaceOrientation,
    };
    View.Layer.AddSublayer(_videoPreviewLayer);
Ben Butzer
  • 915
  • 10
  • 24
  • For me `metaDataOutput.MetadataObjectTypes = AVMetadataObjectType.QRCode | AVMetadataObjectType.Code128Code | AVMetadataObjectType.UPCECode | AVMetadataObjectType.EAN13Code ;` is the solution. – Adam Mrozek Mar 17 '20 at 10:36