Swift derleyici hatası: “çerçeve modülünün içinde modüler olmayan başlık”


204

Şimdi ObjC çerçevemi Swift'e taşımak istiyorum ve aşağıdaki hatayı aldım:

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

Referanslar sadece bir protokol tanımlayan bir başlık dosyası ve ben bu protokolü kullanmak için bazı sınıflarda bu başlık dosyasını kullanın.

Modül özelliğiyle ilgili görünüyor ama şu anda nasıl düzeltileceği tam olarak belli değil, bir çözüm biliyor musunuz?

GÜNCELLEME:

Bu bir Swift derleyici hatasıdır.

GÜNCELLEME 2:

Hızlı bir düzeltme (ancak temel nedeni çözmemek üzere) aşağıdaki ayarı evet olarak ayarlamaktır: CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = EVET


3
Görünüşe göre "CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES" için yeni bir yapı ayarı var
Stephan

1
Bunu herkese açık ve modüler olan içeriklerde gören var mı? Bunu bir vanilya (cocoapods) projesi ile görüyorum: github.com/CocoaPods/CocoaPods/issues/3092 ve dropbox.com/s/trhe5vwhzoa9bf5/…
Chris Conover

Herkes bunu otomatik olarak etkinleştiren hızlı bir script yaptı mı?
fatuhoku

@fatuhoku evet
funroll

Bu çözümlerin hiçbiri benim için işe yaramadı, bir cıvata gibi görünüyor. Silme sorunu çözdü: stackoverflow.com/a/33114309/3324388
Aggressor

Yanıtlar:


316

Başlığınız herkese açık mı?

Proje gezgininde başlık dosyasını seçin. Ardından, xcode'un sağındaki bölümde, hedefin yanında bir açılır menü olduğunu fark edeceksiniz. Bunu "proje" den "herkese açık" olarak değiştirin. Bu benim için çalıştı.

genel başlık


Belirttiğim gibi olsa bile bu cevabı kabul ediyorum.
Stephan

Ayrıca, çerçevenizin Başlık oluşturma aşamasına gidebilir ve hangi başlıkların Genel, Proje ve Özel olduğunu hızlı bir şekilde görebilirsiniz.
Jose Ibanez

Bu basit görevin, SO'ya gelmeden önce bir saatten fazla bir süredir bununla savaştığım için muhtemelen çözüm olabileceğini düşünmüyordum. Bakın, bu TAM çözümdü ve hemen çalıştı.
TMc

1
Ve bu başlıkların dahili olmasını istersem ne olur ?
Raphael

2
Bu da benim sorunumu çözdü! Benim durumumda, başka bir kapsüle bağlı olan bir bölmem modüler sorun nedeniyle içe aktaramaz. Bu nedenle, genel modu kullanarak bazı başlıkları başka bir kapsül için hedef olarak dahil ettim. Ve sorunu çözdü!
Chen Li Yong

135

Bu beklenen bir derleyici davranışıdır ve çok iyi bir nedendir.

Onların arasında geçiş yaptıktan sonra bu sorunlar yaşamaya devam insanların çoğunluğu neden olur düşünmek Application Targetiçin Framework Targetve çerçevenin içine C ve Objective C başlıklarını eklemeye başlayın şemsiye başlığındaki bunun gibi bir aynı davranışı olması bekleniyor uygulamanın Bridging Başlık farklı davranır. Şemsiye başlığı aslında karışık hızlı, obj-c çerçevesi için tasarlanmıştır ve amacı API'ları çerçevenizin objektif-c veya c'de olduğu dış dünyaya maruz bırakmaktır. Bu, koyduğumuz başlıkların kamuya açık olması gerektiği anlamına gelir.

