How to remove all UserDefaults data ? - Swift [duplicate] - ios

This question already has answers here:
Delete all keys from a NSUserDefaults dictionary iOS
(18 answers)
Closed 5 years ago.
I have this code to remove all UserDefaults data from the app:
let domain = Bundle.main.bundleIdentifier!
UserDefaults.standard.removePersistentDomain(forName: domain)
print(Array(UserDefaults.standard.dictionaryRepresentation().keys).count)
But I got 10 from the print line. Shouldn't it be 0?

The problem is you are printing the UserDefaults contents, right after clearing them, but you are not manually synchronizing them.
let domain = Bundle.main.bundleIdentifier!
UserDefaults.standard.removePersistentDomain(forName: domain)
UserDefaults.standard.synchronize()
print(Array(UserDefaults.standard.dictionaryRepresentation().keys).count)
This should do the trick.
Now you don't normally need to call synchronize manually, as the system does periodically synch the userDefaults automatically, but if you need to push the changes immediately, then you need to force update via the synchronize call.
The documentation states this
Because this method is automatically invoked at periodic intervals, use this method only if you cannot wait for the automatic synchronization (for example, if your application is about to exit) or if you want to update the user defaults to what is on disk even though you have not made any changes.

This answer found here https://stackoverflow.com/a/6797133/563381 but just incase here it is in Swift.
func resetDefaults() {
let defaults = UserDefaults.standard
let dictionary = defaults.dictionaryRepresentation()
dictionary.keys.forEach { key in
defaults.removeObject(forKey: key)
}
}

Related

Data written to defaults within an unwanted communications extension isn't persisted

I'm using 4 extensions within my app and use a group in combination with UserDefaults.init(suiteName:) to share settings between the extensions and the app.
However I've just tried adding an unwanted communications extension and found that data writing to the defaults, using the exact same way as its written in the other extensions, isn't saved.
At first I noticed data written by the UCE wasn't present when the app tried to read it, so performed an experiment and found that while the extension is running it can write data to user defaults and read it back, but the next time the extension runs, all that data has gone.
I've tried using the old UserDefaults.synchronize() method after writing the data but that makes no difference.
Why is the UC extension different from every other extension? Is it possible to write and persist data from within it?
let groupName = "group.com.mycompany.appName"
let sharedDefaults = UserDefaults.init(suiteName: groupName)
var theValue = sharedDefaults!.value(forKey: "some key")
NSLog("\(theValue)") // prints nothing, despite the extension having previously run
sharedDefaults!.set("some value", forKey: "some key"))
sharedDefaults!.synchronize()
theValue = sharedDefaults!.value(forKey: "some key")
NSLog("\(theValue)") // prints "some value"

Swift - UserDefaults setting not getting saved inside framework

I have a framework that is generating a device UUID once and saving it using UserDefaults. The app has access to the UserDefaults and everything works as expected. However, the framework is not accessing UserDefaults in some cases.
I sorted this out on an iPhone 8 using the synchronize() method:
func getDeviceID() -> String {
if let device = UserDefaults.standard.object(forKey: "DeviceID") as? String {
return device
} else {
let device = UUID().uuidString
UserDefaults.standard.set(device, forKey: "DeviceID")
UserDefaults.standard.synchronize() // this line helped with an iPhone 8
return device
}
}
However, on an older iPhone SE 1st generation the issue comes back.
First, why is this happening at all, and why is the synchronize() method seemingly helping in a newer device? (Both phones are running iOS 13)
Are there any known limitations when accessing UserDefaults from within a framework?
If it is failing when you're reading data right after writing the deviceId to UserDefaults
Then it could be related to how UserDefaults actually stores the data to disk.
The actual write to disk is asynchronous and batched automatically by NSUserDefaults.
Check this
So there's a chance that it is slower for older devices running new iOS versions.

UIPasteboard not giving value

An object that helps a user share data from one place to another within your app, and from your app to other apps.
This is the statement written at the very beginning of UIPasteboard docs. But when I try to use it in two different apps accessing data set by other app I am getting nil everytime
DispatchQueue.global(qos: .background).async {
var i = 1
while(i > 0) {
let v = UIPasteboard.general.string
sleep(1)
print("Task : \(i)")
print("Value: \(v)")
i = i + 1
}
}
I am fetching data in above code and setting data as in below code.
UIPasteboard.general.string = "Hello"
NB: I have tested locally in this app it is setting data
Are you running iOS >=10? There was a privacy change regarding passing value between apps. Try reading the UIPasteBoard api doc : (https://developer.apple.com/documentation/uikit/uipasteboard).
Tl:dr You need to have both apps to be in the same app group (Communicating and persisting data between apps with App Groups)
To note: iOS apps are sandboxed. So the change in iOS 10 just enforces that feature.
EDITED: Since you can't use App Groups (different developer and/or products), you have to send data via a different channel. Try searching urlSchemes or store/fetch through a common server(tedious tho)

Save updated Set in UserDefaults every time .insert() or .remove(at:) are called

I’m sure this is a silly question, but I’m on a phone, and can’t find any similar questions.
I have a Set:
var mySet: Set<SomeObject>
That I need to persist across app launches, presumably using UserDefaults.
This works ok if I re-create and re-save the Set to UserDefaults every time it is modified, but that seems awfully cumbersome. Is there a way I can support updating the UserDefaults value every time .insert() or .remove(at:) are called?
You can use a property observer for that purpose. Here is a simple
example for a set of integers (saved as an array):
var mySet = Set(UserDefaults.standard.array(forKey: "mySet") as? [Int] ?? []) {
didSet {
// Save new value
UserDefaults.standard.set(Array(mySet), forKey: "mySet")
}
}
Set is a value type, and therefore each modification (insertion,
removal, ...) stores a new value in the variable, and the property
observer is triggered.

Swift 3 Migration Cleared NSUserDefault Data

I'm not sure how to use the new UserDefaults class with the new Swift3 changes.
I had this code prior to the migration to swift3 which successfully retrieved the data stored in the userDefaults:
if NSUserDefaults.standardUserDefaults().objectForKey("profileArray") != nil {
profileArray = NSUserDefaults.standardUserDefaults().objectForKey("profileArray") as! [String]
}
With the migration to swift3 the code is now:
if UserDefaults.standard.object(forKey: "profileArray") != nil {
profileArray = UserDefaults.standard.object(forKey: "profileArray")! as! [NSString]
}
The new syntax makes sense but when I run the project the data that was previously stored in the user default seems to be gone.The userdefault.standard... is now returning empty/nil.
How do I retrieve the data that was stored prior to the swift3 migration?
Appreciate the help with moving to swift3!
I don't know if that solves your problem, but your syntax is not very efficient – you retrieve the object from user defaults unnecessarily twice.
The recommended way is optional binding and the dedicated method to get an array:
if let array = UserDefaults.standard.array(forKey: "profileArray") as? [String] {
profileArray = array
}
Im Swift use always String rather than NSString unless you have no choice.
I have finally figured this out. The userDefaults weren't "cleared". but the userDefaults are specific to a device. so with the migration to xcode8 the iOS simulators were also upgraded....and these are technically new devices where userDefaults had never been captured.
I proved this theory by adding a simulator (you can go back and re-install iOS 9.x simulators) and this worked.
I also tested on a real device using iOS 9.x & the new swift 3 code and the defaults persisted on that device.
So problem solved! :)

Resources