What is difference between below 2 lines? [duplicate] - ios

This question already has answers here:
What's the difference between "as?", "as!", and "as"?
(3 answers)
Closed 4 years ago.
I am trying to add code in cellForRowAt indexPath method like below
cell.itemNameLabel.text = nameArray[indexPath.row]
but it is showing error as Cannot assign value of type 'Any' to type 'String?'
so it can be solved by below 2 ways,
cell.fruitName.text = fruitArray[indexPath.row] as? String
or
cell.fruitName.text = (fruitArray[indexPath.row] as! String)
so, my question is what is the difference between 2 answers?

cell.fruitName.text = fruitArray[indexPath.row] as? String
Above return type is optional value. means it will be nil value return if array is not consist string value.
cell.fruitName.text = (fruitArray[indexPath.row] as! String)
Above return type is non-optional value. means it will be fire fatal error if array is not consist string value.

Below is the generic information for all optionals. Please find it.
When you are using ! and the fruitArray[indexPath.row] is nil it will trigger run time error but if use ? it will fail gracefully.
You can find more detail information in Apple document

Related

Cast from 'Double' to unrelated type 'String' always fails [duplicate]

This question already has answers here:
Swift double to string
(16 answers)
Closed 3 years ago.
I'm getting the data from the api response
I decoded the data properly
then I assigned the values to tableview cell
But I'm getting the warning
Cast from 'Double' to unrelated type 'String' always fails
how can I solve this , So that I can assign the double value to the UILabel and get my result
I tried this following code
var rate : Double
cell.priceOfVehicleLabel.text = details.rate as? String
You need
cell.priceOfVehicleLabel.text = "\(details.rate)"
You can use String's init(describing:), i.e.
cell.priceOfVehicleLabel.text = String(describing: details.rate)
It's simply cell.priceOfVehicleLabel.text = String(details.rate).

App crashed when getting string from Dictionary (swift)

I converted a JSON to Dictionary and got some String by
title = json?.objectForKey("Titel_Live") as! String
But some times app will be crashed. I cannot reproduce this problem, just get information from crash reports.
Could someone help me and tell why? Thanks
Error at line 163
Crash reports
title = json?.objectForKey(“Titel_live”) as! String
This line of code where you are doing force unwrapped (Don't force the cast using !) is the cause means if object with key Titel_live dot not find then should be crashed, better go with optional chaining or use gaurd but yes your Json does't contain any object with key Titel_live(may be spelling mistake or object is array so validate once).
//better go like this check if exist or not.
if let t = json?.objectForKey(“Titel_live”) {
title = t
}
You should not force the casting to String.
You can try :-
title = json?.objectForKey("Title_Live") as? String (if title is optional variable)
if title is not optional then use:
title = (json?.objectForKey("Title_Live") as? String ?? "")
Because objectForKey will return nil if no value is associated with that key and force casting nil to String fails and causes crash.

How to use optional "?" and "!" in swift? [duplicate]

This question already has answers here:
What does "Fatal error: Unexpectedly found nil while unwrapping an Optional value" mean?
(16 answers)
Closed 6 years ago.
I am studying XCode7.3. The "?" and "!" always make me confused.
I have code like below.
The lines name : name, type : type and image : image displaying error message :
Value of optional type 'String?' not unwrapped, did you mean to use '!' or '?'?
#IBAction func unwindToHomeScreen( segue : UIStoryboardSegue ) {
if let addRestaurantController = segue.sourceViewController as? AddRestaurantController {
let name = addRestaurantController.name
let location = addRestaurantController.location
let type = addRestaurantController.type
let isVisited = addRestaurantController.isVisited
let image = addRestaurantController.imageView
restaurants.append( Restaurant(
name : name,
type : type,
location : location,
phoneNumber : "UNKNOW",
image : image,
isVisited : isVisited? ?? false
) )
print( addRestaurantController.imageView )
}
}
I modify code to name : name! or name : name?, it still doesn't work. How can I fix it?
I think this will solve your problem.
If addRestaurantController.location, addRestaurantController.name and addRestaurantController.type are optional.
#IBAction func unwindToHomeScreen( segue : UIStoryboardSegue ) {
if let addRestaurantController = segue.sourceViewController as? AddRestaurantController , name = addRestaurantController.name, location = addRestaurantController.location, type = addRestaurantController.type, isVisited = addRestaurantController.isVisited, image = addRestaurantController.imageView
{
restaurants.append( Restaurant(
name : name,
type : type,
location : location,
phoneNumber : "UNKNOW",
image : image,
isVisited : isVisited? ?? false
) )
}
}
You haven't specify that whether addRestaurantController.location, addRestaurantController.name and addRestaurantController.type are optional or not. And you randomly submitted your question without even analysing it properly.
Please give more value to other people's time. And ask meaningful questions. Read more about guidelines for a Stackoverflow question.
There might be few reasons, but first I'd suggest you to read about optionals (?) and explicitly unwrapped optionals (!) here https://itunes.apple.com/us/book/swift-programming-language/id881256329?mt=11
As far as the problem, it is most likely that optionality of variable name in Restaurant is defined differently comparing to local definition. While locally variable name is defined to be optional, e.g. let name: String?, Restaurant expects it to be non optional (probably it defined as let name: String (note no ? at the end)). That mean that you need to unwrap optional value to pass it to the Restaurant (please see the link above for ways of unwrapping, there are few depending on your use-case)
If you are switching to Swift 3, keep in mind that behavior of explicitly unwrapped optionals changed. For motivation and in depth description, please read this proposal https://github.com/apple/swift-evolution/blob/master/proposals/0054-abolish-iuo.md
But as it's been pointed out, Swift 3 can not be compiled in Xcode 7, you need to download beta of Xcode 8 for that

Cannot subscript a value of type [String: AnyObject]? with an index of type String

I know have many the same question but still cannot find the way to fix my error. Please see the image for more detail. I used Xcode 7 and swift 2.0
Edit: fcking the warning of Swift. finnaly (change?[NSKeyValueChangeNewKey]?.boolValue)! fixed the error
change is an optional. Either unwrap the optional
let isCaptureStillImage = change![NSKeyValueChangeNewKey]!.boolValue
or use optional bindings
if let changeNewKey = change?[NSKeyValueChangeNewKey] {
let isCaptureStillImage = changeNewKey.boolValue
...

Set objects to empty NSDictionary in Swift [duplicate]

This question already has answers here:
Swift dictionary bug?
(6 answers)
Closed 8 years ago.
I can create an NSDictionary
var namesDictionary=Dictionary<String,String>()
namesDictionary["Jacob"] = "Marry"
But, when I create a empty dictionary like coded below, line 1 i okie, but line 2 (adding values) throws an error.
var namesDictionary =[:]
namesDictionary["Jacob"] = "Marry"
Error is "Cannot assign to the result of this expression". Is there any other way to assign the values.
It looks like it's an issue with swift interpreting the type of your dictionary. Try explicitly typing your empty dictionary.
var namesDictionary: Dictionary<String, String> = [:]
namesDictionary["Jacob"] = "Marry"
I think a better use for [:] is for emptying an already defined dictionary. If you add a third line namesDictionary = [:], you will be able to call namesDictionary["Jacob"] = "Marry" again since the compiler knows what type of dictionary it is from the inital declaration.

Resources