Lỗi trình biên dịch Swift: Tiêu đề không mô-đun bên trong mô-đun khung


204

Bây giờ tôi muốn chuyển khung ObjC của mình sang Swift và tôi đã gặp lỗi sau:

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

Các tham chiếu là một tệp tiêu đề chỉ xác định một giao thức và tôi sử dụng tệp tiêu đề này trong một số lớp để sử dụng giao thức này.

Có vẻ như liên quan đến tính năng mô-đun nhưng hiện tại vẫn chưa rõ cách khắc phục, bạn có biết một giải pháp không?

CẬP NHẬT:

Đây là lỗi trình biên dịch Swift.

CẬP NHẬT 2:

Cách khắc phục nhanh (nhưng không giải quyết được nguyên nhân gốc) là đặt cài đặt sau thành có: CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = CÓ


3
Dường như có một cài đặt bản dựng mới cho "CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES"
Stephan

1
Có ai nhìn thấy điều này bao gồm công khai và mô-đun? Tôi thấy điều này với một dự án vanilla (cocoapods): github.com/CocoaPods/CocoaPods/issues/3092dropbox.com/s/trhe5vwhzoa9bf5/ trộm
Chris Conover

Có ai đã thực hiện một kịch bản nhanh chóng cho phép điều này tự động?
fatuhoku


Không có giải pháp nào trong số này làm việc cho tôi, có vẻ như đó là một vụ va chạm bolts.framework trong trường hợp của tôi. Xóa nó đã giải quyết được vấn đề: stackoverflow.com/a/33114309/3324388
Kẻ xâm phạm

Câu trả lời:


316

Là tiêu đề của bạn công khai?

Chọn tệp tiêu đề trong trình thám hiểm dự án. Sau đó, trong phần bên phải trong xcode, bạn sẽ nhận thấy có một danh sách thả xuống bên cạnh mục tiêu. Thay đổi từ "dự án" thành "công khai". Điều này làm việc cho tôi.

tiêu đề công cộng


Tôi chấp nhận câu trả lời này ngay cả khi nó giống như tôi đã nêu.
Stephan

Bạn cũng có thể đi đến giai đoạn xây dựng Tiêu đề trong khung của mình và nhanh chóng xem các tiêu đề nào là Công khai, Dự án và Riêng tư.
Jose Ibanez

Tôi không nghĩ nhiệm vụ đơn giản này có thể là giải pháp vì tôi đã chiến đấu với nó trong hơn một giờ trước khi đến đây với SO. Xin thưa, đây chính xác là giải pháp và hoạt động ngay lập tức.
TMc

1
Và nếu tôi muốn những tiêu đề này là nội bộ thì sao?
Raphael

2
Điều này cũng giải quyết vấn đề của tôi! Trong trường hợp của tôi, một nhóm của tôi phụ thuộc vào nhóm khác không thể nhập nó do vấn đề mô-đun. Vì vậy, tôi đã thực hiện một số tiêu đề được bao gồm làm mục tiêu cho nhóm khác, sử dụng chế độ công khai. Và nó giải quyết vấn đề!
Chen Li Yong

135

Đây là một hành vi biên dịch dự kiến ​​và vì một lý do rất tốt.

Tôi nghĩ đa số người dân chạy vào các vấn đề này là do sau khi họ chuyển từ Application Targetđến Framework Targetvà bắt đầu thêm C và header C Mục tiêu vào khuôn khổ của tiêu đề ô mong đợi nó để có một hành vi tương tự như Bridging Tiêu đề của ứng dụng , mà ứng xử khác nhau. Tiêu đề ô thực sự được chỉ định cho swift hỗn hợp, khung obj-c và mục đích của nó là đưa các API ra thế giới bên ngoài mà khung của bạn có trong object-c hoặc c. Điều đó có nghĩa là các tiêu đề chúng tôi đặt ở đó phải nằm trong phạm vi công cộng.

Không nên sử dụng nó làm nơi trưng bày các tiêu đề Objective-C / C không phải là một phần của khung công tác đối với mã nhanh chóng của khung công tác của bạn. Bởi vì trong trường hợp đó, các tiêu đề này cũng sẽ được đưa ra như một phần của mô-đun khung của chúng ta với thế giới bên ngoài, thường không phải là những gì chúng ta muốn làm vì nó phá vỡ mô-đun. (Và đó chính xác là lý do tại sao Cho phép Không mô-đun Bao gồm trong Mô-đun khung mặc định thành NO )

