我有一个要写入 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 []
}
}
这里是 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 中。我无法弄清楚这个问题,我对 Swift
和 XCode
编辑:我忘记提及的一件事是,我正在尝试用它创建一个插件。我所有的代码都在 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/