在项目中使用CocoaPods引入OpenVPNAdapter

在项目中使用CocoaPods引入OpenVPNAdapter

一、背景

最近公司的项目需要实现接入OpenVPN功能,去github上找了一下,TunnelKit和OpenVPNAdapter是不错的选择,但是由于TunnelKit只支持ios15+,并且只能使用Swift Package Manager进行引用;加上TunnelKit依赖WireGuard,但是WireGuard没有对iOS18.2进行兼容,从GitHub上下载的TunnelKit demo运行报错。报错原因就是WireGuard导致的。我们的项目支持iOS13+,并且已经引用了WireGuard,所以TunnelKit不适合。另外,虽然OpenVPNAdapter不再更新,但是经过多年的发展,它还是非常稳定的。所以我们决定选择接入OpenVPNAdapter。

二、收益

项目支持OpenVPN

三、引入OpenVPNAdapter

通过github上OpenVPNAdapter的介绍,结合项目现状,我们决定使用cocoapods引用OpenVPNAdapter。

Profile文件增加如下行:

ruby 复制代码
target 'Your Target Name' do
  use_frameworks!
  pod 'OpenVPNAdapter', :git => 'https://github.com/ss-abramchuk/OpenVPNAdapter.git', :tag => '0.8.0'
end

然后执行pod install, 并选择项目

四、遇到的问题

安装好OpenVPNAdapter后选择项目,直接报错:

五、分析问题

错误原因分析:shared不能在app extension中使用。

原因说明:iOS的app extension运行在一个"沙盒"环境中,没有完整的生命周期和权限,不能访问全局单例,Apple明确限制app extension使用这个API是为了确保app extension的稳定性。

查看了一下NetworkExtension中的代码,也没有调用过shared呀,奇怪了???

去Google了一下,搜到一篇文章对这种错误给出了解决方案。其中以下这个答案让我找到了解决此次错误的方案:

于是我猜测可能是OpenVPN做了什么手脚。

在导入OpenVPNAdapter前,我们的项目还能正常运行的,为什么导致OpenVPNAdapter就运行报错了呢?问题大概率出在OpenVPNAdapter身上。

github上OpenVPNAdapter看了一下OpenVPNAapter的podspec文件。

果然在OpenVPNAdapter.podspec文件中看到了对应的设置。

APPLICATION_EXTENSION_API_ONLY = YES是xcode的一个构建设置,它的作用是:限制使用仅可用于App Extention的API,比如UIApplication.sharedApplication和openURL:不能在App Extension中使用。

通过在podspec中设置APPLICATION_EXTENSION_API_ONLY = YES会导致pod install后,将项目里面所有的xcconfig文件都设置成APPLICATION_EXTENSION_API_ONLY = YES。

包括Pods-xxx.xcconfig文件

包括第三方库:

明确了问题所在,现在就要想办法解决此问题。

六、解决问题

解决报错,在Profile文件下设置以下代码:

ruby 复制代码
post_install do |installer
  #修改第三方库
  installer.pods_project.targets.each do |target|
      target.build_configurations.each do |config|
        # 只对你的主工程 target 生效
        if ['YYKeyboardManager','TPEBBannerView','TYSnapshotScroll','LEEAlert','JKCategories','HWPanModal','DCKit','CJBaseHelper'].include?(target.name)
          # 解决'sharedApplication' is unavailable: not available on iOS (App Extension) - Use view controller based solutions where appropriate instead.问题
          config.build_settings['APPLICATION_EXTENSION_API_ONLY'] = 'NO'
        end
      end
  end
  
  #修改Pods-
  installer.pods_project.targets.each do |target|
      target.build_configurations.each do |config|
        xcconfig_file_ref = config.base_configuration_reference
        next unless xcconfig_file_ref
        path = xcconfig_file_ref.real_path
        next unless path.basename.to_s.start_with?("Pods-你的工程名")
        content = File.read(path)
        if content.include?("APPLICATION_EXTENSION_API_ONLY = YES")
          new_content = content.gsub("APPLICATION_EXTENSION_API_ONLY = YES", "APPLICATION_EXTENSION_API_ONLY = NO")
          File.write(path, new_content)
          puts "✅ Modified: #{path}"
        else
          puts "🔍 Skip (no YES found): #{path}"
        end
      end
   end
end

我们将会引发编译错误的所有第三方库进行了修改,将这些第三方库的APPLICATION_EXTENSION_API_ONLY改回为NO。并且将需要修改的Pods-xxx.xcconfig文件也进行了修改;
注意:App-Extension如果依赖了pod,其实是不需要修改的。

最后重新pod install,再编译就可以Success了。

七、总结

当发生错误时,要先找到导致问题的原因。再针对原因找到对应的解决方案。

相关推荐
RobinDevNotes22 分钟前
从 Electron 到 GPUI,9 个跨平台桌面方案该怎么选
前端·javascript·rust·electron·openresty·前端开发工具
jay神1 小时前
基于 YOLOv8 的轴承缺陷检测(Web 版)
前端·人工智能·yolo
jay神1 小时前
基于 YOLOv8 的森林火灾检测系统(Web 版)
前端·yolo
code2cat2 小时前
HTML基础篇之第一张网页:从index.html到浏览器里的任务清单
前端·html
miss2 小时前
AI 改完不敢上线?OpenSpec 规约驱动开发实战
前端·代码规范·前端工程化
AiMan3 小时前
腾讯ima还是不可以导出左侧所有对话,只能单条导出,方法不对吗
前端
去伪存真3 小时前
并发量一高就装死?Agent 全链路“防猝死”手册
前端·agent
Moment3 小时前
AI 编程时代,聊聊我的 Mac mini 双屏桌面
前端·后端
AiMan3 小时前
先确认能不能一次把Microsofat Copilot所有内容打包一个文件导出
前端
总要学点什么3 小时前
第97篇:三维数据加载-城市建筑白模自定义着色器——让一条光带沿高度扫上去,快慢却由帧率说了算
前端·gis·webgl·cesium·着色器·空间分析·白模