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.