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")
}
Related
So I have the following lines:
let theUsername = "\(String(describing: selectedPost?.user.username!))"
if selectedPost?.user.username! != nil {
print("Contains a value!")
username.text = theUsername//Fails here
} else {
print("Doesn’t contain a value.")
username.text = "No username found: Weird"
}
The error message:
Unexpectedly found nil while implicitly unwrapping an Optional value
would make one think the value inside is nil. However when printing:
print("\(String(describing: selectedPost?.user.username!))", " LIT555")
I get:
Optional("C22AE009-8CC6-490A-9328-23A08AAD3A10") LIT555
How can I turn the value into a non optional (ie. get rid of the Optional() part), so it can work without it failing?
Try
if let res = selectedPost?.user.username { // to unwrap the optional value
// check textfield is not nil
username.text = res
}
else {
username.text = "default"
}
Or shortly
username.text = selectedPost?.user.username ?? "default"
According to the crash your textfield is nil , check the IB connection
When you do this
var selectedPost : Post? { didSet { getMediaStats() loadP3Data() } }
and assign a value to selectedPost in the prepare method of the previous vc , the destination vc outlets are still nil because it's not loaded yet and since didSet is called instantly before the load , hence the crash
So remove didSet and call what inside it in viewDidLoad
Even thought you're using ! at the username, this expression is still optional because you have the ? in selectedPost. I strongly suggest you to never use forced unwraps (!), always use if let or guard let to make sure you can unwrap an optional and avoid those crashes.
This is what your code could look like:
if let theUsername = selectedPost?.user.username {
username.text = theUsername
} else {
username.text = "No username found: Weird"
}
or
username.text = selectedPost?.user.username ?? "No username found: Weird"
In my UITableViewController, I have an optional property which is a CNContact. If not nil, I want to populate some text fields with the contact's data.
Here is the property:
var contact: CNContact? = nil {
didSet {
if contact != nil {
prefillFromContact(contact!)
}
}
}
And here is the code setting a text field
func prefillFromContact(con: CNContact) {
print(con.givenName)
firstNameTextField.text = con.givenName
}
The print statement works, and returns the contact's name, but the following line throws an error.
Kate
fatal error: unexpectedly found nil while unwrapping an Optional value
I can't work out why it works on the print statement, but not the following line.
I assume firstNameTextField is declared as an implicit optional, like this:
var firstNameTextField: UITextField!
And you are causing this code to be called before viewDidLoad.
If so, firstNameTextField is nil. It is only possible to set the values of UIViews loaded from XIB/Storyboards once they are loaded. Before that, their outlets are nil.
As an aside (even though this isn't what is causing your problem):
if contact != nil {
prefillFromContact(contact!)
}
is more Swifty like this:
if let contact = contact {
// this is only true if contact != nil, and you have a contact variable
// that is of type CNContact, not CNContact?
prefillFromContact(contact)
}
The code below is giving me the error " 'AnyObject' is not convertible to 'String' " at the line where I put my "if let" statement to unwrap the optional productData pulled from Parse. I'm just trying to pull a String from an object in Parse. I've checked everywhere and all the standard answers/solutions aren't working. Any thoughts?
Most of this code is taken straight from the Parse iOS docs Here
import Foundation
import Parse
func getDataFromParse () {
var productDataFromParse = PFQuery(className:"Product")
productDataFromParse.getObjectInBackgroundWithId("uyeXHufDgq") {
(productData: PFObject?, error: NSError?) -> Void in
if error == nil && productData != nil {
if let productTitle = productData["productTitle"] as! String {
self.productTitle = productTitle
}
} else {
println(error)
}
}
}
productData: PFObject? object is an optional itself. You can't subscript over it yet, because it needs to be unwrapped before. You can replace the productData != nil check with optional chaining.
In Swift 1.2 you can do that and your error checking in the same statement:
if let productTitle = productData?["productTitle"] as? String
where error == nil {
self.productTitle = productTitle
}
Note the additional ? between the productData and the square brackets.
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() {
}
I want to display the highest scores of a GKPlayer with a GKLeaderboard in Swift.
func login() {
if (GKLocalPlayer.localPlayer().authenticated) {
var leaderboardRequest: GKLeaderboard!
leaderboardRequest.identifier = "Best_Score"
// Error: fatal error: unexpectedly found nil while unwrapping an Optional value
func loadLeaderboardsWithCompletionHandler(completionHandler: (([AnyObject]!,
NSError!) -> Void)!) {
var localPlayerScore: GKScore = leaderboardRequest.localPlayerScore
}
}
}
Though, func loadLeaderboardsWithCompletionHandler returns this error message: fatal error: unexpectedly found nil while unwrapping an Optional value because I'm forcing unwrapping an Optional that contains nil.
Where's the error with my code?
You're declaring GKLeaderboard, but not initializing it. Note also that loadLeaderboardWithCompletionHandler is a class function of GKLeaderBoard. Do this instead:
if (GKLocalPlayer.localPlayer().authenticated) {
GKLeaderboard.loadLeaderboardsWithCompletionHandler { objects, error in
if let e = error {
println(e)
} else {
if let leaderboards = objects as? [GKLeaderboard] {
for leaderboard in leaderboards {
if let localPlayerScore = leaderboard.localPlayerScore {
println(localPlayerScore)
}
}
}
}
}
}
As a sidenote, it's not safe to use implicitly unwrapped optionals, i.e., anything declared with a !. Take for example your program here: you can compile it and have to dig through your code to find where the runtime error actually occurred. If you would have declared var leaderBoardRequest: GKLeaderBoard?, you would have been able to identify the source of your problem immediately without having to compile and run.