在循环中保存到核心数据

时间:2015-01-29 16:36:53

标签: ios swift core-data

我有一个我想写入CoreData的json对象列表。 Json对象来自API。我有一个方法将数据Upsert到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 []
    }
}

以下是SettingCoreDataModel createInManagedObjectContext

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()并没有帮助。

我在upsertSetting上致电application didFinishLaunchingWithOptions。在那之后,在我的第一个视图中,我尝试按键获取单个记录并在表视图中使用它:

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()无效。

1 个答案:

答案 0 :(得分: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 ?? ""