I have an image that I download from Parse and load into an image view. When I do so I get the following error (with included print of image to show existence):
<UIImage: 0x13707c950>, {2045, 2588}
fatal error: unexpectedly found nil while unwrapping an Optional value
It is definitely linked up. I have tried cleaning, restarting Xcode, and deleting the view and image and remaking it. I have a companion project that is similar to this, and uses the same code (in a separate method I convert the PFFile into the image). I also know this method works because at another part in the project I load the image in this exact way.
if let image = objectsKeyValues[indexNumber]["image"] {
print(image)
sALargeNoteImage.imageView.image = image as? UIImage
sALargeNoteImage.imageView.contentMode = UIViewContentMode.ScaleAspectFit
}
I can't for the life of me figure out what's happening. I have done plenty of reworking in the storyboard, even at one point refactoring. This could suggest that it is related (as I have read on SO) to Xcode getting "confused". Not really sure what I should try next, short of remaking the storyboard its on (that would be a lot of work). I suppose I could remake it and copy paste the code..
Anybody have any ideas? I don't use a simulator, instead I load it onto an iPad. I have tried deleting and reinstalling the app.
The part that gets highlighted from the error is:
sALargeNoteImage.imageView.image = image as? UIImage
update:
var sALargeNoteImage = SALargeNoteImage()
class SALargeNoteImage: UIViewController {
#IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
sALargeNoteImage = self
}
At one point I was testing out if it would clear the image when I set:
lSLargeNoteImage.imageView = nil
vs
lSLargeNoteImage.imageView.image = nil
I had left it like that by accident, and the function that does that runs before this.
Since you are creating sALargeNoteImage using a simple init, it will not be connected to any of the outlets in the storyboard.
You need to use something like
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let sALargeNoteImage=storyboard.instantiateViewControllerWithIdentifier("largeNoteViewController") as! SALargeNoteImage
in order to instantiate the view controller and link all of the IBOutlets
I would highly recommend that you avoid the use of var someVariable=SomeType() if all you are trying to do is suppress the error from the compiler that properties must be initialised and you intend to initialise the property properly later. It is much better to use var someVariable:SomeType! as this will throw an exception if you forget to assign a value to the property rather than resulting in obscure bugs where a default value is used.
Related
I am relatively new to iOS development with Swift (I actually have 3 years of experience with Android development with Java, trying to learn a new technology). I am creating an app that requires the usage of a library known as SearchTextField:
https://github.com/apasccon/SearchTextField
In a shellnut, it's a UITextField subclass that has a dropdown suggestions/autocomplete functionality.
Below is the ViewController that uses it...
#IBOutlet var homeAddressTextField: SearchTextField!
#IBOutlet var workAddressTextField: SearchTextField!
override func viewDidLoad() {
super.viewDidLoad()
homeAddressTextField.delegate = self
workAddressTextField.delegate = self
homeAddressTextField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
workAddressTextField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
//vvvvvvvvv EXC_BAD_ACCESS CODE 2 THROWN BELOW vvvvvvvv
homeAddressTextField.filterStrings(["foo","bar"])
}
homeAddressTextField should be instantiated, otherwise any reference to it above should throw the same exception. When breakpointing into the problematic line, homeAddressTextField is NOT nil, and correctly shows that it is an instance of SearchTextField.
I have tried many things to fix or at least find the source of the error. As you can tell, I used a strong var instead of weak var for the Outlet.
I have tried using zombies to track any attempt to access a deallocated memory block, yet the zombie Instruments came up with no zombies accessed.
If it is worth noting, the error disappears as soon as the problematic line containing filterStrings() is removed. Any help is appreciated!
It seems bug in library, could you please check here
SearchTextField Issue
It is in still open issues at their repository.
Kindly watch issues in repository, if you try to use someone readymade code.
Are you sure you've attached your IBOutlet in interface builder?
Try putting a breakpoint on the line that's crashing. That will stop it right before executing that line. Then, in the console (command+shift+y) you'll see a line that says "lldb" - put your cursor there and type po homeAddressTextField and see if it returns a value, or nil. If nil, then the IBOutlet is not set properly, which would cause bad access.
Additionally, if it is indeed nil, you'll want to make sure that the subclass and module are both set within interface builder on the SearchTextField, as well as making sure to set the outlet itself. You can also try filtering these strings in the viewDidAppear() method just to see if it is indeed an issue with the reference to the SearchTextField.
Edit: I've looked through the code a bit of the repo. You might not want to set the datasource and delegate properties, as the SearchTextField has a datasource and delegate of its own. You simply need to set the filterable strings as you are on the last line. So try removing the calls to make the view controller the datasource/delegate.
Clicking the textField and then adding class name = SearchTextField.swift worked for me.
I've read several answers to this question and have tried all recommendations with no success. I'm fairly new to swift and am building an app with Swift, PHP and MySQL. I'm receiving the error after the user has logged in to the app and the system should be displaying the username via a label using UILabel.text. The error is occurring on setting a value to the UILabel.text variable. My code is included below. I've tried to hardcode values on other pages and am getting this error throughout my project.
import UIKit
class HomeViewController: UITabBarController {
#IBOutlet var usernameLbl: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// set global variables
let username = (user!["username"] as AnyObject).uppercased
// label values
print(usernameLbl ?? username!)
usernameLbl.text = username
}
}
I'm accessing the HomeViewController programmatically. The app uses a tab bar and the first page of it is Home. The code is from a course I'm taking on Udemy. Here is how I'm accessing Home:
// func to pass to home page or to tabBar
func login() {
// refer to our Main.storyboard
let storyboard = UIStoryboard(name: "Main", bundle: nil)
// store our tabBar Object from Main.storyboard in tabBar var
let tabBar = storyboard.instantiateViewController(withIdentifier: "tabBar")
// present tabBar that is storing in tabBar var
window?.rootViewController = tabBar
}
You might want to follow best practices and avoid the use of ! as much as possible.
The error you've got happens when you try to access a value or reference stored in an optional that does not contain any value (i.e., it is nil).
In your case, if usernameLbl is nil, usernameLbl.text will crash your app (Think "null pointer exception" in Java, perhaps?).
It is very common to define outlests as:
#IBOutlet weak var label: UILabel!
...instead of the safer:
#IBOutlet weak var label: UILabel?
...because the first one allows you to access its properties without using the ? (i.e. label.text vs. label?.text). But there's an implicit assumption that the label is not nil: the ! by itself does nothing to prevent this (it only silences the compiler, telling it "I know what I'm doing, trust me!").
That shouldn't be a problem as long as you only access it after viewDidLoad() and your outlets are proerly connected in Interface Builder/storyboard, because in that case it will be guaranteed to not be nil.
My guess is that you forgot to hook up the outlet to your label.
Here is a tutorial on storyboards in case it helps.
The whole reason outlets need to be defined as optionals (implicitly unwrapped ! or "standard" ?) is that in Swift, all properties must have a value by the time the instance is initialized (actually, even before calling the super class initializer if that applies).
For view controllers, instance initialization happens before the subviews can be initialized and assigned to the properties/outlets. That happens in the method loadView(), which is called lazily (only just before the view is actually needed for display). So by making all subviews optional (and variable, not constant), they can have the temporary "value" of nil by the time the initializer completes execution (thus satisfying Swift's rules).
Edit: If your outlet is still nil at runtime even though it is connected in interface builder, you can at least try to intercept any code resetting it and see what's going on, with a property observer:
#IBOutlet weak var label: UILabel! {
didSet {
if label == nil {
print("Label set to nil!")
// ^ SET A BREAKPOINT IN THIS LINE
}
}
}
Seeing an #IBOutlet on a UITabBarController is very suspicious. You generally have a tab bar controller which presents child UIViewController subclasses, and put labels on those child view controllers, not the tab bar controller. A tab bar controller does not generally have IBOutlet references. The child view controllers would have them.
Double check to which class you've connected that #IBOutlet and confirm whether it's a subclass of UIViewController or UITabBarController.
Think of the ! operator as the "crash if nil" operator. It's actually called the "force unwrap" operator, and is used to "unwrap" an Optional. If the optional contains a nil, it triggers the same error as trying to dereference a null pointer in other languages.
You should avoid the ! operator until you really understand what it does.
IB (Interface Builder) sets up outlets as force-unwrapped so that you can reference them without having to constantly check them for nil. The idea is that your outlets should never be nil, and if they are it's a problem and you WANT to crash. Think of it as a fuse. It triggers an obvious, early failure that's easy to find and fix.
Having a broken outlet (or missing IBAction) is one of the easiest mistakes to make. With an outlet declared as
#IBOutlet var someOutlet: UILabel!
The compiler lets you reference it without unwrapping it, but you will crash if the outlet is nil.
You can avoid the force-unwrap by adding a ? after the outlet name, or using and if let or a guard statement.
However, with outlets, the thing to do is to realize you've got a broken outlet and just fix it. Then your code works fine.
To fix a broken outlet, control-drag from IB to the #IBoutlet declaration in your code. Think of it as hooking up a cable in your entertainment system.
When you declare an outlet in your code the editor puts a little open circle in the margin to the left of the #IBOutlet declaration. When the outlet is connected, the editor shows a filled-in circle, so it's easy to see if an outlet is connected or not. (Same with #IBAction methods.)
I have done lots of research, yet I am stilling having the same problem. I am trying to load a website onto a web view in swift, although every time I run the project, it is giving me the following error message:
EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP,subcode=0x0)
The following two lines of code are what I am attempting to use to load the url onto the web view. I want to let you know that these 2 lines of code came from the following video: https://www.youtube.com/watch?v=rcVv1N1hReQ. Here are the lines of code:
var URL = NSURL(string: "https://www.google.com")
petInfo.loadRequest(NSURLRequest(URL: URL!))
In case you are wondering what the outlet for petInfo looks like, it is displayed in the following block of code:
#IBOutlet weak var petInfo: UIWebView!
The outlet is getting initialized immediately before the viewDidLoad() function. The url is being loaded inside the viewDidLoad() function. Thank you in advance for any help.
I finally figured the answer out. The problem was that my WebView was equal to nil, although my function was requesting a value, so the app crashed. Instead of using the ! to unwrap the outlet, I changed it to the following:
if let pet = petInfo{
//do normal function stuff like loading the web views.
}
I want to thank you for the answer, although it was not what I was looking for. If anybody doesn't understand the code below, just type up a comment (make sure to add +Andrew_Wilson214) and then I will explain it to you further.
I suspect that you have not connected the WebView to the IBOutlet in your ViewController. In the screenshot below you will see that I have defined #IBOutlet weak var petInfo: UIWebView but the grey circle in the gutter next to that line is not filled. It is not connected to the UI element yet. Also check your console to see if get the same fatal error 'unexpectedly found nil while unwrapping an Optional value'.
This question already has answers here:
What does "Fatal error: Unexpectedly found nil while unwrapping an Optional value" mean?
(16 answers)
Closed 6 years ago.
I was using an UICollectionView in Swift but I get when I try to change the text of the cell's label.
func collectionView(collectionView: UICollectionView!, numberOfItemsInSection section: Int) -> Int
{
return 5
}
func collectionView(collectionView: UICollectionView!, cellForItemAtIndexPath indexPath: NSIndexPath!) -> UICollectionViewCell!
{
var cell = collectionView.dequeueReusableCellWithReuseIdentifier("title", forIndexPath: indexPath) as TitleCollectionViewCell
// Next line: fatal error: unexpectedly found nil while unwrapping an Optional value
cell.labelTitle.text = "This is a title"
return cell
}
Does anyone know about this?
You can prevent the crash from happening by safely unwrapping cell.labelTitle with an if let statement.
if let label = cell.labelTitle{
label.text = "This is a title"
}
You will still have to do some debugging to see why you are getting a nil value there though.
Almost certainly, your reuse identifier "title" is incorrect.
We can see from the UITableView.h method signature of dequeueReusableCellWithIdentifier that the return type is an Implicitly Unwrapped Optional:
func dequeueReusableCellWithIdentifier(identifier: String!) -> AnyObject! // Used by the delegate to acquire an already allocated cell, in lieu of allocating a new one.
That's determined by the exclamation mark after AnyObject:
AnyObject!
So, first thing to consider is, what is an "Implicitly Unwrapped Optional"?
The Swift Programming Language tells us:
Sometimes it is clear from a program’s structure that an optional will
always have a value, after that value is first set. In these cases, it
is useful to remove the need to check and unwrap the optional’s value
every time it is accessed, because it can be safely assumed to have a
value all of the time.
These kinds of optionals are defined as implicitly unwrapped
optionals. You write an implicitly unwrapped optional by placing an
exclamation mark (String!) rather than a question mark (String?) after
the type that you want to make optional.
So, basically, something that might have been nil at one point, but which from some point on is never nil again. We therefore save ourselves some bother by taking it in as the unwrapped value.
It makes sense in this case for dequeueReusableCellWithIdentifier to return such a value. The supplied identifier must have already been used to register the cell for reuse. Supply an incorrect identifier, the dequeue can't find it, and the runtime returns a nil that should never happen. It's a fatal error, the app crashes, and the Console output gives:
fatal error: unexpectedly found nil while unwrapping an Optional value
Bottom line: check your cell reuse identifier specified in the .storyboard, Xib, or in code, and ensure that it is correct when dequeuing.
Check if the cell is being registered with self.collectionView.registerClass(cellClass: AnyClass?, forCellWithReuseIdentifier identifier: String). If so, then remove that line of code.
See this answer for more info:
Why is UICollectionViewCell's outlet nil?
"If you are using a storyboard you don't want to call this. It will overwrite what you have in your storyboard."
I don't know is it bug or something but your labels and other UIs does not initialized automatically when you use custom cell. You should try this in your UICollectionViewController class. It worked for me.
override func viewDidLoad() {
super.viewDidLoad()
let nib = UINib(nibName: "<WhateverYourNibName>", bundle: nil)
self.collectionView.registerNib(nib, forCellReuseIdentifier: "title")
}
Replace this line
cell.labelTitle.text = "This is a title"
with
cell.labelTitle?.text = "This is a title"
I got his error when i was trying to access UILabel. I forgot to connect the UILabel to IBOutlet in Storyboard and that was causing the app to crash with this error!!
I was having this issue as well and the problem was in the view controllers. I'm not sure how your application is structured, so I'll just explain what I found. I'm pretty new to xcode and coding, so bear with me.
I was trying to programmatically change the text on a UILabel. Using "self.mylabel.text" worked fine until I added another view controller under the same class that didn't also include that label. That is when I got the error that you're seeing. When I added the same UILabel and connected it into that additional view controller, the error went away.
In short, it seems that in Swift, all view controllers assigned to the same class have to reference the code you have in there, or else you get an error. If you have two different view controllers with different code, assign them to different classes. This worked for me and hopefully applies to what you're doing.
fatal error: unexpectedly found nil while unwrapping an Optional value
Check the IBOutlet collection , because this error will have chance to unconnected uielement object usage.
:) hopes it will help for some struggled people .
I searched around for a solution to this myself. only my problem was related to UITableViewCell Not UICollectionView as your mentioning here.
First off, im new to iOS development. like brand new, sitting here trying to get trough my first tutorial, so dont take my word for anything. (unless its working ;) )
I was getting a nil reference to cell.detailTextLabel.text - After rewatching the tutorial video i was following, it didnt look like i had missed anything. So i entered the header file for the UITableViewCell and found this.
var detailTextLabel: UILabel! { get } // default is nil. label will be created if necessary (and the current style supports a detail label).
So i noticed that it says (and the current style supports a detail label) - Well, Custom style does not have a detailLabel on there by default. so i just had to switch the style of the cell in the Storyboard, and all was fine.
Im guesssing your label should always be there?
So if your following connor`s advice, that basically means, IF that label is available, then use it. If your style is correctly setup and the reuse identifier matches the one set in the Storyboard you should not have to do this check unless your using more then one custom cell.
Nil Coalescing Operator can be used as well.
rowName = rowName != nil ?rowName!.stringFromCamelCase():""
I had the same problem on Xcode 7.3. My solution was to make sure my cells had the correct reuse identifiers. Under the table view section set the table view cell to the corresponding identifier name you are using in the program, make sure they match.
I was having the same issue and the reason for it was because I was trying to load a UIImage with the wrong name. Double-check .setImage(UIImage(named: "-name-" calls and make sure the name is correct.
Same message here, but with a different cause. I had a UIBarButton that pushed a segue. The segue lacked an identifier.
I'm getting stuck on some code with the dreaded "Can't unwrap Optional.None" error in my code.
I'm following the Shutterbug code from the iTunes U Stanford university course.
This is the code given in Objective-C for one of the classes.
http://pastebin.com/LG2k3BBW
and what I've come up with in Swift;
http://pastebin.com/pGtSzu6z
After tracing the errors these lines in particular seem to be giving me the problems
self.scrollView.zoomScale = 1.0
and
self.image = nil
Any advice on what's going wrong here?
I had originally put all the setters in the ViewDidLoad function and was receiving the same error.
This line is called when you are preparing for segue:
ivc.imageURL = flickerFetcher.URLforPhoto(photo, format: FlickrFetcher.FlickrPhotoFormat.Large)
Which calls the setter on imageURL:
set {
self.startDownloadingImage()
}
startDownloadingImage() calls the setter on image which is where you get all of your errors:
set{
self.imageView.image = image
self.scrollView.zoomScale = 1.0
self.spinner.stopAnimating()
self.imageView.frame = CGRectMake(0, 0, image!.size.width, image!.size.height)
}
Since all of this is happening in prepareForSegue, the view controller hasn't been loaded at this point and all of the outlets are nil hence the can't unwrap Optional.none.
You need to restructure your program's logic so that it isn't trying to do stuff with outlets before they are loaded.
Check your outlets are connected. Outlets are defined as implicitly unwrapped Optionals, so you'd expect to see that error if you referred to a property that wasn't set (e.g. If the outlet was not connected)
I've downloaded your project and there was a problem with the outlets - the scrollview and spinner were kind of grayed out in Xcode. Here's how the scrollview and spinner showed up for me:
This means that the items are not installed for the currently selected size class. If you go to the attributes inspector for that view, make sure the Installed option is checked for the size classes you care about:
In your project, the top box (representing any size class) was not checked.
However, there are many more problems within the code, too numerous to go into in full detail in this answer. You have several issues which are causing problems, including (I did give up after a while):
Infinite loops in your property accessors - for example, the get closure for imageURL
Implementing set or willSet closures when you actually want didSet - for example, the willSet on the scrollView would be better as a didSet, or you should be using newValue instead of scrollView, because at the point of willSet, scrollView is still nil.
Setting a value of nil to your image property, then accessing it in the setter block for that property
Something odd going on in your downloading logic (at this point, I decided to call it a day, sorry)