NSManagedObject의 특정 하위 클래스를 찾을 수 없습니다


136

Core Data로 앱을 개발 중입니다. 내가 사용하여 인스턴스를 만들 때 :

let entity = NSEntityDescription.entityForName("User", inManagedObjectContext: appDelegate.managedObjectContext)
let user = User(entity: entity, insertIntoManagedObjectContext: appDelegate.managedObjectContext)

로그에 경고가 있습니다.

CoreData: warning: Unable to load class named 'User' for entity 'User'.  Class not found, using default NSManagedObject instead.

어떻게 고칠 수 있습니까?

또 다른 질문은 NSManagedObject 서브 클래스에서 인스턴스 메소드를 어떻게 정의 할 수 있습니까?

편집하다:

다음 스크린 샷과 같이 엔티티 클래스를 지정했습니다.

여기에 이미지 설명을 입력하십시오


7
핵심 데이터 관리 객체 서브 클래스 구현에 설명 된대로 엔티티 클래스 이름 앞에 모듈 이름을 접했 습니까?
Martin R

@ MartinR : 내 질문의 업데이트를 참조하십시오.
MsrButterfly

2
클래스는 "YourAppName.User"여야합니다 (문서의 이전 주석 링크 참조).
Martin R

@MartinR : 도와 주셔서 감사합니다. 효과가있다.
MsrButterfly

가장 좋은 방법은 해당 클래스를 삭제하고 다시 작성하는 것입니다. 이것은 나를 위해 일했다
Abhishek

답변:


220

Xcode 7 업데이트 (최종) : Xcode 6 및 Xcode 7의 초기 베타 릴리스와 같이 모듈 이름을 클래스 앞에 추가 할 필요가 없습니다. 핵심 데이터 관리 객체 서브 클래스 구현 Apple 문서 가 이에 따라 업데이트되었습니다.

데이터 모델 인스펙터는 이제 엔티티에 대해 "Class"및 "Module"이라는 두 개의 필드를 갖습니다.

여기에 이미지 설명을 입력하십시오

