Swift: Trying to print an empty string – The process has been returned to the state before expression evaluation - swift

I have a model with a column entry, which is a String. Sometimes entry has some text in it, sometimes it doesn't and it's an empty string.
When I try to print the string in console, I'm getting The process has been returned to the state before expression evaluation. (running e object.entry)
Not sure why it isn't just printing ""
Trying e object.entry! gives me error: operand of postfix '!' should have optional type; type is 'String'
Any ideas on how to fix this?

Empty String "" doesn't mean nil, and entry is not an optional type.
I think you are supposed to declare entry as "" when initialize the object
class object {
var entry = ""
//do anything you want next
}

Related

What is the difference between a `String x = expr` and `var x = expr as String`?

While developing a Flutter app, I ran into a problem where out of two seemingly similar things, only one really works. The other gives an error.
// this does NOT work
// gives error: E/flutter (13080): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception:
// type 'MaterialPageRoute<dynamic>' is not a subtype of type 'Route<String>?' in type cast
onButtonPress() async {
String ret = await Navigator.of(context).pushNamed("/page");
print(ret);
}
// this works !
onButtonPress() async {
var ret = await Navigator.of(context).pushNamed("/page") as String;
print(ret);
}
Both looks like doing the same thing - casting the value returned from the route into a String. But why does only one of them works ?
As your error states:
// gives error: E/flutter (13080): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception:
// type 'MaterialPageRoute<dynamic>' is not a subtype of type 'Route<String>?' in type cast
onButtonPress() async {
String ret = await Navigator.of(context).pushNamed("/page");
print(ret);
}
You are trying to assign a MaterialPageRoute<dynamic!> to a Route<String!>.
This is a simple case of type mismatching.
In the other example that you have posted, you are using var instead of String. This allows you to assign every type that you want to it.
await Navigator.of(context).pushNamed("/page") returns a future, which is not a string.
the scope of a var is just a generic variable that can be anything upon assignation.
When you assign a variable as String X , that means you tell the program specifically that - I am sure that the value I am going to get will be String and I want it to be stored in X . If the value returned is not String type it will throw an error.
When you assign the variable as var X , that means you are telling the program that I am not sure what will be the type of value which will be returned but I want the returned value to be returned as 'String ' (so even if you get any response as int or double or anything else it will try to use the complete value returned as string) . So var helps in getting rid of type errors when you are not sure of the type , but it's always best practice to know what type you are getting and define accordingly.

Swift - Binary operator '>=' cannot be applied to operands of type 'String' and 'Int'

