[objective-c] 신속한 컴파일러 오류 : “프레임 워크 모듈 내부의 비 모듈 식 헤더”

이제 ObjC 프레임 워크를 Swift로 마이그레이션하고 싶습니다. 다음과 같은 오류가 발생했습니다.

include of non-modular header inside framework module 'SOGraphDB'

참조는 프로토콜을 정의하는 헤더 파일에 대한 것이며 일부 클래스에서는이 헤더 파일을 사용하여이 프로토콜을 사용합니다.

모듈 기능과 관련이있는 것 같지만 현재 해결 방법이 명확하지 않습니다. 솔루션을 알고 있습니까?

최신 정보:

이것은 스위프트 컴파일러 오류입니다.

업데이트 2 :

빠른 수정 (그러나 근본 원인을 해결하지는 않음)은 다음 설정을 yes로 설정하는 것입니다. CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES



답변

헤더가 공개되어 있습니까?

프로젝트 탐색기에서 헤더 파일을 선택하십시오. 그런 다음 xcode의 오른쪽 섹션에서 대상 옆에 드롭 다운이 있음을 알 수 있습니다. “프로젝트”에서 “공용”으로 변경하십시오. 이것은 나를 위해 일했습니다.

공개 헤더


답변

이것은 예상되는 컴파일러 동작이며 매우 좋은 이유입니다.

이 문제를 겪고있는 사람들의 대다수는 C와 Objective C 헤더를 전환 하고 응용 프로그램의 Bridging Header 와 동일한 동작을 기대하는 프레임 워크의 우산 헤더에 추가 Application Target하기 Framework Target시작한 후에 발생한다고 생각합니다 . 엄브렐러 헤더는 실제로 혼합 된 신속한 obj-c 프레임 워크 용으로 지정되었으며 목적은 프레임 워크가 objective-c 또는 c에있는 외부 세계에 API를 노출시키는 것입니다. 그것은 우리가 넣은 헤더가 공개 범위에 있어야 함을 의미합니다.

프레임 워크의 일부가 아닌 Objective-C / C 헤더를 프레임 워크의 신속한 코드에 노출하는 장소로 사용해서는 안됩니다. 이 경우 이러한 헤더는 프레임 워크 모듈의 일부로 외부에 노출되기 때문에 모듈성을 깨뜨리기 때문에 수행하지 않는 경우가 많습니다. (그래서 프레임 워크 모듈에 비 모듈 식 포함 허용이 기본값으로 NO 인 이유 )

Objective-C / C 라이브러리를 프레임 워크 스위프트 코드에 노출 시키려면 해당 라이브러리에 대해 별도의 스위프트 모듈을 정의해야합니다. 그런 다음 표준 스위프트를 import YourLegacyLibrary사용할 수 있습니다.

libxml2프레임 워크에 포함하는 몇 가지 일반적인 시나리오에서이를 설명하겠습니다 .

1. 먼저 module.modulemap다음과 같은 파일 을 작성해야합니다 .

OSX 프레임 워크의 경우 :

module SwiftLibXML2 [system] {
  header "/usr/include/libxml2/libxml/xpath.h"
  export *
}

iOS 프레임 워크의 경우 :

module SwiftLibXML2 [system] {
  header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/libxml2/libxml/xpath.h"
  export *
}

그것은 swift 모듈 내에서 헤더와 참조하는 다른 헤더를 마무리하여 swift가 이러한 C 인터페이스에 대한 신속한 바인딩을 생성 할 수 있도록하는 것입니다.

2. xcode 프로젝트 디렉토리에 폴더 SwiftLibXML2를 만들고이 모듈을 넣습니다.

3. 에서 빌드 설정 , 추가 $(SDKROOT)/usr/include/libxml2헤더 검색 경로

4. 에서 빌드 설정 , 추가 $(SRCROOT)/SwiftLibXML2가져 오기 경로

5. 아래에서 프로젝트의 일반 탭을 추가 libxml2.tbd링크 된 프레임 워크 및 라이브러리 .

이제 필요한 곳에서이 모듈을 가져옵니다.

import SwiftLibXML2

(보다 완전한 module.map 예제를 보려면에서 Darwin의 module.modulemap을 참조하는 것이 좋습니다 .Xcode /usr/include/module.modulemap명령 줄 도구가 설치되어 있어야합니다 .OS X El Capitan에 / usr / include 누락 참조 )


답변

빠른 수정 사항을 자동으로 적용하여 Pods.xcodeproj매번 수동으로 변경할 필요가 없습니다 pod install.

이 스 니펫을 Podfile 끝에 추가하십시오.

post_install do |installer|
  installer.pods_project.build_configuration_list.build_configurations.each do |configuration|
    configuration.build_settings['CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES'] = 'YES'
  end
end


답변

나를위한 해결책은 대상-> 빌드 설정-> 프레임 워크 모듈의 비 모듈 형 포함 스위치를 YES로 전환하는 것입니다!


답변

나는이 문제를 해결했다고 생각합니다. 프레임 워크에서 sqlite3을 사용하는 모델 코드가 있습니다. 필자의 경우 범인은 <sqlite3.h>였습니다.

문제는 내 Module / Module.h 헤더에서 <sqlite3.h>를 가져온 공용 헤더를 가져 왔다는 것입니다. 해결책은 모든 sqlite3_xxx 유형을 숨기고 공개 .h에서 보이지 않도록하는 것입니다. sqlite3에 대한 모든 직접 참조는 비공개 또는 프로젝트 가시성으로 만들어졌습니다. 예를 들어, 나는 sqlite3_stmt 포인터가 매달려있는 공개 싱글 톤을 가지고있었습니다. 나는 그것들을 이제는 그 공용 헤더에서 앞으로 선언하는 별도의 클래스로 옮겼습니다. 이제 만들 수 있습니다.

또한 CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES 설정이 작동하지 않았습니다. 프레임 워크와 종속 프로젝트 모두에서 설정을 시도했습니다. 이유는 확실하지 않지만이 해결 방법이 필요했습니다.


답변

에서 스위프트 :

1. 아래에서 언급 한대로 Xcode 프로젝트 및 대상의 빌드 설정을 수정하십시오.

프레임 워크 모듈에 비 모듈 식 포함 허용 : 아니요

비트 코드 활성화 : 예

2. GoogleMaps iOS SDK에서 사용할 수있는 최신 버전을 사용하십시오 (CocoaPod를 사용하여 사용).

Google지도 (1.10.4)

3. 문제가있는 가져 오기에 주석을 답니다.

//import GoogleMaps

4. 문제가있는 가져 오기를 추가하여 브리징 헤더 파일을 작성하거나 수정하십시오.

[귀하의 Xcode 프로젝트 이름] -Bridging-Header.h

// Use this file to import your target's public headers 
// that you would like to expose to Swift.
#import <GoogleMaps/GoogleMaps.h>

5. Xcode 프로젝트를 정리하고 다시 빌드하십시오.


답변

이 답변은 구식입니다.

프레임 워크를 가져올 때 루트 헤더와 종속성을 공유하는 모든 헤더 파일 을 가져와야 합니다 . 이것이 항상 작동하도록하는 가장 쉬운 방법은 프레임 워크의 “Headers”폴더에있는 모든 헤더를 공용 헤더 경로로 가져 오는 것입니다.

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

Swift 컴파일러는이 정보를 사용하여 얽 히지 않은 심볼의 맵과 관련 유형 정보를 생성합니다.