2016-07-24 2 views
4

У меня есть объект (тип) Core Data, называемый NoteEntity. Он имеет управляемую переменную, называемую noteDocument, которая имеет тип NotesDocument (мой подкласс NSDocument). Я изменил автоматически сгенерированный класс NoteEntity + Основные свойства данных, так что читаетЗапрос на выбор одного атрибута Transformable (Swift)

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") 
} 

То, что я хочу быть в состоянии сделать, это найти noteEntity объекты в управляемом контексте с заданным значением noteDocument. Так что я запускаю этот код (передавая ему 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 в базе данных, но с предикатом там я ничего не получаю. Ясно, что что-то не так с поиском, который я пытаюсь сделать в предикате. I думаю это потому, что значение является Transformable, но я не уверен, куда идти оттуда. Я знаю, что вы не можете запускать запросы на выборку для членов массивов Transformable, но разве не возможно запускать запросы на выборку для отдельных атрибутов Transformable? Если это не так, то какие существуют альтернативы?

EDIT: класс 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) 
} 


} 
+1

Вы хотите сравнить документы или URL-адреса? – Willeke

+0

Я пытаюсь сравнить объекты Document (класса NoteDocument, который подклассы NSDocument). Должен ли я соответственно менять NSCoding? –

+0

Вы используете магазин SQLite? – Willeke

ответ

1

В коде вы показываете, что единственное, что вы кодирования является URL. В этом случае это имеет гораздо больший смысл и обеспечивает большую полезность использования простой строки в сущности для хранения URL-адреса и добавления атрибута переходного процесса (или создания класса-оболочки для объединения объекта и документа) для документа. Таким образом, вы можете использовать URL-адрес в предикате и легко построить предикат из документа. Хранение документа в качестве трансформируемого никоим образом не помогает вам.

+0

См. Выше edit. Я пытаюсь сохранить весь документ, чтобы изменения в документе (особенно, но не только переменная noteText) можно было сохранить в постоянном хранилище (а не только в файловой системе). URL был только ключом, который я использовал для части NSCoding. Теперь мне ясно, что это моя проблема, но я не уверен, что делать по-другому. Большинство примеров, которые я видел в NSCoding, делают примерно так: возьмите один атрибут в качестве ключа, который входит в магазин, и оставьте его таким. Есть ли лучший способ реализовать трансформируемое? –

+0

мой ответ стоит - в базовых данных, преобразуемых, вы получаете только то, что сохраняется в вашей реализации NSCoding. весь документ не сохраняется в постоянном хранилище. почему вы даже хотите сохранить две разные копии одной и той же вещи? – Wain

+0

Ну, я надеюсь, что постоянное хранилище на основе реляционных баз данных будет быстрее загружаться, чем жесткий диск/вторичная память. Чтобы я проверял изменение даты в версии в файловой системе и постоянном хранилище и загружал только документ из файловой системы, если он был более поздним, чем версия в магазине. Я предполагаю, что если бы я все еще хотел это сделать, способ сделать это будет заключаться в том, чтобы NSCoding кодировал текстовые примечания и модифицированные по дате переменные в качестве ключей вместе с URL-адресом? –

Смежные вопросы