What's the meaning of Optional("nil") in Swift? - ios

Here is my code. If defaults did not ever save the lat, lng, then give it a lat lng.
The problem is error:
fatal error: unexpectedly found nil while unwrapping an Optional value
when using self.lat and self.lng after the code below. Every time console print out is
the saved gps is Optional("nil")
What's the meaning for Optional("nil") and the difference from Optional(nil)?
I am using Xcode 7.1 and Swift 2.
var lat : String = ""
var lng : String = ""
let defaults = NSUserDefaults.standardUserDefaults()
if defaults.stringForKey("lat") != nil {
self.lat = defaults.stringForKey("lat")!
self.lng = defaults.stringForKey("lng")!
print ("the saved gps is \(defaults.stringForKey("lat"))")
} else {
self.lat = "34.7009333"
self.lng = "135.4942047"
print ("the init gps is \(self.lat) , \(self.lng)")
}

it show the actual value...
let digit = sender.currentTitle!
suppose your sender value is 10 then output is 10.
suppose your sender value is nil then app carsh.
it show the optional value
let digit = sender.currentTitle
suppose your sender value is 10 then output is optional("10").
suppose your sender value is nil then app is not carsh.
& display value like this optional("nil")

Related

Backendless column with data type double will result to a nil value

I have a table in backendless which has 2 columns (latitude and longitude) with double data type.
In my class, BlTable I have this 2 fields
var latitude: Double?
var longitude: Double?
My backendless query is this:
let query = BackendlessDataQuery()
query.whereClause = "latitude IS NOT NULL AND longitude IS NOT NULL"
backendlessInstance.persistenceService.of(Post.ofClass()).find(query,
response: { blPosts in
guard let posts = blPosts.data as? [Post] else {
reject(BackendlessError.InvalidTypeForObject(name: "Post"))
return
}
fulfill(posts)
},
error: { fault in
reject(BackendlessError.ReceivedFault(fault))
})
When I logged the value for the latitude and longitude, it returned a nil value. I've checked with my backendless data the column lat and long are filled.
Are there other things that needs to be considered here?
Got the double value. But what I did was to set the data type of the Swift Entity to NSNumber and then use .doubleValue
in Backendless fields of types Int, Double, Float and Bool cannot be optional, they must be initialized:
https://backendless.com/documentation/data/ios/data_data_object.htm

Multidimensional Array Unwrapping an Optional

so I'm having this problem where I can't unwrap an optional for outputting it into the label, I've even tried just printing it in the console and it still gives me an optional
The code and array are in different files.
Code It's in a VC:
for var i = 0; i < stateName.count; i++ {
if tax.state == stateName[i][0] {
stateName[i][1] = Double(taxNumb.text!)!
print(stateName[i][1])
output.text = String(stateName[i][1])
}
}
Array Code I made this in an empty swift file:
var tax : Taxes? = nil
var stateName = [
["AK - Alaska", tax?.alaska!],
["AL - Alabama", tax?.alabama!],
["AR - Arkansas", tax?.arkansas!],
["AZ - Arizona", tax?.arizona!],
["CA - California", tax?.california!]
]
As I wrote in my comment to your previous question use the "Nil Coalescing" ?? operator:
output.text = String(stateName[i][1] ?? "not set")
Or using the alternate swift String magic
output.text = "\(stateName[i][1] ?? "not set")"
The operator returns the first value if it not nil, otherwise it returns the second value.

What is the difference between " as string" and "stringvalue" in swift?

I have a code :
var i : AnyObject!
i = 10
println(i as String)
println(i.stringValue)
it get crashed on as String line but runs in second i.stringValue.
What is the difference between as String and stringValue in the above lines?
.stringValue is a way to extract Integer into string value but as String will not work for that And if you use as String then Xcode will force you to add ! with as which is not good and it will never succeed and it would crash your app. you can't cast Int to String. It will always fail. Thats why when you do as! String it crashes the app.
So casting is not a good idea here.
And here is some more ways to extract Integer into string value:
let i : Int = 5 // 5
let firstWay = i.description // "5"
let anotherWay = "\(i)" // "5"
let thirdWay = String(i) // "5"
Here you can not use let forthway = i.stringValue because Int Doesn't have member named stringValue
But you can do same thing with anyObject as shown below:
let i : AnyObject = 5 // 5
let firstWay = i.description // "5"
let anotherWay = "\(i)" // "5"
let thirdWay = String(i) // "5"
let forthway = i.stringValue // "5" // now this will work.
Both are casting an Int to String but this will not work anymore.
In Swift 2 its not possible to do it like that.
U should use:
let i = 5
print(String(format: "%i", i))
This will specifically write the int value as a String
with as String, you can not cast the value but you define that the variable contains String but in you case it is Int.so it crashes.
while the other way i.e. of i.stringValue cast your value into String.So it doesn't gives you any crash and successfully cast into String value.
Note: As you are using AnyObject, variable have member stringvalue...but Int doesn't have...To cast Int value check out #Dharmesh Kheni answer

