在设备上本地保存自定义类的数组

时间:2018-01-04 08:05:15

标签: arrays swift nsuserdefaults nskeyedarchiver

我有一个自定义类,可用作数组的模型。他们的数组元素来自使用 Alamofire 的API。 应用程序的用户可以从桌面视图中保存阵列的某些元素,即使他们没有互联网也能显示。我试图使用用户默认值但是收到错误。

数组的自定义类

class LatestNews {

    private var _id : Int!
    private var _link : Int!
    private var _category : String!
    private var _tag : String!
    private var _headline : String!
    private var _story : String!

    var latestNews : LatestNews!
    var latest = [LatestNews]()

    var id : Int {
        if _id == nil {
            _id = 0
        }
        return _id
    }

    var link : Int {
        if _link == nil {
            _link = 0
        }
        return _link
    }

    var category : String {
        if _category == nil {
            _category = ""
        }
        return _category
    }

    var tag : String {
        if _tag == nil {
            _tag = ""
        }
        return _tag
    }

    var headline : String {
        if _headline == nil {
            _headline = ""
        }
        return _headline
    }

    var story : String {
        if _story == nil {
            _story = ""
        }
        return _story

    init(getLatest : [String: Any]) {

        if let id = getLatest["id"] as? Int {
            self._id = id
        }

        if let link = getLatest["link"] as? Int {
            self._link = link
        }

        if let category = getLatest["category"] as? String {
            self._category = category
        }

        if let tag = getLatest["tag"] as? String {
            self._tag = tag
        }

        if let headline = getLatest["headline"] as? String {
            self._headline = headline
        }

        if let story = getLatest["story"] as? String {
            self._story = story
        }
    }

}

UserDefaults功能

func transferOfflineData(news: [LatestNews]) {
        self.offlineData = news

        if UserDefaults.standard.object(forKey: "OfflineData") == nil {
            let encodedData: Data = NSKeyedArchiver.archivedData(withRootObject: self.offlineData)
            UserDefaults.standard.set(encodedData, forKey: "OfflineData")
            UserDefaults.standard.synchronize()
        } else {
            self.prevOfflineData = UserDefaults.standard.object(forKey: "OfflineData") as! [LatestNews]
            self.prevOfflineData.append(offlineData.first!)
            let encodedData: Data = NSKeyedArchiver.archivedData(withRootObject: self.prevOfflineData)
            UserDefaults.standard.set(encodedData, forKey: "OfflineData")
            UserDefaults.standard.synchronize()
        }
    }

我遇到错误

2018-01-04 00:26:54.967563+0530 Khabar7[74210:3333998] *** NSForwarding: warning: object 0x7f7f0ee0c0b0 of class 'Khabar7.LatestNews' does not implement methodSignatureForSelector: -- trouble ahead
Unrecognized selector -[Khabar7.LatestNews replacementObjectForKeyedArchiver:]
2018-01-04 00:26:54.970076+0530 Khabar7[74210:3333998] Unrecognized selector -[Khabar7.LatestNews replacementObjectForKeyedArchiver:]

请告诉我,如果有更好的方法可以解决这个问题,或者我做错了什么,我可以改进我的代码。

1 个答案:

答案 0 :(得分:2)

要使用NSKeyedArchiver,您的班级必须从NSObject继承,并且必须采用NSCoding。由于所有属性都符合属性列表,因此我更喜欢JSONSerializationPropertyListSerialization

如果您使用的是Swift 4,Codable协议提供了一种非常方便的方法来序列化类和结构,而无需继承NSObject

旁注:

获取只读变量(也就是常量)的私有后备变量在Swift中是荒谬的。将常量声明为let并忘记带有前导下划线的objective-c-ish实例变量。

你班级的Swift方式是

class LatestNews {

    let id: Int
    let link: Int
    let category: String
    let tag: String
    let headline: String
    let story: String

    var latestNews: LatestNews!
    var latest = [LatestNews]()

    init(dictionary: [String: Any]) {
        id = dictionary["id"] as? Int ?? 0
        link = dictionary["link"] as? Int ?? 0
        category = dictionary["category"] as? String ?? ""
        tag = dictionary["tag"] as? String ?? ""
        headline = dictionary["headline"]  as? String ?? ""
        story = dictionary["story"] as? String ?? ""
    }
}