getting "unexpectedly found nil" AFTER performing nil check - swift

Despite checking for nil, I am getting fatal error: unexpectedly found nil while unwrapping an Optional value the error is being caught in the conditional (first line below)
if (obj.prop != nil && obj.prop?.otherprop != nil) {
anotherObj.yetanotherprop = (obj.prop?.otherprop as NSURL).absoluteString
}
I have also tried this with if let as follows (xcode highlights the 2nd let as being where the unexpected nil is found):
if let objA = obj.prop,
let otherProp = objA.otherPROP {
anotherObj.yetanotherprop = (otherProp as NSURL).absoluteString
}
Why don't either of these work?!
I am getting the source object (obj in both cases above) from a 3rd party library that is written in objective c. I am suspecting that I am checking for nil wrong somehow?

So in writing this up I think I sort of figured it out. I don't knwo why the first one doesn't work, but the second works as:
if let objA = obj.prop,
let otherProp = objA?.otherPROP {
anotherObj.yetanotherprop = (otherProp as NSURL).absoluteString
}

Related

How to read null values from SQLite database using Swfit [duplicate]

I am reading from a dbtable and get an error at a specific position of the table. My sql is ok, because I could already read from the same table, but at a specific row I get an error and I would like to know howto handle this error. I am not looking for a solution to solve my db-issue, I am just looking for handling the error, so it doesn't crash.
I have the following code :
let unsafepointer=UnsafePointer<CChar>(sqlite3_column_text(statement, 2));
if unsafepointer != nil {
sText=String.fromCString(unsafepointer)! // <<<<<< ERROR
} else {
sText="unsafe text pointer is nil !";
}
I get an error:
"fatal error: unexpectedly found nil while unwrapping an Optional value"
at line marked with <<<<<< ERROR.
The unsafe pointer's value is not nil:
pointerValue : 2068355072
How can I handle this error, so my app is not crashing ?
Another possible solution is this:
let unsafepointer=UnsafePointer<CChar>(sqlite3_column_text(statement, 2));
var sText = "unsafe text pointer is nil !";
if unsafepointer != nil{
if let text = String.fromCString(unsafepointer) as String?{
sText = text;
}
}
let statementValue = sqlite3_column_text(statement, 2)
var sText = withUnsafeMutablePointer(&statementValue) {UnsafeMutablePointer<Void>($0)}
if sqlite3_column_text(statement, 2) != nil {
print("do something")
} else {
YourString = ""
}

unexpectedly found nil while unwrapping an Optional value

I put the m3u8 in GCDWebServer to play. When I use Wi-Fi, it is no problem. But using 4G, appears this problem.
You are force unwrapping m3u8 in your code. If that's ever nil, you're going to have a problem. You're saying that it will never be nil when you force unwrap using that !.
You can use the if let approach, or you can test for nil too.
// Are you sure dataServer isn't nil too here?
if let serverAddress = dataServer!.serverURL.URLByAppendingPathComponent(self.m3u8) {
//Should be safe
}
Or
if m3u8 == nil {
print("m3u8 is nil")
return
}
I have already solved the problem.When I use 4 g, access to the dataServer!ServerURL is nil.My solution is to give it a local IP
if davServer?.serverURL == nil {
serverAddress = NSURL.init(string: "http://localhost/playts.m3u8")!
}else{
serverAddress = (davServer?.serverURL.URLByAppendingPathComponent(self.m3u8!))!
}

Difference between error = error vs error != nil

