在NSUserDefaults中存储[String]

40

我想将一个Swift风格的字符串数组保存到NSUserDefaults中,但实际上代码中的"if"语句表明returnValue始终为nil。

稍后在代码中(iOS 8),我想使用“food += [“spaghetti”]”来添加新条目。

var food : [String] {
    get {
        var returnValue : [String]? = NSUserDefaults.standardUserDefaults().objectForKey("food") as? [String]
        if returnValue == nil      //Check for first run of app
        {
            returnValue = ["muesli", "banana"]; //Default value
        }
        return returnValue!
    }
    set (newValue) {
        NSUserDefaults.standardUserDefaults().setObject(newValue, forKey: "food")
        NSUserDefaults.standardUserDefaults().synchronize()
    }
}

我也尝试了这个链接中的几种方法:https://dev59.com/x2Ag5IYBdhLWcg3wDHQ3,但是它们都没有解决问题。 - Thomas
看起来你的问题是你从未将这些值保存到用户默认设置中,因为向数组添加新项不会调用setter。你需要在某个地方直接设置实际的food(例如food = ["such", "and", "such"])以便保存它。 - holex
我刚刚在最新的Xcode7和Swift2.0中尝试了你的代码,它实际上是完美的。 - LiangWang
这是NSUserDefault的最佳示例:http://iosdevcenters.blogspot.com/2016/05/save-data-using-nsuserdefaults-in-swift.html - Chetan Prajapati
5个回答

33
以下代码应该可以帮助您解决问题:
import UIKit

class ViewController: UIViewController {

    var food: [String] {
        get {
            if let returnValue = NSUserDefaults.standardUserDefaults().objectForKey("food") as? [String] {
                return returnValue
            } else {
                return ["muesli", "banana"] //Default value
            }
        }
        set {
            NSUserDefaults.standardUserDefaults().setObject(newValue, forKey: "food")
            NSUserDefaults.standardUserDefaults().synchronize()
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        print(food) // prints: ["muesli", "banana"] (at first launch)

        food = ["cake"]
        print(food) // prints: ["cake"]

        food += ["spaghetti"]
        print(food) // prints: ["cake", "spaghetti"]

        food = []
        print(food) // prints: []

        NSUserDefaults.standardUserDefaults().setObject(nil, forKey: "food")
        print(food) // prints: ["muesli", "banana"]
    }

}

然而,使用之前的代码,如果你设置 food = [],将会出现问题,因为food不会返回["muesli", "banana"]。为了避免这种情况,您可能更喜欢以下代码:

import UIKit

class ViewController: UIViewController {

    var food: [String] {
        get {
            if let returnValue = NSUserDefaults.standardUserDefaults().objectForKey("food") as? [String] {
                return returnValue == [] ? ["muesli", "banana"] : returnValue
            } else {
                return ["muesli", "banana"] //Default value
            }
        }
        set {
            NSUserDefaults.standardUserDefaults().setObject(newValue, forKey: "food")
            NSUserDefaults.standardUserDefaults().synchronize()
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        print(food) // prints: ["muesli", "banana"] (at first launch)

        food = ["cake"]
        print(food) // prints: ["cake"]

        food += ["spaghetti"]
        print(food) // prints: ["cake", "spaghetti"]

        food = []
        print(food) // prints: ["muesli", "banana"]

        NSUserDefaults.standardUserDefaults().setObject(nil, forKey: "food")
        print(food) // prints: ["muesli", "banana"]
    }

}

好奇,为什么你会将food声明为[NSString]而不是[String]?你可以将其转换为[NSString]以便在NSUserDefaults中进行存储,然后从NSUserDefaults返回时再将其转换为[String]。 - Dylan

13
根据文档所述:
对于NSArray和NSDictionary对象,它们的内容必须是属性列表对象。
这意味着在保存时,您需要将您的String对象转换为NSString对象,类似于以下代码即可:
var food : [String] {
    get {
        var returnValue : [String]? = NSUserDefaults.standardUserDefaults().objectForKey("food") as? [String]
        if returnValue == nil      //Check for first run of app
        {
            returnValue = ["muesli", "banana"]; //Default value
        }
        return returnValue!
    }
    set (newValue) {
        //  Each item in newValue is now a NSString
        let val = newValue as [NSString]
        NSUserDefaults.standardUserDefaults().setObject(val, forKey: "food")
        NSUserDefaults.standardUserDefaults().synchronize()
    }
}

看起来这是最好的选择,因为你只是将 [NSString] 转换为存储,而从存储中返回 [String]。 - Dylan

9
在Swift 3.0中,

Store

指的是存储。
UserDefaults.standard.set(newValue, forKey: "yourkey")
UserDefaults.standard.synchronize()

检索

var returnValue: [NSString]? = UserDefaults.standard.object(forKey: "yourkey") as? [NSString]

移除

UserDefaults.standard.removeObject(forKey: "yourkey")

参考:NSUserdefault对象类型


2

使用函数设置和获取NSUserDefault

使用下面的函数可以全局使用,在任何类中声明并在整个应用程序中使用。

声明

func setUserDefault(ObjectToSave : AnyObject?  , KeyToSave : String)
{
    let defaults = NSUserDefaults.standardUserDefaults()

    if (ObjectToSave != nil)
    {

        defaults.setObject(ObjectToSave, forKey: KeyToSave)
    }

    NSUserDefaults.standardUserDefaults().synchronize()
}

func getUserDefault(KeyToReturnValye : String) -> AnyObject?
{
    let defaults = NSUserDefaults.standardUserDefaults()

    if let name = defaults.valueForKey(KeyToReturnValye)
    {
        return name
    }
    return nil
}

如何调用

Classname_where_this_function_declare.sharedInstance.setUserDefault("value", KeyToSave: "key")**  

-1

//

    class func saveCustomObject(_ object: AnyObject?, key: String) { 
      let encodedObject = NSKeyedArchiver.archivedData(withRootObject: object!) 
      let userDefaults = UserDefaults.standard userDefaults.set(encodedObject, forKey: key) 
      userDefaults.synchronize() 
    } 

//

class func loadCustomObject(_ key: String) -> AnyObject? { 
   let userDefaults = UserDefaults.standard 
   if let userDefaultKey = userDefaults.object(forKey: key) { 
     let encodedObject = userDefaultKey as! NSData 
     return NSKeyedUnarchiver.unarchiveObject(with: encodedObject as Data)! as AnyObject? 
   } else {
     return nil 
   }
} 

//

class func removeCustomObject(_ key: String) { // 
    let encodedObject = NSKeyedArchiver.archivedDataWithRootObject(object!) let userDefaults = 
    UserDefaults.standard userDefaults.removeObject(forKey: key) 
    userDefaults.synchronize()
 }

调用方法

let aParams : [String : String] = [ "DeviceType" : "iOS", ]
CommonMethods.saveCustomObject(aParams as AnyObject?, key:Constants.kLoginData)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接