2017-03-02 3 views
0

NSCodingとNSObjectを使用してアーカイブに問題があります。これは、Playgroundで完璧に機能します。しかし、Xcodeではうまくいかないようです。誰かがこの問題を解決するのに役立つことができますか?Xcode-projectはNSKeyedArchiverを使用してアーカイブしませんが、プレイグラウンドは

NSKeyedArchiver.archiveRootObject(person, toFile: "person") 

それが動作して遊び場にtrueを返しますが、それはプロジェクトにfalseを返します:私は呼ん

毎回。私はシミュレータを使用しません。

私は同じタイプの問題を探していましたが、これに関連するものは見つけられません。

class Person: NSObject, NSCoding { 

private var _name: String = "name" 
private var _birthdate: Date = Date() 
private var _income: Int = -1 
private var _wealth: Int = -1 

var name: String { 
    get { return _name } 
    set (newName) { _name = newName } 
} 
var birthdate: Date { 
    get { return _birthdate } 
    set (newBirthdate) { _birthdate = newBirthdate } 
} 
var income: Int { 
    get { return _income } 
    set (newIncome) { _income = newIncome } 
} 
var wealth: Int { 
    get { return _wealth } 
    set (newWealth) { _wealth = newWealth } 
} 

override init(){} 

required convenience init(coder unarchiver: NSCoder) { 

    self.init() 

    if let name = unarchiver.decodeObject(forKey: "name") as? String { 
     self.name = name 
    } 
    if let birthdate = unarchiver.decodeObject(forKey: "birthdate") as? Date { 
     self.birthdate = birthdate 
    } 
    let income = unarchiver.decodeInteger(forKey: "income") 
    self.income = income 

    let wealth = unarchiver.decodeInteger(forKey: "wealth") 
    self.wealth = wealth 

} 

func encode(with archiver: NSCoder) { 

    archiver.encode(name, forKey: "name") 
    archiver.encode(birthdate, forKey: "birthdate") 
    archiver.encode(income, forKey: "income") 
    archiver.encode(wealth, forKey: "wealth") 
} 
} 

次に、人を作成してアーカイブします。

let person = Person() 
NSKeyedArchiver.archiveRootObject(person, toFile: "person") 
+0

filePathの問題のようです。私の知識では、Playgroundsは実際にはホームディレクトリを使用しますが、プロジェクトはサンドボックスを使用します。 'FileManager.default.urls(.documentDirectoryの場合:.userDomainMask).first!.appendingPathComponent(" person ")'のようなものを使用するとどうなりますか? – Prientus

+0

私はFileManagerが何をしているのか分かりませんが、このように使用しました: 'let person = Person() let path = FileManager.default.urls(.documentDirectory、for:.userDomainMask)。最初.appendingPathComponent( "人物") personWasUploaded てみましょう!ブール= NSKeyedArchiver.archiveRootObject(人、toFileの: "\(パス)") プリント(パス) プリント( "アップロードされた人:\(personWasUploaded)") ' – Jer

+0

' file:/// var/mobile/Containers/Data/Application/4843FF38-BEFD-47F0-A1E2-DE4ADDAAD97F/Documents/person'のようなファイルを作成します。しかし、アプリケーションとドキュメントの間で、数字/文字は毎回変わります – Jer

答えて

2

Personクラスのinitに対して小さな編集を加える必要があります。 convenienceキーワードを削除し、self.init()super.init()と交換してください:あなたはそれを行うならば、あなたはそれをこのようなパスを与えて(私はテストのために、それは働いていた私のviewDidLoadでそれをやった)好きな場所アーカイバ呼び出すことができます

class Person: NSObject, NSCoding { 

    private var _name: String = "name" 
    private var _birthdate: Date = Date() 
    private var _income: Int = -1 
    private var _wealth: Int = -1 

    var name: String { 
     get { return _name } 
     set (newName) { _name = newName } 
    } 
    var birthdate: Date { 
     get { return _birthdate } 
     set (newBirthdate) { _birthdate = newBirthdate } 
    } 
    var income: Int { 
     get { return _income } 
     set (newIncome) { _income = newIncome } 
    } 
    var wealth: Int { 
     get { return _wealth } 
     set (newWealth) { _wealth = newWealth } 
    } 

    override init() {} 

    required init(coder unarchiver: NSCoder) { 

     super.init() 

     if let name = unarchiver.decodeObject(forKey: "name") as? String { 
      self.name = name 
     } 
     if let birthdate = unarchiver.decodeObject(forKey: "birthdate") as? Date { 
      self.birthdate = birthdate 
     } 
     let income = unarchiver.decodeInteger(forKey: "income") 
     self.income = income 

     let wealth = unarchiver.decodeInteger(forKey: "wealth") 
     self.wealth = wealth 

    } 

    func encode(with archiver: NSCoder) { 

     archiver.encode(name, forKey: "name") 
     archiver.encode(birthdate, forKey: "birthdate") 
     archiver.encode(income, forKey: "income") 
     archiver.encode(wealth, forKey: "wealth") 
    } 
} 

let person = Person() 
let path = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent("person").path 
let personWasUploaded: Bool = NSKeyedArchiver.archiveRootObject(person, toFile:path) 
print(path) 
print("person uploaded: \(personWasUploaded)") 
+0

ありがとうございました!私はFileManagerを使用せず、あなたが示唆したようにinit()を変更するだけで、FileManagerなしで方法を見つけました。主な問題は、私がどのように初期化するかであったと思います。 – Jer

関連する問題