엔티티에 대한 Swift 관리 오브젝트 서브 클래스를 작성할 때 "모듈"필드는 "현재 제품 모듈"로 설정되며이 설정으로 인스턴스 작성은 기본 응용 프로그램 및 단위 테스트 모두에서 작동합니다. 관리 객체 서브 클래스에 마크를 표시 해서는 안됩니다@objc(classname) ( https://stackoverflow.com/a/31288029/1187415 에서 관찰 됨 ).

또는 "모듈"필드를 비우고 ( "없음"으로 표시) 관리 객체 하위 클래스를 표시 할 수 있습니다 @objc(classname)( https://stackoverflow.com/a/31287260/1187415 참조 ).


비고 : 이 답변은 원래 Xcode 6 용으로 작성된 것입니다.이 문제와 관련하여 다양한 Xcode 7 베타 릴리스에서 일부 변경 사항이있었습니다. 그것은 많은 upvotes와 그것에 대한 링크로 받아 들여진 대답이기 때문에 현재 Xcode 7 최종 버전의 상황을 요약하려고했습니다.

나는 내 자신의 "연구"를 수행 하고이 질문과 비슷한 질문 CoreData에 대한 모든 대답을 읽었습니다 . 경고 : 이름이 지정된 클래스를로드 할 수 없습니다 . 따라서 속성을 구체적으로 나열하지 않더라도 속성은 모든 속성에 적용됩니다.


Xcode 6에 대한 이전 답변 :

핵심 데이터 관리 객체 하위 클래스 구현에 설명 된대로 모델 엔터티 관리자의 클래스 필드에서 엔터티 클래스 이름 앞에 모듈 이름 (예 : "MyFirstSwiftApp.User")을 접두사로 추가해야합니다.


2
이것은 나를 위해 일하고 있습니다. 질문 : 핵심 데이터가 프레임 워크에 포함 된 경우 아직 실제 앱이 없기 때문에 ManagedObject 하위 클래스 이름 앞에 접두사를 붙이는 방법은 무엇입니까?
Allan Macatingrao

9
@Allan : @objc(ClassName)Christer의 답변에서 제안한 방법을 시도해 볼 수 있습니다.
Martin R

8
작동하지만 엔티티 검사기에서 클래스 이름을 "APPNAME.User"로 설정하면 모델 클래스를 다시 생성 할 수 없습니다 .Xcode가 접두사와 혼동되어 이름과 파일 / 클래스를 생성합니다 APPNAME. 뭔가 빠졌습니까?
Pascal Bourque

1
정적 라이브러리에서 코어 데이터를 사용할 때 Objective-C에서이 오류가 발생하면 어떻게합니까?
George Taskos

1
@ Suragch : 나는 마침내 대답을 업데이트했으며, 모든 것이 지금 정확하기를 바랍니다.
Martin R

62

부수적으로. 나는 같은 문제가 있었다. 그리고 내가해야 할 일은 @objc(ClassName)내 수업 파일 에 추가 하는 것입니다.

예:

@objc(Person)
class Person { }

그리고 그것은 내 문제를 해결했습니다.


1
그런 식으로 Objective-C에서 typealias (<% ProjectName %>. Person-> Person)를 정의 했으므로 작동합니다.
MsrButterfly

애플이 신속하게 그것을 완전히 전환하는 것을 잊어 버린 것 같습니다. 왜 그런지 모르겠지만 이것은 나를 위해 그것을 부드럽게 부드럽게
고쳤습니다

7
이는 여러 대상이있는 프로젝트가 있고 각 대상이 CoreData 모델을 공유하는 경우에 특히 유용합니다. 이러한 경우, CD 모델을 대상 중 하나에 만 유용하게하므로 클래스 이름 앞에 대상 ID의 클래스 이름을 붙일 수 없습니다.
djbp dec

@djbp 그리고 "왜 안돼?" 알고 싶습니다. 나는 이름 공간이라는 개념을 좋아하지만 MacBook을 창 밖으로 던져 버리고 싶습니다 (확장 프로그램이있는 응용 프로그램이 있고 확장 프로그램을 실행할 때이 문제가 발생했습니다). 네임 스페이스를 사용하여이 작업을 수행하는 "올바른"방법이 있어야합니다.
S'pht'Kr

네, 이것은 작업 공간에서 공유 데이터 모델로 작업 할 때 저에게
효과적

31

이 질문에 대한 대답은 같은 문제를 해결하는 데 도움이되었지만 다른 사람들에게 도움이 될 것이라는 경고가있었습니다. 프로젝트 (모듈) 이름에 공백이 있으면 공백을 밑줄로 바꿔야합니다. 예를 들면 다음과 같습니다.

엔터티 : MyEntity 클래스 : My_App_Name.MyClass


내가 찾던 바로 그거야! 건배!
manosim

AppName.ClassName으로 클래스 이름을 설정하면 Xcode 9는 점을 제거하고 점이없는 클래스를 만듭니다. 따라서 이것은 더 이상 Xcode 9. *에 없습니다.
yo2bh


9

앱 대 테스트로 실행 중인지 여부에 따라 문제는 앱이 찾고 있거나 테스트로 <appName>.<entityName>실행 중일 때 찾고있는 것일 수 있습니다 <appName>Tests.<entityName>. 현재 사용하는 솔루션 (Xcode 6.1)은 ClassCoreData UI 의 필드를 채우지 않고 대신 코드로 수행하는 것입니다.

이 코드는 앱 대 테스트로 실행 중인지 감지하고 올바른 모듈 이름을 사용하여를 업데이트합니다 managedObjectClassName.

lazy var managedObjectModel: NSManagedObjectModel = {
    // The managed object model for the application. This property is not optional...
    let modelURL = NSBundle.mainBundle().URLForResource("Streak", withExtension: "momd")!
    let managedObjectModel = NSManagedObjectModel(contentsOfURL: modelURL)!

    // Check if we are running as test or not
    let environment = NSProcessInfo.processInfo().environment as [String : AnyObject]
    let isTest = (environment["XCInjectBundle"] as? String)?.pathExtension == "xctest"

    // Create the module name
    let moduleName = (isTest) ? "StreakTests" : "Streak"

    // Create a new managed object model with updated entity class names
    var newEntities = [] as [NSEntityDescription]
    for (_, entity) in enumerate(managedObjectModel.entities) {
        let newEntity = entity.copy() as NSEntityDescription
        newEntity.managedObjectClassName = "\(moduleName).\(entity.name)"
        newEntities.append(newEntity)
    }
    let newManagedObjectModel = NSManagedObjectModel()
    newManagedObjectModel.entities = newEntities

    return newManagedObjectModel
}()

1
솔루션을 시도했지만 NSManagedObject를 실제 클래스로 캐스팅 할 때 "치명적 오류 : NSArray 요소가 Swift Array 요소 유형과 일치하지 못했습니다"라는 메시지가 표시됩니다. 실제로 캐스팅 할 때가 아니라 for 루프로 들어 가려고 할 때 실제로.
Rodrigo Ruiz

1
모델에 상속이 있으면이 예제가 작동하지 않습니다. 모든 새 엔티티에 대해 하위 엔티티를 반복하고 작성한 새 엔티티로 업데이트해야합니다.
Anton

8

프로젝트 이름에 "My-App"과 같은 하이픈을 사용하는 경우 "My_App.MyManagedObject"와 같은 하이픈 대신 밑줄을 사용하십시오. 일반적으로 xcdatamodeld 파일의 이름을보고 해당 이름과 동일한 접두사를 사용하십시오. 즉, "My_App_1.xcdatamodeld"에는 접두사 "My_App_1"이 필요합니다.


1
와. 감사합니다 감사합니다 나는 애플 문서에서 그 작은 덩어리가 어디에 있는지 아는 것에 관심이있다 :)
nh32rg

5

이것은 같은 문제가 발생하는 사람들에게 도움이 될 수 있습니다. 나는 Swift 2와 Xcode 7 베타 2를 사용했습니다.

내 경우 의 해결책 은에서 주석 처리하는 것이 었 @objc(EntityName)습니다 EntityName.swift.


3

내 앱이 정상적으로 실행되는 것처럼 보이지만 동일한 경고가 발생했습니다. 문제는 마지막 화면에서 Editor> Create NSManagedObject Subclass를 실행할 때 대상이 표시되거나 확인되지 않은 기본 그룹 위치를 사용하여 MyApp.xcodeproj가 위치한 최상위 MyApp 디렉토리에 하위 클래스를 저장했다는 것입니다.
대신 그룹을 MyApp 하위 폴더에 있도록 변경하고 MyApp 대상을 확인하면 경고가 사라졌습니다.


2

위의 답변이 도움이되었습니다. 이 빠른 위생 검사는 시간을 절약 할 수 있습니다. 프로젝트> 빌드 단계> 소스 컴파일로 이동하여 "-"버튼으로 xcdatamodeld 및 모델 파일을 제거한 다음 "+"버튼으로 다시 추가하십시오. 재건-돌보아 줄 수도 있습니다.


2

그건 그렇고 당신이 접두사로 추가 한 것을 조심하십시오 : 내 앱은 "ABC-def"이며 Xcode는 "-"를 "_"로 변환했습니다.

파인더를 안전하게 살펴 보려면 프로젝트 파일을 찾아서 데이터 모델에 대한 내용 (예 : "ABC_def.xcdatamodeld")을보고 정확히 작성된 내용을 사용하십시오 !!!


1

위의 답변은 Objective-C와 관련된 다른 문제를 해결하는 데 도움이되었습니다 (아마도 누군가를 도울 것입니다).

엔터티 이름을 리팩토링 한 경우 "유틸리티 패널"에서 "클래스"도 변경해야합니다.


0

위의 답변이 도움이되었지만 누군가에게 도움이 될 수 있습니다. 나처럼 당신이 그들을하고 여전히 문제가있는 경우, 단순히 '프로젝트를 청소'를 기억하십시오. XCode8의 경우 제품> 청소 그런 다음 다시 실행하십시오.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.