如何使用 Codable 处理 Coredata 中的重复条目

问题描述 投票:0回答:1

这个

init
函数每次都会插入一个新实体,即使
user_id
是相同的。

我该如何解决这个问题?我希望每个实体都只是一个具有 user_id 的实体。

我的代码是这样的:

public convenience init(from decoder: Decoder) throws {
    // Create NSEntityDescription with NSManagedObjectContext
    guard let contextUserInfoKey = CodingUserInfoKey.managedContext,
        let managedObjectContext = decoder.userInfo[contextUserInfoKey] as? NSManagedObjectContext,
        let entity = NSEntityDescription.entity(forEntityName: "User", in: managedObjectContext) else {
            fatalError("Failed to decode User!")
    }
    self.init(entity: entity, insertInto: managedObjectContext)

    let userInfo = try decoder.container(keyedBy: UserInfoKeys.self)
    username = try userInfo.decodeIfPresent(String.self, forKey: .username)
    user_id = try userInfo.decode(String.self, forKey: .user_id)
}
ios swift codable
1个回答
0
投票

我也遇到了同样的问题,我的解决方案基本上是在调用任何

init
之前执行重复检查,使用条件语句以 2 种方式对其进行
init
,具体取决于是否找到重复项。这是我的解决方案:

import Foundation
import CoreData

@objc(MyItem)
public class MyItem: NSManagedObject, Decodable {
    private enum CodingKeys: String, CodingKey {
        case id, value
    }

    required convenience public init(from decoder: Decoder) throws {
        guard let context = decoder.userInfo[.managedObjectContext] as? NSManagedObjectContext else {
            throw DecoderConfigurationError.missingManagedObjectContext
        }
        
        /// Check if a duplicate exists before the init
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let id = try container.decode(UUID.self, forKey: .id)
        let fetchRequest: NSFetchRequest<MyItem> = MyItem.fetchRequest()
        fetchRequest.predicate = NSPredicate(format: "id == %@", id as CVarArg)

        /// If duplicate is found, we insert it into nothing (nil)
        let existingItems = try context.fetch(fetchRequest)
        if let existingItem = existingItems.first {
            self.init(entity: .entity(forEntityName: "MyItem", in: context)!, insertInto: nil)
        } 
        
        /// Otherwise, we insert it into the current context
        else {
            self.init(context: context)
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.