在项目中使用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了。

七、总结

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

相关推荐
福兮说7 分钟前
前端下载大文件,点了按钮半天没反应:fetch + blob 的三个问题和三种替代写法
前端·javascript·性能优化·文件下载
GreenTea15 分钟前
我把 Agent 的 while 循环拆掉了:一种你可能没想到的 Agent 架构
前端·后端·架构
科技观察哨33 分钟前
六足平台选型与纳米定位系统集成:HEB-640六自由度位移台在半导体光刻对准中的参数边界与国产替代评估
前端·人工智能
niucloud-admin1 小时前
JAVA V6 多商户商城 开发文档——web前端
前端
颜进强1 小时前
16 · NestJS LifecycleEvents 生命周期事件:五个钩子、三条边界,和 rag-server 的优雅停机
前端·后端·ai编程
今年下半年3 小时前
【VUE】整合腾讯地图、自定义区域边界、村委名称及资产统计(放大显示资产点位)
前端·javascript·vue.js
郑州光合科技余经理3 小时前
同城电商系统:库存变更怎么同步到订单
java·开发语言·前端·后端·uni-app·php·ai编程
前端snow4 小时前
ai agent --- DeepAgents 中间件
前端
data analyse 4565 小时前
报表能自定义的国内统计工具有哪些
前端·数据分析