Can't figure out why I get a fatal error: unexpectedly found nil while unwrapping an Optional value

I keep getting this error :
fatal error: unexpectedly found nil while unwrapping an Optional value
and cannot figure out how to debug it!
Here's my code :
func readCSV() -> Array<String> {
// Creates a new array of strings
var csvArray : Array<String> = Array<String>()
if let url: NSURL = NSURL(string : "URLFROMCSV" ) {
// Creates an Input Stream that will load the datas from our URL
let data :NSData! = NSData(contentsOfURL: url)!
let stream : NSInputStream! = NSInputStream(data: data)
// Opens the receiving stream
stream.open()
// Sets a buffer with a given size size
let bufferSize = 1024
var buffer = Array <UInt8>(count: bufferSize, repeatedValue: 0)
// String variable initialization
var csvFullString : String = ""
// While the stream receives datas, parses datas, convert them into strings and then concatenate them into one big string
while (stream.hasBytesAvailable) {
let readSize = stream.read(&buffer, maxLength: bufferSize)
let csvRaw = NSString (bytes: &buffer, length: readSize, encoding: NSUTF8StringEncoding)
let csvString = csvRaw as String!
csvFullString = csvFullString + csvString
}
// Fills the array with each strings. Separation between strings is made when a Θ character is parsed
csvArray = csvFullString.componentsSeparatedByString("Θ")
// Delete each null string
for(var i = 0 ; i < csvArray.count; i++) {
if(csvArray[i] == "") {
csvArray.removeAtIndex(i)
}
}
}
return csvArray
}
After searching on the web, I'm pretty sure it has something to do with unwrapping elements but the fact is when I debug it, i don't get any nil value anywhere.
PS: Would like to upload a screen but can't because i don't have 10 reputation, so bad!
Thanks in advance!
EDIT : Line let data :NSData! = NSData(contentsOfURL: url)! got the error.
Terry
You're probably creating the error in one of these two lines (though it may show up later):
let data :NSData! = NSData(contentsOfURL: url)!
let stream : NSInputStream! = NSInputStream(data: data)
You're assigning an optional value to an implicitlyUnwrappedOptional type and then using it without checking if you have a valid value.
This is why if let exists. It's a little funny that you've started to indent as if you're using if let but aren't.
Try this instead:
if let url = NSURL(string : "http://gorillaapplications.com/etablissements.csv" ) {
// Creates an Input Stream that will load the datas from our URL
if let data = NSData(contentsOfURL: url) {
let stream = NSInputStream(data: data)
stream.open()
// rest of your code here
}
else {
println("Didn't get a data object")
}
}
else {
println("Didn't get a URL object")
}
You really need to grasp Optionals for Swift. I'd recommend reading my Optionals chapter in this iBook: https://itunes.apple.com/us/book/swift-optionals-generics-for/id943445214?mt=11&uo=4&at=11lMGu
Update:
Since you added a bit more in your comments above, you're saying you get the error on this line: let data: NSData! = NSData(contentsOfURL: url)!. This is because of the ! at the end, which tells Swift you're sure that this function will return a valid value, so just use it, without checking if it's nil first. In your case, the function is returning nil and so your app crashes. Using the sample code I've provided above, you'll see that you'll no longer get a crash, but your code will execute the "Didn't get a data object" line. You'll need to correctly handle the case where you can't load data from that URL.

Swift: Checking for the existence of a uitextfield

I have a controller that will have a variable number of textfields. On a button press I want to check for the existence of, whether or not its empty, and check the character count of the input.
I'm trying the following, which works fine if homePhone exists
if homePhone?.text != ""{
if countElements(homePhone1.text) != 10{
validInput = false
validationError = "Home Phone must be 10 digits"
}
}
But when a textfield does not exist (mobile) I get a fatal error
if mobilePhone?.text != ""{
if countElements(mobilePhone.text) != 10{
validInput = false
validationError = "Mobile Phone must be 10 digits"
}
}
fatal error: unexpectedly found nil while unwrapping an Optional value
Obviously I'm not doing the check correctly, optionals and unwrapping is continually tripping me up.
You can unwrap your textfield and check if it exists:
if let mobilePhoneField = mobilePhone{
if mobilePhoneField.text != ""{
if countElements(mobilePhoneField.text) != 10{
validInput = false
validationError = "Mobile Phone must be 10 digits"
}
}
}
This will check if your optional variable is nil or not so you can safely unwrap it, actualy it will do it for you.
if let value = myOptionalVariable{
//my optionalVariable is not nill i can do whatever i want
value.text = "Yaay"
}

Resources