Casting to an optional value in swift - ios

When I wrote this:
// json is of type AnyObject
var status : String? = json.valueForKeyPath("status") as String?
Xcode seems to blocked in an infinite loop during the compilation:
Is there something wrong in my code?
I've done some tests and when I wrote:
var status : String? = json.valueForKeyPath("status") as? String
Xcode is able to compile but what will be the behavior when valueForKeyPath will return nil.

As the documentation says:
Because downcasting can fail, the type cast operator comes in two different forms. The optional form, as?, returns an optional value of the type you are trying to downcast to.
Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/au/jEUH0.l
This means that when you write as? String, the return value is automatically wrapped in an optional for you, so the actual type produced by this is String?, which is the behaviour that you want, so your second option is correct.
In your first example, you are trying to cast the value returned by valueForKeyPath, which is of type AnyObject! (! means implicitly unwrapped), to String?, which is explicitly wrapped, and this the value is not automatically wrapped in an optional for you, so, since these types are not identical, casting between them probably won't work.
TL;DR: your first option is actually incorrect (although it shouldn't crash the compiler, that's a bug), and your second option is correct and does what you want.

Your second version is correct. An optional value is supposed to be assigned to a statement that can return nil. This is the flow of that line:
valueForKeyPath returns an implicitly unwrapped optional of AnyObject (AnyObject!). This means that it can be nil or it can have a value.
An attempt is made to convert it to a String
If it is not possible to convert it to a String, return nil making status nil. If it is indeed a non-nil String return that making status whatever string is returned

Related

Argument type 'String?' does not conform to expected type 'StringProtocol'

