Swift UserDefaults get values from array - arrays

I have UserDefaults array like:
let userValue = ["name": self.nameLbl.text ?? "", "lastName": self.lastNameLbl.text ?? "", "city": cityLbl.text ?? ""] as! [String : String]
var userArray = UserDefaults.standard.array(forKey: "userInfo") as? [[String: String]] ?? []
userArray.append(userValue)
UserDefaults.standard.set(userArray, forKey: "userInfo")
How can I get key values example to print type
[["name": .., "lastName":..,],["name": .., "lastName":..,],["name": .., "lastName":..,]...]
If I print like this :
if let array = UserDefaults.standard.array(forKey: "userInfo") as? [[String: String]] {
for dictionary in array {
print(dictionary["name"])
print(dictionary["lastName"])
print(dictionary["city"])
}
}
in console get :
Lars
James
Ulrich
Hetfield
Gentofte
California
I want it like this : [[ Lars, Ulrich,Gentofte],[James, Hetfield, California]]

You have to add key-value pair in the array and then print array. You will get your expected answer
let userValue = ["name": self.nameLbl.text ?? "", "lastName": self.lastNameLbl.text ?? "", "city": cityLbl.text ?? ""] as! [String : String]
var userArray = UserDefaults.standard.array(forKey: "userInfo") as? [[String: String]] ?? []
// Appending the different -2 userValue to userArray
userArray.append(userValue)
userArray.append(userValue)
UserDefaults.standard.set(userArray, forKey: "userInfo")
if let array = UserDefaults.standard.array(forKey: "userInfo") as? [[String: String]] {
var dataValues = Array<Any>()
array.forEach { (object) in
dataValues.append(Array(object.values))
}
print(dataValues)
}
Here you can check demo:
let userValue = ["name": "j", "lastName": "o", "city": "g"] as! [String : String]
// Appending the different -2 userValue to userArray
var a = [userValue, userValue, userValue]
var b = Array<Any>()
a.forEach { (object) in
b.append(Array(object.values))
}
print(b)

To add an key-value pair to existing array, you just to need to append userValue to your array. Like:
let userValue = ["name": self.nameLbl.text ?? "", "lastName": self.lastNameLbl.text ?? "", "city": cityLbl.text ?? ""] as! [String : String]
var userArray = UserDefaults.standard.array(forKey: "userInfo") as? [[String: String]] ?? []
// Append the userValue to userArray
userArray.append(userValue)
UserDefaults.standard.set(userArray, forKey: "userInfo")
To fetch the dictionary from the array you can use
if let array = UserDefaults.standard.array(forKey: "userInfo") as? [[String: String]] {
for dictionary in array {
print(dictionary["name"])
print(dictionary["lastName"])
print(dictionary["city"])
}
}

Related

How to add data inside two arrays inside for loop

I'm trying to add data to array inside for loop and again to array in another for loop.
Its working on first for loo, but in second data is empty. How to fix that
This is how it currently looks inside firestore and you can see scores missing.
this is code:
func updateCourseData() {
var data = ["endTime": Timestamp(date: Date()),
"players": []] as [String : Any]
for i in 0..<players.count {
var playerData = ["playerId": games[i].id,
"scores": []] as [String : Any]
var existingItems = data["players"] as? [[String: Any]] ?? [[String: Any]]()
existingItems.append(playerData)
data["players"] = existingItems
for score in 0..<selectedPage + 1 {
let scoreData = ["hole": games[i].scores[score].hole,
"score": games[i].scores[score].score] as [String : Any]
var existingScores = playerData["scores"] as? [[String: Any]] ?? [[String: Any]]()
existingScores.append(scoreData)
playerData["scores"] = existingScores
}
}
Constants.FirebaseCollection.gamesCollection.document(documentId).updateData(data) { error in
if let error = error {
print(error.localizedDescription)
}
print("Game updated")
}
}

NSUserDefaults check if value exist for key

