我一直在做一個項目,我需要寫一些對象到磁盤,然後再讓它們回來。我使用NSKeyedArchiver
和NSKeyedUnarchiver
來完成寫作和閱讀,確保我的自定義類符合NSCoding
。它沒有工作,所以,在嘗試調試它並搜索Web很長一段時間後,我決定隔離這個問題。爲什麼NSKeyedArchiver和NSKeyedUnarchiver在這裏按預期工作?
有人可以告訴我爲什麼這段代碼沒有做我期望它做的事嗎?這可能很明顯,但在盯着它好幾個小時後,我仍然無法解決它。
我得在Main.storyboard
與UILabel
,一個UITextField
和UIButton
定義的視圖控制器。這個想法是,用戶可以鍵入內容,按'發佈'按鈕,標籤將顯示他們輸入的內容。每次用戶輸入我希望它寫入磁盤的內容時,如果應用程序退出並再次加載視圖,則該消息將被帶回並由標籤顯示。
此刻,標籤顯示用戶輸入的內容,但如果我退出應用程序並重新打開該應用程序,標籤上只會顯示'Your message here',這是我在故事板中分配的字符串。
我有一種感覺,這可能是一些做的unarchiveObject(withFile:)
呼叫和/或強制轉換爲String
,因爲我讀的地方,因爲斯威夫特3,值類型必須使用自己的方法,未歸檔(如unarchiveBool(withFile:)
)儘管String
似乎沒有這種方法。
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var outputLabel: UILabel!
@IBOutlet weak var textBox: UITextField!
var filePath: URL!
override func viewDidLoad() {
super.viewDidLoad()
filePath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("message")
// Load message
if let loadedMessage = NSKeyedUnarchiver.unarchiveObject(withFile: filePath.absoluteString) as? String {
outputLabel.text = loadedMessage
}
}
@IBAction func textFieldDoneEditing(_ sender: UITextField) {
sender.resignFirstResponder()
}
@IBAction func postButtonTapped(_ sender: Any) {
outputLabel.text = textBox.text
textBox.text = ""
let str = outputLabel.text!
// Save message
let data = NSKeyedArchiver.archivedData(withRootObject: str)
do {
try data.write(to: filePath)
} catch {
print("Couldn't write file.")
}
}
}
好吧,@gkchristopher指出,NSCoder
不能String
直接工作,所以我應該在包裝符合NSCoding
類我的數據。所以這裏有一個小的類,它試圖做到這一點:
class DataThing: NSObject, NSCoding {
var message: String!
init(withMessage message: String) {
self.message = message
}
required convenience init?(coder aDecoder: NSCoder) {
self.init(withMessage: aDecoder.decodeObject(forKey: "message") as! String)
}
func encode(with aCoder: NSCoder) {
aCoder.encode(message, forKey: "message")
}
}
我可以使用此類數據寫入罰款:
let dataThing = DataThing(withMessage: str)
// Save message
let data = NSKeyedArchiver.archivedData(withRootObject: dataThing)
do {
try data.write(to: filePath)
} catch {
print("couldn't write file.")
}
然而,閱讀仍然不能正常工作:
if let loadedData = NSKeyedUnarchiver.unarchiveObject(withFile: filePath.absoluteString) as? DataThing {
outputLabel.text = loadedData.message
}
我誤解了'將數據包裝在課堂中'?
你是否已經介入調試器? – Paulw11
是的。它似乎正在成功寫入數據(沒有拋出異常),但是當我重建並運行應用程序時,'loadedMessage'字符串在本地變量查看器中寫有「無法讀取數據」。基於此,我認爲數據寫入方式存在問題(以至於以後無法讀取),或者讀取數據時出現問題。 – xander
我現在已經將'filePath'設置爲'URL(fileURLWithPath:「/ Users/Xander/Desktop」).appendingPathComponent(「message」)'來看看如果我試圖直接寫入我的桌面會發生什麼。它工作,並且該文件似乎包含數據。仍然沒有解除它的存檔... – xander