ios - 循环保存到CoreData

标签 ios swift core-data

我有一个要写入 CoreData 的 json 对象列表。 Json 对象来自 API。我有一种方法可以将数据更新到 CoreData 中。其代码如下。

public class func upsertSetting (resultsArr : NSArray, settingTypeId: Int, countryId: Int) {
    if let moc = CoreDataHelper().managedObjectContext {

        var settings : [Setting]
        settings = resultsArr as [Setting]

        var existingSettings : [SettingCoreDataModel]?
        existingSettings = fetchAllSettings(settingTypeId, countryId: countryId)

        for result in settings {

            var key = result.key
            var value = result.value
            if (value == nil)
            {
                value = ""
            }

            var id = result.id
            var settingTypeId = result.settingTypeId
            var countryId = result.countryId



            var settingCoreData: [SettingCoreDataModel]?
            var existingSetting: SettingCoreDataModel?

            if(existingSettings? == nil){
                existingSetting = nil
            }
            else{
                settingCoreData = filter(existingSettings!) { (e:SettingCoreDataModel) in e.key == key }
                if(settingCoreData? != nil && settingCoreData?.count > 0){
                existingSetting = settingCoreData?.first
                }
            }
            if(existingSetting == nil){                    
                SettingCoreDataModel.createInManagedObjectContext(moc, key: key!, value: value!, id: id!, settingTypeId: settingTypeId!, countryId: countryId!)
            }
            else if(existingSetting?.value != value!){
                existingSetting?.value = value!
                save()
            }
        }
    }
}

public class func save() {
    var error : NSError?
    if !CoreDataHelper().managedObjectContext!.save(&error) {
       println("Could not save \(error), \(error?.userInfo)")
    }
}

fetchAllSettings 看起来像这样:

public class func fetchAllSettings (settingTypeId: Int, countryId: Int) -> [SettingCoreDataModel]?
{
    let fetchRequest = NSFetchRequest(entityName: "SettingCoreDataModel")

    let predicate = NSPredicate(format: "settingTypeId == %d AND countryId == %d", settingTypeId, countryId)

    fetchRequest.predicate = predicate

    if let fetchResults = CoreDataHelper().managedObjectContext!.executeFetchRequest(fetchRequest, error: nil) as? [SettingCoreDataModel] {
        return fetchResults
    }
    else{
        return []
    }
}

这里是 SettingCoreDataModelcreateInManagedObjectContext :

public class SettingCoreDataModel: NSManagedObject {

@NSManaged var key: String
@NSManaged var value: String
@NSManaged var id: NSNumber
@NSManaged var settingTypeId: NSNumber
@NSManaged var countryId: NSNumber

class func createInManagedObjectContext(moc: NSManagedObjectContext, key: NSString, value: NSString, id: int, settingTypeId: int, countryId: int) -> SettingCoreDataModel {
        let newItem = NSEntityDescription.insertNewObjectForEntityForName("SettingCoreDataModel", inManagedObjectContext: moc) as? SettingCoreDataModel
        newItem?.key = key
        newItem?.value = value
        newItem?.id = id
        newItem?.settingTypeId = settingTypeId
        newItem?.countryId = countryId

        return newItem!
    }
}

我的问题是,当我调用 createInManagedObjectContext 时,它似乎没有保存到 CoreData 中。我无法弄清楚这个问题,我对 SwiftXCode

还很陌生

编辑:我忘记提及的一件事是,我正在尝试用它创建一个插件。我所有的代码都在 Pod 中,但我的数据模型在示例项目中。我不确定这是否有任何不同,但在获取和一切似乎工作正常。

顺便说一下,使用 save() 也没有帮助。

我在 application didFinishLaunchingWithOptions 上调用了 upsertSetting。之后,在我的第一个 View 中,我尝试按键获取单个记录并在 TableView 中使用它:

var textColorSetting: Setting?   
override func viewDidLoad() {
    super.viewDidLoad()
textColorSetting = SettingCoreData.fetchSetting("text_color", countryId: 3)
}

表格单元格:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier(kCellIdentifier) as UITableViewCell

    textColorSetting = SettingCoreData.fetchSetting("text_color", countryId: 3)

   var textColor = textColorSetting?.value

    if (textColor? == nil){
        textColor = "#ff00ff"
    }
    let color = SettingCoreDataModel.hexStringToUIColor(textColor!)
    cell.textLabel?.textColor = color
}

获取单个设置:

public class func fetchSetting(key : NSString, countryId: Int) -> Setting? {

    let fetchRequest = NSFetchRequest(entityName: "SettingCoreDataModel")

    var existingSetting: SettingCoreDataModel?

    let predicate = NSPredicate(format: "key == %@ AND countryId == %d", key, countryId)

    fetchRequest.predicate = predicate

    var error: NSError?

    if let fetchResults = CoreDataHelper().managedObjectContext!.executeFetchRequest(fetchRequest, error: &error) as? [SettingCoreDataModel] {
        println(fetchResults.count)
        if (!fetchResults.isEmpty && fetchResults.count > 0) {
            existingSetting = fetchResults.first!
            var setting: Setting?
            setting?.id = existingSetting?.id as? Int
            setting?.key = existingSetting?.key
            setting?.value = existingSetting?.value
            setting?.settingTypeId = existingSetting?.settingTypeId as? Int
            setting?.countryId = existingSetting?.countryId as? Int
            return setting
        } else {
            return nil
        }
    } else {
        return nil
    }
}

这里 println(fetchResults.count) 总是打印 0。这就是为什么我认为 save() 不工作的原因。

最佳答案

在创建新设置的情况下,您需要调用保存(或者更好的是,将保存从循环内部取出并在循环后调用一次)

if(existingSetting == nil){                    
    SettingCoreDataModel.createInManagedObjectContext(moc, key: key!, value: value!, id: id!, settingTypeId: settingTypeId!, countryId: countryId!)
    save()    // this is missing
}

一些其他的观察和简化:

fetchAllSettings 将始终返回一个有效的设置数组(可能为空),将其声明为 -> [SettingCoreDataModel] 而不是将其声明为可选:

public class func fetchAllSettings (settingTypeId: Int, countryId: Int) -> [SettingCoreDataModel]

var existingSettings = fetchAllSettings(settingTypeId, countryId: countryId)

完成后,您可以使用首先返回可选的事实来简化查找现有设置的逻辑:

var existingSetting = existingSettings.filter({ (e:SettingCoreDataModel) in e.key == key }).first

要确保该值始终具有有效值,因此您不必担心解包它,请使用 nil 检查:

var value = result.value ?? ""

关于ios - 循环保存到CoreData,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28219874/

相关文章:

Swift 字典键类型

SwiftUI RoundedRectangle 在底部被切除

ios - CoreData 异步获取导致并发调试器错误

ios - iPhone SDK : GameKit and large files + connection lost

Swift 协议(protocol) : Why does the compiler complain that my class doesn't conform to a protocol?

ios - 视网膜显示屏图像看起来模糊不清。没有理由为什么?

cocoa-touch - 如何检查 NSManagedObject 子类在运行时是否存在属性

objective-c - 为什么 NSArrayController "losing"在插入对象后是它的排序?

ios - 快速使用 obj-c 类。运行但给出未声明的类型错误

ios恢复谷歌地图sdk GMSMapsView的状态