How to Save Data with UserDefaults - Swift
HTML-код
- Опубликовано: 4 сен 2024
- In this tutorial we walk through the basics of saving data using UserDefaults is Swift. We'll discuss what types of data you can save, some of the security issues involved, and how to make it all happen. In this example, we'll store a light or dark mode preference, as well as the name of a pet as a String. This tutorial was done in Swift 4.2 and Xcode 10.
If you like my teaching style, I've released my first iOS dev course which is all about the take-home project job interview for iOS developers.
Course Info - seanallen.teac...
Source Code (Xcode 10, Swift 4.2):
www.dropbox.co...
How I Became an iOS Developer:
gumroad.com/l/...
Check out my podcast, iOS Dev Discussions:
itunes.apple.c...
Book and learning recommendations that help out the channel if you decide to purchase (Affiliate Links):
Ray Wenderlich Books:
store.raywende...
Ray Wenderlich Videos:
store.raywende...
Paul Hudson's Hacking With Swift:
gumroad.com/a/...
Learn Advanced Swift Here:
gumroad.com/a/...
Links to my Developer & RUclips Setup
www.amazon.com...
Personal Links:
Twitter:
/ seanallen_dev
Instagram:
@seanallen_dev
Website:
seanallen.co
Watch Next - iOS Take Home Project - Job Interview Practice - Free Preview - ruclips.net/video/MSIe2y6Fee8/видео.html
This tutorial was just what i needed right now. Btw, I find your way to use structs to prevent typos very useful.
Happy to hear it, Erik. There are a few different ways to create constants for your stings. Structs are just one of many. But glad to hear you found it helpful.
Just as I'm about to implant UserDefaults again your video pops up. Great timing. Needed the refresher
Hope it helped!
When I first saw the title "save data" I thought you're going to "save user data" and almost started writing a comment about why doing that is a very bad practice, but then I realized you are talking about just saving user preferences :) When I just started developing for MacOS back in 2005 I quickly learned what should be saved in UserDefaults and what should be not. There is a well-known practice in MacOS world that if you need to reset you app to defaults the best way to do that is just to delete your preferences plist file, that way you simulate fresh start of your app on your system, and no real user data/documents should be lost by doing that. That makes a simple rule: everything stored in UserDefaults should be discardable without the risk of user's personal data loss.
That's a really good way to think about what should be saved. I like that.
That's a really good way to think about what should be saved. I like that.
Really Nice example and clean code with good explanation of what to save into that especially, waiting for database and core data examples.
Glad you liked it, Govind.
Great example and really well explained - more of these please Sean!
Thanks Richard!
I really like your videos! they are simple, easy to follow and clear... thank you very much for your help!
Glad you like them!
I knew this concept very well however it's always good to see your videos as hoping to learn something more and I do always :) Thanks for your time brining this quality videos for any expertise level iOS developer.
Happy to hear you liked it, Hemang!
Great video! Very concise and to the point
Glad you liked it!
Great points about what to save and what not to save! Thanks Sean
Glad you liked it, Gregory!
Great tutorial Sean! It would be great to follow this up with a tutorial on how to save data securely.
I have a Keychain one on my list. As well as using Codable to save custom objects. So many videos, so little time... But....coming soon (copy/pasted from twitter, lol).
Dang you reply fast on here and twitter! Your killing it man! Thanks for everything.
i needed of this tutorial, it's great thanks
Happy to help
Wow Great video. It is just a little too fast paced video for a newbie like me. I had to pause and rewind to get the concept digested. But no worries you explained it very well. Thanks for putting out this video.
Thanks for that insight, Nilesh. I've been working on slowing down. It's hard (impossible) to find a pace that works for everyone. For some it's too slow, for some it's too fast. That's the great thing about RUclips tho... you can stop and rewind.
Sean Allen no complaints. You have great content.
@nileshjdarji
It's been 5 years since this comment! How have things been for you?? 🙂
Very useful tutorial! I loved it.
Glad to hear that!
Love the videos, would it be possible to do a tutorial in the future about how to scan QR/Barcodes for inventory management? Like something that adds and deletes from either a simple SQL table or core data? Thanks in advance!
Thank you, Sean! Yours tutorials are great!! 👍🤠
Glad you liked it Nikolay 👍
Here we go with another awesome tutorial! ❤👍✌
Glad you liked it, AliReza 👍
VERY HELPFUL. Great Job
Glad you enjoyed it, Evan!
Hello, thank you for the amazing tutorial and neat code provided! I have a question, I want to do the same exact thing (changing background color) but for my entire app pages. I have tried keeping the checkForStylePreference() in the viewDidLoad()of another page but it did not recognize it. I copy pasted the whole checkForStylePreference() but still other pieces of code were missing. Is the only way to do it is by copy pasting all of the methods of the viewController in all App pages? Or there is a much simpler way as a believe to reduce amount of code? Please advise I am new to Swift.
great tutorials Sean! keep at it
Thanks Charles! Glad you liked it.
Always clear and sharp as usual. Great job Sean Allen
Thanks James! Glad you liked it.
Thanks Sean for another great video.
One request, can you make one video where you can show how to store the login status of the user. For eg if user is logged in he'll directly go to home screen else show the login screen.
Also if that app has on boarding screens which user can see only once when the fresh app is installed.
Again thanks for your all the efforts for making these videos.
I'll add that to my list. But one (of many) possible ways to do this would be to save a boolean like "isOnboardComplete", and check for that in your app delegate, and then take them to the correct screen.
You are the best Sean.
Thanks!
Thank you! Been waiting for this
Happy to help!
wow man , You always come with awesome topic with nice explanation
Thanks Junaid!
Good video, Sean. Thanks.
Thanks Glenn!
Yes! New video👍Thank you!
Hope you like it!
Yesssss. I needed this video🙏🏾 Bless
Glad you liked it 👍
Awesome as always!
Thanks Nate!
Thank you!
happy it helped, Murat
Sean Allen
It helps. Your videos are perfect. Thank you, again.
Thanks for the tutorial! Just a minor nitpick: your Keys struct is better off as an enum since it's strictly used as a namespace and you would never want to initialize an instance of Keys() 😋
private enum Keys {
static let prefersDarkMode = "prefersDarkMode"
...
}
Fair point. Thanks for clarifying this 👍
Mat - are there any performance benefits from using enum over struct in this case? I like the struct option to keep it clear. (rather than using Keys.prefersDarkMode.rawValue) to reference the string.
You can also do:
enum Keys: String {
case currency
}
& then currency's rawValue would be its string equivalent. Thanks for the incredibly useful vid Sean!
Very helpful sean
Glad you liked it, Vamsi.
Hey Sean make a video on converting image to string data and Thank q for your quality videos👍
Hey Sean how do you save an integer value, I've been trying for a bit now but I can't seem to get it working. Thanks.
There's a "set(Int, forKey)" function on defaults. You can use that. And then to retrieve it, use defaults.integer(forKey:).
Can u pls do a tutorial on using CoreData to save files?
You have a ternary operator for name constant inside checkForSavedName(). Why there is no ternary operator for prefersDarkMode inside checkForStylePreference() ? How does Xcode know that the default value of prefersDarkMode is false?. It is not initialized as false anywhere. I got a little confused so thought of asking you.
Nice sir thanks for providing
Happy to help.
Great video! I have no coding background, but have managed to build an MVP app on XCode using Chat GPT. I now want to test the app, but struggling to work out the next step in saving the data for users. I have built a Sign Up/Sign in page, and then a form page with data input fields. I feel like this (UserDefaults) is not the right saving function for it but wondered if you could help? Thanks!
Please make video for userdefault save class
Can you clarify what you mean? Do you mean saving a custom object? Like a "user" object?
Thank you for the tutorial, but why when I try to do it it only works 7 times out of ten? For some reason those 3 times (when saving a number) it decreases or the opposite by two. I have revisited my code s many times and is really exhausting cuze I know the code is fine, :( It is an apple mistake?
Hi, first of all awesome video! second - do we still need to do nil coalescing even tho the default value of a String is an empty String? I mean the program wont crash, just want to know what's the right thing to do and what good programers do :)
Hello, Sean! Could you tell me, please, why weren't your ui element outlets marked as weak?
I discovered a couple months ago (and discussed it on a Swift News episode) that it's recommended by Apple that they are strong. Here's an article talking about it. cocoacasts.com/should-outlets-be-weak-or-strong
@@seanallen very interesting topic, somehow. Didn't think about it
Hey Sean Allen, cool video, just one question, what is the best way to save a user's profile picture? Cuz You mentioned that saving in the user defaults will affect the speed of the app. I appreciate your feedback :)
SO useful
hey can u make a video on using firebase built-in ui or simply authentication methods fb, twitter etc?
btw love ur channel ^^
Glad you like the channel! Unfortunately, I don't use Firebase in my projects. They all have custom built back ends. So I have no experience with Firebase, so can't really do tutorials on it.
@@seanallen its okay ^^, was looking for options about managing authentication and real time data, so landed across firebase xd, lets see what else can i find
@@mihirluthra7762 stackoverflow is a good place to look and ask for
@@donathmm3881 yepps bro ^_^
Hi Sean. I have a case where I am using 3 segments in segmented control so I cannot use the bool for storing segmented control state. I have to use integer in this case. all works great but only problem I am running into is I cannot make my UI to update properly. after retrieving from userdefaults, in viewdidload, if I try to do "segmentControl.selectedSegmentIndex = selectedIndex" I am always getting this fatal error of "Unexpectedly found nil while unwrapping an Optional value" and I am not understanding this because how can it be nil if I am saving and retrieving the userdefaults. I have been struggling this for 3 days and finally tried to seek your help. Any idea?
Awesome tutorials man, I have a question:
Could it be used to store a class like user data? For example: name, age and gender?
You can, but it's meant for smaller things. So as long as that user data doesn't become huge, it's fine.
Sean Allen I searched more about this and maybe NSCoding is more useful isn't it? But for me it seems a little difficult, could you make a tutorial of this topic?
@@seanallen The only tutorial about NSCoding is this: www.raywenderlich.com/6733-nscoding-tutorial-for-ios-how-to-permanently-save-app-data
It seems pretty complex and I don't know why they create so much files, specially if you compare with this part of the only one tutorial that I've seen from IOS Developer Apple documentation: developer.apple.com/library/archive/referencelibrary/GettingStarted/DevelopiOSAppsSwift/PersistData.html#//apple_ref/doc/uid/TP40015214-CH14-SW1
Hey Sean, great stuff. One suggestion, you could have avoided force unwrapping the optional for saving pet name. It would crash the app is you hit save while textfield is nil. setValue takes Any? And UITextField text accepts a String? again nil coalescing is not required.
That app doesn't crash when you tap save an empty textfield. Source code is in the description if you want to download.
It doesn't crash once you entered something and then you remove it. Because then it is no longer nil it's an empty string. But run it on fresh device or simulator and try saving.
That’s exactly what I just tested. I erased all contents from my simulator, fresh install of the app, then tapped save before doing anything else. No crash.
Shouldn't it crash actually? Because it is an optional forced unwrapping. Textfield is just initialised and layed out so textfield.text should return nil. Maybe it returns an empty string.
I thought it would crash too. But it didn't.
If certain data like isPremium shouldn't be saved in UserDefaults where should it be stored then?
You can encrypt things like that in the Keychain
Then how do we save profile pictures for example locally? Or do we just get that from database every time they log into the app?
Depends on the situation. Typically you'll get them from the database every time as saving a ton of profile pictures locally isn't what UserDefaults is meant for. However, if you just want to save one user's profile picture (the main user of your app), converting 1 small image to data and storing it in UserDefaults isn't bad.
this doesnt work for me at all, i dont know why? I have the exact same code an logic. The difference is i have to go from my homeviw to the other view which has the contact info. But every time i save the data and i come back is blank
Great video! What is about storing auth token in it ?
I would recommend Keychain for that - developer.apple.com/documentation/security/keychain_services
@@seanallen thank you. I will dig into that when I need it :)
I'm trying to save an array of coordinates (CLLocationCoordinate2D), but it's saying it's a non-property-list object. Is an array of coordinates technically not an NSArray?
You can only save the basic types in user defaults, and CLLocationCoordinate2D is not a basic type. You can convert it to the Data type and save and array of Data
gonna grab a hoodie. What is the difference between the two. I looked at the site and it says they are the same material only difference is the white draw string, if the quality is the same I'd rather get the all black. If the $60 is better quality id rather that. let me know. I did try to look myself, but the site doesn't give much info.
The more expensive is better quality. It’s a softer material. You can get gray or black in both qualities. Just change the color option. The one I wear in the Swift News video is the higher quality gray one (just for context). I appreciate the long time support!
@@seanallen ok cool thanks Sean, I def want the better quality. Thanks for the content. Gonna have to check the Book out too.
sean! do you have any Udemy courses?im new in programming and tried Fullstack and SAP Abap so far, but i really liked ios development a lot more. thanks for you great videos!
I don't have any courses yet. I'll be looking to release my first one in the second half of 2019.
@@seanallen Grand!!Cant wait!!!
Masha Allah u are doing great.
I appreciate the kind words 😀
@@seanallen Again google translate would have helped xD.
so then how do we save stuff that is private(API keys, password, etc)
Keychain - developer.apple.com/documentation/security/keychain_services
Sean Allen hi! What about user’s abilities to access premium features? Where this data should be saved?
Great 👏🏽
Bomb ass video my guy!
Awesome ❤️ ❤️ ❤️
Also, why the textField.text was not retrieved as a String ?
Can you be more specific? When I retrieve the name from user defaults, I cast it as a string.
@@seanallen Sure). I mean, by calling value(Any?, forKey: String), instead of string(forKey: String). May be, that is a better practice)
Yes. That was a mistake on my part. For some reason string(forKey) didn’t show up on my list of auto completes next to bool, int, float, etc... so I went with Any?. Again, a mistake on my part. string(forKey:) would be the better way to go.
@@seanallen That's just a quick remark, don't get me wrong, I appreciate your work and experience). Thanks for the video, Sean!)
All good. That’s the good thing about putting out my code. If I mess up, I’ll know about it. It makes me better.
Hello, I've tried reaching you through earn but I need a quick response before a project submission, I wanted to ask when is the approximate time you reply back? Thank you
I don't see anything in my Earn inbox. What was your question?
@@seanallen Hello Sean, thank you for the amazing tutorial and neat code provided! I have a question, I want to do the same exact thing (changing background color) but for my entire app pages. I have tried keeping the checkForStylePreference() in the viewDidLoad()of another page but it did not recognize it. I copy pasted the whole checkForStylePreference() but still other pieces of code were missing. Is the only way to do it is by copy pasting all of the methods of the viewController in all App pages? Or there is a much simpler way as a believe to reduce amount of code? Please advise I am new to Swift.
@@seanallen I have tried creating another GeneralVC as a parent for the ViewController that has the updateStyle() and check saveStylePreference() But it did not work out, please advise
Love your content. Thanks for sharing this. But please, don't speak so fast lol. It gets harder to understand you when we have english as second language hahaha
I've been working on it. Sometimes I slip back into it. It's my natural speaking speed so I have to try to remember to slow down. I'll keep working on it!
Nice and neat... although couldn't you simply make your isDarkMode BOOL a variable with a GET & SET so that you don't have to repeat any code. Simply change the variable and it writes to UserDefaults.
eg:
var isDarkMode: Bool {
get {
return UserDefaults.standard.bool(forKey: "prefersDarkMode")
}
set {
UserDefaults.standard.set(newValue, forKey: "prefersDarkMode")
}
}
Then you just treat it like any other variable... except that it is persisted in UserDefaults. No need to call in in viewDidLoad, or to write any fancy methods. Just read/write to that BOOL and it automatically reads/writes to UserDefaults!
Yup. This is correct. For the sake of tutorials I like to break things out into separate methods for easy understanding for someone just learning. But this is a more efficient way to do it for sure.
Well that's interesting. Why does defaults.value return nil if there is no key specified (same behavior for url, data, string [btw. you could've used string instead of value, it would eliminate the necessity to cast value as a string]), but it returns 0 when we use defaults.integer, returns false when we use defaults.bool (these are just examples). Maybe we wanted to save a 0 or false explicitly in defaults. It is then unclear whether we specified an invalid key, or if the key actually contained "false", or 0. That's just plain confusing
Interesting point. It wouldn't be clear if that was the value you saved or the default return value.
First to comment !
In case anyone needs the starter project: drive.google.com/drive/folders/10cSk16SKYp81c5G4G2bShVtCcFPZtYzx?usp=sharing
You sound like Jacksepticeye
Also watch this video this is very informative :
ruclips.net/video/AvktQmqltaw/видео.html
devmountain(dot)com... lost me with their stupid marketing, collecting information, and ask me for 100 question, before even to have an idea what they do.
Excellent as always and very timely. Thank you.
Glad you liked it, Forrest 👍