iOS UI测试无法识别NSUserDefaults中的项目

时间:2017-12-02 04:52:11

标签: ios

我正在编写一个演示应用程序,我将项目存储在NSUserDefaults中。 iOS UI测试如下所示:

 func test_should_create_account_successfully() {

        app.textFields["usernameTextField"].tapAndType(text: "johndoe")
        app.textFields["passwordTextField"].tapAndType(text: "password")

        app.buttons["registerButton"].tap()

        let users = dataAccess.getUsers()
        XCTAssertTrue(users.count > 0)
    }

registerButton tap触发了以下代码:

 @IBAction func saveButtonClicked() {

    let user = User(username: self.usernameTextField.text!, password: self.passwordTextField.text!)
    self.dataAccess.saveUser(user)
}

DataAccess类定义如下:

  func saveUser(_ user:User)  {

        user.userId = UUID().uuidString

        var users = getUsers()
        users.append(user)

        let usersData = NSKeyedArchiver.archivedData(withRootObject: users)

        // save the user
        let userDefaults = UserDefaults.standard
        userDefaults.setValue(usersData, forKey: "users")
        userDefaults.synchronize()

    }

    func getUsers() -> [User] {

        let userDefaults = UserDefaults.standard
        let usersData = userDefaults.value(forKey: "users") as? Data
        if usersData == nil {
            return [User]()
        }

        let users = NSKeyedUnarchiver.unarchiveObject(with: usersData!) as! [User]
        return users
    }

问题是以下行总是返回0个用户:

let users = dataAccess.getUsers() 

这仅在iOS UI测试中发生,而不是在正常的单元测试目标中。

更新:用户类兼容NSCoding协议

public class User : NSObject, NSCoding {

    var username :String!
    var password :String!
    var userId :String!

    init(username :String, password :String) {
        self.username = username
        self.password = password
    }

    public func encode(with aCoder: NSCoder) {

        aCoder.encode(self.userId,forKey: "userId")
        aCoder.encode(self.username, forKey: "username")
        aCoder.encode(self.password, forKey: "password")
    }

    public required init?(coder aDecoder: NSCoder) {

        self.userId = aDecoder.decodeObject(forKey: "userId") as! String
        self.username = aDecoder.decodeObject(forKey: "username") as! String
        self.password = aDecoder.decodeObject(forKey: "password") as! String
    }

}

1 个答案:

答案 0 :(得分:0)

这是因为您的类User没有正确编码,就像这个示例类一样(在swift 3中):

class User: NSObject, NSCoding  {
    let name : String
    let url : String
    let desc : String

    init(tuple : (String,String,String)){
        self.name = tuple.0
        self.url = tuple.1
        self.desc = tuple.2
    }
    func getName() -> String {
        return name
    }
    func getURL() -> String{
        return url
    }
    func getDescription() -> String {
        return desc
    }
    func getTuple() -> (String, String, String) {
        return (self.name,self.url,self.desc)
    }

    required init(coder aDecoder: NSCoder) {
        self.name = aDecoder.decodeObject(forKey: "name") as? String ?? ""
        self.url = aDecoder.decodeObject(forKey: "url") as? String ?? ""
        self.desc = aDecoder.decodeObject(forKey: "desc") as? String ?? ""
    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(self.name, forKey: "name")
        aCoder.encode(self.url, forKey: "url")
        aCoder.encode(self.desc, forKey: "desc")
    }
}

然后保存并从UserDefaults中获取,如下所示:

func save() {
    let data  = NSKeyedArchiver.archivedData(withRootObject: object)
    UserDefaults.standard.set(data, forKey:"userData" )
}

func get() -> MyObject? {
    guard let data = UserDefaults.standard.object(forKey: "userData") as? Data else { return nil }
    return NSKeyedUnarchiver.unarchiveObject(with: data) as? MyObject
}