This error occurs when using compare on a String in Swift 5, it accepts only StringProtocol, but I want to use it on String and can't find nowhere how to do it.
I've searched all over and can't understand what seems to be the issue.
Problem that Optional<String> (aka String?) is not conform to StringProtocol (and that makes sense). You should unwrap optional, there is several ways:
Unwrapping by if let/guard
(if let version = dbData?.version {
//compare
})
Providing default value ( `(dbData?.version ?? "")), which is not recommended, because it can provide unnecessary collisions
Force unwrap dbData!.version, which is highly not recommended, because it can involve crashing an app, if Optional was nil

Int64 can't be converted if store in Realm

I need to save 11 digits number in Realm, for that am using Int64.
When am reading it I need to convert it's datatype to String
let icnStr = employeeObj["icn"] as! String
but it is showing following error.
Could not cast value of type '__NSCFNumber' (0x186d21c) to 'NSString' (0xefd5e4).
Try String(employeeObj["icn"]), hope it help, dont downcast it but create String instance with value of the Int
You need to do following otherwise you'll be not able to unwrap it.
Use following code.
let icnStr = String(describing: employeeObj["icn"]!)
It'll unwrap Optional value, because when it becomes String you can't unwrap it. It'll give the following error.
cannot force unwrap value of non-optional type string

Check if a String Contains Another String in Swift [duplicate]

I'm learning Swift for iOS 8 / OSX 10.10 by following this tutorial, and the term "unwrapped value" is used several times, as in this paragraph (under Objects and Class):
When working with optional values, you can write ? before operations
like methods, properties, and subscripting. If the value before the ?
is nil, everything after the ? is ignored and the value of the whole
expression is nil. Otherwise, the optional value is unwrapped, and
everything after the ? acts on the unwrapped value. In both cases, the
value of the whole expression is an optional value.
let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")
let sideLength = optionalSquare?.sideLength
I don't get it, and searched on the web without luck.
What does this means?
Edit
From Cezary's answer, there's a slight difference between the output of the original code and the final solution (tested on playground) :
Original code
Cezary's solution
The superclass' properties are shown in the output in the second case, while there's an empty object in the first case.
Isn't the result supposed to be identical in both case?
Related Q&A : What is an optional value in Swift?
First, you have to understand what an Optional type is. An optional type basically means that the variable can be nil.
Example:
var canBeNil : Int? = 4
canBeNil = nil
The question mark indicates the fact that canBeNil can be nil.
This would not work:
var cantBeNil : Int = 4
cantBeNil = nil // can't do this
To get the value from your variable if it is optional, you have to unwrap it. This just means putting an exclamation point at the end.
var canBeNil : Int? = 4
println(canBeNil!)
Your code should look like this:
let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")
let sideLength = optionalSquare!.sideLength
A sidenote:
You can also declare optionals to automatically unwrap by using an exclamation mark instead of a question mark.
Example:
var canBeNil : Int! = 4
print(canBeNil) // no unwrapping needed
So an alternative way to fix your code is:
let optionalSquare: Square! = Square(sideLength: 2.5, name: "optional square")
let sideLength = optionalSquare.sideLength
EDIT:
The difference that you're seeing is exactly the symptom of the fact that the optional value is wrapped. There is another layer on top of it. The unwrapped version just shows the straight object because it is, well, unwrapped.
A quick playground comparison:
In the first and second cases, the object is not being automatically unwrapped, so you see two "layers" ({{...}}), whereas in the third case, you see only one layer ({...}) because the object is being automatically unwrapped.
The difference between the first case and the second two cases is that the second two cases will give you a runtime error if optionalSquare is set to nil. Using the syntax in the first case, you can do something like this:
if let sideLength = optionalSquare?.sideLength {
println("sideLength is not nil")
} else {
println("sidelength is nil")
}
The existing correct answer is great, but I found that for me to understand this fully, I needed a good analogy, since this is a very abstract and weird concept.
So, let me help those fellow "right-brained" (visual thinking) developers out by giving a different perspective in addition to the correct answer. Here is a good analogy that helped me a lot.
Birthday Present Wrapping Analogy
Think of optionals as being like birthday presents that come in stiff, hard, colored wrapping.
You don't know if there's anything inside the wrapping until you unwrap the present — maybe there is nothing at all inside! If there is something inside, it could be yet another present, which is also wrapped, and which also might contain nothing. You might even unwrap 100 nested presents to finally discover there was nothing but wrapping.
If the value of the optional is not nil, now you have revealed a box containing something. But, especially if the value is not explicitly typed and is a variable and not a predefined constant, then you may still need to open the box before you can know anything specific about what's in the box, like what type it is, or what the actual value is.
What's In The Box?! Analogy
Even after you unwrap the variable, you are still like Brad Pitt in the last scene in SE7EN (warning: spoilers and very R-rated foul language and violence), because even after you have unwrapped the present, you are in the following situation: you now have nil, or a box containing something (but you don't know what).
You might know the type of the something. For example, if you declared the variable as being type, [Int:Any?], then you'd know you had a (potentially empty) Dictionary with integer subscripts that yield wrapped contents of any old type.
That is why dealing with collection types (Dictionaries and Arrays) in Swift can get kind of hairy.
Case in point:
typealias presentType = [Int:Any?]
func wrap(i:Int, gift:Any?) -> presentType? {
if(i != 0) {
let box : presentType = [i:wrap(i-1,gift:gift)]
return box
}
else {
let box = [i:gift]
return box
}
}
func getGift() -> String? {
return "foobar"
}
let f00 = wrap(10,gift:getGift())
//Now we have to unwrap f00, unwrap its entry, then force cast it into the type we hope it is, and then repeat this in nested fashion until we get to the final value.
var b4r = (((((((((((f00![10]! as! [Int:Any?])[9]! as! [Int:Any?])[8]! as! [Int:Any?])[7]! as! [Int:Any?])[6]! as! [Int:Any?])[5]! as! [Int:Any?])[4]! as! [Int:Any?])[3]! as! [Int:Any?])[2]! as! [Int:Any?])[1]! as! [Int:Any?])[0])
//Now we have to DOUBLE UNWRAP the final value (because, remember, getGift returns an optional) AND force cast it to the type we hope it is
let asdf : String = b4r!! as! String
print(asdf)
Swift places a high premium on type safety. The entire Swift language was designed with safety in mind. It is one of the hallmarks of Swift and one that you should welcome with open arms. It will assist in the development of clean, readable code and help keep your application from crashing.
All optionals in Swift are demarcated with the ? symbol. By setting the ? after the name of the type in which you are declaring as optional you are essentially casting this not as the type in which is before the ?, but instead as the optional type.
Note: A variable or type Int is not the same as Int?. They are two different types that can not be operated on each other.
Using Optional
var myString: String?
myString = "foobar"
This does not mean that you are working with a type of String. This means that you are working with a type of String? (String Optional, or Optional String). In fact, whenever you attempt to
print(myString)
at runtime, the debug console will print Optional("foobar"). The "Optional()" part indicates that this variable may or may not have a value at runtime, but just so happens to currently be containing the string "foobar". This "Optional()" indication will remain unless you do what is called "unwrapping" the optional value.
Unwrapping an optional means that you are now casting that type as non-optional. This will generate a new type and assign the value that resided within that optional to the new non-optional type. This way you can perform operations on that variable as it has been guaranteed by the compiler to have a solid value.
Conditionally Unwrapping will check if the value in the optional is nil or not. If it is not nil, there will be a newly created constant variable that will be assigned the value and unwrapped into the non-optional constant. And from there you may safely use the non-optional in the if block.
Note: You can give your conditionally unwrapped constant the same name as the optional variable you are unwrapping.
if let myString = myString {
print(myString)
// will print "foobar"
}
Conditionally unwrapping optionals is the cleanest way to access an optional's value because if it contains a nil value then everything within the if let block will not execute. Of course, like any if statement, you may include an else block
if let myString = myString {
print(myString)
// will print "foobar"
}
else {
print("No value")
}
Forcibly Unwrapping is done by employing what is known as the ! ("bang") operator. This is less safe but still allows your code to compile. However whenever you use the bang operator you must be 1000% certain that your variable does in fact contain a solid value before forcibly unwrapping.
var myString: String?
myString = "foobar"
print(myString!)
This above is entirely valid Swift code. It prints out the value of myString that was set as "foobar". The user would see foobar printed in the console and that's about it. But let's assume the value was never set:
var myString: String?
print(myString!)
Now we have a different situation on our hands. Unlike Objective-C, whenever an attempt is made to forcibly unwrap an optional, and the optional has not been set and is nil, when you try to unwrap the optional to see what's inside your application will crash.
Unwrapping w/ Type Casting. As we said earlier that while you are unwrapping the optional you are actually casting to a non-optional type, you can also cast the non-optional to a different type. For example:
var something: Any?
Somewhere in our code the variable something will get set with some value. Maybe we are using generics or maybe there is some other logic that is going on that will cause this to change. So later in our code we want to use something but still be able to treat it differently if it is a different type. In this case you will want to use the as keyword to determine this:
Note: The as operator is how you type cast in Swift.
// Conditionally
if let thing = something as? Int {
print(thing) // 0
}
// Optionally
let thing = something as? Int
print(thing) // Optional(0)
// Forcibly
let thing = something as! Int
print(thing) // 0, if no exception is raised
Notice the difference between the two as keywords. Like before when we forcibly unwrapped an optional we used the ! bang operator to do so. Here you will do the same thing but instead of casting as just a non-optional you are casting it also as Int. And it must be able to be downcast as Int, otherwise, like using the bang operator when the value is nil your application will crash.
And in order to use these variables at all in some sort or mathematical operation they must be unwrapped in order to do so.
For instance, in Swift only valid number data types of the same kind may be operated on each other. When you cast a type with the as! you are forcing the downcast of that variable as though you are certain it is of that type, therefore safe to operate on and not crash your application. This is ok as long as the variable indeed is of the type you are casting it to, otherwise you'll have a mess on your hands.
Nonetheless casting with as! will allow your code to compile. By casting with an as? is a different story. In fact, as? declares your Int as a completely different data type all together.
Now it is Optional(0)
And if you ever tried to do your homework writing something like
1 + Optional(1) = 2
Your math teacher would have likely given you an "F". Same with Swift. Except Swift would rather not compile at all rather than give you a grade. Because at the end of the day the optional may in fact be nil.
Safety First Kids.
'?' means optional chaining expression
the'!'means is force-value
There are 7 ways to unwrapping optional value in Swift.
Optional Binding - Safe
Optional Chaining - Safe
Optional Pattern - Safe
Nil Coalescing - Safe
Guard Statement - Safe
Force Unwrapping - Unsafe
Implicit Unwrapping - Unsafe

CGPDFDictionaryGetString function nil parameter exception

I found away of getting the types of content in a pdf. I built my code on this example where I am trying to read the content types from the dictionary. I found out that the key for type is Type. However I am getting an Error:
fatal error: unexpectedly found nil while unwrapping an Optional value
Here is my code:
pdfDoc = CGPDFDocumentCreateWithURL(url)
if (pdfDoc != nil) {
let pdfCatalog=CGPDFDocumentGetCatalog(pdfDoc)
var uriStringRef: UnsafeMutablePointer< CGPDFStringRef>!
if (CGPDFDictionaryGetString(pdfCatalog, "Type", uriStringRef)) { //error
print(uriStringRef)
}
}
The only nil parameter is uriStringRef. However from the example, I am not supposed to set to any value before passing to CGPDFDictionaryGetString, and according to Apple's documentation, this should get the string returned value based on the key "Type". Am I right?
How can I solve this problem?
You are passing an uninitialized pointer to the CGPDFDictionaryGetString method, that is unsafe because you cannot know whether the method being called tries to read from a pointer before writing to it.
From the Swift blog post Interacting with C Pointers:
Pointers as In/Out Parameters
C and Objective-C don’t support multiple return values, so Cocoa APIs frequently use pointers as a way of passing additional data in and out of functions. Swift allows pointer parameters to be treated like inout parameters, so you can pass a reference to a var as a pointer argument by using the same & syntax.
For safety, Swift requires the variables to be initialized before being passed with &. This is because it cannot know whether the method being called tries to read from a pointer before writing to it.
So initialize the CGPDFStringRef 'pointer' like this:
var uriStringRef = CGPDFStringRef.init()
And pass it to the method using the inout syntax:
CGPDFDictionaryGetString(pdfCatalog, "Type", &uriStringRef)

What is an "unwrapped value" in Swift?

I'm learning Swift for iOS 8 / OSX 10.10 by following this tutorial, and the term "unwrapped value" is used several times, as in this paragraph (under Objects and Class):
When working with optional values, you can write ? before operations
like methods, properties, and subscripting. If the value before the ?
is nil, everything after the ? is ignored and the value of the whole
expression is nil. Otherwise, the optional value is unwrapped, and
everything after the ? acts on the unwrapped value. In both cases, the
value of the whole expression is an optional value.
let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")
let sideLength = optionalSquare?.sideLength
I don't get it, and searched on the web without luck.
What does this means?
Edit
From Cezary's answer, there's a slight difference between the output of the original code and the final solution (tested on playground) :
Original code
Cezary's solution
The superclass' properties are shown in the output in the second case, while there's an empty object in the first case.
Isn't the result supposed to be identical in both case?
Related Q&A : What is an optional value in Swift?
First, you have to understand what an Optional type is. An optional type basically means that the variable can be nil.
Example:
var canBeNil : Int? = 4
canBeNil = nil
The question mark indicates the fact that canBeNil can be nil.
This would not work:
var cantBeNil : Int = 4
cantBeNil = nil // can't do this
To get the value from your variable if it is optional, you have to unwrap it. This just means putting an exclamation point at the end.
var canBeNil : Int? = 4
println(canBeNil!)
Your code should look like this:
let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")
let sideLength = optionalSquare!.sideLength
A sidenote:
You can also declare optionals to automatically unwrap by using an exclamation mark instead of a question mark.
Example:
var canBeNil : Int! = 4
print(canBeNil) // no unwrapping needed
So an alternative way to fix your code is:
let optionalSquare: Square! = Square(sideLength: 2.5, name: "optional square")
let sideLength = optionalSquare.sideLength
EDIT:
The difference that you're seeing is exactly the symptom of the fact that the optional value is wrapped. There is another layer on top of it. The unwrapped version just shows the straight object because it is, well, unwrapped.
A quick playground comparison:
In the first and second cases, the object is not being automatically unwrapped, so you see two "layers" ({{...}}), whereas in the third case, you see only one layer ({...}) because the object is being automatically unwrapped.
The difference between the first case and the second two cases is that the second two cases will give you a runtime error if optionalSquare is set to nil. Using the syntax in the first case, you can do something like this:
if let sideLength = optionalSquare?.sideLength {
println("sideLength is not nil")
} else {
println("sidelength is nil")
}
The existing correct answer is great, but I found that for me to understand this fully, I needed a good analogy, since this is a very abstract and weird concept.
So, let me help those fellow "right-brained" (visual thinking) developers out by giving a different perspective in addition to the correct answer. Here is a good analogy that helped me a lot.
Birthday Present Wrapping Analogy
Think of optionals as being like birthday presents that come in stiff, hard, colored wrapping.
You don't know if there's anything inside the wrapping until you unwrap the present — maybe there is nothing at all inside! If there is something inside, it could be yet another present, which is also wrapped, and which also might contain nothing. You might even unwrap 100 nested presents to finally discover there was nothing but wrapping.
If the value of the optional is not nil, now you have revealed a box containing something. But, especially if the value is not explicitly typed and is a variable and not a predefined constant, then you may still need to open the box before you can know anything specific about what's in the box, like what type it is, or what the actual value is.
What's In The Box?! Analogy
Even after you unwrap the variable, you are still like Brad Pitt in the last scene in SE7EN (warning: spoilers and very R-rated foul language and violence), because even after you have unwrapped the present, you are in the following situation: you now have nil, or a box containing something (but you don't know what).
You might know the type of the something. For example, if you declared the variable as being type, [Int:Any?], then you'd know you had a (potentially empty) Dictionary with integer subscripts that yield wrapped contents of any old type.
That is why dealing with collection types (Dictionaries and Arrays) in Swift can get kind of hairy.
Case in point:
typealias presentType = [Int:Any?]
func wrap(i:Int, gift:Any?) -> presentType? {
if(i != 0) {
let box : presentType = [i:wrap(i-1,gift:gift)]
return box
}
else {
let box = [i:gift]
return box
}
}
func getGift() -> String? {
return "foobar"
}
let f00 = wrap(10,gift:getGift())
//Now we have to unwrap f00, unwrap its entry, then force cast it into the type we hope it is, and then repeat this in nested fashion until we get to the final value.
var b4r = (((((((((((f00![10]! as! [Int:Any?])[9]! as! [Int:Any?])[8]! as! [Int:Any?])[7]! as! [Int:Any?])[6]! as! [Int:Any?])[5]! as! [Int:Any?])[4]! as! [Int:Any?])[3]! as! [Int:Any?])[2]! as! [Int:Any?])[1]! as! [Int:Any?])[0])
//Now we have to DOUBLE UNWRAP the final value (because, remember, getGift returns an optional) AND force cast it to the type we hope it is
let asdf : String = b4r!! as! String
print(asdf)
Swift places a high premium on type safety. The entire Swift language was designed with safety in mind. It is one of the hallmarks of Swift and one that you should welcome with open arms. It will assist in the development of clean, readable code and help keep your application from crashing.
All optionals in Swift are demarcated with the ? symbol. By setting the ? after the name of the type in which you are declaring as optional you are essentially casting this not as the type in which is before the ?, but instead as the optional type.
Note: A variable or type Int is not the same as Int?. They are two different types that can not be operated on each other.
Using Optional
var myString: String?
myString = "foobar"
This does not mean that you are working with a type of String. This means that you are working with a type of String? (String Optional, or Optional String). In fact, whenever you attempt to
print(myString)
at runtime, the debug console will print Optional("foobar"). The "Optional()" part indicates that this variable may or may not have a value at runtime, but just so happens to currently be containing the string "foobar". This "Optional()" indication will remain unless you do what is called "unwrapping" the optional value.
Unwrapping an optional means that you are now casting that type as non-optional. This will generate a new type and assign the value that resided within that optional to the new non-optional type. This way you can perform operations on that variable as it has been guaranteed by the compiler to have a solid value.
Conditionally Unwrapping will check if the value in the optional is nil or not. If it is not nil, there will be a newly created constant variable that will be assigned the value and unwrapped into the non-optional constant. And from there you may safely use the non-optional in the if block.
Note: You can give your conditionally unwrapped constant the same name as the optional variable you are unwrapping.
if let myString = myString {
print(myString)
// will print "foobar"
}
Conditionally unwrapping optionals is the cleanest way to access an optional's value because if it contains a nil value then everything within the if let block will not execute. Of course, like any if statement, you may include an else block
if let myString = myString {
print(myString)
// will print "foobar"
}
else {
print("No value")
}
Forcibly Unwrapping is done by employing what is known as the ! ("bang") operator. This is less safe but still allows your code to compile. However whenever you use the bang operator you must be 1000% certain that your variable does in fact contain a solid value before forcibly unwrapping.
var myString: String?
myString = "foobar"
print(myString!)
This above is entirely valid Swift code. It prints out the value of myString that was set as "foobar". The user would see foobar printed in the console and that's about it. But let's assume the value was never set:
var myString: String?
print(myString!)
Now we have a different situation on our hands. Unlike Objective-C, whenever an attempt is made to forcibly unwrap an optional, and the optional has not been set and is nil, when you try to unwrap the optional to see what's inside your application will crash.
Unwrapping w/ Type Casting. As we said earlier that while you are unwrapping the optional you are actually casting to a non-optional type, you can also cast the non-optional to a different type. For example:
var something: Any?
Somewhere in our code the variable something will get set with some value. Maybe we are using generics or maybe there is some other logic that is going on that will cause this to change. So later in our code we want to use something but still be able to treat it differently if it is a different type. In this case you will want to use the as keyword to determine this:
Note: The as operator is how you type cast in Swift.
// Conditionally
if let thing = something as? Int {
print(thing) // 0
}
// Optionally
let thing = something as? Int
print(thing) // Optional(0)
// Forcibly
let thing = something as! Int
print(thing) // 0, if no exception is raised
Notice the difference between the two as keywords. Like before when we forcibly unwrapped an optional we used the ! bang operator to do so. Here you will do the same thing but instead of casting as just a non-optional you are casting it also as Int. And it must be able to be downcast as Int, otherwise, like using the bang operator when the value is nil your application will crash.
And in order to use these variables at all in some sort or mathematical operation they must be unwrapped in order to do so.
For instance, in Swift only valid number data types of the same kind may be operated on each other. When you cast a type with the as! you are forcing the downcast of that variable as though you are certain it is of that type, therefore safe to operate on and not crash your application. This is ok as long as the variable indeed is of the type you are casting it to, otherwise you'll have a mess on your hands.
Nonetheless casting with as! will allow your code to compile. By casting with an as? is a different story. In fact, as? declares your Int as a completely different data type all together.
Now it is Optional(0)
And if you ever tried to do your homework writing something like
1 + Optional(1) = 2
Your math teacher would have likely given you an "F". Same with Swift. Except Swift would rather not compile at all rather than give you a grade. Because at the end of the day the optional may in fact be nil.
Safety First Kids.
'?' means optional chaining expression
the'!'means is force-value
There are 7 ways to unwrapping optional value in Swift.
Optional Binding - Safe
Optional Chaining - Safe
Optional Pattern - Safe
Nil Coalescing - Safe
Guard Statement - Safe
Force Unwrapping - Unsafe
Implicit Unwrapping - Unsafe

Resources