I would like to know is there big difference between
if let error = error{} vs if error != nil? Or is it just how people are different, like how they express themselves in code?
For example if I take this code:
user?.delete { error in
if let error = error {
print(error)
} else {
}
Because I can do the same like this and the output is the same:
user?.delete { error in
if error != nil {
print(error)
}else{
}
The only difference I can see other than "people are different" is that if I do not print error it would be better to use if error != nil because otherwise it would be declaring variable you do not use. Am I right?
As you already recognized at the end of your question, I would agree with you, that I would use if let, if I want to use the error variable to print it out for example. If I would just check if it's not nil and don't need the error variable, I would use if error != nil. You could also do if let _ = error, which is the same as if error != nil as Eric Aya mentioned in the comments of your question

Swift 3 change to NSErrorPointer?

I have code I've been using for SwiftyJSON and I'm trying to update to Swift 3 using XCode 8.0 Beta 3. I'm running into an issue where the compiler doesn't like the argument 'error: &err' as it did before. I've been searching for how to correctly pass an NSErrorPointer but everything I've found says to re-write, leave out the error and throw an error back. Since this isn't my code I'd rather leave it as it is. So what's the correct new way to use an NSErrorPointer?
var err : NSError?
// code to get jsonData from file
let json = JSON(data: jsonData, options: JSONSerialization.ReadingOptions.allowFragments, error: &err)
if err != nil {
// do something with the error
} else {
return json
}
The code above results in compiler error: '&' can only appear immediately in a call argument list. I've tried creating an NSErrorPointer so I can use that instead but I can't find anything on how to initialize one (the type alias declaration is not enough). I've already been to Using Swift with Cocoa and Obj-C, it does not contain the word NSErrorPointer, instead goes over the new way of throwing errors. I've also looked over a couple dozen posts all using the &err so apparently this is new to Swift 3.
Is there anyone out there that's solved this one? What's the answer to using NSErrorPointer?
Thanks,
Mike
That seems to be an error in the Swift 3 branch of SwiftyJSON at
https://github.com/SwiftyJSON/SwiftyJSON/blob/swift3/Source/SwiftyJSON.swift
which defines the init method as
public init(data:Data, options opt: JSONSerialization.ReadingOptions = .allowFragments, error: NSErrorPointer? = nil) {
do {
let object: AnyObject = try JSONSerialization.jsonObject(with: data, options: opt)
self.init(object)
} catch let aError as NSError {
if error != nil {
error??.pointee = aError
}
self.init(NSNull())
}
}
In the Swift 3 that comes with Xcode 8 beta 3, NSErrorPointer is an optional:
public typealias NSErrorPointer = AutoreleasingUnsafeMutablePointer<NSError?>?
as a consequence of
SE-0055: Make unsafe pointer nullability explicit using Optional
Therefore the error parameter should have the type NSErrorPointer,
not NSErrorPointer? (and consequently error??.pointee
changed to error?.pointee).
With these changes the init method becomes
public init(data:Data, options opt: JSONSerialization.ReadingOptions = .allowFragments, error: NSErrorPointer = nil) {
do {
let object: AnyObject = try JSONSerialization.jsonObject(with: data, options: opt)
self.init(object)
} catch let aError as NSError {
if error != nil {
error?.pointee = aError
}
self.init(NSNull())
}
}
and then your code compiles and runs as expected.

unexpectedly found nil while unwrapping an Optional value while reading from DS with fromCString

I am reading from a dbtable and get an error at a specific position of the table. My sql is ok, because I could already read from the same table, but at a specific row I get an error and I would like to know howto handle this error. I am not looking for a solution to solve my db-issue, I am just looking for handling the error, so it doesn't crash.
I have the following code :
let unsafepointer=UnsafePointer<CChar>(sqlite3_column_text(statement, 2));
if unsafepointer != nil {
sText=String.fromCString(unsafepointer)! // <<<<<< ERROR
} else {
sText="unsafe text pointer is nil !";
}
I get an error:
"fatal error: unexpectedly found nil while unwrapping an Optional value"
at line marked with <<<<<< ERROR.
The unsafe pointer's value is not nil:
pointerValue : 2068355072
How can I handle this error, so my app is not crashing ?
Another possible solution is this:
let unsafepointer=UnsafePointer<CChar>(sqlite3_column_text(statement, 2));
var sText = "unsafe text pointer is nil !";
if unsafepointer != nil{
if let text = String.fromCString(unsafepointer) as String?{
sText = text;
}
}
let statementValue = sqlite3_column_text(statement, 2)
var sText = withUnsafeMutablePointer(&statementValue) {UnsafeMutablePointer<Void>($0)}
if sqlite3_column_text(statement, 2) != nil {
print("do something")
} else {
YourString = ""
}