2017-12-02 12 views
0

NSUserDefaultsにアイテムを保存するデモアプリケーションを作成しています。 iOSのUIテストは、次のようになります。iOS UIテストでNSUserDefaultsの項目が認識されない

@IBAction func saveButtonClicked() { 

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

DATAACCESSクラスが以下に定義されています:

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タップは、次のコードを解雇

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 Testでのみ発生し、通常のUnit Testターゲットでは発生しません。

UPDATE:Userクラスは、互換性の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 
    } 

} 

答えて

0

あなたのクラスのユーザー(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 
} 
+0

ありがとうございますが、私はそれを試してみましたが、それは問題ではありませんでした。ユニットテストプロジェクト(iOS UIテストプロジェクトではありません)を使用すると、うまく永続化されるので、これはうまくコード化されています。 –

+0

デバッグ用のUserdefaulsのすべてのキー値のペアを印刷してみてください。 –

+0

NSUserDefaultsにアクセスすると、ターゲットの問題が深刻になると思います。奇妙な部分は、通常のiOSユニットテストプロジェクトが動作することです。 – azamsharp

関連する問題