I have UICollectionView contains: UIlabel and UIButton (text in labels comes from API)
when I press UIButton text from UIlabel and CostLbl stored in UserDefaults.standard.array(forKey: "car")
let imageData = UIImageJPEGRepresentation(image.image!, 1.0) as NSData?
let newValues = ["name": self.nameLbl.text ?? "", "price": self.costLbl.text ?? "", "image": imageData]
var mArray = UserDefaults.standard.array(forKey: "car") as? [[String: Any]]
maAr?.append(newValues)
Question : when UIButton is press need to check if text from UIlabel is in array(forKey: "car") , if not - can to stored for key,, and if text already in array(forKey: "car") cant add to array
I wrote as vadian suggested
var maAr = UserDefaults.standard.array(forKey: "car") as? [[String: Any]] ?? []
if !maAr.contains(where: newValues) {
maAr.append(newValues)
def.set(maAr, forKey: "car")
}
but catch error to (where: newValues) -
Cannot convert value of type '[String : Any]' to expected argument type '([String : Any]) throws -> Bool'
How can this be changed?
First of all declare the dictionary as [String:String] in this case there is no type cast and no annotation.
let newValues = ["name": nameLbl.text ?? "", "price": costLbl.text ?? ""]
Read the array, check if the array contains the value, if NO append the item and save the array back, if YES do nothing
var carArray = UserDefaults.standard.array(forKey: "car") as? [[String: String]] ?? []
if !carArray.contains(newValues) {
carArray.append(newValues)
UserDefaults.standard.set(carArray, forKey: "car")
}

Resave NSUserDefaults value for selected key for index.row

