I'm getting a crash in the following code:
var gmsBounds: GMSMutablePath {
get {
let path = GMSMutablePath(with: self.boundaries)
return path!
}
}
Currently it crashes when initializing the GMSMutablePath according to Crashlytics. However this code isn't ever called before the class is initialized, and self.boundaries is stored during initialization, so I'm not sure how self.boundaries could be nil. I'm also personally unable to recreate the crash, so it is not a bug that affects every user. Any help is appreciated, computed variables are a new concept for me.
When I make code reviews always i avoid forced unwrapping, at first sight you can believe that it never will turn to nil but I prefer avoid that
return path!
Try to unwrapping (safely) it first or change the variable definition for optional:
var gmsBounds: GMSMutablePath? {
get {
let path = GMSMutablePath(with: self.boundaries)
return path!
}
}
Related
I have no idea why I get this error.
The problem code is here
for i in 0..<itemDataJson?.count {
imageUrls.append(appDelegate.itemDataJson![i]["image_url"].string!)
}
When I print(itemDataJson?.count) it prints Optional(1).
What am I doing wrong?
Thank you.
It's printing Optional(1) because the variable itemDataJson is nullable, so the count would therefore have to be nullable, because we don't know if itemDataJson actually has a value.
The main problem that I see in your code is that you are force-unwrapping variables. Force-unwrapping a variable is a code smell (usually, although I do it myself from time to time, but you need to be careful).
When you force unwrap a variable, you need to ask yourself the question, "Do I want the app to crash here if this variable is nil?". If the answer is yes, then using a force unwrap is acceptable, otherwise, you should create a non-nullable variable or if that is not possible, you should use the guard statement in swift.
This could be used like this:
guard let itemDataJson = itemDataJson else {
// itemDataJson was null do something
return
}
You can use the if let construct as well, but be careful of the pyramid of doom if you don't use the if let construct correctly. See here for using it correctly, or use a guard statement.
I would recommend checking out the documentation on optionals if you have not done so already.
I would change the code to this version:
if (itemDataJson != nil) {
for i in 0..<itemDataJson!.count {
imageUrls.append(appDelegate.itemDataJson![i]["image_url"].string!)
}
}
You should check all optionals before you try to access the underlying value. Best course of action would be to use if let statements.
if let itemDataJSON = itemDataJSON {
for i in 0..<itemDataJSON.count {
if let items = appDelegate.itemDataJSON {
if let imageURL = items[i]["imageURL"].string {
imageUrls.append(imageURL)
}
}
}
}
Other than that, it's a bad practice to store data in AppDelegate. You should create your own data layer that is not dependent of AppDelegate to make data handling more efficient and easier.
instead of checking for nil you should try this.
if let item = itemDataJson {
for i in 0..<item.count {
imageUrls.append(appDelegate.itemDataJson![i]["image_url"].string!)
}
}
Getting the following error:
fatal error: unexpectedly found nil while unwrapping an Optional value
I am making a registration form application. The app allows users to create custom questions to be added to a form. At the moment I'm using a Singleton design pattern to pass the list of questions between the editing tab and the tab used to display the form.
My singleton class:
class Singleton {
static let sharedInstance = Singleton()
var questions: [Question] = []
}
In the editing form the user will press a button to update the form that people can then fill out. Here is that code and is also where I'm getting the error:
var mySingleton: Singleton!
#IBAction func updateForm(sender: AnyObject) {
for index in mySingleton.questions.count...questionsArray.count {
mySingleton.questions.append(questionsArray[index])
}
}
Thank you for your help.
This is where the error is occurring:
for index in mySingleton.questions.count...questionsArray.count {
mySingleton.questions.append(questionsArray[index])
}
The final index that is looped through is questionsArray.count. When you access questionsArray[questionsArray.count], you are outside the bounds of the array. This index should never be accessed.
Instead, change your loop to the following:
for index in mySingleton.questions.count..<questionsArray.count {
mySingleton.questions.append(questionsArray[index])
}
The only difference is that ... becomes ..<, in order to leave out the last index that is causing the error.
Edit: after looking back at the code, it seems likely that mySingleton was never set equal to anything. Before this code is executed, you could set mySingleton = Singleton.sharedInstance, or simply get rid of mySingleton and directly use Singleton.sharedInstance.
I'm getting a strange crash using a failable initializer in Swift. I pretty sure it's a bug in Swift, but figured I do a quick post to see if I'm missing something obvious.
I'm writing an app using CloudKit and added a new convenience initializer to CKRecord:
extension CKRecord {
convenience init?(cloudInfo: NSData?) {
guard let info = cloudInfo else { return nil }
self.init(coder: NSKeyedUnarchiver(forReadingWithData: info))
}
This just uses archived data I created using CKRecord's encodeSystemFieldsWithCode: method to create a CKRecord instance. I used to simply have a method in my class to do this same thing and it worked fine.
When I call this initializer like this:
let record: CKRecord
if let rec = CKRecord(cloudInfo: self.cloudInfo) {
record = rec
} else {
record = CKRecord(recordType: "Item", recordID: CKRecordID(recordName: self.id))
}
When I make that call, I get a crash. It doesn't matter if I pass in nil for cloudInfo or a value. When stepping through the code, the crash seems to happen between returning from the init call and getting back to the caller. For example, if I pass nil and step into the guard statement in the init that seems to work, but as soon as I step off of it, I crash.
I've tried getting rid of guard and going with a simple if let construct, but same outcome. And, I've also just returned nil from the init without any other code, and that also crashes.
I've done the usuals: cleaned the build folder, rebooted, etc.
BTW, by "crash" I mean I'm getting: EXC_BAD_ACCESS (code=1, address=0xfffffffc) at the call site.
Does anyone have any ideas? Maybe it's something obvious that I'm missing.
Thanks.
According to The Swift Programming Language (Swift 2.1) book,
For classes, however, a failable initializer can trigger an initialization failure only after all stored properties introduced by that class have been set to an initial value and any initializer delegation has taken place.
Taken from here.
You can't extend an existing class with stored properties, so the first requirement is met. But to meet the second requirement, you have to delegate your initialization process like in code below:
extension CKRecord {
convenience init?(cloudInfo: NSData?) {
guard let info = cloudInfo else {
self.init(coder: NSKeyedUnarchiver(forReadingWithData: NSData()))
return nil
}
self.init(coder: NSKeyedUnarchiver(forReadingWithData: info))
}
}
Actually in Swift 3, there seems to be a bug and a regression from Swift 2: returning nil from a failable intializer crash the runtime.
Im creating simple app where i can manipulate my display which holds numbers(double). App works perfectly on simulator but not on a real device.
I found the reason for that error. Its my getter. Its returning nil(pretty sure about that) Anyone got idea how to fix my getter?
var displayValue: Double {
get {
return NSNumberFormatter().numberFromString(display.text!)!.doubleValue
}
set {
display.text = String(format: "%g", newValue)
}
}
You must be trying to get value of displayValue before assigning it any value, and your are force unwrapping it so, obviously it will crash.
In your current code just try setting value to your display label (like display.text = "5") before accessing it, then it would work.
And its better to use if let check in case of force unwrapping, if you know your variable value can be nil.
This solves everything. Thanks https://stackoverflow.com/users/2227743/eric-d
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/OptionalChaining.html#//apple_ref/doc/uid/TP40014097-CH21-ID245
I have a field stored on a core data object called "metadata" which is of type String (no optional, because Apple docs say not to mess with optionals in CD). Sometimes, the metadata field is nil. In checking whether this value is nil, I do the following check:
if object.metadata as String? != nil {
...
}
However, my code continuously crashes on this line as an EXC_BAD_ACCESS. I have also tried:
if let metadata = object.metadata as String? {
...
}
Which doesn't work either. I cast objects successfully to optionals in other parts of my code, so I don't understand why this particular case isn't working. How do you check whether a core data property is a nil string?
It looks like what you really want is this:
if object.metadata != nil {
...
}
or this:
if let metadata = object.metadata as? String {
// You can now freely access metadata as a non-optional
...
}
--EDIT--
My mistake, I didn't read the first part of your question thoroughly enough. It looks like the duplicate answer has a solution for this. Essentially, the generated managed object subclass is a bug and you should modify the properties to be either optional or implicitly unwrapped. You can check both of those using the first method for implicitly unwrapped and second for optionals.
There are several questions which discuss the issue of the generated subclasses not producing optional properties. I wouldn't be too concerned about editing the subclasses; there's nothing special about them except that Apple is making it easier to create them.
Check if property is set in Core Data?
Swift + CoreData: Cannot Automatically Set Optional Attribute On Generated NSManagedObject Subclass
--Edit2--
If you really don't want to touch the subclass you can access the property using valueForKey() and could add that as an extension if you wanted something a bit cleaner.
if let metadata = object.valueForKey("metadata") as String? {
...
}
In an extension:
extension ObjectClass {
var realMetadata: String? {
set {
self.setValue(newValue, forKey: "metadata")
}
get {
return self.valueForKey("metadata") as String?
}
}
}