在Swift 3

时间:2018-01-14 23:15:42

标签: arrays xcode class swift3 local

我试图在xCode 8,Swift 3中保存名为Lokacija(英语:Location)的本地Array of Custom Class。

我尝试使用UserDefault保存它,但不幸的是它不能使用自定义类。所以我找到了这篇文章:http://ioscake.com/how-to-archive-and-unarchive-custom-objects-in-swift-or-how-to-save-custom-object-to-nsuserdefaults-in-swift.html。我尝试了两种解决方案,但它们都没有为我工作。 BTW文章是用Swift 2.x编写的,正如我所说我使用的是Swift 3,所以我不得不翻译它。

我首先尝试了这个:

    class Lokacija: NSObject, NSCoding {

        var _name : String
        var _address : String
        var _long : Double
        var _lat : Double

        init(name : String, address : String, lat : Double, long : Double) {
            _name = name
            _address = address
            _lat = lat
            _long = long
            //day month year
        }

        func encode(with aCoder: NSCoder) {
            print("ENCODINGGG!!!")
            aCoder.encode(_name, forKey: "name")
            aCoder.encode(_address, forKey: "address")
            aCoder.encode(_long, forKey: "long")
            aCoder.encode(_lat, forKey: "lat")
        }
    }


//in custom .swift "Utils"

static func saveLocations(lokacije: [Lokacija]) {
    let dataBlob = NSKeyedArchiver.archivedData(withRootObject: lokacije)

    UserDefaults.standard.set(dataBlob, forKey: "lista")
    UserDefaults.standard.synchronize()
}

static func loadLocations() -> [Lokacija]? {
    guard let decodedDataBlob = UserDefaults.standard.object(forKey: "lista") as? Data, let loadedLocations = NSKeyedUnarchiver.unarchiveObject(with: decodedDataBlob) as? [Lokacija] else {
        return nil
    }

    return loadedLocations
}


    //on action
lista.append(selectedLoc)
Utils.saveLocations(lokacije: lista)

//in view did load
    if let listaBase = Utils.loadLocations() {
        lista = listaBase
        self.plannerTable.reloadData()
        print(listaBase.count)
        print(lista.count)
    } else {
        print("PATKA MOREEE!!!")
    }

问题是它没有在listaBase中写任何东西,它是空的。 然后我尝试了第二个解决方案:

class Lokacija: NSObject, NSCoding {

    var _name : String
    var _address : String
    var _long : Double
    var _lat : Double

    init(name : String, address : String, lat : Double, long : Double) {
        _name = name
        _address = address
        _lat = lat
        _long = long
        //day month year
    }

    func encode(with aCoder: NSCoder) {
        print("ENCODINGGG!!!")
        aCoder.encode(_name, forKey: "name")
        aCoder.encode(_address, forKey: "address")
        aCoder.encode(_long, forKey: "long")
        aCoder.encode(_lat, forKey: "lat")
    }

    required convenience init?(coder aDecoder: NSCoder) {
        print("DECODEDDD!!!")
        guard let unName = aDecoder.decodeObject(forKey: "name") as? String, let unAddress = aDecoder.decodeObject(forKey: "address") as? String, let unLong = aDecoder.decodeObject(forKey: "long") as? Double, let unLat = aDecoder.decodeObject(forKey: "lat") as? Double
            else {
                return nil
        }
        self.init(name: unName, address: unAddress, lat: unLat, long: unLong)
    }

    private class func getFileUrl() -> NSURL {

        let documentsDirectory = FileManager().urls(for: (.documentDirectory), in: .userDomainMask).first!
        let archiveURL = documentsDirectory.appendingPathComponent("lista")

        return archiveURL as NSURL
    }

    class func saveLocations(locations: [Lokacija]){

        let success = NSKeyedArchiver.archiveRootObject(locations, toFile: Lokacija.getFileUrl().path!)
        if !success {
            print("failed to save")
        }

    }

    class func loadLocations() -> [Lokacija] {

        if let locBase = NSKeyedUnarchiver.unarchiveObject(withFile: Lokacija.getFileUrl().path!) as? [Lokacija] {
            return locBase
        }
        print("NIL")
        return [Lokacija]()
    }

}


//on action
    lista.append(selectedLoc)
    Lokacija.saveLocations(locations: lista)

    //on view did load      
    if Lokacija.loadLocations() != nil {
    let retrivedLocations = Lokacija.loadLocations()
    lista = retrivedLocations
    self.plannerTable.reloadData()
    print(retrivedLocations.count)
    print(lista.count)
}
else {
    print("FAILL!!!")
}

我遇到了完全相同的问题。

1 个答案:

答案 0 :(得分:0)

您解码Double值的方式存在问题。使用以下代码作为解码初始化程序,它将起作用:

required convenience init?(coder aDecoder: NSCoder) {
    print("DECODEDDD!!!")
    guard let unName = aDecoder.decodeObject(forKey: "name") as? String, let unAddress = aDecoder.decodeObject(forKey: "address") as? String else {
            return nil
    }

    let unLong = aDecoder.decodeDouble(forKey: "long")
    let unLat = aDecoder.decodeDouble(forKey: "lat")
    self.init(name: unName, address: unAddress, lat: unLat, long: unLong)
}