I'm storing a set of strings (Set<String>
) into a NSUserDefaults.standardUserDefaults()
and when retrieving back the object, it comes back as an array of strings instead of a set.
This block works, as I'm recreating the array as a NSSet
if let products = NSUserDefaults.standardUserDefaults().objectForKey("products") as? [String] {
// recreate the array into a NSSet / Set
if let productSet = NSSet(array: products) as? Set<NSObject> {
// now it's a set
}
}
However, it's not possible to get the object directly as a swift Set:
if let products = NSUserDefaults.standardUserDefaults().objectForKey("products") as? Set<String> {
// will not cast into Set<String>
}
I assume NSUserDefaults
coverts set into an array internally? Is there a way to receive the items as a set and not an array?
Short answer : No
NSUserDefaults
cannot store sets. It's documented that way and it's because of the limitations of the format used to store the data on disk.
If saving a set works for you and automatically converts it to an array, you're actually lucky as I don't think this is a documented behavior and it should just throw an error.
EDIT : It doesn't work and you should not try it.
The best practice is to convert it to an array before saving and convert it back to a set after retrieving. You could also write a category on NSUserDefaults
that does that automatically. Here is an example with objective-C :
//
// NSUserDefaults+SetAdditions.h
//
#import <Foundation/Foundation.h>
@interface NSUserDefaults (SetAdditions)
- (NSSet *)setForKey:(NSString *)defaultName;
- (void)setSet:(NSSet *)set forKey:(NSString *)defaultName;
@end
//
// NSUserDefaults+SetAdditions.m
//
#import "NSUserDefaults+SetAdditions.h"
@implementation NSUserDefaults (SetAdditions)
- (NSSet *)setForKey:(NSString *)defaultName
{
NSArray *array = [self arrayForKey:defaultName];
if (array) {
return [NSSet setWithArray:array];
} else {
return nil;
}
}
- (void)setSet:(NSSet *)set forKey:(NSString *)defaultName
{
if (set) {
[self setObject:[set allObjects] forKey:defaultName];
} else {
[self setObject:nil forKey:defaultName];
}
}
@end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With