Để hiển thị thư viện Objective-C / C cho mã swift khung của bạn, chúng ta nên xác định một mô-đun swift riêng cho thư viện đó. Sau đó, một swift tiêu chuẩn import YourLegacyLibrarycó thể được sử dụng.

Hãy để tôi chứng minh điều này trên một số kịch bản điển hình: nhúng libxml2vào khuôn khổ của chúng tôi.

1. Trước tiên bạn cần tạo một module.modulemaptệp trông theo cách này:

Đối với khung OSX:

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

Đối với khung iOS:

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

Tất cả những gì nó làm là nó bọc tiêu đề và bất kỳ tiêu đề nào khác mà nó tham chiếu bên trong mô-đun swift, do đó swift sau đó sẽ có thể tạo các liên kết nhanh cho các giao diện C này.

2. Sau đó, trong thư mục dự án xcode của bạn tạo một thư mục SwiftLibXML2và đặt module.modulemap này vào đó

3. Trong Cài đặt bản dựng , thêm $(SDKROOT)/usr/include/libxml2vào Đường dẫn tìm kiếm tiêu đề

4. Trong Cài đặt bản dựng , thêm $(SRCROOT)/SwiftLibXML2vào đường dẫn nhập

5. Trong tab Chung của Dự án , thêm libxml2.tbdvào Thư viện và Khung được liên kết .

Bây giờ bạn nhập mô-đun này khi cần thiết với:

import SwiftLibXML2

(nếu bạn muốn xem một ví dụ module.map hoàn chỉnh hơn, tôi khuyên bạn nên tham khảo module.modulemap của Darwin tại /usr/include/module.modulemap, bạn sẽ cần cài đặt các công cụ dòng lệnh Xcode để đến đó, tham khảo Thiếu / usr / bao gồm trong OS X El Capitan )


1
Tên tệp module.mapkhông được dùng nữa, nên đổi tên thành module.modulemap clang.llvm.org/docs/Modules.html#attribut
Hyperbole

Làm thế nào để import SwiftLibXML2trong Objective-C? Cảm ơn!
Itachi

giống như mọi cách nhập obj-c khác: #import <libxml / xpath.h> nhưng hãy đảm bảo bạn đã thực hiện các bước 3-5.
ambientlight

Chúng tôi đã làm điều này, nhưng sau đó không thể di chuyển tạo phẩm xây dựng giữa các máy: mô-đun Objective-C (phụ) được liên kết rõ ràng bằng cách sử dụng các đường dẫn tuyệt đối, gây ra lỗi khi biên dịch, giả sử, một ứng dụng sử dụng khung mà bạn đã vận chuyển.
Raphael

lỗi rất có thể cụ thể đối với quá trình xây dựng của bạn, đây chỉ là một định nghĩa mô-đun để các ngôn ngữ hỗ trợ các mô-đun có thể giao tiếp với người khác, tôi không nghĩ nó có thể ảnh hưởng đến các tạo phẩm xây dựng của bạn, cộng đồng có thể sửa lỗi cho tôi không sai rồi
ambientlight

55

Đây là cách tự động áp dụng sửa chữa nhanh để bạn không phải thay đổi Pods.xcodeprojthủ công sau mỗi lần sửa pod install.

Thêm đoạn mã này vào cuối Podfile của bạn:

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

29

Giải pháp cho tôi là đi vào mục tiêu-> xây dựng cài đặt-> Cho phép phi mô-đun bao gồm trong Mô-đun khung chuyển sang CÓ!


Cũng đã làm việc với Cocoapods ở đây. Không cần phải làm phép thuật từ câu trả lời khác sau khi cài đặt pod
brainray

3
Tôi đã thực hiện bước này .. nó đã hoạt động được một lúc .. và bây giờ nó không hoạt động ... Tôi cũng bao gồm bước cài đặt pod. Nhưng bây giờ nó lại thất bại. Bất cứ điều gì khác tôi nên được kiểm tra? Tôi không thấy GoogleMobileAds.Framework là một tùy chọn để thay đổi tiêu đề thành Công khai.
Michael Rowe

