Unexpectedly finding nil, even after unwrapping - ios

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)
}

Related

Unexpectedly found nil while implicitly unwrapping an Optional value despite conditional binding

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"

I am getting a warning comparing my OPTIONAL value to not-nil will always return true

I have declared a type called "JournalEntry" as an optional and have it set to nil. Then when the VC loads I test to make sure that the object has been injected before trying to use it, but I get an error that says "Comparing non-optional value of type 'JournalEntry' to nil always returns true".
But I have it set as an optional and to nil...
Here's the code:
class AddJournalEntryVC: UIViewController, UITextViewDelegate {
var willEdit:Bool?
var entryForEdit:JournalEntry? = nil
override func viewDidLoad() {
super.viewDidLoad()
if isEditing {
guard let entry = entryForEdit, entry != nil else{ //Comparing non-optional value of type 'JournalEntry' to nil always returns true
return
}
dateLabel.text = entry.dateString!
timeLabel.text = entry.timeString!
timestamp = entry.timestamp!
}
}
Where has my thinking gone wrong? Thank you.
Just remove the entry != nil clause and it will work as you require. The if let statement that proceeds it performs the not-nil check already.
guard let entry = entryForEdit else {
return
}

unexpectedly found nil while unwrapping an Optional value?

I'm facing with an error: "unexpectedly found nil while unwrapping an Optional value"
when I insert new data in coreData and reload my tableview, I recall this function
var unique = [String]()
var loadMovie = [String:[Movie]]()
func insertMovie(movie : Movie) {
let genre = movie.genre!
if unique.contains(genre) {
loadMovie[genre]!.append(movie)
} else {
unique.append(genre)
loadMovie[genre] = [movie]
}
}
and fetch data:
func fetchAndSetResults() {
let app = UIApplication.sharedApplication().delegate as! AppDelegate
let context = app.managedObjectContext
let fetchRequest = NSFetchRequest(entityName: "Movie")
do {
let movies = try context.executeFetchRequest(fetchRequest) as! [Movie]
loadMovie.removeAll()
for movie in movies {
insertMovie(movie)
}
} catch let err as NSError {
print(err.debugDescription)
}
}
and the app crushes for the error mentioned above on line: " loadMovie[genre]!.append(movie)" but if I reload app, my data are stored and visible in tableview. What's the problem?
you unwrapped optional variable means you just resolving the compile time error only. In swift you unwrapping the variable means it is represents that variable won't get the nil.You are just telling to the compiler .But now you are getting the nil (Run time Error) you need to handle this by using Optional Binding.
if let movies = try context.executeFetchRequest(fetchRequest)
{
loadMovie.removeAll()
}
Your variable loadMovie is a Dictionary with Strings as the keys and Arrays of Movies as what is stored for each key. If you are getting the error "unexpectedly found nil while unwrapping an Optional value" for line " loadMovie[genre]!.append(movie)" it means without a doubt the String called genre is sometimes not a stored as a key in your loadMovie Dictionary.
Use the code below to first make sure you can get the Array stored for that key (stored in the genre string), and if you can't then print out the String so you can debug, to find out what key is missing.
var unique = [String]()
var loadMovie = [String:[Movie]]()
func insertMovie(movie : Movie) {
let genre = movie.genre!
if unique.contains(genre) {
if let genreArray = loadMovie[genre]{
genreArray.append(movie)
} else {
NSLog("The missing genre: \(genre)")
}
} else {
unique.append(genre)
loadMovie[genre] = [movie]
}
}
Anytime you want a value that could be nil (not there) you can use the if/let pattern above. So for your second question in the comments you could replace return loadMovie[genre].count with:
if let genreArray = loadMovie[genre]{
return genreArray.count
} else {
return 0 // zero because there are no items
}
There are other ways too. You should checkout a good basic swift tutorial like: http://www.tutorialspoint.com/swift/
If you look at the section on optionals this should all be more clear. Here at stack overflow you are generally expected to first have tried to find out answers for yourself, and understand the basic theory. Unfortunately, that is why you are getting so many down votes. I hope this has helped.
If this has helped you please accept this answer by clicking on the checkmark next to it.

How do I retrieve a score from a leaderboard in iOS?

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.

unexpectedly found nil when use userDefaults

I add #IBAction for button:
#IBAction func addThemeAction(sender: AnyObject) {
var userDefaults:NSUserDefaults=NSUserDefaults.standardUserDefaults()
var itemList:NSMutableArray!=userDefaults.objectForKey("itemList") as NSMutableArray}
When I press button I get fatal error: unexpectedly found nil while unwrapping an Optional value.
There's no object for the key itemList in your NSUserDefaults. Instead of force unwrapping it with !, check if optional is nil and conditionally unwrap it:
let userDefaults = NSUserDefaults.standardUserDefaults()
var itemList = userDefaults.objectForKey("itemList") as? [AnyObject]
if let itemList = itemList {
// itemList is not nil, use it here
} else {
// itemList has never been set, perhaps use some default
}
Also, userDefaults doesn't need to be a var.
You can change [AnyObject] to something else if you know the type (like [String], for example).
One: You can never guarantee that some key is present in your user defaults, so this is a crash waiting to happen. Two: I don't think dictionaries that you read from user defaults are mutable.

Resources