2017-03-20 3 views
0

Swift 3에서 NSkeyed 아카이브로 저장된 개체를 검색 할 수 없으며 머리를 스크래치하고 있습니다. 개체가 성공적으로 PLIST로 저장하지만, 다시로드 할 때 전무로 반환됩니다 여기 Swift3에서 올바르게 저장된 NSKeyArchived 개체를 검색 할 수 없습니다.

내가 사용하는 코드입니다.

클래스 자체를 객체로 저장하는 매우 간단합니다 :

import Foundation 

class ItemList:NSObject, NSCoding { 

    var name: String = "" //Name of the Item list 
    var contents: [Int] = [] //Ints referencing the CoreData PackItems 

    init (listname:String, ContentItems:[Int]) { 
     self.name=listname 
     self.contents=ContentItems 
    } 

    //MARK: NSCoding 
    public convenience required init?(coder aDecoder: NSCoder) { 
     let thename = aDecoder.decodeObject(forKey: "name") as! String 
     let thecontents = aDecoder.decodeObject(forKey: "contents") as! [Int] 
     self.init(listname: thename,ContentItems: thecontents) 
    } 

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

} 

로드하고 객체 저장 코드 : 마지막으로

class FileHandler: NSObject { 

    class func getDocumentsDirectory() -> URL { 
     let filemgr = FileManager.default 
     let urls = filemgr.urls(for: .documentDirectory, in: .userDomainMask) 
     let result:URL = urls.first! 
     return result 
    } 

    ///This returns the contents of the handed file inside the Documents directory as the object it was saved as. 
    class func getFileAsObject(filename:String) -> AnyObject? { 

     let path = getDocumentsDirectory().appendingPathComponent(filename) 

     if let result = NSKeyedUnarchiver.unarchiveObject(withFile: path.absoluteString) { 
      //Success 
      print("Loaded file '"+filename+"' from storage") 
      return result as AnyObject? 
     } else { 
      print("Error: Couldn't find requested object '"+filename+"' in storage at "+path.absoluteString) 
      return nil 
     } 
    } 

    ///This saves the handed object under the given filename in the App's Documents directory. 
    class func saveObjectAsFile(filename:String, Object:AnyObject) { 
     let data = NSKeyedArchiver.archivedData(withRootObject: Object) 
     let fullPath = getDocumentsDirectory().appendingPathComponent(filename) 

     do { 
      try data.write(to: fullPath) 
      print("Wrote file '"+filename+"' to storage at "+fullPath.absoluteString) 
     } catch { 
      print("Error: Couldn't write file '"+filename+"' to storage") 
     } 
    } 

} 

을 ... 그리고, 이것은 내가 모두를 호출 할 것입니다 :

그래서 내가 (그리고 확인했다) 파일이 제대로 만들어 졌는지 -이 내 자신의 출력입니다

Wrote file 'Test.plist' to storage at file:///…/data/Containers/Data/Application/6747B038-B0F7-4B77-85A8-9EA02BC574FE/Documents/Test.plist 
Error: Couldn't find requested object 'Test.plist' in storage at file:///…/data/Containers/Data/Application/6747B038-B0F7-4B77-85A8-9EA02BC574FE/Documents/Test.plist 

참고 : 617,451,515,

let testobject:ItemList = ItemList.init(listname: "testlist", ContentItems: [0,0,1,2]) 

     FileHandler.saveObjectAsFile(filename:"Test.plist",Object:testobject) 
     let tobi = FileHandler.getFileAsObject(filename:"Test.plist") as! ItemList 

아아, 나는 출력으로이 얻을. 그러나 그것은 단지 적재되지 않을 것입니다. 아무도 내가 뭘 잘못하고 있다고 말할 수 있습니까?

답변

2

문제는 unarchiveObject(withFile:)에 전달하는 경로입니다.

변경 :

if let result = NSKeyedUnarchiver.unarchiveObject(withFile: path.absoluteString) { 

에 :

if let result = NSKeyedUnarchiver.unarchiveObject(withFile: path.path) { 

보조 노트에, 당신은 당신의 쓰기와 읽기 로직 대칭 API를 사용합니다. 데이터를 쓸 때 Data 개체에 루트 개체를 보관 한 다음 Data 개체를 파일에 씁니다. 하지만 읽을 때 파일 경로가 주어지면 오브젝트 트리를 직접 아카이브 해제하십시오.

쓰기 코드를 archiveRootObject(_:toFile:)으로 변경하거나 파일에서 Data을로드하도록 읽는 코드를 변경 한 다음 데이터의 보관을 취소하십시오. 현재 코드가 작동하지만 (일단 경로 문제를 수정하면) 일관성이 없습니다.

+0

감사합니다. Maddy, 이것은 우수하고 간결한 답변이었습니다! – Averett

관련 문제