Might be an easy question for the experts but as a newbie I'm struggling to figure this out and confusing myself so I thought I would just post it here. What I would like to do is create a nested array when this Add button is pressed. I would like to build a list of "selections" to store in UserDefaults under each "id". I've simplified the code but I already have "id" and "selection" being called in from elsewhere, so those variables are working, I just need to know how to add the selection to list of selections under the id. I hope this makes sense. 1 id, list of many selections.
Code below that I've been working with, found through this tutorial
#State var id = ""
#State var selection = ""
let userDefaults = UserDefaults.standard
Button(action: {
userDefaults.set(dictionary, forKey: "myKey")
var strings: [String:String] = userDefaults.object(forKey: "myKey") as? [String:String] ?? [:]
strings[id] = selection
userDefaults.set(strings, forKey: "myKey")
}) {
Text("Add")
}
Related
I am trying to save data to UserDefaults using an UIAlertController , but the code fails to retrieve the data.
Retrieve the Data
func displayCreatedPhrases(){
phrases = uDefaults.stringArray(forKey: "createdPhrases") ?? [String]()
print(phrases)
}
Setting the Data
self.uDefaults.set(textfield.text, forKey: "createdPhrases")
self.uDefaults.synchronize()
print("Saved the data!")
self.phraseTableView.reloadData()
You are setting the string as a value for key 'createdPhrases' and then asking uDefaults to return an array of string?
func displayCreatedPhrases() {
phrases = uDefaults.value(forKey: "createdPhrases") as? String
print(phrases)
}
The above code should work for you.
Also no need to use below line (Link to UserDefaults synchronize)
self.uDefaults.synchronize()
Reason:
textfield.text is of type String? and not [String]. In your code, you're saving the data as a String value and retrieving it as an [String] value. That's the reason, retrieving the data doesn't work.
Solution:
func displayCreatedPhrases(){
phrases = uDefaults.string(forKey: "createdPhrases") ?? ""
print(phrases)
}
Also, phrases must be of type String.
I am developing an app that has a textView in FirstViewController and a tableView in the SecondViewController. In the app user types in a string using a textView, which is then turned into an array with the press of a button (indicated by an IBAction buttonIsPressed) and transferred onto a tableView in the next view controller with the help of UserDefaults. Right now, I want the code to be able to append all of the strings into one array every time user types in a string in textView. I have tried every single method I found on the internet to append either strings or arrays into one array but none of them worked. I would really appreciate if some of you can help me out. Here is the code:
#IBAction func buttonIsPressed(_ sender: Any) {
var newitems = textField.text!.components(separatedBy: CharacterSet(charactersIn: ", []()\n.:"))
print(newitems)
if newitems.contains(""){
newitems.removeAll { $0 == ""}
UserDefaults.standard.set(newitems, forKey: "items")
print(newitems)
}else{
let newitems = textField.text!.components(separatedBy: CharacterSet(charactersIn: ", []()\n.:"))
UserDefaults.standard.set(newitems, forKey: "items")
}
textField.text = ""
}
First: you shouldn't use userdefaults for temporary storage
UserDefaults.standard.set(newitems, forKey: "items")
unless you save them for next launch
Second: create an array inside the source vc like
var arr = [String]()
and append to it the latest content
arr += newitems
then pass arr to the destination vc
I am tracking a user's preferences in my iOS app using UserDefaults -- when a user selects a table cell, it adds the cell's text to my key. That part works.
Now, I want to allow the user to remove the matching key value from the key when a row is selected. If a cell says "Episode 1", it should remove the value from UserDefaults.
From the documentation, there's an instance method for removeObject. Here's what I wrote:
let defaults = UserDefaults.standard
var myarray = defaults.stringArray(forKey: "SavedStringArray") ?? [String]()
if let datastring = TableData[indexPath.row] as? String {
if !myarray.contains(datastring) {
myarray.append(datastring)
defaults.removeObject(myarray, forKey: "SavedStringArray")
defaults.synchronize()
}
This returns an error for Extra argument in call -- I assume it means myarray, but if I can't add that argument, how can I tell it to remove only one value (stored in myarray)?
If I print the UserDefaults.standard, it will return a list of stored episode values like `["First Episode", "Second Episode", "Third Episode"]
Any idea how I can remove Third Episode when that cell is clicked here?
I have following code which will work for you.
if myarray.contains(datastring) {
myarray.remove(at: myarray.index(of: datastring)!)
} else {
myarray.append(datastring)
}
defaults.set(myarray, forKey: "SavedStringArray")
This code will remove element from array and set array again in User defaults for same key, So it will replace you array with new array.
You can add if string is not present or remove the string if it is present. And then update the array.
Then set that array for the key.
if !myarray.contains(datastring) {
myarray.append(datastring)
} else {
myarray = myarray.filter{$0 != datastring}
}
defaults.set(myarray, forKey: "SavedStringArray")
You can try This logic for array of type String i.e. [String]
var arrStr:[String] = ["Cat","Rat","Mouse"]
print(arrStr)
let datastring = "Rat"
if !arrStr.contains(datastring) {
arrStr.append(datastring)
} else {
arrStr.remove(at: arrStr.index(of: datastring)!)
}
print(arrStr)
UserDefaults.standard.set(arrStr, forKey: "SavedStringArray")
UserDefaults.standard.synchronize()
Having a real hard time figuring this out. So if anyone could help would appreciate it. I have some data I want to pull from google firebase and store them into a struct them populate a tableview. But I have having some issues with the table being called before the data is all pulled. Im not sure if I'm using the right database calls for firebase but this is what I have so far.
struct provStru {
var name = String()
var last = String()
}
var store = [provStru]()
var ref: FIRDatabaseReference!
ref = FIRDatabase.database().reference()
var name = String()
var last = String()
var counter = 0
while counter<10 {
ref.child("Prov").child("\(counter + 1)").observeSingleEvent(of: .value, with: { (snapshot) in
// Get user value
if !snapshot.exists() {
print("doesnt exist")
} else {
let value = snapshot.value as? NSDictionary
name = value?["Name"] as! String
last = value?["Last"] as! String
self.store.append(provStru(name: name, last: last)
}
}) { (error) in
print(error.localizedDescription)
}
counter += 1
}
Then I would like to use that data from the struct to populate the tableview cells. But when I run this code the counter is like an infinite loop. Ive been trying to figure this out for a while. Thanks
This is how the data looks in firebase
This is what the database looks like then the next value would be 2 then 3 going down
I want to make a user query, removing the name of each, and go keeping the names in an array, then display them on a table. The problem is I can not keep them in the settlement, how can I fix it? Thus I make the query to extract the names of users:
var users = [String]()
let ref = Firebase(url:"https:mydatabase/users")
ref.queryOrderedByChild("name").observeEventType(.ChildAdded,
withBlock: { snapshot in
if let username = snapshot.value["name"] as! String {
self.users.append(username)
print("username")
}
})
So I have my users table in firebase
The username var does have the name, but when adding the content of the var the settlement, does not, at the time of execution of the application does not throw any errors.
There are just a few typo's your code
Try this:
let usersRef = self.myRootRef.childByAppendingPath("users")
usersRef.queryOrderedByChild("name").observeEventType(.ChildAdded, withBlock: { snapshot in
if let username = snapshot.value["name"] as? String {
self.userArray.append(username)
print("\(username)")
}
})
Be sure to define the userArray as a property of the class so it will be available to other functions.
class MyClass: NSObject {
let myRootRef = Firebase(url:"https://your-app.firebaseio.com")
var userArray = [String]()