在项目中使用CocoaPods引入OpenVPNAdapter

在项目中使用CocoaPods引入OpenVPNAdapter

一、背景

最近公司的项目需要实现接入OpenVPN功能,去github上找了一下,TunnelKitOpenVPNAdapter是不错的选择,但是由于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.sharedApplicationopenURL:不能在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了。

七、总结

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

相关推荐
掘金者阿豪10 分钟前
把业务数据变成共享仪表盘:Metabase可视化与远程访问实践
前端·后端
kyriewen30 分钟前
折腾了半年 AI 编程工作流,最后发现效率瓶颈是桌上那块屏幕
前端·javascript·ai编程
蜗牛前端1 小时前
codex 全流程开发上线的高颜值礼簿小程序
前端·微信小程序
大龄秃头程序员2 小时前
我在图文流 App 里落地双层缓存、弱网降级与 OOM 治理
前端
老王以为2 小时前
React Renderer 分离的多平台架构
前端·react native·react.js
hunterandroid2 小时前
Kotlin Coroutines 与 Flow:让异步任务更清晰
前端
Bigger2 小时前
从零搭建 AI 代码审查服务:一份前端也能看懂的 Python 学习笔记
前端·ci/cd·ai编程
lichenyang4533 小时前
JSAPI、NAPI、Biz、Imp:ASCF Demo 如何真正调用系统能力和 C++ 能力
前端
lichenyang4533 小时前
IPC、JSVM、UIThread、libuv:ASCF 架构图里最容易混的几个词
前端
用户059540174463 小时前
Redis记忆存储故障恢复测试踩坑实录:手动测试让我漏掉了2个一致性Bug
前端·css