if let with OR condition - ios

Is it possible to use an "OR" condition using Swift's if let?
Something like (for a Dictionary<String, AnyObject> dictionary):
if let value = dictionary["test"] as? String or as? Int {
println("WIN!")
}

This would make no sense, how would you be able to tell whether value is an Int or a String when you only have one if statement? You can however do something like this:
let dictionary : [String : Any] = ["test" : "hi", "hello" : 4]
if let value = dictionary["test"] where value is Int || value is String {
print(value)
}
(Tested in Swift 2.0)
You can also do this if you need to do different things depending on the types:
if let value = dictionary["test"] {
if let value = value as? Int {
print("Integer!")
} else if let value = value as? String {
print("String!")
} else {
print("Something else")
}
}

Unfortunately to my knowledge you cannot. You will have to use two separate if statements.
if let value = dictionary["test"] as? String {
doMethod()
} else if let value = dictionary["test"] as? Int {
doMethod()
}
There are multiple ways of getting around this problem. This is just one of them.
Please refer to the Apple documentation on Optional Chaining for more information on this special type of if statement. This is with using Swift 1.2

Related

How to check String value for nil before converting it to Double

Currently I'm learning by Apple's Swift tutorials. There is a task where I need to attempt to convert String into a number.
Create a variable total2 of type Double set to 0. Loop through the collection again, adding up all the integers and doubles. For each string that you come across during the loop, attempt to convert the string into a number, and add that value to the total. Ignore booleans. Print the total.
I am trying to use optional binding
else if let someItem = value as? String {
if let someItemUnwrapped = someItem {
total2 += Double(someItemUnwrapped) // TODO (NOT WORKING)
}
}
to check if I can convert String into Double, but I receive this error:
initializer for conditional binding must have Optional type, not 'String'
Here's my code:
var dictionary: [String: Any] = ["Apples": 5, "LightIsOn": false, "Score": 16.3, "IsBusy": true, "Book": "Hamlet"]
for (key, value) in dictionary {
print("Key: \(key); Value: \(value)")
}
var total2: Double = 0
for (key, value) in dictionary {
if let someItem = value as? Int {
total2 += Double(someItem)
} else if let someItem = value as? Double {
total += someItem
} else if let someItem = value as? String {
if let someItemUnwrapped = someItem {
total2 += Double(someItemUnwrapped) // TODO (NOT WORKING)
}
}
}
I figured it out.
if let someItemCheck = Double(someItem) {
total += someItemCheck
}
This will be like this:
Double(someItem) - to check if our someItem String value contains numbers like "125" or "753"
If this happens, we assign this value to let constant someItemCheck
And after that, we adding this value to total2

How to access dictionary value by key inside array of dictionary on Swift 3?

I've been away for a while from swift development. And today I got bug report from my client on my old project. The thing is I used to access value from my dictionary with ease just like dictionary[key] then I already got the value, but today I got below error by doing that:
Type 'NSFastEnumerationIterator.Element' (aka 'Any') has no subscript members
and here is my code:
var rollStatusArray = NSMutableArray()
for statusDict in rollStatusArray{
if statusId == "\(statusDict["mark_status_id"]!!)"{
return "\(statusDict["mark_status_name"]!!)"
}
}
How can I access dictionary value on swift 3?
In Swift's use native type Array/[] instead of NS(Mutable)Array.
if let dicArray = rollStatusArray.objectEnumerator().allObjects as? [[String:Any]] {
for statusDict in dicArray {
//Here compiler know type of statusDict is [String:Any]
if let status_id = statusDict["mark_status_id"] as? String, status_id == statusId {
return "\(statusDict["mark_status_name"]!)"
}
}
}
Note I'm force wrapping the mark_status_name value you can use Nil coalescing operator to return empty string to remove force wrapping.
You need to tell compiler the type of your statusDict this way:
for statusDict in rollStatusArray {
if let obj = statusDict as? [String: AnyObject] {
let statusIdFromDict = obj["mark_status_id"] as? String ?? ""
if statusId == statusIdFromDict {
return statusIdFromDict
}
}
}
Using Swift 3, you can access the dictionary value the following way:
var rollStatusArray = NSMutableArray()
for statusDict in rollStatusArray{
if statusId == "\((statusDict as! NSDictionary)["mark_status_id"]!)"{
return "\((statusDict as! NSDictionary)["mark_status_name"]!)"
}
}