I have array NSUserDefaults type :
let userValue = ["name": self.nameLbl.text ?? "", "lastName": self.lastNameLbl.text ?? "", "city": cityLbl.text ?? ""] as! [String : String]
var userArray = UserDefaults.standard.array(forKey: "userInfo") as? [[String: String]] ?? []
UserDefaults.standard.set(userArray, forKey: "userInfo")
And save this array in first `ViewController`
In second ViewController Im display this array in UITAbleView
class ...
var userInfo = [[String:String]]()
override func viewDidLoad() {
super.viewDidLoad()
userInfo = UserDefaults.standard.array(forKey: "userInfo") as? [[String: String]] ?? []
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! UserTableViewCell
var userItem = userInfo[indexPath.row]
cell.nameLbl?.text = item["name"]
cell.lastNameLbl.text = item["lastName"]
cell.cityLbl.text = item["city"]
and under UITAbleView I have 3 UIextField's and UIButton for the opportunity to change user information
When user pass text in UIextField's I want to resave value for key
How can I remove selected name and save new name to correctly user??
To Abhirajsinh Thakore answer :
Im update code in cellForRowAt
var userItem = userInfo[indexPath.row]
cell.nameLbl?.text = item["name"]
cell.lastNameLbl.text = item["lastName"]
cell.cityLbl.text = item["city"]
item["name"] = cell.nameLbl?.text
var maArray = UserDefaults.standard.array(forKey: "userInfo") as? [[String: String]] ?? []
item.updateValue(cell.nameLbl?.text, forKey: "name")
maArray.append(item)
But its not save
You can fetch your complete array from Userdefaults
Now do is that get the new values from textField and replace that at the specific indexPath.row
For e.g:
var userInfo = [[String:String]]()
let data = userInfo[indexPath.row]
data["name"] = txtName.text
data["address"] = txtAddress.text
And now store this full array back to userDefaults and you will get the updated Result every Time.
Hope this helps.
Edit with reference to the code
Do like this:
var maArray = UserDefaults.standard.array(forKey: "userInfo") as? [[String: String]] ?? []
let innerData = maArray[indexPath.row]
innerData["name"] = cell.nameLbl?.text
innerData["lastName"] = cell.lastNameLbl.text
innerData["city"] = cell.cityLbl.text
// And save the maArray back to userDefaults

swift vapor json response to array

using swift vapor and elasticsearch, got a response like:
{
"_shards": {
"failed": 0,
"successful": 5,
"total": 5
},
"hits": {
"hits": [
{
"_id": "3",
"_index": "items_v1",
"_score": 1.2029922,
"_source": {
"property1": "test",
"property2": "another test",
...
},
"_type": "item"
},
...
inside "hits" -> "hits" -> "_source" I got all the properties of my model "Item". How can I create an array of Items "[Item]" from this json response?
Small enhancement, use a guard statement to avoid the nested ifs...
guard
let dict = response as? [String : Any],
let hits = dict["hits"] as? [String : Any],
let hitArray = hits["hits"] as? [[String : Any]]
else
{ throw Abort}
for hit in hitArray {
if let source = hit["_source"] {
arrayOfItems.append(Item(with: source))
}
}
Parse your response in this way, so there will be no crashes if some value will not be sent.
if let dict = response as? [String : Any] {
if let hits = dict["hits"] as? [String : Any] {
if let hitArray = hits["hits"] as? [[String : Any]] {
for hit in hitArray {
if let source = hit["_source"] {
arrayOfItems.append(Item(with: source))
}
}
}
}
}
Int your Item class create init method, where you will initialize item's properties.
init(with dict: [String : Any]) {
if let property1 = dict["property1"] as? Int {
self.property1 = property1
}
super.init()
}
Try like this! I assume that you get the Response and that response in saved in response variable
var myarray = [String]()
let hitDict = response["hits"] as! [String:AnyObject]
let hitArray = hitDict["hits"] as! Array
let someDict = hitArray[0] as! [String:AnyObject]
let sourcDict = someDict["_source"] as! [String:AnyObject]
let property1 = sourcDict["property1"] as! String
let property2 = sourcDict["property2"] as! String
myarray.append(property1)
myarray.append(property2)
var myArray = [String:String]()
//response from try drop.client.get(…)
let bodyReceived = responseFirebaseAssigned?.body.bytes
//JSON object made of bodyReceived
let JsonFirebase:JSON?
for val in JsonFirebase?.object ?? [:]{
let valKey = val.key.string
let valValue = val.value.string
arrayFB[valKey!] = valValue
print("arrayFB is \(arrayFB)")
}

How to use NSUserDefaults to store an array of dictionaries

Trying to store an array of dictionaries with NSUserDefaults.
var theTasks: [[String:Any]] = [["num":1,"title":"example","colour":"red"]]
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(theTasks, forKey: "myTasks")
defaults.synchronize()
let selected = theTasks[1]
Gives error:
Cannot convert value of type '[[String:Any]]' to expected argument of type 'AnyObject?'
Swift 3.x
In Swift 3 it has changed so now it needs to be saved as [Any] Any Array and use UserDefaults array(forKey:) method to load it:
let theTasks: [Any] = [["num": 1, "title": "example", "colour": "red"]]
UserDefaults.standard.set(theTasks, forKey: "myTasks")
if let loadedTasks = UserDefaults.standard.array(forKey: "myTasks") as? [[String: Any]] {
print(loadedTasks)
}
var theTasks: [[String: Any]] {
get {
return UserDefaults.standard.array(forKey: "myTasks") as? [[String: Any]] ?? []
}
set {
UserDefaults.standard.set(newValue as [Any], forKey: "myTasks")
}
}
Swift 2.x
You just need to save it as a AnyObject array and use NSUserDefaults method arrayForKey to load it:
let theTasks: [AnyObject] = [["num": 1, "title": "example", "colour": "red"]]
NSUserDefaults.standardUserDefaults().setObject(theTasks, forKey: "myTasks")
if let loadedTasks = NSUserDefaults.standardUserDefaults().arrayForKey("myTasks") as? [[String: AnyObject]] {
print(loadedTasks)
}
You can also create a computed property with a getter and a setter to do all the work behind the scenes for you as follow:
var theTasks: [[String: AnyObject]] {
get {
return NSUserDefaults.standardUserDefaults().arrayForKey("myTasks") as? [[String: AnyObject]] ?? []
}
set {
NSUserDefaults.standardUserDefaults().setObject(newValue as [AnyObject], forKey: "myTasks")
}
}
print(theTasks) // [["title": example, "colour": red, "num": 1]]
theTasks[0]["title"] = "another example"
print(theTasks) // [["title": another example, "colour": red, "num": 1]]
Just call the .setObject() method directly from NSUserDefaults()and it should work fine.
NSUserDefaults().setObject(theTasks, forKey: "myTasks")

Resources