Extracting values from NSDictionary to individual variables - ios

I really thought this was Xcode playing up as I can't for the life of me see what is causing this error in a fairly simple piece of Swift code but after restarting cleaning the project, restarting Xcode, and restarting my MacBook I'm still getting the same error.... But why!!??!!
Here is the code
// Loop through records saving them
for recordItem in records {
if let record: NSDictionary = recordItem as? NSDictionary {
let time: String = record["time"] as! String
let record: String = record["record"] as! String
let recordId: String = record["record_id"] as! String
let saveTime: String = record["save_time"] as! String
let setId: String = record["set_id"] as! String
// Does more stuff
}
}
records is an NSArray and it is made from data downloaded from a remote server.
All is fine until the line beginning let recordId. This and the two lines below it are giving an error - Cannot subscript a value of type 'String' with an index of type 'String'
Why? And why is there no problem with the 2 lines above? And how do I fix it?
Any help is greatly appreciated as I'm at a bit of a dead end.

You are using the variable record to unwrap the optional recordItem but then you are re-assigning record as record["record"] - so from this point on it becomes a String, not a Dictionary - resulting in the error message Cannot subscript a value of type 'String' with an index of type 'String'
You just need to change one of the record variables
for recordItem in records {
if let unwrappedRecord: NSDictionary = recordItem as? NSDictionary {
let time: String = unwrappedRecord["time"] as! String
let record: String = unwrappedRecord["record"] as! String
let recordId: String = unwrappedRecord["record_id"] as! String
let saveTime: String = unwrappedRecord["save_time"] as! String
let setId: String = unwrappedRecord["set_id"] as! String
// Does more stuff
}
}

The problem is here, you are declaring record as a String, previously it was NSDictionary and due to scope the record in record["record_id"] is String not NSDictionary. Quick fix is to change the name as I did
let time: String = record["time"] as! String
let record1: String = record["record"] as! String
let recordId: String = record["record_id"] as! String
let saveTime: String = record["save_time"] as! String
let setId: String = record["set_id"] as! String

Related

Could not cast value of type 'NSNull' to 'NSString' in firebase

I am trying to pull articles from my database in firebase, but am getting a SIGABRT error in the let author part of this function, what is wrong?
func getAllArticles(handler: #escaping (_ articles: [Article])-> ()){
var articleArray = [Article]()
REF_ARTICLES.observeSingleEvent(of: .value) { (articleMessageSnapshot) in
guard let articleMessageSnapshot = articleMessageSnapshot.children.allObjects as? [DataSnapshot] else {return}
for article in articleMessageSnapshot {
let content = article.childSnapshot(forPath: "content").value as! String
let author = article.childSnapshot(forPath: "author").value as! String
let twitterHandle = article.childSnapshot(forPath: "twitterHandle").value as! String
let articleTitle = article.childSnapshot(forPath: "articleTitle").value as! String
let article = Article(content: content, author: author, twitterHandle: twitterHandle, ArticleTitle: articleTitle)
articleArray.append(article)
}
handler(articleArray)
}
}
I know nothing about Firebase, but from what you have posted, I don't think that is your problem.
This code article.childSnapshot(forPath: "author").value is returning NSNull meaning it found no values to match your criteria. The code as! String is literally saying to crash if the value is not a String. Since NSNull is not String you get the crash.
One solution:
let author = article.childSnapshot(forPath: "author").value as? String ?? "No Author"
Any maybe do that with all the lines. Also read about Swift optionals and Forced Unwrapping.

String value is not have mutable behaviour (swift 3)

I converting my String value to Double shows in below code .In final variable i am getting string value i.e ex - 1435.76 But while i am converting into Double value shows nill. Please help me to get rid into this .Thanks in advance
self.cart = result.value(forKey: "cart") as! NSMutableArray
self.totalsDic = result.value(forKey: "totals") as! NSMutableDictionary
print(self.totalsDic)
// print(self.cart)
let total = self.totalsDic.object(forKey: "total") as! NSMutableDictionary
let final = total.object(forKey: "total") as? String
// final = final?.replacingOccurrences(of: "Rs.", with: "")
let myDouble1 = NumberFormatter().number(from: final!)?.doubleValue
print("My double: \(String(describing: myDouble))")
let myDouble2 = Double(final!)

Swift NSDictionary Child types

