可编码的NSManagedObject失败,原因为ifcodeIfPresent数据类型 [英] Codable NSManagedObject fail on decodeIfPresent Data type

查看:113
本文介绍了可编码的NSManagedObject失败,原因为ifcodeIfPresent数据类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试解码此json时收到此错误:

I obtain this error when i'm trying to decode this json:

[{
    "id": "76f22c25-cee7-4c7a-94fa-1fb85720f580",
    "purchaseDate": "2012-04-05T19:03:43Z",
    "title": "azare",

}, {
    "id": "9b4b9f7d-382f-4555-9eaa-97939b13633f",
    "purchaseDate": "2012-04-05T19:02:46Z",
    "title": "Chocolat",

}, {
    "id": "02a0aa06-2d0c-4ab9-aaaa-af7dee7b4845",
    "purchaseDate": "2012-09-24T17:39:52Z",
    "title": "Some thing",
}]




致命错误: try!表达式意外引发错误:Swift.DecodingError.typeMismatch(Swift.Double,
Swift.DecodingError.Context(codingPath:[ Foundation。(
_12768CA107A31EF2DCE034FD75B541C9中的_JSONKey)(字符串值:索引0,intValue:可选(0)),MyApp.Purchase.CodingKeys.purchaseDate],
debugDescription:预期对Double进行解码,但找到一个字符串/数据
代替。,底层错误:无)):文件
/BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-900.0.69.2/src/swift/stdlib/public/core/ErrorType.swift,
第181

Fatal error: 'try!' expression unexpectedly raised an error: Swift.DecodingError.typeMismatch(Swift.Double, Swift.DecodingError.Context(codingPath: [Foundation.(_JSONKey in _12768CA107A31EF2DCE034FD75B541C9)(stringValue: "Index 0", intValue: Optional(0)), MyApp.Purchase.CodingKeys.purchaseDate], debugDescription: "Expected to decode Double but found a string/data instead.", underlyingError: nil)): file /BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-900.0.69.2/src/swift/stdlib/public/core/ErrorType.swift, line 181



My code:

//Purchase+CoreDataClass.swift
@objc(Purchase)
public class Purchase: NSManagedObject, Codable {

    enum CodingKeys: String, CodingKey {
        case id
        case title
        case purchaseDate
    }

required convenience public init(from decoder: Decoder) throws {

var context : NSManagedObjectContext = MyAppCoreDataManager.sharedInstance.persistentContainer.viewContext
        guard let entity = NSEntityDescription.entity(forEntityName: "Purchase", in: context!) else { fatalError() }

        self.init(entity: entity, insertInto: context!)
        let container = try decoder.container(keyedBy: CodingKeys.self)

        self.title = try container.decodeIfPresent(String.self, forKey: .title)
        self.id = try container.decodeIfPresent(String.self, forKey: .id)
        self.purchaseDate = try! container.decodeIfPresent(Date.self, forKey: .purchaseDate)

    }

    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(id, forKey: .id)
        try container.encode(title, forKey: .title)
try container.encode(purchaseDate, forKey: .purchaseDate)
}
}

//   Purchase+CoreDataProperties.swift

extension Purchase {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Purchase> {
        return NSFetchRequest<Purchase>(entityName: "Purchase")
    } 


    @NSManaged public var id: String?
    @NSManaged public var title: String?
    @NSManaged public var purchaseDate: Date?
}

//CALL

   let decoder = JSONDecoder()

                    decoder.dataDecodingStrategy = .base64
                    let purchases = try decoder.decode([Purchase].self, from: value)

If i remove "purchaseDate" everything works correctly


推荐答案

有一个普遍的误解,错误大约是 Date 而不是数据

There is a general misunderstanding, the error is about Date not Data

发生错误是因为JSON解码器默认不解码ISO8601日期。默认值为 TimeInterval aka Double

The error occurs because the JSON decoder does not decode ISO8601 dates by default. The default is a TimeInterval aka Double.

错误消息就是这样:它期望 Double ,但发现了 String

That's what the error message says: It expects a Double but found a String

您必须设置解码器的 DateDecodingStrategy .iso8601

You have to set the DateDecodingStrategy of the decoder to .iso8601

decoder.dateDecodingStrategy = .iso8601

并在 try中删除感叹号!移交错误

这篇关于可编码的NSManagedObject失败,原因为ifcodeIfPresent数据类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