我正在使用下面的块引用中提到的谓词执行获取请求,但我似乎得到了#34;逻辑错误的获取请求"。这条消息意味着什么,我应该采取什么步骤来找到问题并解决它?
注释:逻辑错误的获取请求(实体:国家;谓词:(" alpha3Code" ==" KOR"); sortDescriptors:((null)); type:NSManagedObjectResultType;)短路。
以下是我从
获取错误的代码let record = Currency.fetch(id: currency)[0] as! Currency
其中Currency类如下。 "取"在NSManagedObjectProtocol trait中实现
public class Currency: NSManagedObject, NSManagedObjectProtocol, XMLImporterDelegate {
private static let attributes = ["name", "currency", "decimalUnit", "isUsed"]
private static let xmlRecordTag = "CcyNtry"
private static let xmlAttributeTags = ["CcyNm": attributes[0],
"Ccy": attributes[1],
"CcyMnrUnts": attributes[2]]
static func setValue(managedObject: NSManagedObjectProtocol, object: Dictionary<String, Any>) {
let currency = managedObject as! Currency
currency.name = getString(from: object, withKeyValue: attributes[0])
currency.currency = getString(from: object, withKeyValue: attributes[1])
currency.decimalUnit = getInt16(from: object, withKeyValue: attributes[2])
currency.isUsed = getBool(from: object, withKeyValue: attributes[3])
return
}
static func getPredicates(forID id: Dictionary<String, Any>) -> [NSPredicate] {
var predicates: [NSPredicate] = []
predicates.append(NSPredicate.init(format: "%@ = %@", attributes[1], getString(from: id, withKeyValue: attributes[1])))
return predicates
}
func isEqual(object: NSManagedObjectProtocol) -> Bool {
if let object = object as? Currency {
if object.currency == self.currency { return false }
return true
} else {
return false
}
}
static func recordTag() -> String {
return xmlRecordTag
}
static func attribute(byTag tag: String) -> String? {
return xmlAttributeTags[tag]
}
static func getUsed() -> [Any]?{
var predicates: [NSPredicate] = []
predicates.append(NSPredicate.init(format: "%@ = %@", attributes[3], NSNumber(booleanLiteral: false)))
return fetch(predicates: predicates)
}
}
NSManagedObjectProtocol具有以下特征
extension NSManagedObjectProtocol {
public static func add(from objectValue: Dictionary<String, Any>) -> NSManagedObjectProtocol? {
let exists = fetch(id: objectValue)
if exists.count > 0 {
NSLog("Object already exists in CoreData : %@", objectValue.description)
return nil
} else {
return newObject(object: objectValue)
}
}
public static func addOrChange(from object: Dictionary<String, Any>) -> NSManagedObjectProtocol {
let exists = fetch(id: object)
if exists.count > 0 {
// TODO: confirm if data needs to be changed rather than delete and insert
}
delete(id: object)
return add(from: object)!
}
public static func getString(from object: Dictionary<String, Any>, withKeyValue key: String) -> String {
return object[key] as! String
}
public static func getInt16(from object: Dictionary<String, Any>, withKeyValue key: String) -> Int16 {
if let stringValue = object[key] as? String {
if let intValue = Int(stringValue) {
return Int16(intValue)
} else {
return 0
}
} else if let intValue = object[key] as? Int {
return Int16(intValue)
} else {
return 0
}
}
public static func getBool(from object: Dictionary<String, Any>, withKeyValue key: String) -> Bool {
if let boolValue = object[key] as? Bool {
return boolValue
} else {
return false
}
}
public static func fetch(predicates: [NSPredicate] = [], sortDescriptors: [NSSortDescriptor] = []) -> [Any] {
let request = Self.request(predicates: predicates)
do {
return try CoreDataHelper.getCoreDataHelper().context.fetch(request)
} catch {
return []
}
}
public static func fetch(id: Dictionary<String, Any>) -> [Any] {
return Self.fetch(predicates: Self.getPredicates(forID: id))
}
public static func delete(predicates: [NSPredicate] = []) {
let context = CoreDataHelper.getContext()
let fetchRequest = request(predicates: predicates)
let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
do {
try context.execute(deleteRequest)
CoreDataHelper.getCoreDataHelper().saveContext()
} catch {
NSLog("Delete request failed")
return
}
}
public static func delete(id: Dictionary<String, Any>) {
delete(predicates: getPredicates(forID: id))
}
// MARK: - Private API
private static func newObject(object: Dictionary<String, Any>) -> NSManagedObjectProtocol {
let entityName = String(describing: self)
let context = CoreDataHelper.getContext()
let managedObject = NSEntityDescription.insertNewObject(forEntityName: entityName, into: context) as! NSManagedObjectProtocol
setValue(managedObject: managedObject, object: object)
CoreDataHelper.getCoreDataHelper().saveContext()
return managedObject
}
private static func request(predicates: [NSPredicate] = [], sortDescriptors: [NSSortDescriptor] = []) -> NSFetchRequest<NSFetchRequestResult> {
// Prepare a request
let entityName = String(describing: self)
let classObject: AnyClass! = NSClassFromString(entityName)
let objectType: NSManagedObject.Type = classObject as! NSManagedObject.Type!
let request: NSFetchRequest<NSFetchRequestResult> = objectType.fetchRequest()
// Add predicates
if predicates.count > 0 {
request.predicate = NSCompoundPredicate.init(andPredicateWithSubpredicates: predicates)
}
// Add sortDescriptors
if sortDescriptors.count > 0 {
request.sortDescriptors = sortDescriptors
}
return request
}
}
最后,这就是CoreDataHelper的样子。
class CoreDataHelper: NSObject {
var context: NSManagedObjectContext!
var model: NSManagedObjectModel!
var coordinator: NSPersistentStoreCoordinator!
var store: NSPersistentStore!
let storeFilename = "Accounting.sqlite"
func setupCoreData() {
self.loadStore()
}
func saveContext() {
if (self.context.hasChanges) {
do {
try context.save()
} catch {
}
}
}
func applicationDocumentDictionary() -> String {
let directory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).last!
NSLog("SQLite Directory : %@", directory)
return directory
}
func applicationStoresDirectory() -> URL {
let storesDirectory = URL.init(fileURLWithPath: self.applicationDocumentDictionary()).appendingPathComponent("Stores")
let fileManager = FileManager.default
if (!fileManager.fileExists(atPath: storesDirectory.path)) {
do {
try fileManager.createDirectory(at: storesDirectory,
withIntermediateDirectories: true,
attributes: nil)
} catch {
}
}
return storesDirectory
}
func storesURL() -> URL {
return self.applicationStoresDirectory().appendingPathComponent(storeFilename)
}
override init() {
super.init()
model = NSManagedObjectModel.mergedModel(from: nil)
coordinator = NSPersistentStoreCoordinator(managedObjectModel: model)
context = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
context.persistentStoreCoordinator = coordinator
}
func loadStore() {
if (store != nil) {
return
} else {
do {
try store = coordinator.addPersistentStore(ofType: NSSQLiteStoreType,
configurationName: nil,
at: self.storesURL(),
options: nil)
} catch {
}
}
}
static func getCoreDataHelper() -> CoreDataHelper {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
return appDelegate.coreDataHelper
}
static func getContext() -> NSManagedObjectContext {
return getCoreDataHelper().context
}
}
只是为了让你知道Country类有alpha3Code。
extension Country {
@nonobjc public class func fetchRequest() -> NSFetchRequest<Country> {
return NSFetchRequest<Country>(entityName: "Country");
}
@NSManaged public var englishName: String?
@NSManaged public var frenchName: String?
@NSManaged public var alpha2Code: String?
@NSManaged public var alpha3Code: String?
@NSManaged public var countryNumber: Int16
}
答案 0 :(得分:2)
使用建议的格式说明符%K
作为密钥(路径)而非%@
,如Predicate Documentation
predicates.append(NSPredicate.init(format: "%K = %@", attributes[1], getString(from: id, withKeyValue: attributes[1])))