Çerçevenizin bir parçası olmayan Objective-C / C başlıklarını çerçevenizin hızlı koduna maruz bırakan bir yer olarak kullanılmamalıdır. Çünkü bu durumda bu başlıklar aynı zamanda çerçeve modülümüzün dış dünyaya bir parçası olarak ortaya çıkacaktır, bu da modülerliği bozduğu için yapmak istediğimiz şey değildir. (Tam da bu yüzden Çerçeve Modüllerine Modüler Olmayan Eklemelere İzin Ver, varsayılan olarak NO'dur )

Objective-C / C kütüphanesini çerçeve swift kodunuza göstermek için, bu kütüphane için ayrı bir swift modülü tanımlamalıyız. Daha sonra standart bir kaydırma import YourLegacyLibrarykullanılabilir.

Bunu bazı tipik senaryolarda göstereyim: libxml2çerçevemize gömmek .

1. İlk önce module.modulemapşu şekilde görünecek bir dosya oluşturmanız gerekir :

OSX çerçevesi için:

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

İOS çerçevesi için:

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

Yaptığı tek şey, üstbilgiyi ve swift modülünün içinde referans verdiği diğer başlıkları sararak, böylece daha sonra hızlılık bu C arayüzleri için hızlı bağlar oluşturabilir.

2. Daha sonra xcode proje dizininizde bir klasör oluşturun SwiftLibXML2ve bu module.modulemap dosyasını buraya yerleştirin

3. yılında Yapı Ayarlar eklemek $(SDKROOT)/usr/include/libxml2için Başlık Arama Yolları

4. yılında Yapı Ayarlar eklemek $(SRCROOT)/SwiftLibXML2için İthalat Yollar

5. Altında Projesi Genel sekmesi eklemek libxml2.tbdiçin Bağlantılı kafes ve Kütüphaneleri .

Şimdi bu modülü gereken yerlerde içe aktarın:

import SwiftLibXML2

(daha eksiksiz bir module.map örneğine bakmak istiyorsanız, Darwin'in module.modulemap'ine /usr/include/module.modulemapbaşvurmayı öneririm , oraya gitmek için Xcode komut satırı araçlarına sahip olmanız gerekir, Eksik / usr / OS X El Capitan'a bakın )


1
Dosya adı module.mapkullanımdan kaldırıldı, module.modulemap clang.llvm.org/docs/Modules.html#attributes
Hyperbole

import SwiftLibXML2Objective-C'de nasıl yapılır ? Teşekkürler!
Itachi

diğer obj-c ithalatlarıyla aynı şekilde: #import <libxml / xpath.h> ancak 3-5. adımları uyguladığınızdan emin olun.
ambientlight

Bunu yaptık, ancak daha sonra yapı artefaktı makineler arasında taşınamaz: Objective-C (alt) modülü, görünüşte mutlak yollar kullanılarak bağlanır ve örneğin, gönderdiğiniz çerçeveyi kullanan bir uygulama derlenirken hatalara neden olur.
Raphael

hata büyük olasılıkla derleme sürecinize özgüdür, bu sadece bir modül tanımıdır, böylece modüllerin desteklendiği llvm dilleri diğerleriyle birlikte çalışabilir, kendi kendinize yapı eserlerinizi etkileyebileceğini düşünmüyorum, topluluk beni düzeltebilirse yanlış
ambientlight

55

Hızlı düzeltmeyi otomatik olarak nasıl uygulayacağınız aşağıda açıklanmıştır, böylece Pods.xcodeprojher birinden sonra manuel olarak değişiklik yapmanız gerekmez pod install.

Bu snippet'i Podfile'ınızın sonuna ekleyin:

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

Benim için çözüm hedefe gitmekti- > yapı ayarları-> Çerçeve Modüllerinde modüler olmayan içeriğe izin ver EVET'e geçin!


Ayrıca burada Cocoapods ile çalıştı. Pod kurulumundan sonra diğer cevabın sihrini yapmaya gerek yok
brainray

3
Bu adımı yaptım .. bir süre çalıştı .. ve şimdi çalışmıyor ... Pod yükleme adımını da dahil ettim. Ama şimdi yine başarısız oluyor. Kontrol etmem gereken başka bir şey var mı? GoogleMobileAds.Framework uygulamasını üstbilgileri Herkese Açık olarak değiştirme seçeneği olarak görmüyorum.
Michael Rowe

Bu benim için işe yaramadı. Ayrıştırma ile hala hatayı alıyorum. Xcode 7.3.1
C0D3

Çalışması için bu değişikliği yaptıktan sonra XCode'u yeniden başlatmak zorunda kaldım.
John Fowler

1
Bu ayarı değiştirmenin etkisi nedir?
nr5

15

Sanırım bunun üstesinden geldim. Bir çerçevede sqlite3 kullanan bazı model kodu var. Benim durumumda suçlu <sqlite3.h> idi.

Sorun, benim Module / Module.h başlığımda, <sqlite3.h> dosyasını alan bir genel üstbilgiyi içe aktarmamdı. Çözüm tüm sqlite3_xxx tiplerini gizlemek ve bunların herhangi bir genel .h dosyasında görünmemelerini sağlamaktı. Sqlite3'e doğrudan yapılan tüm referanslar özel veya proje görünürlüğü haline getirildi. Örneğin, bazı sqlite3_stmt işaretçiler asılı olan bir kamu single vardı. Bunları ayrı bir sınıfa taşıdım. Şimdi inşa edebilirim.

Bu arada, CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES ayarı çalışmadı. Hem çerçevede hem de bağımlı projede ayarlamayı denedim. Bu geçici çözüm gerekliydi, ancak neden olduğundan emin değilim.


Bu tamamen yardımcı oldu! Benim durumumda, ulaşılabilirlikti.
Daniel Brim

4
Çerçeve modülüme SSZipArchive'ı eklemeye çalıştığımda sorunumun çözümü olduğundan eminim. Genel üstbilgi <zlib.h> dosyasını içe aktarıyor ve aynı hatayı veriyor. Kaynak kodunuzu bir yere gönderebilir misiniz, çünkü cevabınızın sadece bir kısmını anladığım için işe koyuluyorum. Teşekkürler!
Bruce

15

In Swift :

1. Xcode projenizi ve hedeflerin Oluşturma Ayarlarını aşağıda belirtildiği şekilde değiştirin:

Çerçeve Modüllerinde Modüler Olmayan İçeriğe İzin Ver: Hayır

Bit kodunu etkinleştir: Evet

2. GoogleMaps iOS SDK için mevcut olan en son sürümü kullanın (almak için CocoaPod'ları kullanın):

GoogleMaps (1.10.4)

3. Sorunlu içe aktarmayı yorumlayın:

//import GoogleMaps

4. Sorunlu içe aktarmayı ekleyerek köprüleme başlık dosyanızı oluşturun veya değiştirin:

[Xcode Proje Adınız] -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 projenizi temizleyin ve yeniden oluşturun.


1
Bu çok yardımcı oluyor! Ayrıca GoogleMobilAds çerçevesiyle harika çalışıyor (Cocoapods ile)
bluenowhere

başlık dosyasının nasıl oluşturulacağı hakkında daha ayrıntılı bilgi için bkz. stackoverflow.com/a/51227304/529663
lenooh

6

Bu cevap eski.

Çerçeveleri içe aktarırken , kök üstbilgiyle bağımlılıkları paylaşan tüm başlık dosyalarını içe aktarmanız gerekir . Bunun her zaman çalışmasını sağlamanın en kolay yolu, çerçevenin "Üstbilgiler" klasöründeki tüm üstbilgileri genel üstbilgiler yolunuza aktarmaktır.

resim açıklamasını buraya girin

Swift derleyicisi, bu bilgileri, ilişkili tür bilgileriyle birlikte yönetilmeyen sembollerin bir haritasını oluşturmak için kullanır.


Bu, Framework dosyalarına sahip olma amacını bozuyor gibi görünüyor, ancak benim için çalıştı. Chartboost ve RevMob yakın zamanda sadece libs yerine Framework dosyalarını kullanmaya başladı. Her şeyi başlıklarından uygulama başlıklarına kopyalamak sorunu çözer.
Jason Short

Tek çözüm bu mu? 6 çerçevem ​​var ve her çerçevenin yaklaşık 20 başlığı var. Bir karmaşa yaratıyor. Alternatif var mı?
vivin

1
Muhtemelen daha fazla. Bu muhtemelen bir Xcode hatası için geçici bir çözüm olduğu için artık geçerli değil.
seo

6

Yapma

#import "MyOtherFramework.h"

Yapmak

#import <MyOtherFramework/MyOtherFramework.h>

3

Başlık dosyası hedefe tahsis edildi, ancak yalnızca proje görünür olarak işaretlendi, sadece herkese açık bir değişiklik bu hatanın çözümlenmesine yol açtı.


Bunu tam olarak nasıl yapabilirim? TwitterKit başlık dosyalarımla sorun yaşıyorum
Vinod Sobale

2

Bunun eski bir soru olduğunu biliyorum, ama aynı sorunu yaşadım ve yukarıdan hiçbir şey bana yardımcı olmadı. Umarım cevabım birisi için faydalı olur. Benim durumumda sorun ALWAYS_SEARCH_USER_PATHS ayarındaydı. Hayır proje olarak ayarlandığında ve inşa tamam ok. Ancak kapsülden birinin EVET olarak ayarlanmasını gerektirdiği sürece bir hata alıyordum

Çerçeve modülünün içine modüler olmayan başlık dahil

Birkaç fincan kahve ve tüm gün araştırdıktan sonra, Xcode 7.1 Beta 2 sürüm notlarının bilinen sorunlarına göre şunu öğrendim :

• Daha önce derlenen bir çerçeve için "Çerçeve modülünün içine modüler olmayan üstbilgiyi dahil et" ifadesini alırsanız, "Her zaman Kullanıcı Yollarını Ara" oluşturma ayarının "Hayır" olarak ayarlandığından emin olun. Yalnızca eski nedenlerle varsayılan "Evet" tir. (22784786)

XCode 7.3 kullanıyordum, ancak bu hata henüz düzeltilmemiş gibi görünüyor.


Bu bana yardımcı oldu! NO'ya geçtikten sonra bazı ithalatları değiştirmek zorunda kaldım, ancak şimdi gerekli çerçevemi içe aktarabildim!
Pavel Gurov

2

Anahtarlama Yapı ayarları> olmayan modüler için Çerçeve Modülleri içerir izin EVET! benim için aynı sorunu çözdü.


2

Sorunla ilgili deneyimimi de eklemek istiyorum.

Özetlemek gerekirse:

  • @ ambientlight'ın yanıtı harika ve sorunların çoğunu çözüyor.
  • modüler olmayan başlıklara izin vermek başka bir çözümdür (yukarıdaki cevapların bazılarına bakınız).
  • çerçevenin başlıklarını herkese açık olarak (yalnızca göstermek istediklerinizi) işaretleme ve bunları şemsiye başlığına aktarma.

Yukarıdaki yanıtlara 2 eklemem:

  • projenizdeki içe aktarma işlemlerini, çerçevelerinizi doğrudan içe aktaran başlıklar için kontrol edin (mümkünse ileri bildirim kullanmak yerine) - başka bir başlık dosyasının içine bir başlık dosyası eklemek iyi bir uygulama değildir; bazen bu bir soruna neden olur, çünkü düzgün yapılmazsa bu bir başlığın birden fazla dahil edilmesine ve bağlayıcı sorunlarına neden olabilir.
  • GÜNCELLEME: kütüphanenin ve onu bağlamak istediğiniz hedefin mimarilerinin olduğundan emin olun.
  • ve son olarak, yukarıdakilerin hepsini yaptıktan sonra, hala bu hataya çarpmaya devam ettim. Bu yüzden biraz daha kazdım ve (elma geliştirici forumlarında buldum, ancak bağlantıyı kaybettim :() Şemsiye başlığına başlıkları eklerseniz böyle olmaz <framework/headerName.h>, ancak sadece bunun gibi "headerName.h", sorun ortadan kalkar.

Bu sonuncusu denedim ve şimdiye kadar bu sorunu yaşamadım, ancak bu çözümün sadece en iyi cevapları uyguladıysanız geçerli olduğunu düşünüyorum (not: hepsi birbiriyle uyumlu değil, örneğin) , modül yaklaşımı ve modüler olmayan başlıklara izin verilmesi dahil).


1

Bir projeye kendi çerçevemi dahil ederken bu problemim vardı. Sqlite3.h dosyasının tüm içe aktarımlarını herkese açık .h dosyalarına değil .m dosyalarına koyarak düzeltildi. Diğer kütüphanelerin Xcode ile benzer sorunları işaretleyebileceğini varsayıyorum.


1

Facebook 4.02 sdk ve FBSDKCoreKit ile ilgili özel bir sorun vardı.

Tüm adımları yaptım ama hala modüler olmayan başlık hakkında hata. i aşamalar>> başlık bölümü oluşturmak için sadece çerçeveden belirli bir başlık sürükleyip bıraktı.

Ardından, üstteki proje gezgininde başlığın otomatik olarak bir kopyasını oluşturdu.

Derleme aşamalarından -> başlığından kaldırdım ve yeni dosyayı sildim ve iyi çalıştım.

Sıfırlanmış gibi falan.


1

Benim durumumda (Xcode 9 beta 6 - Swift 4 - Cocoapods kullanarak) sildim bu çözüldü Podfile.lock ve Bölmeler dizini ve ran pod installtekrar


1

Bir projeyi swift2'den swift3'e güncelledikten sonra bu sorunu aldım. Kodu güncellemek için XCode 8.3.2 kullanıyordum ve “çerçeve modülünün içindeki modüler olmayan başlık” hatalarından kurtulamadım. Aynı projeyi başka bir XCode sürümünde (sürüm 9.0.1) açtığımda hata görünmedi.


0

En sık olarak bu hata seçilen cevaptan kaynaklanır, ancak çerçeve dosyalarını yeni proje klasörüne sürüklerken yanlışlıkla bir kez bu hatayı gördüm. Çerçeveleri silmek için tıkladım ancak yanlışlıkla dosyaları tamamen silmek yerine yalnızca çerçevelere 'Referansı Kaldır' düğmesine bastım. Bu noktada proje klasörümü Finder'da açarsam, orada 'CoreLocation' ve 'AudioToolbox' gibi dosyalar gördüm. Bu dosyaları proje klasöründen silmek ve projeyi temizlemek sorunu çözdü.


0

Modüler olmayan içerikleri içe aktarmaya izin verdikten sonra, Objective-C Köprüleme başlığını kullanarak bu modülü içe aktarmayı deneyebilirsiniz:

#import <YandexMobileMetrica/YandexMobileMetrica.h>

0

ModulesKlasörü çerçeveden kaldırarak çözdüm.

  • Bulucu kullanarak Uygulama Projesi'nde bulunan çerçeve konumunuza göz atın

  • Test.frameworkKlasörün içine gidin (Yukarıdaki durumda olacaktır SOGraphDB.framework) & ModulesKlasörü sil .

  • Temiz ve Yeniden Uygulamayı oluşturun, sorunu çözecektir.


-1

Ayrıştırma çerçevesini içe aktarırken bu sorunla karşılaştım. Bunu çözebilmemin tek yolu, son taahhüdümden bu yana tüm değişiklikleri silmek (sadece çerçeveyi silmek ve projeyi temizlemek işe yaramadı) ve diğer gerekli çerçevelerle tekrar (SDK'nın yeni bir indirilmesinden sonra) eklemek oldu.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.