24

Swift 4.2 にアップグレードして以来、NSKeyedUnarchiver および NSKeyedArchiver メソッドの多くが非推奨になっていることがわかりましたstatic func unarchivedObject<DecodedObjectType>(ofClass: DecodedObjectType.Type, from: Data) -> DecodedObjectType?。データをアーカイブ解除するには type メソッドを使用する必要があります。

NSObject サブクラスである、特注のクラス WidgetData の配列を正常にアーカイブすることができました。

private static func archiveWidgetDataArray(widgetDataArray : [WidgetData]) -> NSData {

    guard let data = try? NSKeyedArchiver.archivedData(withRootObject: widgetDataArray as Array, requiringSecureCoding: false) as NSData
        else { fatalError("Can't encode data") }

    return data

}

このデータを解凍しようとすると、問題が発生します。

static func loadWidgetDataArray() -> [WidgetData]? {

    if isKeyPresentInUserDefaults(key: USER_DEFAULTS_KEY_WIDGET_DATA) {

        if let unarchivedObject = UserDefaults.standard.object(forKey: USER_DEFAULTS_KEY_WIDGET_DATA) as? Data {

            //THIS FUNCTION HAS NOW BEEN DEPRECATED:
            //return NSKeyedUnarchiver.unarchiveObject(with: unarchivedObject as Data) as? [WidgetData]

            guard let nsArray = try? NSKeyedUnarchiver.unarchivedObject(ofClass: NSArray.self, from: unarchivedObject as Data) else {
                fatalError("loadWidgetDataArray - Can't encode data")
            }

            guard let array = nsArray as? Array<WidgetData> else {
                fatalError("loadWidgetDataArray - Can't get Array")
            }

            return array

        }

    }

    return nil

}

ただし、Array.self代わりに使用することNSArray.selfは許可されていないため、これは失敗します。私は何を間違っていますか?また、これを修正してアレイをアンアーカイブするにはどうすればよいですか?

4

6 に答える 6

39

unarchiveTopLevelObjectWithData(_:)によってアーカイブされたデータを解凍するために使用できますarchivedData(withRootObject:requiringSecureCoding:)。(これはまだ廃止されていないと思います。)

ただし、コードを表示する前に、次のことをお勧めします。

  • の使用は避け、代わりNSDataに使用してくださいData

  • try?デバッグに役立つエラー情報を破棄するのを使用しないでください

  • 不要なキャストをすべて削除


これを試して:

private static func archiveWidgetDataArray(widgetDataArray : [WidgetData]) -> Data {
    do {
        let data = try NSKeyedArchiver.archivedData(withRootObject: widgetDataArray, requiringSecureCoding: false)

        return data
    } catch {
        fatalError("Can't encode data: \(error)")
    }

}

static func loadWidgetDataArray() -> [WidgetData]? {
    guard
        isKeyPresentInUserDefaults(key: USER_DEFAULTS_KEY_WIDGET_DATA), //<- Do you really need this line?
        let unarchivedObject = UserDefaults.standard.data(forKey: USER_DEFAULTS_KEY_WIDGET_DATA)
    else {
        return nil
    }
    do {
        guard let array = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(unarchivedObject) as? [WidgetData] else {
            fatalError("loadWidgetDataArray - Can't get Array")
        }
        return array
    } catch {
        fatalError("loadWidgetDataArray - Can't encode data: \(error)")
    }
}

ただし、新しいアプリを作成している場合は、使用を検討することをお勧めしますCodable

于 2018-07-23T22:40:31.167 に答える