文章目录
- 背景
- 环境准备
- 基础工具:xcode安装
- 主要工具
- 安装CocoaPods
- 基本步骤
- 采用Expo go运行
- iOS模拟器运行
- 安装在真机上测试
- 发布到苹果商店
- 原生模块与编译链接问题
- 静态库和 Framework
- use_frameworks!和use_modular_headers!
- 常见问题
- ruby3在macOS上编译失败
- import of module ‘glog.glog.log_severity’ appears within namespace ‘google’
- yarn网络问题
- pod安装失败
- unable to open settings file
- xcode运行报Undefined symbol: _OBJC_CLASS_$_RCTImageLoader
- Unable to resolve "missing-asset-registry-path" from
- Undefined symbols for architecture XXX
- 相关链接
背景
准备将之前的一个React Native应用部署到iOS上,于是开始了探索之旅。
一下子就牵扯出了Ruby,CocoaPods,Expo等新事物,虽然我很早以前搞过Ruby,但早就放弃了,没想到今天还得重新装一把ruby, gems。
React Native本身代码不难写,但打包部署似乎比开发程序还麻烦,当然打包部署是一锤子买卖。
涉及工具:Ruby, Node, CocoaPods, npx, yarn, react native, expo
环境准备
调查研究表明,搭建各种软件环境占据程序员四分之一的时间。采用RN for iOS时,安装pod和编译pod是一大险滩,你在package.json中引入了多少依赖,差不多就要安装多少个pod。各种版本的差异,会导致形形色色的编译问题。
基础工具:xcode安装
brew -v
xcodebuild -version
xcrun swift -version
swift --version
主要工具
先安装nvm,再安装node。我安装的是v20.11.0。
npx是一个由Node.js官方提供的用于快速执行npm包中的可执行文件的工具。它可以帮助我们在不全局安装某些包的情况下,直接运行该包提供的命令行工具。npx会在执行时,检查本地项目中是否安装了对应的依赖,如果没有安装则会自动下载安装,并执行命令。如果本地已经存在该依赖,则直接执行命令。
查看几个主要工具的版本:
## expo版本
npx expo -v
0.17.5
## create-expo-app版本
create-expo-app -v
2.1.1
## react-native版本
react-native -v
react-native-cli: 2.0.1
react-native: 0.73.4
## pod 版本
pod --version
1.15.2
安装CocoaPods
CocoaPods是开发iOS项目的库管理工具。它拥有超过55,000个库,并在超过300万个应用程序中使用。通过CocoaPods可以帮助我们优雅地扩展项目,便捷的导入第三方开源库。
cocoapod 是用ruby写的。在工程文件里执行 pod init 会生成Podfile文件,通过Podfile文件来下载依赖的库。所以少不了和ruby打交道。
CocoaPods is a dependency manager for Swift and Objective-C Cocoa projects. It has over 98 thousand libraries and is used in over 3 million apps. CocoaPods can help you scale your projects elegantly.
安装步骤:
## 先安装rvm和ruby
brew install gnupg
gpg --keyserver hkp://pgp.mit.edu --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
curl -sSL https://get.rvm.io | bash -s stable --ruby## 查看rvm版本:
rvm -v
## 查看现在使用RVM管理的Ruby版本:
which rvm
##列出可供RVM使用的Ruby版本:
rvm list
## 列出可安装的版本:
rvm list known
设置代理:
git config --global http.proxy socks5://127.0.0.1:1080
git config --global https.proxy socks5://127.0.0.1:1080
sudo killall -HUP mDNSResponder ## 刷新本地环境
#取消代理的方式
git config --global --unset http.proxy
git config --global --unset http.https://github.com.proxy
这样,执行pod install 和 pod update速度都会变快
更换gem源和pod源:
gem sources l ## 查看当前源
gem sources --remove https://rubygems.org/
gem sources -a https://mirrors.aliyun.com/rubygems/ ## 添加新阿里巴巴gem镜像
## 在Podfile里添加
source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git'
基本步骤
基本命令:
create-expo-app <项目名称> ## 创建一个expo项目
npx expo prebuild ## 创建iOS或android目录
npx expo run:ios ## 创建目录,且编译
npx expo run:ios --configuration Release
修改Podfile, 增加下面行:
use_frameworks!
#use_modular_headers!
pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec', :modular_headers => false
pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec', :modular_headers => false
#pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec', :modular_headers => false
pod 'RCT-Folly', :podspec => '../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec', :modular_headers => false
#pod 'RCT-Folly.default-Fabric-Futures', :podspec => '', :modular_headers => false
pod 'boost', :podspec => '../node_modules/react-native/third-party-podspecs/boost.podspec', :modular_headers => false
# pod 'React-utils', :podspec => '../node_modules/react-native/ReactCommon/react/utils/React-utils.podspec', :modular_headers => false
# pod 'React-Mapbuffer', :podspec => '../node_modules/react-native/ReactCommon/React-Mapbuffer.podspec', :modular_headers => false
采用Expo go运行
如果采用Expo go托管测试,则运行yarn expo start,然后用iPhone的扫码器扫一下二维码,就可以安装在真机上运行了。这种方式仅用于开发阶段。
iOS模拟器运行
执行npx expo run:ios后正常运行起来后的样子:
这种方式可以用于应用的开发测试。
也可以通过xcode启动模拟器,如果没有编译错误,就能启动模拟器,运行你的app:
安装在真机上测试
如果要部署到真机上测试,可以用xcode打开ios目录下的xcworkspace工程文件,然后点运行即可。设备里选你的真机,就会跑在真机上。这种方式只需要有Apple ID并创建测试证书即可。
发布到苹果商店
采用Expo提供的EAS工具就可以发布到App Store。基本步骤如下:
npm install -g eas-cli ## 安装eas命令行工具
eas build:configure ## 配置你的项目
eas build --platform ios ## 构建你的app
eas submit -p ios ## 提交到Apple store
原生模块与编译链接问题
静态库和 Framework
- *.a 的静态库类似于编译好的机械代码,源代码和库代码都被整合到单个可执行文件中,所以它会和设备架构绑定,并且不包含资源文件比如图片;
- Framework 支持将动态库、头文件和资源文件封装到一起的一种格式,其中动态库的简单理解是:不会像静态库一样被整合到一起,而是在运行或者运行时动态链接;
use_frameworks!和use_modular_headers!
use_frameworks!告诉 CocoaPods 你想使用 Framework 而不是静态库,而默认由于 Swift 不支持静态库,因此有一开始 Swift 必须使用 Framework 的限制。
use_modular_headers! ,它主要是将 pods 转为 Modular,因为 Modular 是可以直接在 Swift中 import ,所以不需要再经过 bridging-header 的桥接。
但是开启 use_modular_headers! 之后,会使用更严格的 header 搜索路径,开启后 pod 会启用更严格的搜索路径和生成模块映射,历史项目可能会出现重复引用等问题,因为在一些老项目里 CocoaPods 是利用Header Search Paths 来完成引入编译,当然使用 use_modular_headers!可以提高加载性能和减少体积。
当LocalPods中的模块使用Swift
1、必须将主项目的podfile改成use_frameworks! :linkage => :static。但是有时执行调用模块内方法会出现unrecognized selector,需要command+k清除之后重新编译。改成dynamic还是每次修改视图显示都要重新编译,否则不生效。
2、本地模块的xx.podspec文件中的s.public_header_files = 'Classes/Public//*.h’这个参数设置好像只能用于.h文件,如果改成“‘Classes/Public//*’”导入了Public目录下.m或.swift文件会有问题。Swift文件能不能被模块外访问可以用open/public访问控制修饰,默认访问控制是internal只能模块内使用这些类,改成open可以被模块外继承重写,public可以被模块外使用。
3、在模块内部的OC文件里不能使用“#import “RCLiveModule(模块名)-Swift.h””,在主项目中可以,因为是use_frameworks!,如果去掉这句则变成模块内部可以使用而在主项目中不可以。而且那些需要被OC访问的类需要有一个父类,并且自定义方法要加上@objc才会自动生成OC方法。
use_frameworks!
1、use_frameworks!使用框架,默认是动态链接,到了cocoapods1.9之后可以指定动态链接(use_frameworks! :linkage => :dynamic)还是静态链接(use_frameworks! :linkage => :static)。
2、OC默认不使用use_frameworks!,Swift只能使用use_frameworks!。
常见问题
ruby3在macOS上编译失败
一般多为openssl版本问题导致,重新安装一下:
brew reinstall openssl@3
rvm install ruby-3.2.2 --reconfigure --enable-yjit --with-openssl-dir=$(brew --prefix openssl@3)
import of module ‘glog.glog.log_severity’ appears within namespace ‘google’
pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec', :modular_headers => false
pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec', :modular_headers => false
pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec', :modular_headers => false
yarn网络问题
yarn config delete proxy
npm config rm proxy
npm config rm https-proxy
yarn config set registry https://registry.npm.taobao.org
yarn install --network-timeout 6000 ## 毫秒
pod安装失败
The Swift pod `ExpoModulesCore` depends upon `glog`, which does not define modules. To opt into those targets generating module maps (which is necessary to import them from Swift when building as static libraries), you may set `use_modular_headers!` globally in your Podfile, or specify `:modular_headers => true` for particular dependencies.
根据上面提示,修改Pofile文件,添加use_modular_headers!,或者为某个依赖指定:modular_headers => true
use_modular_headers!
pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec', :modular_headers => false
pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec', :modular_headers => true
pod 'RCT-Folly', :podspec => '../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec', :modular_headers => true
pod 'boost', :podspec => '../node_modules/react-native/third-party-podspecs/boost.podspec', :modular_headers => false
unable to open settings file
Showing Recent Messages
/Users/XX/Desktop/XX/Pods/Target Support Files/Pods-XX/Pods-XX.debug.xcconfig: unable to open file (in target "XX" in project "XX")
解决方法:
sudo gem install cocoapods --pre
或者 sudo gem install -n /usr/local/bin cocoapods --pre
再:
pod install
pod update(pod install 不行再执行)
xcode运行报Undefined symbol: OBJC_CLASS$_RCTImageLoader
TODO
Unable to resolve “missing-asset-registry-path” from
启动metro服务器后,运行app,报错:
Unable to resolve "missing-asset-registry-path" from "node_modules/@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/AntDesign.ttf"
升级Expo到最新版就解决了,metro水太深。
Undefined symbols for architecture XXX
完整错误示例:
Linking react-native-screens Pods/RNScreens » RNScreens
❌ Undefined symbols for architecture x86_64
┌─ Symbol: _OBJC_CLASS_$_RCTImageLoader
└─ Referenced from: objc-class-ref in RNSScreenStackHeaderConfig.o
在xcode里手动链接。
相关链接
- The New Expo CLI
- cocoapods
- swift下载
- swiftenv
- 2023年最新苹果AppleiOS开发证书申请创建App详细图文流程