Codable NSManagedObject 在 decodeIfPresent 数据类型上失败
Codable NSManagedObject fail on decodeIfPresent Data type
我在尝试解码时收到此错误 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",
}]
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
而不是Data
错误发生是因为JSON解码器默认不解码ISO8601日期。默认值是 TimeInterval
又名 Double
。
这就是错误消息所说的内容:它需要一个 Double
但找到了一个 String
您必须将解码器的 DateDecodingStrategy
设置为 .iso8601
decoder.dateDecodingStrategy = .iso8601
并去掉try!
中的感叹号交错
我在尝试解码时收到此错误 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",
}]
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
而不是Data
错误发生是因为JSON解码器默认不解码ISO8601日期。默认值是 TimeInterval
又名 Double
。
这就是错误消息所说的内容:它需要一个 Double
但找到了一个 String
您必须将解码器的 DateDecodingStrategy
设置为 .iso8601
decoder.dateDecodingStrategy = .iso8601
并去掉try!
中的感叹号交错