Điều này đã không làm việc cho tôi. Vẫn nhận được lỗi với Parse. Xcode 7.3.1
C0D3

Tôi đã phải khởi động lại XCode sau khi thực hiện thay đổi này để nó hoạt động.
John Fowler

1
Tác động của việc thay đổi cài đặt này là gì?
5

15

Tôi nghĩ rằng tôi đã khắc phục điều này. Tôi có một số mã mô hình sử dụng sqlite3 trong một khung. Trong trường hợp của tôi, thủ phạm là <sqlite3.h>.

Vấn đề là trong tiêu đề Module / Module.h của tôi, tôi đã nhập một tiêu đề công khai đã nhập <sqlite3.h>. Giải pháp là ẩn tất cả các loại sqlite3_xxx và đảm bảo chúng không hiển thị trong bất kỳ .h nào. Tất cả các tham chiếu trực tiếp đến sqlite3 đã được hiển thị riêng tư hoặc dự án. Ví dụ, tôi có một singleton công khai có một số con trỏ sqlite3_stmt treo trên đó. Tôi đã chuyển chúng sang một lớp riêng mà giờ chỉ là một khai báo chuyển tiếp trong tiêu đề công khai đó. Bây giờ tôi có thể xây dựng.

Ngẫu nhiên, cài đặt CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES không hoạt động. Tôi đã cố gắng thiết lập cả trong khuôn khổ và dự án phụ thuộc. Cách giải quyết này là cần thiết, mặc dù tôi không chắc tại sao.


Điều này hoàn toàn có ích! Trong trường hợp của tôi, đó là Khả năng tiếp cận.
Daniel Brim

4
Tôi khá chắc chắn rằng đây là giải pháp cho vấn đề của tôi khi tôi cố gắng đưa SSZipArchive vào mô-đun khung của mình. Tiêu đề công khai đang áp dụng <zlib.h> và đưa ra cùng một lỗi. Bạn có thể đăng mã nguồn của bạn ở đâu đó không vì tôi đang cố gắng để nó hoạt động vì tôi chỉ hiểu một phần câu trả lời của bạn .. cảm ơn!
Bruce

15

Trong Swift :

1. Sửa đổi dự án Xcode của bạn và Cài đặt bản dựng của mục tiêu như được đề cập dưới đây:

Cho phép phi mô-đun Bao gồm trong các mô-đun khung: Không

Kích hoạt Bitcode: Có

2. Sử dụng phiên bản mới nhất hiện tại có sẵn cho GoogleMaps iOS SDK (sử dụng CocoaPods để tải xuống):

GoogleMaps (1.10.4)

3. Nhận xét nhập khẩu có vấn đề:

//import GoogleMaps

4. Tạo hoặc sửa đổi tệp tiêu đề bắc cầu của bạn, thêm quá trình nhập có vấn đề:

[Tên dự án Xcode của bạn] -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. Làm sạch và xây dựng lại dự án Xcode của bạn.


1
Điều này giúp rất nhiều! Cũng tuyệt vời làm việc với GoogleMobilAds khuôn khổ (với Cocoapods)
bluenowhere

để biết thêm thông tin chi tiết cách tạo tệp tiêu đề, xem: stackoverflow.com/a/51227304/529663
lenooh

6

Câu trả lời này là lỗi thời.

Khi nhập khung, bạn phải nhập tất cả các tệp tiêu đề chia sẻ phụ thuộc với tiêu đề gốc. Cách dễ nhất để đảm bảo điều này luôn hoạt động là nhập tất cả các tiêu đề trong thư mục "Tiêu đề" của khung vào đường dẫn tiêu đề công khai của bạn.

nhập mô tả hình ảnh ở đây

Trình biên dịch Swift sử dụng thông tin này để tạo ra một bản đồ các ký hiệu không được đọc cùng với thông tin loại liên quan của chúng.


Điều này dường như đánh bại mục đích có các tệp Framework, nhưng nó hoạt động với tôi. Chartboost và RevMob gần đây đã bắt đầu sử dụng các tệp Framework thay vì chỉ libs. Sao chép mọi thứ từ tiêu đề của họ vào tiêu đề ứng dụng của tôi sẽ giải quyết vấn đề.
Jason Short

