web-dev-qa-db-fra.com

Comment résoudre la dépréciation de unarchiveObject (withFile :)

Avec iOS 12.1, unarchiveObject(withFile:) était obsolète.
Comment pouvez-vous convertir NSKeyedUnarchiver.unarchiveObject(withFile: String) pour utiliser un appel à NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data: Data), ou NSKeyedUnarchiver.unarchivedObject(ofClasses: [AnyClass], À partir de: Données), ou NSKeyedUnarchiver.unarchivedObject(ofClass: NSCoding.Protocol, from: Data) ?

Je suppose que vous devez avoir quelque chose comme let fileData = try Data(contentsOf: URL) puis utiliser l'une de ces méthodes pour désarchiver les données. Mais, je ne peux pas le comprendre et la documentation accompagnant l'amortissement n'est pas utile (au moins pour moi).

Les données archivées sont plutôt simples - juste un tableau de chaînes (un tableau de classe NameToBeSaved tel que défini par ce code):

class NameToBeSaved: NSObject, NSCoding {
var name: String

init(userEnteredName: String) {
    self.name = userEnteredName
    super.init()
}

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

required init?(coder aDecoder: NSCoder) {
    name = aDecoder.decodeObject(forKey: "name") as! String
    super.init()
}

Voici le code appelant unarchiveObject (withFile :) -

init() {
    if let archivedCategoryNames = NSKeyedUnarchiver.unarchiveObject(withFile: categoryNameArchiveURL.path) as? [NameToBeSaved] {
        allCategories += archivedCategoryNames
    } else {
        for category in starterCategories {
            let thisNewCategory = NameToBeSaved(userEnteredName: category)
            createNewCategory(thisNewCategory)
        }
        sortCategories()
    }
}
11
Diskprotek

Je ne sais pas si c'est la meilleure solution, mais cela a résolu la conversion pour moi (ancien code commenté pour comparaison):

    init() {

    do {
        let rawdata = try Data(contentsOf: categoryNameArchiveURL)
        if let archivedCategoryNames = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(rawdata) as! [NameToBeSaved]? {
            allCategories += archivedCategoryNames
        }
    } catch {
        print("Couldn't read file")
        for category in starterCategories {
            let thisNewCategory = NameToBeSaved(userEnteredName: category)
            createNewCategory(thisNewCategory)
        }
        sortCategories()
    }

/*        if let archivedCategoryNames = NSKeyedUnarchiver.unarchiveObject(withFile: categoryNameArchiveURL.path) as? [NameToBeSaved] {
            allCategories += archivedCategoryNames
        } else {
            for category in starterCategories {
                let thisNewCategory = NameToBeSaved(userEnteredName: category)
                createNewCategory(thisNewCategory)
            }
            sortCategories()
        }
 */
}
4
Diskprotek

Problème: désarchivez un fichier sks pour l'utiliser comme SKEmitterNode.

ANCIENNE MÉTHODE, DÉCONSEILLÉE:

let filePath = Bundle.main.path(forResource: "myParticleEmitter", ofType: "sks")!
let burnerPathUnarchived = NSKeyedUnarchiver.unarchiveObject(withFile: burnerPath) as! SKEmitterNode

NOUVELLE MÉTHODE:

do {
    let fileURL = Bundle.main.url(forResource: "myParticleEmitter", withExtension: "sks")!
    let fileData = try Data(contentsOf: fileURL)
    let unarchivedData = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(burnerData) as! SKEmitterNode
} catch {
    print("didn't work")
}

Ensuite, vous pouvez faire:

mySKEffectNode.addChild(unarchivedData)
mySKSpriteNode.addChild(mySKEffectNode)
0
Saam Barrager