NSFetchRequest 인스턴스에 유형을 적용하는 방법은 무엇입니까?
스위프트 2에서는 다음과 같은 코드가 작동하고 있었습니다.
let request = NSFetchRequest(entityName: String)
스위프트 3에서는 다음과 같은 오류가 발생합니다.
일반 매개 변수 "ResultType"을(를) 유추할 수 없습니다.
왜냐면NSFetchRequest
이제 일반적인 유형입니다.그들은 문서에 다음과 같이 적었습니다.
let request: NSFetchRequest<Animal> = Animal.fetchRequest
그래서 예를들어 나의 결과수업이Level
어떻게 정확하게 요청해야 합니까?
작동하지 않기 때문입니다.
let request: NSFetchRequest<Level> = Level.fetchRequest
let request: NSFetchRequest<NSFetchRequestResult> = Level.fetchRequest()
아니면
let request: NSFetchRequest<Level> = Level.fetchRequest()
어떤 버전을 원하시는지에 따라서.
메서드 호출이 애매하므로 일반 형식을 지정해야 합니다.
첫 번째 버전은 다음에 대해 정의됩니다.NSManagedObject
, 두 번째 버전은 확장자를 사용하는 모든 개체에 대해 자동으로 생성됩니다.
extension Level {
@nonobjc class func fetchRequest() -> NSFetchRequest<Level> {
return NSFetchRequest<Level>(entityName: "Level");
}
@NSManaged var timeStamp: NSDate?
}
핵심은 문자열 상수의 사용을 제거하는 것입니다.
이렇게 함으로써 효과를 본 것 같습니다.
let request:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Level")
최소한 DataBase에서 데이터를 저장하고 로드합니다.
하지만 이것은 적절한 해결책이 아닌 것처럼 느껴지지만, 현재로서는 효과가 있습니다.
3.0에서 작동하는 가장 간단한 구조는 다음과 같습니다.
let request = NSFetchRequest<Country>(entityName: "Country")
여기서 데이터 개체 유형은 국가입니다.
그러나 Core Data BatchDeleteRequest를 생성하려고 할 때 이 정의가 작동하지 않으며 다음과 같은 형식으로 작업해야 할 것 같습니다.
let request: NSFetchRequest<NSFetchRequestResult> = Country.fetchRequest()
ManagedObject와 FetchRequestResult 형식이 동일해야 함에도 불구하고.
다음은 질문에 대답할 수 있는 일반적인 CoreData 방법입니다.
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)")
}
}
연락처에 대한 NSManagedObject 설정이 있다고 가정하면 다음과 같습니다.
class Contact: NSManagedObject
{
@NSManaged var contactNo: Int
@NSManaged var contactName: String
}
이러한 방법은 다음과 같은 방법으로 사용할 수 있습니다.
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()
이것이 Swift 3.0으로 마이그레이션하는 가장 간단한 방법입니다.<Country>
(tested 및 작업)
let request = NSFetchRequest<Country>(entityName: "Country")
스위프트 3.0 이것은 효과가 있을 것입니다.
let request: NSFetchRequest<NSFetchRequestResult> = NSManagedObject.fetchRequest()
request.entity = entityDescription(context)
request.predicate = predicate
또한 "ResultType"이 오류를 추론할 수 없었습니다.각 개체의 Codegen을 "Class Definition"으로 설정하여 데이터 모델을 재구성하면 삭제됩니다.여기에 단계별 지침을 간단히 작성했습니다.
Swift 3으로 Xcode 8에서 개정된 NSPersistent Container에 대한 명확한 튜토리얼을 찾고 있습니다.
"재구축"이란 새로운 항목과 속성을 가진 새 모델 파일을 만든 것을 의미합니다.조금 지루하지만 효과가 있었습니다!
지금까지 제게 가장 효과적이었던 것은 다음과 같습니다.
let request = Level.fetchRequest() as! NSFetchRequest<Level>
저도 같은 문제가 있었고 다음과 같은 단계로 해결했습니다.
- xcdata modeld 파일을 선택하고 Data Model Inspector(데이터 모델 검사기)로 이동합니다.
- 첫번째 엔터티를 선택하고 섹션 클래스로 이동합니다.
- Codegen "Class Definition"(클래스 정의)이 선택되었는지 확인합니다.
- 생성된 모든 엔터티 파일을 제거합니다.더 이상 필요 없어요
그렇게 한 후 XCode가 코드 생성 버전과 어떻게든 뒤섞이는 것 같아 fetchRequest의 모든 발생을 제거/다시 써야 했습니다.
HTH
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
func loadItemsCategory() {
let request: NSFetchRequest<Category> = Category.fetchRequest()
do {
categoryArray = try context.fetch(request)
} catch {
print(error)
}
tableView.reloadData()
}
언급URL : https://stackoverflow.com/questions/37810967/how-to-apply-the-type-to-a-nsfetchrequest-instance
'programing' 카테고리의 다른 글
C의 잠정적인 정의의 근거는 무엇입니까? (0) | 2023.10.17 |
---|---|
C에서 2d 배열을 자유롭게 하는 방법? (0) | 2023.10.17 |
기본 permallinks working word press 기타는 404 error가 됩니다. (0) | 2023.10.17 |
wordpress WP_Query 'order by'가 작동하지 않습니다. (0) | 2023.10.17 |
PhphStorm을 통해 MariaDB에 연결할 수는 없지만 터미널은 정상적으로 작동합니다. (0) | 2023.10.17 |