failed to emit precompiled header 以及 "xxx-Swift.h" file not found

2,955 阅读3分钟

问题背景

Swift项目引用OC库和OC文件,OC库使用Cocoapods引入,在桥接文件里放入OC库的引用和自己OC文件的引用,OC文件引用"xxx-Swift.h"报两个错误

failed to emit precompiled header "xxx.pch" for bridging header "xxx.h"
"-Swift.h" file not found

问题重现

1、新建了项目没有用pods,创建桥接文件并设置路径(系统创建的会自动设置路径),桥接文件里放入自己的OC文件Swift使用没问题,OC文件里引入xx-Swift.h提示找不到swift的类,倒是没有报"-Swift"file not found,但是也运行不起来
2、使用了pods,桥接文件里放入第三方库文件没问题,OC文件里引入xx-Swift.h没放在桥接文件里使用也没问题,但是桥接文件里再放入自己的OC文件就报问题了:
1、OC文件里的xx-Swift.h file not found
2、failed to emit precompiled header "xxx.pch" for bridging header "xxx.h"

寻找解决办法

CSDN、Stackflow、百度等都找了,下面的解决办法对我没有用,我会在后面写我的解决办法 1、

1 I added $(inherited) non-recursive to Search Path -> Header Search Paths
2 Then added ${PODS_ROOT} recursive to Search Path -> User Header Search Paths

2、 检查了桥接文件文件的名称,检查了项目的名称,检查了桥接文件的路径,检查-Swift文件的名称(有可能更改了项目名称,需要跟着修改)
3、use_frameworks!,删除pod.lock,删除pods,重新pod install
4、看到有个说把"-Swift.h"文件放在.m里引用,果然可以了。但是我.h里需要声明一个swift文件的属性,这是个基础类,swift需要继承这个基础类。把"-Swift.h"文件放在.h文件就会报错,找到原因了。

最后的解决办法

直接在.h里@class那个swift文件,比如HttpModel,在.m里引入"-Swift.h"文件,就可行了

解决思路

来源swift 与 OC混编,互相引用头文件导致编译器报找不到swift.h文件,如何解决? 大佬的回答解决了疑问:
如果桥接文件引用了OC文件,并且OC文件又引用-Swift文件,就会造成循环调用。原因是-Swift.h包含了桥接文件这是没想到的。
之后也就有了经验,比如文件找不到也有可能是循环调用引起的。
比如OC文件.h单独引用-Swift.h是可以的,不要造成循环就可以,swift记得加@objc或@objcMembers才能被OC引用。
Swift文件引用OC文件,把OC文件放入桥接文件就可以了,注意桥接文件的路径要配置在Build Setting里

补充

有帖子说是use_framework!的问题,发现不是,但是也找到了use_frameworks!使用和不使用的区别
默认是pod install是配置好路径的,如果后面手动修改就会出现找不到第三方库文件,使用了use_frameworks,那么在Framework Path后面添加$(inherited) non-recursive,否则在Library Path后面添加。在终端pod install结束后如果有路径问题会有提示的

总结

Swift项目中Swift调用OC还可以通过桥接文件控制需要调用的OC类库,但是OC文件里调用Swift文件需要直接导入"-Swift"文件,意味着导入了所有的.swift文件,这在Swift项目中是不靠谱的,所以还是不建议这么做。
OC项目中OC调用Swift,Swift文件直接开放出来@objc或@objcMembers,Swift调用OC文件使用桥接文件就可以控制,没有这个问题。