Đây có phải là giải pháp duy nhất? Tôi có 6 khung và mỗi khung có khoảng 20 tiêu đề. Nó tạo ra một mớ hỗn độn. Bất kỳ thay thế?
vivin

1
Nhiều khả năng. Điều này có lẽ không còn phù hợp vì nó là một cách giải quyết trong lỗi Xcode.
seo

6

Đừng

#import "MyOtherFramework.h"

Làm

#import <MyOtherFramework/MyOtherFramework.h>

3

Tệp tiêu đề được phân bổ cho mục tiêu nhưng chỉ được đánh dấu là có thể nhìn thấy dự án, chỉ là một thay đổi đối với công khai dẫn đến việc giải quyết lỗi này.


Làm thế nào chính xác tôi có thể làm điều đó? Tôi đang gặp sự cố với các tệp tiêu đề TwitterKit của mình
Vinod Sobale

2

Tôi biết rằng đây là một câu hỏi cũ, nhưng tôi có cùng một vấn đề và không có gì từ phía trên giúp tôi. Vì vậy, tôi hy vọng câu trả lời của tôi sẽ hữu ích cho ai đó. Trong trường hợp của tôi, sự cố nằm ở cài đặt ALWAYS_SEARCH_USER_PATHS. Khi nó được đặt thành KHÔNG dự án được xây dựng và hoạt động tốt. Nhưng theo như một trong các nhóm yêu cầu thì nó phải được đặt thành CÓ Tôi đã nhận được một lỗi

Bao gồm tiêu đề không mô-đun bên trong mô-đun khung

Sau vài tách cà phê và cả ngày nghiên cứu, tôi phát hiện ra rằng theo các vấn đề đã biết của ghi chú phát hành Xcode 7.1 Beta 2 :

• Nếu bạn gặp lỗi thông báo "Bao gồm tiêu đề không mô-đun bên trong mô-đun khung" cho khung đã được biên dịch trước đó, hãy đảm bảo cài đặt xây dựng "Luôn tìm kiếm đường dẫn người dùng" được đặt thành "Không". Mặc định là "Có" chỉ vì lý do cũ. (22784786)

Tôi đã sử dụng XCode 7.3, nhưng có vẻ như lỗi này chưa được sửa.


Đây là những gì đã giúp tôi! Tôi đã phải thay đổi một số nhập khẩu sau khi chuyển sang NO nhưng bây giờ tôi đã có thể nhập khuôn khổ cần thiết của mình!
Pavel Gurov

2

Chuyển cài đặt Build> Cho phép phi mô-đun bao gồm trong Mô-đun khung thành CÓ! giải quyết vấn đề tương tự cho tôi


2

Tôi muốn thêm kinh nghiệm của tôi với vấn đề là tốt.

Chỉ cần tóm tắt:

  • Câu trả lời của @ ambientlight là tuyệt vời và nó khắc phục hầu hết các vấn đề.
  • cho phép các tiêu đề không mô-đun là một giải pháp khác (xem một số câu trả lời ở trên).
  • đánh dấu các tiêu đề của khung là công khai (chỉ những tiêu đề mà bạn muốn trưng ra) và nhập chúng vào tiêu đề ô.