Not really understanding why this isn't working. I'm pretty new to the Swift world.
The error I'm getting is Binary operator '>=' cannot be applied to operands of type 'String' and 'Int'
Could anyone help me understand why I'm getting this error? Do I need to convert the String to a Double or is there something else I'm totally missing? Again I'm new to Swift.
Do I need to convert the String to a Double?
Yes, that's basically it.
You must declare first a variable to accumulate all the inputs:
var inputs = [Double]()
Observe that I'm declaring an array of Double because that's what we are interested in.
Then, each time you ask the input, convert the obtained String to Double and store it in your array:
print("Please enter a temperature\t", terminator: "")
var message : String = readLine()!
let value : Double = Double(message)!
inputs.append(value)
Finally, check all the accumulated values in inputs (you got this part right):
for value in inputs {
// value is already a Double
if value >= 80 {
message = "hot!"
}
// etc.
}
I suggest researching how to convert to Double with error checking (i.e. how to detect "100 hot!" and ignore it because can't be converted).
Also, consider using a loop to read the values.

Swift 3: How to read from "Optional(Optional(stringValue))" without optional?

I got the string value from server like this.
let filename = "\(eventList[index]["filename"])"
But I got the value with Optional(Optional(stringValue)).
So I changed that like this.
let filename = "\(eventList[index]["filename"]!)"
Then I got the value with Optional(stringValue).
I can't do any more for this error.
How can I read the filename without any optional?
Use nil-coalescing operator aka double question mark operation. It is used to provide a default value when unwrapping an optional type.
let filename = eventList[index]["filename"] ?? ""
R̶e̶f̶:̶ ̶h̶t̶t̶p̶:̶/̶/̶w̶w̶w̶.̶j̶e̶e̶n̶a̶l̶i̶n̶f̶o̶t̶e̶c̶h̶.̶c̶o̶m̶/̶b̶l̶o̶g̶s̶/̶i̶o̶s̶/̶h̶o̶w̶-̶t̶o̶-̶d̶o̶-̶o̶p̶t̶i̶o̶n̶a̶l̶-̶v̶a̶r̶i̶a̶b̶l̶e̶-̶a̶s̶s̶i̶g̶n̶m̶e̶n̶t̶-̶w̶i̶t̶h̶-̶d̶e̶f̶a̶u̶l̶t̶-̶v̶a̶l̶u̶e̶-̶d̶o̶u̶b̶l̶e̶-̶q̶u̶e̶s̶t̶i̶o̶n̶-̶m̶a̶r̶k̶/̶
https://medium.com/#milanpanchal24/
Use if-let syntax to unwrap optional:
if let fileName = eventList[index]["filename"] {
// use fileName
}
eventList[index] accesses an array item at the given index. The item you are referring seems to be an optional dictionary so before accessing the dictionary item it needs to be unwrapped: eventLists[index]! (assuming it exists and valid of course otherwise it will crash)
then you can access the dictionary require value which is an optional as well:
eventLists[index]!["fileName"]!
assuming your list is valid you will get the desired String object.
I recommend using the safety checks (if-let or other variants) for preventing crashes

What is Optional({}) at Alamofire mean when i create output of JSON

When I create output of JSON using Alamofire, I saw this in my console
What does Optional({}) mean?
Optional({
0 = (
All,
""
);
C2001 = (
"ARAI Bay Side"
);
C2002 = (
"ARAI Fukuoka"
);
})
I am newbie to swift and this, so any ideas?
What Alamofire gives you is an optional variable, because it can't predict in advance whether the request will succeed and have output or fail and have none.
Similarly, it also gives you an error? variable (note the ?, which means it's also an optional) that will be nil if the request succeeded or will be something (most likely an NSError) if an error occurred.
You can check with if yourVariable != nil to see whether the optional variable is set (contains something), in which case you'll be able to unwrap it with yourVariable!.
You can also use the following :
if let yourUnwrappedVariable = yourVariable!
to unwrap the variable into a new (non-optional) yourUnwrappedVariable variable and execute the code in that if block if the variable was set (contained something, wasn't nil), this time without needing to unwrap the variable again like the previous example (here you already have the yourUnwrappedVariable variable and can use it right away in that if block).
Finally, if you're sure the variable will always be set, you can unwrap it by passing it followed by a ! sign to whatever method call you want like so :
myMethod(initWithData: yourVariable!, anotherArgument: anotherValue)
If the variable ever happens to not contain anything, an exception will be thrown.
What you are seeing is the output from global functions like print() or println(), which enclose optional descriptions inside Optional( ), unless the value of the optional is nil, in which case just nil is printed.
If you have this:
var foo: Int?
foo = 7
println(foo)
The output is Optional(7)
whereas
println(foo!)
just prints 7

It it okay to access an optional variable with question mark without exclamation mark?

I know that an optional constant or variable with a question mark needs an exclamation mark to access its value. then, I tried to exam it with the following code.
var aaa:String? = "3"
println("aaa = \(aaa!)")
Yes. It was okay. It printed "3" on Console Output. and next exam I tried like that
var aaa:String? = "3"
println("aaa = \(aaa)")
It also printed "3" without any error message. It worked well.
I learned about Forced Unwrapping that en exclamation mark is needed to access to a value of Optional. But, I could access it without the mark. Is it right? I wonder what is wrong. Am I misunderstanding Optional?
You are correctly understanding Optionals and Forced Unwrapping. The reason that you can print the optional variable is that the type Optional can also be printed. If you print an Optional instead of the real value, it will either print the value if it has one, or "nil" if it doesn't.
Also, just in case you don't realize it. Forced Unwrapping will cause the whole program to crash if the optional is nil at the time. To be safer, you should use Optional Binding:
var aaa: String? = "3"
if let actualString = aaa {
// actualString becomes a non-optional version of aaa
// if aaa were nil, this block would not be run at all
println(actualString)
}
Also, some extra information about the printing of instances. Printing uses the protocol Printable which defines a description property. Anything that implements this protocol can customize the way they print out. Optional has its own implementation of this protocol which is how it decides to either print "nil" or the description of the actual value.
Println() will print the value if it has any otherwise it will print nil. Just to understand things better just try to assign value of aaa to another string variable. It will throw error that value of optional type not unwrapped.
var aString:NSString? = "Hello"
var bString = aString // Compiler allows, as you are assigning to optional type again.
var cString:NSString = aString // Compiler throws error. You cannot assign optional type without unwrapping.
So to answer your question you need to use ! to get the value.
Edit:
var foo:Bool?
foo = false
if foo { // This always evaluates to `True`
...
}
if foo! { // This condition will now fail
...
}
The reason foo evaluated to True is because it was not unwrapped. Since its not unwrapped its just checking whether it has a value or not(true or false does not matter).
When foo was unwrapped it returned a value False hence the second if condition failed.
The println function is a special case. It automatically unwraps the variable for you. If the variable were nil, it would print nil. In other contexts, you do need to unwrap the variable yourself.