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

七、总结

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

相关推荐
仿生狮子4 小时前
OpenAI 攻下千禧年难题之后,开发者似乎无动于衷
前端·数学·vibecoding
Lvan的前端笔记8 小时前
docker:每个前端项目一个 Nginx 容器还是只有一个Nginx容器
前端·nginx·docker
三天不学习8 小时前
Egg.js 4 突然爆火,原因是否归结于AI 原生落地需求爆发?
前端·javascript·全栈·egg.js
xcs194059 小时前
前端 vue 的前端页面debugger 进不去
前端·javascript·vue.js
明月_清风10 小时前
Deno 终局来了:从挑战 Node 到被 Cloudflare 收编
前端·后端·node.js
Csvn11 小时前
框架性能优化
前端
回眸&啤酒鸭12 小时前
【回眸】OpenSwarm 多智能体协作系统实战指南
大数据·前端·人工智能
用户693717500138413 小时前
2026,程序员的时代拐点到了
android·前端·后端
大龄秃头程序员13 小时前
一次 iBeacon + BLE 无感解锁方案的实现记录
前端
小兔子13 小时前
Python 的 GIL 与 free-threading:3.13 之后「去 GIL」走到哪一步了
前端