问题
In an app I'm developing the user needs to add an "enterprise" to use the app. However, they can add more than one "enterprise" to the app. Every enterprise added needs two things: a name, and an enterprise API key.
I have created an "Enterprise" class:
class Enterprise : NSObject {
var name:String!
var apiKey:String!
init (name:String, apiKey:String) {
self.name = name
self.apiKey = apiKey
}
required init(coder decoder: NSCoder) {
self.name = decoder.decodeObjectForKey("name") as String
self.apiKey = decoder.decodeObjectForKey("apiKey") as String
super.init()
}
func encodeWithCoder(coder: NSCoder) {
coder.encodeObject(self.name, forKey: "name")
coder.encodeObject(self.apiKey, forKey: "apiKey")
}
}
One thing to note about this class, in the example I followed to build this class they have sub-classed the class as NSCoder as well as NSObject, however if I added "NSCoder" to the class, I get the following error:
Multiple inheritance from classes 'NSObject' and 'NSCoder'
When saving the array I'm using the following:
let name = self.enterpriseName.text
let key = self.apiKey.text
if name != "" {
if key != "" {
let defaults = NSUserDefaults.standardUserDefaults()
let objectKey = "enterprise"
var ent = [Enterprise(name: name, apiKey: key)]
var entData = NSKeyedArchiver.archivedDataWithRootObject(ent)
defaults.setObject(entData, forKey: objectKey)
defaults.synchronize()
}
else {
println("No API key")
}
}
else {
println("No name")
}
This seems to work when storing one value, but when I check how many items are in the array at launch, it only shows 1.
Any ideas how I can do this? The end result I'm looking for would be something like:
Enterprises:
Enterprise
name: abc
apiKey: 184nfh692j6j31))8dx
Enterprise
name: def
apiKey: 23oih9823tng893g2gd
Enterprise:
name: ghi
apiKey: sfgYSS4yw44gw31!#%q
With the ability to remove a particular enterprise from the list if the user choose to delete it.
EDIT
Here's what worked, using Leonardo's (below, and accepted answer) method:
let name = self.enterpriseName.text
let apiKey = self.apiKey.text
if name != "" {
if apiKey != "" {
var enterprises = NSMutableDictionary()
var loadedEnterprises = Load.dictionary("enterprises")
if loadedEnterprises != nil {
if(loadedEnterprises.count > 0) {
for (key, value) in loadedEnterprises {
enterprises.setObject(value, forKey: key as String)
}
}
}
enterprises.setObject(apiKey, forKey: name)
Save.dictionary("enterprises", enterprises)
}
else {
println("No API key")
}
}
else {
println("No name")
}
回答1:
You should use a Dictionary otherwise you may end up with the same enterprise with different keys. I have created a class to load and save dictionaries to the user default. You should do as follow:
class Load {
class func dictionary(key:String) -> NSDictionary! {
return NSUserDefaults.standardUserDefaults().objectForKey(key) as? NSDictionary
}
}
class Save {
class func dictionary(key:String, _ value:NSDictionary) {
NSUserDefaults.standardUserDefaults().setObject(value, forKey: key)
}
}
class Remove {
class func object(key:String) {
NSUserDefaults.standardUserDefaults().removeObjectForKey(key)
}
}
var enterprises:[String:String] = ["abc":"184nfh692j6j31))8dx","def":"23oih9823tng893g2gd","ghi":"sfgYSS4yw44gw31!#%q"]
Save.dictionary("enterprises", enterprises)
name = "jkl"
apiKey = "9a4giNifjKJq6v8G4fb"
if !name.isEmpty {
if !apiKey.isEmpty {
enterprises[name] = apiKey
Save.dictionary("enterprises", enterprises)
} else {
println("No API key")
}
} else {
println("No name")
}
for (key, value) in enterprises {
println("\(key)=\(value)")
}
let loadedDictionary = Load.dictionary("enterprises")
for (key, value) in loadedDictionary {
println("\(key)=\(value)")
}
回答2:
You always override 'Enterprise" for 'enterprise' Key, use an array:
var entArray = defaults.objectForKey(objectKey)
entArray?.addObject(entData)
defaults.setObject(entArray, forKey: objectKey)
EDIT:
works for me, but it's not good solution:
func getEnterprise() {
let objectKey = "enterprise"
// get stored array
let defaults = NSUserDefaults.standardUserDefaults()
var array = defaults.objectForKey(objectKey) as? Array<NSData>
if array != nil {
for data in array! {
var enterprise = NSKeyedUnarchiver.unarchiveObjectWithData(data) as? Enterprise
println("\(enterprise!.name)")
}
}
}
func saveEnterprise() {
let name = self.enterpriseName
let key = self.apiKey
if name != "" && name != nil {
if key != "" && key != nil {
let defaults = NSUserDefaults.standardUserDefaults()
let objectKey = "enterprise"
var ent = Enterprise(name: name!, apiKey: key!)
// get stored array
var array = defaults.objectForKey(objectKey) as? Array<NSData>
if array == nil {
array = Array()
}
var entData = NSKeyedArchiver.archivedDataWithRootObject(ent)
array?.append(entData)
defaults.setObject(array, forKey: objectKey)
defaults.synchronize()
}
else {
println("No API key")
}
}
else {
println("No name")
}
}
来源:https://stackoverflow.com/questions/28481299/ios-locally-saving-an-array-of-key-value-pairs