I'd like to add data in the NSUserDefaults object for specific Username but I'm a little bit embarrassed I don't know how can I do it?
I started this way:
//Set data
let defaults = UserDefaults.standard
defaults.set(invnr, forKey: "Person")
defaults.synchronize()
//getData
let name = UserDefaults.standard.string(forKey: "Person")
print(name)
This way works, but for all users, I want to add data in session for specific username. Hope you help me. Thank you
Assuming you have
let username = "Blahblahblah"
So, let's try it in this way:
let defaults = UserDefaults.standard
defaults.set(invnr, forKey: "Person \(username)")
defaults.synchronize()
//getData
let name = UserDefaults.standard.string(forKey: "Person \(username)")
print(name)
Related
I have a two step login process. On the first screen I save the FB user's details to UserDefaults.
When I load the second ViewController it is supposed to load the user's profile image and username (which I create using "fullname"). It actually works the second time I load the user but never the first time, is there some sort of delay? I already tried UserDefaults.standard.synchronize() but that does nothing. It even prints the details so I know it works...
let userName = fullName.replacingOccurrences(of: " ", with: "_")
UserDefaults.standard.setValue(userName, forKey: "username")
if let picture = result["picture"] as? NSDictionary , let data = picture["data"] as? NSDictionary, let url = data["url"] as? String {
UserDefaults.standard.setValue(url, forKey: "userFBPicURL")
let username = UserDefaults.standard.value(forKey: "username") as? String
let profileImage = UserDefaults.standard.value(forKey: "userFBPicURL") as? String
UserDefaults.standard.synchronize()
print ("Details are User:",username, "profileImage:",profileImage)
and in the new VC after self.performSegue(withIdentifier: "UsernameSegue", sender: self):
override func viewDidLoad() {
super.viewDidLoad()
if let username = UserDefaults.standard.value(forKey: "username") as? String {usernameTextfield.text = username}
if FBSDKAccessToken.current() != nil {loadFacebookProfileImage()}
}
I think you are setting the value to UserDefaults after performing segue or after the viewDidLoad gets called.
Steps to try find the issue:
Could you please try set breakpoint and see what goes first and what second?
Try printing from defaults right after you assign there.
Just try getting data not in ViewDidLoad but later. For example on button tap. Just to see if it's there for the 1st time too (but not only for the 2nd)
Question: where do you set the value to defaults?
PS: Also I wouldn't use UserDefaults for that, but yeah it's a different question.
Sorry, that can't provide an exact solution since it requires more info/code from your debugging. Please try the options above. Hope it helps.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I got a task to store multiple user details.
#IBOutlet weak var userName: UITextField!
#IBOutlet weak var email_id: UITextField!
#IBOutlet weak var password: UITextField!
I know in user defaults we can store a value for a particular key and retrieve it but i would like to know how to save multiple values. like the key should be the email_id i have mentioned above and all the three fields should be its values, also i need to maintain all the details even if there is n number of users.
You can save textField Data in dictionary as a key-value and append that dictionary to Array.So you will get the list of users detail.It will not override, every time it make empty dictionary after click on save Button and before append the data.
like that:
class ViewController: UIViewController {
var userDict = [String:Any]()
var userArray = [Any]()
override func viewDidLoad() {
super.viewDidLoad()
}
and save the data after save button click.
#IBAction func SaveBtnTapped(_ sender: Any) {
userDict = [:]
userDict.updateValue(userName.text, forKey: "username")
userDict.updateValue(email_id.text, forKey: "email")
userDict.updateValue(password.text, forKey: "password")
userArray.append(userDict)
}
The best way to do it in this situation is to use a local database, like sqlite. You can follow this tutorial for dealing with a local database. In your situation, you will need a user table to store your users.
If you prefer not to use a local database and use UserDefault instead, you can indeed store an array of objects in UserDefault. Simply use the following code
UserDefaults.standard.set([YourUserObj], forKey: "users")
let userArr = UserDefaults.standard.array(forKey: "users") as? [YourUserObj]
1.You can store multiple values using tuples.
Rule: A default object must be a property list—that is, an instance
of (or for collections, a combination of instances of): NSData,
NSString, NSNumber, NSDate, NSArray, or NSDictionary
If you want to store any other type of object, you should typically archive it to create an instance of NSData.
// you can create NSObject model to store into userdefaults
let users = [User(username: "user1", email: "user1#xxx.com", password: "******"), User(username: "user2", email: "user2#xxx.com", password: "******")]
var userDefaults = UserDefaults.standard
let encodedData: Data = NSKeyedArchiver.archivedData(withRootObject: teams)
userDefaults.set(encodedData, forKey: "users")
userDefaults.synchronize()
Get data by unarchiving like below
let decodedUserDetail = userDefaults.object(forKey: "users") as! Data
let decodedUsers= NSKeyedUnarchiver.unarchiveObject(with: decodedUserDetail) as! [Team]
print(decodedUsers)
2.You can store multiple values using Array of objects.
let userDetails =
[
"username" : "user1",
"email": "user1#xxx.com",
"password" : "******"
]
before storing this get existing details
let userDefault = NSUserDefaults.standardUserDefaults()
var storedUserDetails = userDefault.objectForKey("userDetails") as? [[String:AnyObject]]
storedUserDetails.append(userDetails )
userDefault.setObject(storedCredentials, forKey: "credentials")
userDefault.synchronize()
Create a model
Class User: NSObject, NSCoding{
var userName: String
var email_id: String
var password: String
init(userName: String, email_id: String, password: String){
self.userName = userName
self.email_id = email_id
self.password = password
}
required conveniece init(coder decoder: NSCoder){
let userName = decoder.decodeObject(forKey: "userName") as? String ?? ""
let email_id = decoder.decodeObject(forKey: "email_id") as? String ?? ""
let password = decoder.decodeObject(forKey: "password") as? String ?? ""
self.init(
userName=userName,
email_id=email_id,
password=password
)
}
func encode(with coder: NSCoder){
coder.encode(self.userName, forKet="userName")
coder.encode(self.email_id, forKet="email_id")
coder.encode(self.password, forKet="password")
}
}
After you can instanciate your model with your data
let currentUser = User(userName: userName.text!, email_id: email_id.text!, password: password.text!)
Or a list :
let listUsers = [User(userName: "user_1", email_id: "email#abc.com", password: "password")]
Now you can store the currentUser or listUsers with archivedData
let encodedData = NSKeyedArchiver.archivedData(withRootObject: currentUser)
UserDefaults.standard.set(encodedData, forKey: "currentUser")
UserDefaults.standard.synchronize()
let encodedDataForList = NSKeyedArchiver.archivedData(withRootObject: listUsers)
UserDefaults.standard.set(encodedData, forKey: "listUsers")
UserDefaults.standard.synchronize()
To get the stored user :
if let data = UserDefaults.standard.data(forKey: "currentUser"){
let _currentUser = (NSKeyedUnarchiver.unarchiveObject(with: data) as? User)!
}
For saving user's data, using local db is the most appropriate solution.But if you don't want to go into depth of Core data / Sqlite, use Realm framework.
With Realm you just have to have a user class with dynamic properties & call basic functions like
Initialize RealmDb with
let objRealm = try! Realm()
Create a user class
class UserDataModel: Object {
dynamic var name:String = ""
dynamic var ID = ""
// MARK : Primary Key
override static func primaryKey() -> String? {
return "ID"
}
}
Add user into DB with write function
let obj = UserDataModel(value: ["name": userName,
"ID": userID])
try! objRealm.write {
objRealm.add(obj)
}
Read object from Realm DB
return objRealm.objects(UserDataModel.self)
I am new to programming and I am now working on an app that requires a login system. (A not so secure system). I wrote the following codes
#IBAction func CreateACPressed(_ sender: Any) {
if usernameTextField2.hasText && passswordTExtField2.hasText {
let newUser = accountInfo(username: usernameTextField2.text!, password: passswordTExtField2.text!)
var randomTestingArr : NSArray = [accountInfo]() as NSArray
randomTestingArr.adding(newUser)
let defaults = UserDefaults.standard
defaults.set(randomTestingArr, forKey: "ACArr")
defaults.synchronize()
let array = defaults.array(forKey: "ACArr") as? [accountInfo] ?? [accountInfo]()
for i in array{
print("username: \(i.username) password: \(i.password)")
}
// temp retrieve
}else {
print("you havent entered anything")
}
}
but when I hit the create button on my app, the console did not print out the username and password I entered.
what is the problem here?
The way you are trying to saving may be creating problem.
Instead of this
let defaults = UserDefaults.standard
defaults.set(randomTestingArr, forKey: "ACArr")
defaults.synchronize()
Replace with this:
let defaults = UserDefaults.standard
defaults.set(usernameTextField2.text!, forKey: "UserName")
defaults.set(passswordTExtField2.text!, forKey: "Password")
defaults.synchronize()
And I am sure that it will works fine.
UserDefaults are not working in my App. Please find the below code under AppDelegate file.
let sharingData = UserDefaults.init(suiteName: "group.macuser79.xxx");
sharingData?.set("vincenzo", forKey:"username");
sharingData?.synchronize();
In the InterfaceController of the app to Watch, to be able to retrieve the value so I did this:
override func awake(withContext context: Any?) {
let sharingData = UserDefaults.init(suiteName: "group.macuser79.xxx");
let username = sharingData?.object(forKey: "username");
print("Value username \(username)");
}
Please let me know, what I'm doing wrong!
In Swift3 UserDefaults made much smarter to obtained stored value. In below line, you are storing String value without specifying it!:
sharingData?.set("vincenzo", forKey:"username");
So, in order to get that, you need to write like below:
let username = sharingData?.string(forKey: "username");
print("Value username \(username)");
}
This is much more better context in getting values based on you Store.
Try this instead:
let defaults = UserDefaults.standard
defaults.set("group.macuser79.xxx", forKey:"username")
defaults.synchronize()
To access the store:
let defaults = UserDefaults.standard
let username = defaults.string(forKey: "username")
I admit that I haven't tried to init() my own UserDefaults instance before, but the standard instance of it, which is made into a singleton by iOS, is good practice to use.
Also, don't forget to unwrap the optional properly.
To set:
UserDefaults(suiteName: "group.macuser79.xxx")?.set("vincenzo", forKey: "username")
To access:
UserDefaults(suiteName: "group.macuser79.xxx")!.string(forKey: "username")
I'm trying to save a variable in Xcode so that it saves even after the app has closed, how ever when I access it I do it from a several different classes and files, and I change the value of the variable when I access it. Therefore similar threads do not completely apply, the value to be stored is a string and here is the code I have up until now:
var defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(Token, forKey: "") as! String
I believe this is the correct format, but I don't know how to call it to change it because when I try I get an error message saying expected declaration.
Anyway any help would be very much appreciated.
First of all you have to specify an unique key to store the variable (in the example MyKey ).
In AppDelegate > applicationDidFinishLaunching register the key with a default value.
The benefit is you can use a non-optional variable and you have a defined default value.
let defaults = UserDefaults.standard
let defaultValue = ["MyKey" : ""]
defaults.register(defaults: defaultValue)
Now you can from everywhere read the value for the key
let defaults = UserDefaults.standard
let token = defaults.string(forKey: "MyKey")
and save it
let defaults = UserDefaults.standard
defaults.set(token, forKey: "MyKey")
Swift 3
(thanks to vadian's answer)
In AppDelegate > applicationDidFinishLaunching :
let defaults = UserDefaults.standard
let defaultValue = ["myKey" : ""]
defaults.register(defaults: defaultValue)
to save a key:
let defaults = UserDefaults.standard
defaults.set("someVariableOrString", forKey: "myKey")
defaults.synchronize()
to read a key:
let defaults = UserDefaults.standard
let token = defaults.string(forKey: "myKey")
Let's say you have a string variable called token
To save/update the stored value on the device:
NSUserDefaults.standardUserDefaults().setObject(token, forKey: "mytoken")
NSUserDefaults.standardUserDefaults().synchronize()
In the code above I made sure to give the key a value ("mytoken"). This is so that we later can find it.
To read the stored value from the device:
let token = NSUserDefaults.standardUserDefaults().objectForKey("mytoken") as? String
Since the method objectForKey returns an optional AnyObject, I'll make sure to cast it to an optional String (optional meaning that it's either nil or has a value).
Add default.synchronize() after setting value.