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
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.
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.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.
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()
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")
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!
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>
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
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
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