Dưới đây là 2 bổ sung của tôi cho (các) câu trả lời trên:

  • kiểm tra cẩn thận việc nhập trong dự án của bạn để biết các tiêu đề nhập trực tiếp khung của bạn vào chúng (thay vì sử dụng khai báo chuyển tiếp, nếu có thể) - không nên bao gồm tệp tiêu đề bên trong tệp tiêu đề khác; đôi khi điều này gây ra một vấn đề, bởi vì nếu không được thực hiện đúng cách, điều này có thể dẫn đến nhiều bao gồm một tiêu đề và tạo ra các vấn đề liên kết.
  • CẬP NHẬT: đảm bảo rằng các kiến ​​trúc của thư viện và mục tiêu mà bạn muốn liên kết nó để phù hợp.
  • và cuối cùng, sau khi thực hiện tất cả những điều trên, tôi vẫn tiếp tục va vào lỗi đó. Vì vậy, tôi đã đào thêm một chút và tìm thấy (trong các diễn đàn dành cho nhà phát triển apple, nhưng tôi đã mất liên kết :() rằng nếu bạn bao gồm các tiêu đề trong tiêu đề ô không như thế này <framework/headerName.h>, nhưng chỉ như thế này "headerName.h", vấn đề sẽ biến mất.

Tôi đã thử cái cuối cùng này và cho đến nay tôi vẫn chưa gặp phải vấn đề này nữa, tuy nhiên tôi nghi ngờ rằng giải pháp này chỉ hợp lệ nếu bạn đã áp dụng một số câu trả lời hàng đầu (ví dụ: chúng không tương thích với nhau , cách tiếp cận mô-đun và cho phép tiêu đề không mô-đun bao gồm).


1

Tôi đã có vấn đề chính xác này khi bao gồm khuôn khổ của riêng tôi trong một dự án. Đã sửa nó bằng cách đặt tất cả các lần nhập của sqlite3.h trong các tệp .m không ở dạng .h công khai. Tôi giả định rằng các thư viện khác có thể gắn cờ các vấn đề tương tự với Xcode.


1

Tôi đã gặp sự cố cụ thể với sdk Facebook 4.02 và FBSDKCoreKit.

Tôi đã làm tất cả các bước nhưng vẫn lỗi về tiêu đề không mô-đun. tôi kéo và thả chỉ tiêu đề cụ thể từ khung để xây dựng phần tiêu đề giai đoạn->.

Sau đó, tự động tạo một bản sao của tiêu đề trên trình điều hướng dự án ở trên cùng.

Tôi đã xóa nó khỏi các giai đoạn xây dựng -> tiêu đề và xóa tệp mới và hoạt động tốt.

Giống như nó được đặt lại hoặc một cái gì đó.


1

Trong trường hợp của tôi (Xcode 9 beta 6 - Swift 4 - sử dụng Cocoapods), điều này đã được giải quyết khi tôi xóa Podfile.lock và thư mục Pods và chạy pod installlại


1

Tôi đã gặp vấn đề này sau khi cập nhật một dự án từ swift2 lên swift3. Tôi đã sử dụng XCode 8.3.2 để cập nhật mã và không thể thoát khỏi tiêu đề không mô-đun lỗi bên trong mô-đun khung. Khi tôi mở cùng một dự án trong một phiên bản XCode khác (phiên bản 9.0.1), lỗi không xuất hiện.


0

Thông thường nhất lỗi này là do câu trả lời đã chọn, nhưng tôi đã gặp lỗi này một lần do tai nạn khi kéo các tệp khung vào thư mục dự án mới của tôi. Tôi đã bấm để xóa các khung nhưng vô tình nhấn để chỉ 'Xóa tham chiếu' cho các khung thay vì thực sự xóa các tệp hoàn toàn. Tại thời điểm này, nếu tôi mở thư mục dự án của mình trong Finder, tôi đã thấy các tệp như 'CoreLocation' và 'AudioToolbox' ở đó. Xóa các tệp này khỏi thư mục dự án và làm sạch dự án đã khắc phục sự cố.


0

Sau khi cho phép nhập không bao gồm mô-đun, bạn có thể thử nhập mô-đun đó bằng tiêu đề Cầu nối Objective-C:

#import <YandexMobileMetrica/YandexMobileMetrica.h>

0

Tôi đã giải quyết nó loại bỏ Modulesthư mục từ khung.

  • Duyệt đến vị trí khung của bạn có trong Dự án ứng dụng bằng công cụ tìm

  • Đi vào Test.frameworkthư mục bên trong (Trong trường hợp trên sẽ là SOGraphDB.framework) & Xóa Modulesthư mục.

  • Làm sạch và xây dựng lại ứng dụng, nó sẽ giải quyết vấn đề.


-1

Tôi gặp vấn đề này khi nhập khung Parse. Cách duy nhất tôi có thể khắc phục là loại bỏ tất cả các thay đổi kể từ lần cam kết cuối cùng của tôi (chỉ cần xóa khung và làm sạch dự án không hoạt động) và thêm Parse một lần nữa (sau khi tải xuống SDK mới) với các khung yêu cầu khác.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.