I am trying to activate the iPhone LED with this code (connected to a UIButton):
#IBAction func toggleFlash(sender: AnyObject) {
let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
if (device.hasTorch) {
device.lockForConfiguration(nil)
if (device.torchMode == AVCaptureTorchMode.On) {
device.torchMode = AVCaptureTorchMode.Off
} else {
device.setTorchModeOnWithLevel(1.0, error: nil)
}
device.unlockForConfiguration()
}
}
Then I get the error:
fatal error: unexpectedly found nil while unwrapping an Optional value
For the following code:
if (device.hasTorch) {
It also says: EXC_BAD_INSTRUCTION (code=...)
What should I do, add delete?!!
THANK YOU!
defaultDeviceWithMediaType() returns nil if there is no device available for that media type. You must check to make sure there is a device before calling other methods on it
#IBAction func toggleFlash(sender: AnyObject) {
if let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo) {
if (device.hasTorch) {
device.lockForConfiguration(nil)
if (device.torchMode == AVCaptureTorchMode.On) {
device.torchMode = AVCaptureTorchMode.Off
} else {
device.setTorchModeOnWithLevel(1.0, error: nil)
}
device.unlockForConfiguration()
}
}
}
With Swift 1.2, you can do the check with this code:
if let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo) where device.hasTorch {
//do your work with device
} else {
NSLog("Device is nil or device does not have Torch")
}
In Swift 1.2, the pattern "if let" is more powerful. According to the release notes:
The “if let” construct has been expanded to allow testing multiple
optionals and guarding conditions in a single if (or while) statement
using syntax similar to generic constraints:
if let a = foo(), b = bar() where a < b,
let c = baz() {
}
Related
Noob programmer here.
I'm trying to become a good programmer with the help of the internet. So, I subscribed to Rob Percivals iOS class. I'm having trouble with this bit of my code. Must've been a recent update that's making it fail on my system although it is the same code as his.
CLGeocoder().reverseGeocodeLocation(userLocation) { (placemarks, error) in
if (error != nil) {
print(error)
} else {
if let p = CLPlacemark(placemark: placemarks![0] as! CLPlacemark) {
print(p)
}
}
}
}
Please try to put it in baby english if possible guys. Thanks!
placemarks is of type [CLPlacemark]?. Therefore you should try something like the following:
if let placemarks = placemarks {
if let p0 = placemarks.first {
print (p0)
}
}
Don't use !. Use if let instead.
The error message just says that the initializer CLPlacemark(placemark:) does never return a nil value so reduce the code and even remove the type casting, because according to the signature [CLPlacemark]?is returned. Optional binding is not needed because if the error is nil the array is guaranteed to exist.
...
} else {
if !placemarks!.isEmpty {
let p = CLPlacemark(placemark: placemarks![0])
print(p)
}
}
I'd recommend taking it a step further with a guard statement, and being a little more verbose with the variable name p... Guard is a good way to exit from the current flow without cluttering your code with if statements, especially since the 'if let' optional unwrapping syntax came around.
CLGeocoder().reverseGeocodeLocation(userLocation) { (placemarks, error) in
guard error == nil else {
print(error)
return
}
if let placemark = placemarks?.first {
let currentPlacemark = CLPlacemark(placemark: placemark)
print(currentPlacemark)
}
}
This is Swift 2. I can't seem to find anything on this. I am getting the error
Cannot invoke 'lockForConfiguration' with an argument list of type '(() -> ())'
On the second line here.
if let device = captureDevice {
device.lockForConfiguration() {
device.videoZoomFactor = 1.0 + CGFloat(ratioValue)
device.unlockForConfiguration()
}
print(ratioValue)
}
In Swift 2 the method lockForConfiguration doesn't take any arguments but instead can throw an NSError. You should wrap it in a do-try-catch statement.
do {
try device.lockForConfiguration()
} catch {
// handle error
return
}
// When this point is reached, we can be sure that the locking succeeded
device.videoZoomFactor = 1.0 + CGFloat(ratioValue)
device.unlockForConfiguration()
Shouldn't it be like this?
if let device = captureDevice {
device.lockForConfiguration(nil)
device.videoZoomFactor = 1.0 + CGFloat(ratioValue)
device.unlockForConfiguration()
print(ratioValue)
}
You can try this line of code:
device.lockForConfiguration(nil)
I'm trying to use TwitterKit framework for my iOS app (in Swift). But when I use Twitter.sharedInstance().APIClient, it occurs an error saying fatal error: unexpectedly found nil while unwrapping an Optional value.
Here is my code:
import TwitterKit
func getUserInfo () {
let twUserID = "my twitter user_id" // This is not nil
let client = Twitter.sharedInstance() // This is not nil
let apiClient = Twitter.sharedInstance().APIClient // This is nil
// This occurs an error
// fatal error: unexpectedly found nil while unwrapping an Optional value
Twitter.sharedInstance().APIClient.loadUserWithID (twUserID, completion: {
(user, error) in
if let validUser = user {
println("Success!")
}
else {
println("Failed...")
}
})
}
Any help?
Even on old Objective-C frameworks that haven't been updated with nullability attributes, you can use Optional binding to ensure that force-unwrapped Optionals have a value before using them.
In the example listed above, you can optionally bind to the value of Twitter.sharedInstance().APIClient, like this:
if let apiClient = Twitter.sharedInstance().APIClient {
apiClient.loadUserWithID (twUserID, completion: {
(user, error) in
if let validUser = user {
println("Success!")
}
else {
println("Failed...")
}
})
}
I am trying to set the preferred input to my AVAudioEngine. I have the following code:
var iphoneInput: AVAudioSessionPortDescription = AVAudioSession.sharedInstance().availableInputs[0] as! AVAudioSessionPortDescription
var error: NSError?
session.setPreferredInput(inPort: iphoneInput, error: error)
but Xcode keeps giving me errors for the last line stating taht it cannot invoke setPreferredinput with an arguement list of type '(AVAudioSessionPortDescription, NSError?)'
I am assuming it wants a NSErrorPointer for the error but I do not know how to create one in swift. Is this my problem and if so how do I create one? thanks!
Add a & character before the variable to make it a pointer:
var myError: NSError?
session.setPreferredInput(iphoneInput, error: &myError)
if myError == nil {
// do stuff
}
Note: in Swift you don't have to use the method's first parameter's name.
for swift 3 does not work... you have to do (translated from ADC:
https://developer.apple.com/library/content/qa/qa1799/_index.html
)
private func setupSession(){
let session = AVAudioSession.sharedInstance()
// setup session:
do {
try session.setCategory(AVAudioSessionCategoryPlayAndRecord, with: .defaultToSpeaker)
try session.setActive(true)
}
catch _{
}
// https://developer.apple.com/library/content/qa/qa1799/_index.html
// let portDescr = AVAudioSessionPortDescription()
// headers:
// AVAudioSessionPortLineIn: String // Line level input on a dock connector
// AVAudioSessionPortBuiltInMic: String // Built-in microphone on an iOS device
// AVAudioSessionPortHeadsetMic: String // Microphone on a wired headset. Headset refers to an accessory that has headphone outputs paired with a microphone.
// You cannot set directly..
// portDescr.portType = AVAudioSessionPortLineIn
guard let availableInputs = session.availableInputs else {
return
}
var mic : AVAudioSessionPortDescription? = nil
for input in availableInputs {
if input.portType == AVAudioSessionPortBuiltInMic{
mic = input
}
}
guard mic != nil else{
return
}
do {
try session.setPreferredInput(mic)
}catch _ {
print("cannot set mic ")
}
}
I'm using CLGeocoder for reverse geolocation and get array of CLPlacemark. When I use GPS outside the US (i.e. -27,127) and then access placemark.postalCode, the app crashes with:
"fatal error: unexpectedly found nil while unwrapping an Optional value".
It seems, that placemark.postalCode is nil where no postal code is available. But postalCode return type in Swift is String!:
var postalCode: String! { get } // zip code, eg. 95014
So I can't even test is for nil, because the crash is caused by the getter of postalCode.
Any ideas how to prevent this crash? Thank you!
Being an optional, even if implicitly unwrapped, you can check it for nil:
if placemark.postalCode != nil {
}
and the app won't crash because of that :)
To prove it, just try this code in a playground, where 2 implicitly unwrapped properties (a computed and a stored) are checked for nil:
struct Test {
var nilComputed: String! { return nil }
var nilStored: String! = nil
}
var test = Test()
if test.nilComputed != nil {
print("It's not nil")
} else {
print("It's nil")
}
if test.nilStored != nil {
print("It's not nil")
} else {
print("It's nil")
}