接手的公司iOS项目是组件化开发,项目也比较大,App Store显示的包有400多M,并且无法适配模拟器。所以,首先我来进行模拟器适配。
1、报错building for iOS Simulator, but linking in object file built for iOS
如报错
In /Users/zhanyu/Workspace/iOS/********_iOS/Pods/ZYMapKit/BaiduMapFramework/BaiduMapAPI_Utils.framework/BaiduMapAPI_Utils(BMKOpenPoiOption.o), building for iOS Simulator, but linking in object file built for iOS, file
'/Users/zhanyu/Workspace/iOS/********_iOS/Pods/ZYMapKit/BaiduMapFramework/BaiduMapAPI_Utils.framework/BaiduMapAPI_Utils' for architecture arm64
这个问题目前应该只出现在M1芯片的Mac上,似乎又是一个兼容性问题,因为M1芯片的Mac本身就是arm架构,所以模拟器自然也支持arm架
第一步修改Podfile文件
# config.build_settings['VALID_ARCHS'] = ['arm64', 'x86_64','arm64-apple-ios']
config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
第二步修改,在编译设置中,对模拟器排除 arm64
然后pod install
再检查
第三步:在主项目和pod项目的PROJECT的Build Settings中,删除VALID_ARCHS(整个删除,不能只删除value留下Key
Xcode 12不再支持VALID_ARCHS,需移除!采用Excluded Architectures过滤掉不需要的架构即可!
如果项目在Build Settings下的User-Defined中添加了VALID_ARCHS属性,需要将其移除,否则无法在Xcode 12编译运行设备。
如果确实需要设定支持/不支持的架构,通过Excluded Architectures配置即可。
ps:ios模拟器运行报错
Command PhaseScriptExecution failed with a nonzero exit code,也可以尝试以上方式解决
2、模拟器不支持的库瑞修德、推送、PKI、PLPlaykit、爱心推PLMediaStreamingKit
如报错Could not find module 'RXD_SDK' for target 'x86_64-apple-ios-simulator'; found: arm64, arm64-apple-ios, at:
先用如以下方式过滤import和调用代码
#if targetEnvironment(simulator)
import RXD_SDK
#else
#endif
如报错
Undefined symbol: OBJC_CLASS$_HDtuiliuVideoViewController
在HDtuiliuVideoViewController类中找到代码引用PLPlaykit代码
#if TARGET_IPHONE_SIMULATOR
#else
// 初始化 PLPlayerOption 对象
PLPlayerOption *option = [PLPlayerOption defaultOption];
// 更改需要修改的 option 属性键所对应的值
[option setOptionValue:@10 forKey:PLPlayerOptionKeyTimeoutIntervalForMediaPackets];
[option setOptionValue:@2000 forKey:PLPlayerOptionKeyMaxL1BufferDuration];
[option setOptionValue:@1000 forKey:PLPlayerOptionKeyMaxL2BufferDuration];
[option setOptionValue:@(YES) forKey:PLPlayerOptionKeyVideoToolbox];
[option setOptionValue:@(kPLLogNone) forKey:PLPlayerOptionKeyLogLevel];
self.player = [PLPlayer playerLiveWithURL:[NSURL URLWithString:self.model.playUrl] option:option];
self.player.delegate = self;
self.player.playerView.frame = CGRectMake(0, 180, kScreenWidth, 250);
[self.videoView addSubview:self.player.playerView];
[self.player play];
#endif
如调用了PLMediaStreamingKit中代码也报错,可以修改
#if TARGET_IPHONE_SIMULATOR
#else
[PLStreamingEnv initEnv];
#endif
其他的地方,如
#if targetEnvironment(simulator)
#else
if viewController is QYSessionViewController {
printLog(message: "已进入客服页面")
#endif
#if targetEnvironment(simulator)
#else
let option = QYSDKOption.init()
option.appKey = ThirdLibConfig.shared.QY_NIM_Appkey
option.appName = ""
option.isFusion = false
QYSDK.shared().register(with: option)
#endif
/** 获取Wifi Ssid */
public func getSsid() -> String? {
if let interface : CFArray = CNCopySupportedInterfaces() {
#if targetEnvironment(simulator)
#else
NSLog("\(interface)");
for i in 0..<CFArrayGetCount(interface) {
let interfaceName: UnsafeRawPointer = CFArrayGetValueAtIndex(interface, i);
NSLog("\(interfaceName)");
let rec = unsafeBitCast(interfaceName, to: AnyObject.self)
if let unsafeInterfaceData = CNCopyCurrentNetworkInfo("\(rec)" as CFString), let interfaceData = unsafeInterfaceData as? [String : AnyObject] {
if let ssid = interfaceData["SSID"] as? String {
return ssid
}
}
}
}
#endif
return nil;
}
3、七牛 - Qiniu (= 7.2.5)版本中HappyDNS问题
dyld[52532]: Library not loaded: @rpath/HappyDNS.framework/HappyDNS
Reason: tried: '/Users/zhanyu/Library/Developer/Xcode/DerivedData/***-fjmngiqwdvbcdyasnbmgeutgqouy/Build/Products/Debug-iphonesimulator/HappyDNS.framework/HappyDNS' (errno=2), '/Users/zhanyu/Library/Developer/CoreSimulator/Devices/CFD4C541-F60A-4190-8CEB-4CFC402A7431/data/Containers/Bundle/Application/3C0A8B63-C41B-49CA-8073-960CF74711ED/*****.app/Frameworks/HappyDNS.framework/HappyDNS' (fat file, but missing compatible architecture (have 'armv7,arm64', need 'x86_64')),
PLShortVideoKit在podspec中dependency了Qiniu7.2.5,Qiniu7.2.5有个0.3版本HappyDNS.framework依赖,但是这个版本压根没用还会导致报错。
这个问题我想了很多方式解决都没用,
如果升级PLShortVideoKit到3.2.5,七牛变成8.2.0,会导致其他报错。
如果删除HappyDNS.framework的引用 -framework "HappyDNS",模拟器能跑起来,但是pod install后,删除的内容又会复原。
最终方法:
在本地引入PLShortVideoKit.podspec,版本还是3.1.1,但不依赖s.dependency 'Qiniu', '7.2.5'
在本地引入Qiniu.podspec,版本还是7.2.5,但不依赖s.dependency 'HappyDNS', '~> 0.3'
然后再Podfile中
# PLShortVideoKit用自己编写的podspec,剔除HappyDNS,解决HappyDNS不适配模拟器问题
pod 'PLShortVideoKit', :podspec => 'PLShortVideoKit.podspec'
pod 'Qiniu', :podspec => 'Qiniu.podspec'
pod install后完美解决问题
模拟器能跑起来了
打包时爆了个错
error: Build input file cannot be found: '/Users/zhanyu/Library/Developer/Xcode/DerivedData/***-bilorlkikiiqdgbzqzutxjdoxkfz/Build/Intermediates.noindex/ArchiveIntermediates/JFDriver/IntermediateBuildFilesPath/UninstalledProducts/iphoneos/JFDriverWidgetExtension.appex/***WidgetExtension'. Did you forget to declare this file as an output of a script phase or custom build rule which produces it? (in target '***WidgetExtension' from project 'JFDriver')
在***WidgetExtension target 以下地方release也要进行设置
如果一个.framework只有真机库,需要在模拟器中运行,此时加载库的时候会报错。
解决方法:在Excluded Source File Names中配置
只有在模拟器环境下,不使用的库:(如果在代码中还要加上#if TARGET_OS_SIMULATOR进行模拟器的逻辑判断。)