我有一个名为NoteEntity的核心数据实体(类型).它有一个名为noteDocument的托管变量,它是自定义类型NoteDocument(我的NSDocument的子类).我更改了自动生成的NoteEntity核心数据属性类,以便进行读取
import Foundation import CoreData extension NoteEntity { @NSManaged var noteDocument: NoteDocument? // changed @NSManaged var belongsTo: NSSet? }
因此noteDocument的类型为NoteDocument而不是NSObject. NoteDocument类确实实现了NSCoding,如下所示:
required convenience init(coder theDecoder: NSCoder) { let retrievedURL = theDecoder.decodeObjectForKey("URLKey") as! NSURL self.init(receivedURL: retrievedURL) } func encodeWithCoder(theCoder: NSCoder) { theCoder.encodeObject(fileURL, forKey: "URLKey") }
我希望能够做的是在托管上下文中找到具有给定noteDocument值的noteEntity实体.所以我运行这段代码(传递一个参数theNote,对应于我知道在托管上下文中存在的noteDocument):
var request = NSFetchRequest(entityName: "NoteEntity") let notePredicate = NSPredicate(format: "noteDocument == %@", theNote) request.predicate = notePredicate print("Text in the NoteEntity with the NoteDocument for "+theNote.filename+":") do { let notesGathered = try context.executeFetchRequest(request) as? [NoteEntity] for n in notesGathered! { print (n.noteDocument!.filename) print (n.noteDocument!.noteText) } } catch let error as NSError { print("Could not run fetch request. \(error), \(error.userInfo)") }
但它不返回任何条目.如果我注释掉谓词,我会在数据库中获得所有NoteEntity值,但是在那里使用谓词我什么也得不到.很明显,我在谓词中尝试做的搜索有问题.我认为这是因为价值是可转换的,但我不知道从那里去哪里.我知道你不能对Transformable数组的成员运行获取请求,但是不可能在单个Transformable属性上运行获取请求吗?如果不是,还有哪些替代方案?
编辑:NoteDocument类包含的不仅仅是NSCoding.正如我所说,它是一个NSDocument子类. NSCoding使用URL作为其键,因为它是NoteDocument类的“主键” – 它是初始化类的内容.这是本课程的其余部分,不包括上面的NSCoding:
import Cocoa class NoteDocument: NSDocument, NSCoding { var filename: String var noteText: String var attributes: NSDictionary? var dateCreated: NSDate? var dateString: String? init (receivedURL: NSURL) { self.filename = "" self.noteText = "" super.init() self.fileType = "net.daringfireball.markdown" self.fileURL = receivedURL // Try to get attributes, most importantly date-created. let fileManager = NSFileManager.defaultManager() do { attributes = try fileManager.attributesOfItemAtPath(fileURL!.path!) } catch let error as NSError { print("The error was: "+String(error)) } if let dateCreated = attributes?.fileCreationDate() { // print("dateCreated is "+String(dateCreated!)) // Format the date-created to an appropriate string. dateString = String(dateCreated) } else { print("Did not find the attributes for "+filename) } if let name = self.fileURL?.lastPathComponent { filename = name } else { filename = "Unnamed File" } noteText = "" do { noteText = try NSString(contentsOfURL: self.fileURL!, encoding: NSUTF8StringEncoding) as String } catch let error as NSError { print("Error trying to get note file:"+String(error)) } } // MARK: - Document functions override class func autosavesInPlace() -> Bool { // print ("autosavesInPlace ran.") return true } override func dataOfType(typeName: String) throws -> NSData { var outError: NSError! = NSError(domain: "Migrator", code: 0, userInfo: nil) // Post: Document is saved to a file specified by the user. outError = NSError(domain: NSOSStatusErrorDomain, code: unimpErr, userInfo: nil) if let value = self.noteText.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) { // Convert noteText to an NSData object and return that. return value } print("dataOfType ran.") throw outError } override func readFromData(data: NSData, ofType typeName: String) throws { // Currently unused; came free with NSDocument. throw NSError(domain: NSOSStatusErrorDomain, code: unimpErr, userInfo: nil) } }在代码中,您显示您编写的唯一内容是URL.在这种情况下,它更有意义,并提供更多实用程序来在实体中使用普通字符串来存储URL并为文档添加瞬态属性(或创建包装类来组合实体和文档).通过这种方式,您可以在谓词中使用URL,并且可以轻松地从文档构建谓词.将文档存储为可转换文件并不会以任何方式帮助您.