I'm having a lot of frustration with Swift when it comes to working with Dictionaries and NSDictionaries.
I am pulling data from a server. One of the values is a Bool.
I started with a Swift Dictionary and moved to NSDictionary out of frustration. However, I still cannot get the values from the dictionary.
All of the following fail with contradictory errors:
let unread:Bool = data!["unread"] as! Bool
let unread:Bool = data?["unread"] as! Bool
let unread:Bool = data?.objectForKey("unread") as! Bool
let unread:NSNumber = data?["unread"] as! NSNumber
error: Could not cast value of type 'NSTaggedPointerString' (0x110c1eae8) to 'NSNumber' (0x10e0ab2a0).
Okay, looks like that data is coming in as a String... let's try:
let unreadStr:String = data!["unread"] as! String
let unreadStr:NSString = data!["unread"] as! NSString
error: Could not cast value of type '__NSCFBoolean' (0x1097413b8) to 'NSString' (0x106bcdb48).
So I'm confused. When I try to convert it to a Bool it says I cannot convert a String to a Number. When I try to convert it to a String, it says I cannot convert a number to a string.
Here is what the data looks like:
Optional({
senderId = 10154040;
sent = 1460844986973;
text = "Test Message 1";
unread = false;
})
You should try something along these lines:
let data: [String : Any] = ["first" : "test", "second" : 2, "third" : true]
let first = data["first"] as! String
let second = data["second"] as! Int
let third = data["third"] as! Bool
print(first)
print(second)
print(third)

How to unwrap Swift optional and cast type at the same time using guard?

I have the following code. the response.result.value is of type Optional(AnyObject), I want to check
it's of type [[String: AnyObject]]
unwrap the optional
check the count of the array
I prefer one line guard over if...return... statement
Alamofire.request(.GET, API.listArticle).responseJSON { response in
print(response.result.value)
guard let articles = response.result.value as? [[String: AnyObject]] where articles.count > 0 else {
return
}
for article in articles {
let entity = NSEntityDescription.insertNewObjectForEntityForName("Article", inManagedObjectContext: DBHelper.context()) as! Article
entity.title = article["title"]
entity.content = article["content"]
}
}
The error is article["content"] line:
Cannot subscript a value of type Dictionary<String, AnyObject> with an index of type String
Also do I need to check if title exist in article? Is it gonna crash or just do nothing?
The problem is that you are using a dictionary where the value has type AnyObject to populate the title and the content properties that are probably String (right?)
You cannot put something that (at compile time) is declared AnyObject into a String property.
Just replace this
entity.title = article["title"]
entity.content = article["content"]
with this
entity.title = article["title"] as? String
entity.content = article["content"] as? String
Update
This updated for will discard articles where the title and content values are not correct Strings.
for article in articles {
if let
title = article["title"] as? String,
content = article["content"] as? String {
let entity = NSEntityDescription.insertNewObjectForEntityForName("Article", inManagedObjectContext: DBHelper.context()) as! Article
entity.title = title
entity.content = content
}
}

text field receiving optional('value") instead of "value "

I'm trying to pass a text that is correct api put in swift he arrives with the message of "optional". this is my code:
let accountValues:NSArray = account!.accountNumber.componentsSeparatedByCharactersInSet(NSCharacterSet(charactersInString: "-"))
self.accountTextField.text = accountValues.objectAtIndex(0) as? String
self.accountDigitTextField.text = accountValues.objectAtIndex(1) as? String
When retrieving the value, use ! after the value. The downcast should force unwrap any optionals. Anything set as? can be force unwrapped by using !.
For example,
let intString = 7 as? String
print(intString!)
This should print "7", rather than Optional("7")
please replace these lines :
self.accountTextField.text = accountValues.objectAtIndex(0) as? String
self.accountDigitTextField.text = accountValues.objectAtIndex(1) as? String
by :
self.accountTextField.text = (accountValues.objectAtIndex(0) as! String)
self.accountDigitTextField.text = (accountValues.objectAtIndex(1) as! String)
You're using Optional Value "As? String". So, it will return an Optional('value').
Try this:
let accountValues:NSArray = account!.accountNumber.componentsSeparatedByCharactersInSet(NSCharacterSet(charactersInString: "-"))
self.accountTextField.text = "\(accountValues.objectAtIndex(0))"
self.accountDigitTextField.text = "\(accountValues.objectAtIndex(1))"

Resources