Jak zastosować typ do instancji NSFetchRequest?

W Swift 2 działał następujący kod:

let request = NSFetchRequest(entityName: String)

Ale w Swift 3 daje błąd:

Parametr ogólny "ResultType" nie mógł zostać wywnioskowany

Ponieważ NSFetchRequest jest teraz typem generycznym. W swoich dokumentach napisali tak:

let request: NSFetchRequest<Animal> = Animal.fetchRequest

Więc jeśli moja klasa wyników jest na przykład Level Jak mam poprawnie poprosić?

Ponieważ to nie działa:

let request: NSFetchRequest<Level> = Level.fetchRequest
Author: Braiam, 2016-06-14

9 answers

let request: NSFetchRequest<NSFetchRequestResult> = Level.fetchRequest()

Lub

let request: NSFetchRequest<Level> = Level.fetchRequest()

W zależności od wersji, którą chcesz.

Musisz podać typ generyczny, ponieważ w przeciwnym razie wywołanie metody jest niejednoznaczne.

Pierwsza wersja jest zdefiniowana dla NSManagedObject, druga wersja jest generowana automatycznie dla każdego obiektu używającego rozszerzenia, np.:

extension Level {
    @nonobjc class func fetchRequest() -> NSFetchRequest<Level> {
        return NSFetchRequest<Level>(entityName: "Level");
    }

    @NSManaged var timeStamp: NSDate?
}

Chodzi o usunięcie użycia stałych łańcuchowych.

 122
Author: Sulthan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-10 08:27:33

Myślę, że udało mi się to zrobić:

let request:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Level")

Przynajmniej zapisuje i ładuje dane z bazy danych.

Ale wydaje mi się, że nie jest to właściwe rozwiązanie, ale na razie działa.
 53
Author: Deniss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-14 12:14:35

Najprostsza struktura, która działa w 3.0 jest następująca:

let request = NSFetchRequest<Country>(entityName: "Country")

Gdzie typem jednostki danych jest kraj.

Podczas próby utworzenia podstawowego Batchdeleterequest danych, jednak okazało się, że ta definicja nie działa i wydaje się, że musisz przejść z formularza:

let request: NSFetchRequest<NSFetchRequestResult> = Country.fetchRequest()

Mimo, że formaty ManagedObject i FetchRequestResult mają być równoważne.

 32
Author: Ron Diel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-11 19:45:03

Oto kilka ogólnych metod CoreData, które mogą odpowiedzieć na twoje pytanie:

import Foundation
import Cocoa

func addRecord<T: NSManagedObject>(_ type : T.Type) -> T
{
    let entityName = T.description()
    let context = app.managedObjectContext
    let entity = NSEntityDescription.entity(forEntityName: entityName, in: context)
    let record = T(entity: entity!, insertInto: context)
    return record
}

func recordsInTable<T: NSManagedObject>(_ type : T.Type) -> Int
{
    let recs = allRecords(T.self)
    return recs.count
}


func allRecords<T: NSManagedObject>(_ type : T.Type, sort: NSSortDescriptor? = nil) -> [T]
{
    let context = app.managedObjectContext
    let request = T.fetchRequest()
    do
    {
        let results = try context.fetch(request)
        return results as! [T]
    }
    catch
    {
        print("Error with request: \(error)")
        return []
    }
}

func query<T: NSManagedObject>(_ type : T.Type, search: NSPredicate?, sort: NSSortDescriptor? = nil, multiSort: [NSSortDescriptor]? = nil) -> [T]
{
    let context = app.managedObjectContext
    let request = T.fetchRequest()
    if let predicate = search
    {
        request.predicate = predicate
    }
    if let sortDescriptors = multiSort
    {
        request.sortDescriptors = sortDescriptors
    }
    else if let sortDescriptor = sort
    {
        request.sortDescriptors = [sortDescriptor]
    }

    do
    {
        let results = try context.fetch(request)
        return results as! [T]
    }
    catch
    {
        print("Error with request: \(error)")
        return []
    }
}


func deleteRecord(_ object: NSManagedObject)
{
    let context = app.managedObjectContext
    context.delete(object)
}

func deleteRecords<T: NSManagedObject>(_ type : T.Type, search: NSPredicate? = nil)
{
    let context = app.managedObjectContext

    let results = query(T.self, search: search)
    for record in results
    {
        context.delete(record)
    }
}

func saveDatabase()
{
    let context = app.managedObjectContext

    do
    {
        try context.save()
    }
    catch
    {
        print("Error saving database: \(error)")
    }
}

Zakładając, że istnieje konfiguracja Nsmanagedobject dla kontaktu w następujący sposób:

class Contact: NSManagedObject
{
    @NSManaged var contactNo: Int
    @NSManaged var contactName: String
}

Metody te można stosować w następujący sposób:

let name = "John Appleseed"

let newContact = addRecord(Contact.self)
newContact.contactNo = 1
newContact.contactName = name

let contacts = query(Contact.self, search: NSPredicate(format: "contactName == %@", name))
for contact in contacts
{
    print ("Contact name = \(contact.contactName), no = \(contact.contactNo)")
}

deleteRecords(Contact.self, search: NSPredicate(format: "contactName == %@", name))

recs = recordsInTable(Contact.self)
print ("Contacts table has \(recs) records")

saveDatabase()
 7
Author: iphaaw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-15 07:47:18

Jest to najprostszy sposób na migrację do Swift 3.0, wystarczy dodać <Country>

(przetestowane i obrobione)

let request = NSFetchRequest<Country>(entityName: "Country")
 6
Author: letanthang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-19 07:36:18

Miałem też" ResultType " nie można wywnioskować błędów. Wyczyścili, gdy przebudowałem model danych, ustawiając Kod każdej jednostki na "definicję klasy". Zrobiłem krótki opis z instrukcją krok po kroku tutaj:

Szukam przejrzystego samouczka na temat poprawionego NSPersistentContainer w Xcode 8 z Swift 3

Przez "rebuilt" rozumiem, że utworzyłem nowy plik modelu z nowymi wpisami i atrybutami. Trochę nudne, ale zadziałało!

 0
Author: Michael Garito,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:19

To, co do tej pory działało dla mnie najlepiej, to:

let request = Level.fetchRequest() as! NSFetchRequest<Level>
 0
Author: benhofmann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-30 09:57:57

Miałem ten sam problem i rozwiązałem go następującymi krokami:

  • Wybierz plik xcdatamodeld i przejdź do Inspektora modelu danych
  • Wybierz swój pierwszy obiekt i przejdź do klasy Section
  • Upewnij się, że wybrano Codegen "definicja klasy".
  • Usuń Wszystkie wygenerowane pliki encji. Już ich nie potrzebujesz.

Po zrobieniu tego musiałem usunąć / przepisać wszystkie wystąpienia fetchRequest, ponieważ Xcode wydaje się jakoś mieszać z codegenerated version.

HTH

 0
Author: Oliver Koehler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-23 08:29:43

Swift 3.0 to powinno zadziałać.

let request: NSFetchRequest<NSFetchRequestResult> = NSManagedObject.fetchRequest()
request.entity = entityDescription(context)
request.predicate = predicate
 0
Author: Chamath Jeevan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-26 08:33:36