Cannot properly convert value from JSON dictionary

I'm stuck on a weird problem.
I'm parsing a JSON response via Alamofire, and want to fetch a variable that just keeps throwing errors regardless whether I cast it to a String or Number, whilisting changing the error message every time I do :/
If I cast it to a String like this:
let kolicina = jsonCategory["kolicina"] as! String
if Int(kolicina) > 0 {
I get the error:
"Could not cast value of type '__NSCFNumber' (0x10f051368) to 'NSString' (0x10e627b48)."
When I try to cast it to a NSNumber:
let kolicina = jsonCategory["kolicina"] as! NSNumber
if kolicina.integerValue > 0 {
I get:
"Could not cast value of type 'NSTaggedPointerString' (0x10effcae8) to 'NSNumber' (0x10e5d32a0)."
This is what I get for that specific variable when I print the Dictionary:
kolicina = 0;
Can someone point me in the right direction?
It seems you have a combination of strings and integers in there. I would recommend you to fix the JSON and keep the data either as a string or a number, not both.
If you want to parse such a format, you will have to try to parse it as a NSNumber or as a NSString, e.g.:
let kolicina = jsonCategory["kolicina"]
if let kolicinaString = kolicina as? String {
...
} else if let kolicinaInt = kolicina as? Int {
...
}
with the > 0 checks you could do something like this:
if let kolicinaString = kolicina as? String,
kolicinaInt = Int(kolicinaString) where kolicinaInt > 0 {
print("String: \(kolicinaInt)")
} else if let kolicinaInt = kolicina as? Int where kolicinaInt > 0 {
print("Int: \(kolicinaInt)")
}
or using a ternary operator:
let kolicinaInt = (kolicina is String) ? Int(kolicina as! String) : kolicina as? Int
if kolicinaInt > 0 {
print("Kolicina: \(kolicinaInt)")
}
Try this .. don't make force unwrap
if let kolicina = jsonCategory["kolicina"] as? Int{
// Success: your kolicina is Int
print(kolicina)
}
else{
// Not an Int
}

How can I set a string as a Null in swift, when server is returning null value?

let debitCardNum = responseObject!["card_number"] as! String
This is my code and I am getting this error
Could not cast value of type 'NSNull' (0x384db1b4) to 'NSString'
(0x384e073c).
use let do like
if let Value = responseObject!["card_number"] as? String {
debitCardNum = Value
}
else
{
//error
}
This is a good candidate for optionals.
let debitCardNum = responseObject["card_number"] as? String
Later on when you want to do something use an if let to ensure the variable has a value
if let debitCardNum = debitCardNum {
// do something
}

Type 'String' does not conform to protocol 'NSCopying' error when downcast AnyObject to String

I'm tring to parse a JSON format like this:
{
"key_1" : {
"key_2" : "value"
}
}
and then assign "value" to a variable.
Here is my code:
var variableShouldBeAssigned: String
if let x = (jsonResult["key_1"]? as? NSDictionary) {
if let y = (x["key_2"]? as? String) {
variableShouldBeAssigned = y
}
}
However, an error occurs when I try to downcast from x["key_2"]? to a String, but it's fine to downcast from jsonResult["key_1"]? to an NSDictionary.
I can solve the error by using x["key_2"] to replace x["key_2"]?, but I don't really know why it only works for jsonResult["key_1"]?.
Can anybody tell me the reason?
String does not conform to NSCopying, but surely NSString does!
Also, going from NSString to String is instantaneously implied...
So I would say try something like this... Change String to NSString
here is a sample, assuming that you handle the jsonResult as a NSDictionary...
func giveDictionary(jsonResult:NSDictionary) -> String?
{
if let x = (jsonResult["key_1"]? as? NSDictionary)
{
if let y = (x["key_2"]? as? NSString)
{
return y
}
}
return nil
}
You can simplify all your type checking by using a Swift dictionary at the beginning:
var variableShouldBeAssigned: String
if let dict = jsonResult as? [String:[String:String]] {
if let key1Dict = dict["key_1"] {
if let value = key1Dict["key_2"] {
variableShouldBeAssigned = value
}
}
}
In fact, you can even combine the two last if statements:
var variableShouldBeAssigned: String
if let dict = jsonResult as? [String:[String:String]] {
if let value = dict["key_1"]?["key_2"] {
variableShouldBeAssigned = value
}
}
In general, you should using Swift Dictionaries instead of NSDictionary

Resources