NSFetchRequest 인스턴스에 유형을 적용하는 방법은 무엇입니까?
Swift 2에서는 다음 코드가 작동했습니다.
let request = NSFetchRequest(entityName: String)
그러나 Swift 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")
적어도 데이터베이스에서 데이터를 저장하고로드합니다.
그러나 적절한 해결책이 아닌 것 같지만 지금은 작동합니다.
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)")
}
}
다음과 같이 Contact에 대한 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>
(테스트 및 작업)
let request = NSFetchRequest<Country>(entityName: "Country")
I also had "ResultType" could not be inferred errors. They cleared once I rebuilt the data model setting each entity's Codegen to "Class Definition". I did a brief writeup with step by step instructions here:
Looking for a clear tutorial on the revised NSPersistentContainer in Xcode 8 with Swift 3
By "rebuilt" I mean that I created a new model file with new entries and attributes. A little tedious, but it worked!
What worked best for me so far was:
let request = Level.fetchRequest() as! NSFetchRequest<Level>
I had the same issue and I solved it with the following steps:
- Select your xcdatamodeld file and go to the Data Model Inspector
- Select your first Entity and go to Section class
- Make sure that Codegen "Class Definition" is selected.
- Remove all your generated Entity files. You don't need them anymore.
After doing that I had to remove/rewrite all occurences of fetchRequest as XCode seem to somehow mix up with the codegenerated version.
HTH
Swift 3.0 This should work.
let request: NSFetchRequest<NSFetchRequestResult> = NSManagedObject.fetchRequest()
request.entity = entityDescription(context)
request.predicate = predicate
참고URL : https://stackoverflow.com/questions/37810967/how-to-apply-the-type-to-a-nsfetchrequest-instance
'program story' 카테고리의 다른 글
레일 3에서 CSRF 토큰 끄기 (0) | 2020.08.21 |
---|---|
WKWebView가 target =“_ blank”인 링크를 열지 않는 이유는 무엇입니까? (0) | 2020.08.21 |
Maven :이 프로젝트의 패키징은 빌드 아티팩트에 파일을 할당하지 않았습니다. (0) | 2020.08.20 |
.NET 프로젝트 용 Elastic Beanstalk와 CloudFormation의 차이점은 무엇입니까? (0) | 2020.08.20 |
JSON 문자열에서 C # 클래스 파일을 자동 생성하는 방법 (0) | 2020.08.20 |