hi i got this error from a QR scanner it was an old code so i try my best to pass to swift 4.2
2018-10-30 17:30:26.105369-0600 qrtest[5870:1814650] [MC] System group container for systemgroup.com.apple.configurationprofiles path is /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles
2018-10-30 17:30:26.105684-0600 qrtest[5870:1814650] [MC] Reading from public effective user settings.
2018-10-30 17:30:31.668783-0600 qrtest[5870:1814650] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArray0 objectAtIndex:]: index 0 beyond bounds for empty NSArray'
*** First throw call stack:
(0x18e6dbef8 0x18d8a9a40 0x18e5ebee0 0x102997b38 0x1029aead8 0x10257e288 0x10257edf4 0x194806ae4 0x19480639c 0x191ccfdfc 0x191ced4cc 0x1034f8de4 0x1034fc1e0 0x10350ecac 0x103500cd8 0x103501bb4 0x103506914 0x18e66a1bc 0x18e665084 0x18e6645b8 0x1908d8584 0x1bb50cbc8 0x1025812c8 0x18e124b94)
libc++abi.dylib: terminating with uncaught exception of type NSExceptionthis might be the cause
video = AVCaptureVideoPreviewLayer(session: session)
video.frame = view.layer.bounds //this part as the error says
view.layer.addSublayer(video)
self.view.bringSubviewToFront(square)
session.startRunning()this is the code
import AVFoundation
import UIKit
class ViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
var video = AVCaptureVideoPreviewLayer()
@IBOutlet var square: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let session = AVCaptureSession()
let captureDevice = AVCaptureDevice.default(for: AVMediaType.video)
do
{
let input = try AVCaptureDeviceInput(device: captureDevice!)
session.addInput(input)
}
catch{
print("error")
}
let output = AVCaptureMetadataOutput()
session.addOutput(output)
output.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
// en el objecttype se puede con la cara para otra app
output.metadataObjectTypes = [AVMetadataObject.ObjectType.qr]
video = AVCaptureVideoPreviewLayer(session: session)
video.frame = view.layer.bounds
view.layer.addSublayer(video)
self.view.bringSubviewToFront(square)
session.startRunning()
}
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
if metadataObjects != nil && metadataObjects.count != nil {
if let object = metadataObjects[0] as? AVMetadataMachineReadableCodeObject{
if object.type == AVMetadataObject.ObjectType.qr{
let alert = UIAlertController(title: "QR code", message: object.stringValue, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "RETAKE", style: .default, handler: nil))
alert.addAction(UIAlertAction(title: "Copy", style: .default, handler: { (nil) in
//aqui especificar donde se va a ir la copia en este caso se va a clipboard
UIPasteboard.general.string = object.stringValue
}))
present(alert, animated: true, completion: nil)
}
}
}
}
}any ideas?
In the exception message, the class it shows is "__NSArray0", which is of course a private subclass of NSArray, but it's almost certainly a constant empty array. The trick is to find where in your code you cause that to be created.
This line doesn't look right:
if metadataObjects != nil && metadataObjects.count != nil {because the compiler won't accept a comparison between an Int ("count") and nil.
FWIW, you can rewrite code like this:
if metadataObjects != nil && metadataObjects.count != nil {
if let object = metadataObjects[0] as? AVMetadataMachineReadableCodeObject{
as something like this:
if let object = metadataObjects?.first as? AVMetadataMachineReadableCodeObject {
It may look a bit strange, but it coalesces all the optionals in one place, so in the end it's a more readable test.
Anyway, you should try to find out where the exception is thrown by symbolicating your crash log, or running the app through the debugger.