NSKeyedUnarchiver, кажется, ничего не читает - PullRequest
0 голосов
/ 05 апреля 2020

Я пытаюсь написать массив объектов, используя NSKeyedArchiver.

Вот некоторые части из моего кода:

EventStore.swift - удержание массива событий:

class EventStore{

    private var events: [EventItem] = [EventItem]()
    static let sharedStore = EventStore()

    private init() {
    }


    static func getEventFile() -> URL{
        let directory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
        let file = directory.appendingPathComponent("events.bin")
        return file
    }

    func addEvent(withEvent event:EventItem){
        events.append(event)
    }

    func getEvents()->[EventItem]{
        return events
    }

}

Нет eventItem, где я реализовал NSCoding:

class EventItem: NSObject, NSCoding {

    private var id:Int
    private var timestamp:Int64

    //Object initialization
    init(withId id:Int,withTimestamp timestamp:Int64) {
        self.id = id
        self.timestamp = timestamp
    }

    required convenience init?(coder: NSCoder) {
        //get value from stored key if exists
        guard let id = coder.decodeObject(forKey: "id") as? Int,
            let timestamp = coder.decodeObject(forKey: "timestamp") as? Int64

        //exit init after decoding if a value is missing
        else {
            NSLog("Unable to decode event")
            return nil
        }

        self.init(withId:id,withTimestamp:timestamp)
    }

    func getId()->Int{
        return id
    }

    func getTimestamp()->Int64{
        return timestamp
    }

    //encode values to keys
    func encode(with aCoder: NSCoder) {
        NSLog("Encoding event")
        aCoder.encode(id, forKey: "id")
        aCoder.encode(timestamp, forKey: "timestamp")
    }

}

Наконец, когда пользователь записывает на ленту кнопку, я добавляю событие в массив и сохраняю его:

var eventStore = EventStore.sharedStore

    @IBAction func TakeAction() {

        //generate new event
        let timestamp = Int64(NSDate().timeIntervalSince1970 * 1000)
        let newEvent = EventItem(withId: eventStore.eventCount(), withTimestamp: timestamp)
        eventStore.addEvent(withEvent: newEvent)
        saveEvents()

        //refresh ui
        updateTakeText()

    }

    func saveEvents(){
           do{
               let data = try NSKeyedArchiver.archivedData(withRootObject: eventStore.getEvents(), requiringSecureCoding: false)
               NSLog("Data being written : \(data)")
               try data.write(to: EventStore.getEventFile())
               NSLog("Write events to file :\(EventStore.getEventFile())")
           }catch{
               NSLog(error.localizedDescription)
           }
       }

       func loadEvents() {
           do{
               let data = try Data(contentsOf: EventStore.getEventFile())
               NSLog("Data loaded from file path: \(data)")

               //try get data else return empty array
               let events = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? [EventItem] ?? [EventItem]()
               NSLog("Events retrived from file: \(events.count)")
               eventStore.setEvents(withEvents:events)
           }catch{
               NSLog(error.localizedDescription)
           }
       }

Я добавил много отладки, и кажется, что кодирование и запись в файл работают нормально, но декодирование не удалось. Он всегда получает ноль значений.

Любая подсказка?

Заранее спасибо

1 Ответ

0 голосов
/ 05 апреля 2020

При кодировании значений Int вы должны декодировать их с помощью coder.decodeInteger (forKey: "xxx")

...