ios - AVCaptureSession Runtime crash. fatal error: unexpectedly found nil while unwrapping an Optional value (lldb) -
fatal error: unexpectedly found nil while unwrapping optional value (lldb)
this message because variable set nil code expecting not nil. don't have solution. when remove question mark casting , assignment other errors happen.
thread1 fatal error green highlighted line @ if deviceinput == nil!. , error green highlighted line @ beginsession() call.
the app starts, camera torch gets turned on automatically per code app crashes there. app stays running stuck on launch screen torch still on.
could please see how camera session set , tell me what's wrong? thanks
import uikit import foundation import avfoundation import coremedia import corevideo class viewcontroller: uiviewcontroller, avcapturevideodataoutputsamplebufferdelegate { let capturesession = avcapturesession() var capturedevice : avcapturedevice? var validframecounter: int = 0 // sampling camera enum currentstate { case statepaused case statesampling } var currentstate = currentstate.statepaused override func viewdidload() { super.viewdidload() capturesession.sessionpreset = avcapturesessionpresethigh let devices = avcapturedevice.devices() // loop through capture devices on phone device in devices { // make sure particular device supports video if (device.hasmediatype(avmediatypevideo)) { // check position , confirm we've got camera if(device.position == avcapturedeviceposition.back) { capturedevice = device as? avcapturedevice if capturedevice != nil { //println("capture device found") beginsession() // fatal error } } } } } // configure device camera , focus mode // start capturing frames func beginsession() { // create avcapture session var err : nserror? = nil capturesession.addinput(avcapturedeviceinput(device: capturedevice, error: &err)) if err != nil { println("error: \(err?.localizeddescription)") } // automatic switch on torch mode if capturedevice!.hastorch { // lock device configuration capturedevice!.lockforconfiguration(nil) // check if torchmode on or off. if on turns off otherwise turns on capturedevice!.torchmode = capturedevice!.torchactive ? avcapturetorchmode.off : avcapturetorchmode.on // sets torch intensity 100% capturedevice!.settorchmodeonwithlevel(1.0, error: nil) // unlock device capturedevice!.unlockforconfiguration() } // create avcaptureinput camera device var deviceinput : avcaptureinput = avcapturedeviceinput.deviceinputwithdevice(capturedevice, error: &err) as! avcaptureinput if deviceinput == nil! { // fatal error: unexpectedly found nil while unwrapping optional value (lldb) println("error: \(err?.localizeddescription)") } // set output var videooutput : avcapturevideodataoutput = avcapturevideodataoutput() // create queue run capture on var capturequeue : dispatch_queue_t = dispatch_queue_create("capturequeue", nil) // setup ourself capture delegate videooutput.setsamplebufferdelegate(self, queue: capturequeue) // configure pixel format videooutput.videosettings = [kcvpixelbufferpixelformattypekey string : int(kcvpixelformattype_32bgra)] // kcvpixelbufferpixelformattypekey cfstring btw. // set minimum acceptable frame rate 10 fps capturedevice!.activevideominframeduration = cmtimemake(1, 10) // , size of frames want - we'll use smallest frame size available capturesession.sessionpreset = avcapturesessionpresetlow // add input , output capturesession.addinput(deviceinput) capturesession.addoutput(videooutput) // start session capturesession.startrunning() func setstate(state: currentstate){ switch state { case .statepaused: // goes here? this? uiapplication.sharedapplication().idletimerdisabled = false case .statesampling: // goes here? this? uiapplication.sharedapplication().idletimerdisabled = true } } // sampling camera currentstate = currentstate.statesampling // stop app sleeping uiapplication.sharedapplication().idletimerdisabled = true // update our ui on timer every 0.1 seconds nstimer.scheduledtimerwithtimeinterval(0.1, target: self, selector: selector("update"), userinfo: nil, repeats: true) func stopcameracapture() { capturesession.stoprunning() } // pragma mark pause , resume of detection func pause() { if currentstate == currentstate.statepaused { return } // switch off torch if capturedevice!.istorchmodesupported(avcapturetorchmode.on) { capturedevice!.lockforconfiguration(nil) capturedevice!.torchmode = avcapturetorchmode.off capturedevice!.unlockforconfiguration() } currentstate = currentstate.statepaused // let application go sleep if phone idle uiapplication.sharedapplication().idletimerdisabled = false } func resume() { if currentstate != currentstate.statepaused { return } // switch on torch if capturedevice!.istorchmodesupported(avcapturetorchmode.on) { capturedevice!.lockforconfiguration(nil) capturedevice!.torchmode = avcapturetorchmode.on capturedevice!.unlockforconfiguration() } currentstate = currentstate.statesampling // stop app sleeping uiapplication.sharedapplication().idletimerdisabled = true } } }
looking @ code, should try out of habit of force-unwrapping optionals using ! @ opportunity, “make compile". speaking, if ever find writing if != nil, there’s better way write want. try looking @ examples in this answer idioms copy. might find this answer useful high-level explanation of why optionals useful.
avcapturedeviceinput.deviceinputwithdevice returns anyobject, , force-casting avcaptureinput line:
var deviceinput = avcapturedeviceinput.deviceinputwithdevice(capturedevice, error: &err) as! avcaptureinput (you don’t need state type of deviceinput way, swift can deduce value on right-hand side)
when write as!, telling compiler “don’t argue me, force result of type avcaptureinput, no questions asked”. if turns out returned of different type, app crash error.
but on next line, write:
if deviceinput == nil! { i’m quite astonished compiles @ all! turns out does, , it’s not surprising crashes. force-unwrapping value nil crash, , doing in it’s purest form, force-unwrapping nil literal :)
the problem is, you’ve stated deviceinput non-optional type avcaptureinput. force-casting result not right thing do. docs state,
if device cannot opened because no longer available or because in use, example, method returns
nil, , optional outerror parameter pointsnserrordescribing problem.
the right way handle check result nil, , act appropriately. want like:
if let deviceinput = avcapturedeviceinput.deviceinputwithdevice(capturedevice, error: &err) as? avcaptureinput // use deviceinput } else { println("error: \(err?.localizeddescription)") }
Comments
Post a Comment