iOS CI 自动生成IPA

iOS第二十四篇 iOS自动化构建与CI/CD权威指南 Ruby/Python脚本封装Fastlane自动化工具集成静态代码检查集成scan(构建高效的iOS CI/CD管道需要综合考虑团队规模、项目复杂度和发布频率等因素。随着技术的不断发展,建议定期评估和优化您的自动化流程,保持对新兴工具和实践的关注。记住,好的CI/CD系统应该像呼吸一样自然——不可或缺但几乎感觉不到它的存在。减少手动错误和重复工作加快反馈循环提高代码质量实现可靠的持续交付最终为用户提供更高质量的应用体验。 阅读详情

使用CI脚本为iOS 应用生成IPA, 常用的方法是使用xcodebuild生成app之后, 再调用

xcrun -sdk iphoneos -v PackageApplication $APP_NAME -o $IPA_NAME

不幸的是, xcode更新到8.3之后, PackageApplication工具已经被废弃了, 这个方法无法奏效, 不过apple 还是为脚本生成IPA提供了另外一种方法, 那就是

  • 第一步:使用xcodebuild生成archive
  • 第二部: 将生成的archive文件打包成IPA.
    示例代码如下:
xcodebuild -scheme $SCHEME_NAME clean archive -archivePath $ARCHIVE_NAME
xcodebuild -exportArchive -archivePath $ARCHIVE_NAME -exportPath $IPA_NAME -exportOptionsPlist-exportOptionsPlist $PLIST_NAME

美中不足的是, 这个方法需要使用scheme 指定一个用户的scheme, 无奈之下, 为CI服务器生成了一个scheme,放到了代码仓储.
scheme的信息可以用命令 xcodebuild -list 查看

iOS项目CI/CD搭建指南 swift。 阅读详情

相关推荐

CICDiOS:测试iOS CICD

CICDiOS:测试iOS CICD

【开发工具】iOS项目工程CI配置

提交日志检查 按照语义化的提交日志规范,可以同时对 commit message 和 merge request title 做校验。 语义化提交日志规范 Git Semantic Commit Messages 推荐使用Git Semantic Commit Messages,固定提交日志格式,有助于我们成为一个更好的开发者。 格式: (): 其中 是可选的。 格式说明: feat: add hat wobble ^--^ ^------------^ | | | +-> S

freeWayWalker的专栏 1017

ipa_install_plist_generator:生成可用于 IPA 安装的 .plist 并可生成 .plist 文件的安装链接

IPA 安装 Plist 和链接生成器 Ruby GEM 生成可用于 IPA 安装的 .plist。 这个 GEM 可以直接在你的 Ruby 项目中使用,或者你可以安装它并在你的命令行/终端中使用它。 您可以通过将它添加到您的 Gemfile 来使用这个 GEM: gem 'ipa_install_plist_generator' 或者将其安装为系统范围的 GEM / CLI: gem install ipa_install_plist_generator 您可以在两种模式下将此 GEM 用作 CLI: 生成一个 .plist 文件,您可以将其保存到您的服务器以安装 iOS 应用程序 .ipa。 在命令行/终端中使用ipa_plist_gen命令。 一旦你有一个安装 .plist 文件并将它上传到你的服务器(URL 必须是 HTTPS,从 iOS 8 开始,一个普通的 HT

ios CI/CD 持续集成 组件化专题四-(手动发布私有库-组件化搭建)

在git下下创建一个新的库,这个库用来保存私有库的podspec文件,取名叫xxxSpec用以区分这个库的作用,如下base_ios_spec索引库。接着创建本地索引库,也就是将刚才创建的远程索引库dp_base_ios_spec关联到本地。例如:dp_base_ios_spec 在本地不存在该私有索引库。执行完第六步再次执行上面的远程校验显示如下,代表远程校验通过。此时本地就有了 base_ios_spec这个索引库。首先检查本地是否存在需要的私有索引库。首先创建本地私有库(该库是代码库)

m0_61164038的博客 1562

iOS中配置Jenkins集成打包测试发布CI系统

iOS中配置Jenkins集成打包测试发布CI系统,一步一步教你如何构建自己的持续集成系统

ios-ci:Spotify的脚本集合在其开源iOS项目上运行

Spotify CI脚本 :police_car_light: 不再维护 :police_car_light: :police_car_light: Spotify已停止为我们的开源项目使用ios-ci的工具。 :police_car_light: Spotify脚本集合可在其开源iOS,tvOS,watchOS和OS X项目上运行。 这些脚本是自带的,不适用于任何CI设置。 但是,如果您选择与我们类似的堆栈,它们也应该为您工作。 我们目前正在使用以下堆栈: OS X(因为这适用于Apple平台)。 Travis-CI,用于运行CI作业。 其他配置项提供的可能会起作用。 用于代码覆盖率报告和可视化的Codecov。 正在安装 关于如何将脚本添加到存储库的方法主要有两条。 作为git子模块(仅适用于应用程序)或使用git子树合并。 对于应用 如果要将ios-ci作为依赖项添加到应用程序,请将存储库添加为。 完成后,继续 对于框架和库 如果您想将ios-ci作为依赖项添加到框架或库,则更喜欢。 因为它将

10分钟搭建iOS动画库的自动化部署流水线:Spring框架实战指南

你是否还在为iOS动画库的手动打包、测试和发布流程感到困扰?每次修改后都要重复执行繁琐的命令,不仅耗时还容易出错?本文将以Spring动画库(A library to simplify iOS animations in Swift)为例,带你打造一套完整的CI/CD流水线,从代码提交到自动发布全流程自动化,让你专注于动画效果开发而非工程配置。 读完本文你将掌握: - 如何配置GitHub Ac...

gitblog_01108的博客 1002

计组头哥实验 实验三 MIPS寄存器实验

了解 MIPS 寄存器文件基本概念,进一步熟悉多路选择器、译码器、解复用器等 Logisim 组件的使用,并利用相关组件构建 MIPS 寄存器文件。

gdz0007的博客 1万+

iOS混淆与IPA加固全流程(iOS混淆 IPA加固 Ipa Guard实战)

实战战术:用 MobSF/class-dump 做侦察、Swift Shield 做源码混淆、Ipa Guard 对 IPA 成品混淆,配合 Fastlane/Jenkins 自动化、Frida/Hopper 动态验证与 KMS 管理映射表,构建可复用、可审计、可回滚的 iOS 加固闭环,适配无源码与多框架场景。

2501_91592143的博客 704

FAST-LIO2实战:从零搭建香港大学火星实验室SLAM框架(附官方数据集测试指南)

本文提供了一份详细的FAST-LIO2实战指南,帮助读者从零开始搭建香港大学火星实验室开源的这一高效激光惯性里程计框架。内容涵盖系统环境配置、依赖安装、源码编译、官方数据集测试以及参数调优,旨在让开发者快速上手并应用于机器人SLAM项目。

ppp33的博客 688

牛耕式全覆盖算法-matlab代码

牛耕式路径全覆盖算法,也称为牛耕算法或者蚂蚁算法,是一种用于解决路径规划问题的启发式算法。这个算法的灵感来自于牛在耕田时的行为。在这个算法中,假设有一块田地需要耕作,牛从田地的某个角落开始行走,走过的路径会被标记。牛会优先选择尚未经过的路径,当所有的路径都走过后,算法停止。在路径规划问题中,田地可以看作是一个由节点和边构成的图。每个节点代表一个位置,每条边代表两个节点之间的连接。路径全覆盖问题是找出一组路径,使得每个节点都被至少一条路径经过。牛耕式路径全覆盖算法的基本思想是以启发式的方式逐步构建路径。

m0_69611489的博客 1689

iOS 混淆实操指南多工具组合实现 IPA 混淆、加固与发布治理 IPA 加固

本文提供一套工程化 iOS 混淆方案:结合 MobSF/class-dump 静态侦察、Swift Shield 源码混淆(若可)、Ipa Guard 成品混淆、Fastlane/Jenkins等

2501_91373349的博客 882

Seedance 2.5、HappyHorse 1.1与豆包Seed 2.1:一周内三大模型技术参数分析

音频生成延续原生音画同步架构,将文本、画面、音频统一序列建模,生成过程同步产出匹配口型的原声音频,支持中、英、日、韩、德、法、阿拉伯7种语言唇形对齐,无需二次调音。从行业趋势看,30秒直出、4K分辨率、7语种唇形同步正在成为视频生成的标配,编程Agent化和多模态理解正在成为语言模型的标配。技术狂奔的同时,监管在同步收紧。我理解这里的关键在于,视频生成模型的商业化落地不仅取决于生成质量,更取决于推理效率——生成一段15秒1080P视频需要多少秒、消耗多少算力,直接决定了模型的商用可行性。

lichunchuan1的博客 323

iOS IPA上传到App Store Connect的三种方案详解

将IPA文件上传到App Store Connect是iOS应用发布流程中的关键一步。无论你是使用Xcode进行原生开发,还是通过uni-app、Flutter等跨平台框架构建应用,苹果提供了多种上传方式来满足不同场景的需求。Xcode上传适合简单、直接的操作,altool命令行工具则为自动化部署提供了极大的灵活性,而Transporter则是独立于Xcode的批量上传利器。

weixin_39339407的博客 9974

littlefs系列:wear leveling

wear leveling的功能是通过block alloctor实现的。littlefs通过两个方法实现磨损均衡: 1) 检测和恢复bad blocks 2)通过dynamic blocks均衡磨损 检测和恢复bad blocks和block alloctor的关系并不紧密,主要依靠文件系统本身来检测坏块并标记。在littlefs中,检测坏块主要是通过写后回读并比较的方式实现的,如果数据不一致则说明是一个坏块。一旦检测到了坏块就要进行恢复。 如果是写入错误,因为数据才RAM中还有备份,因此需.

nstcl的博客 2568

CLCD土地覆盖数据在ArcGIS中的实战应用:从导入到空间分析的完整指南

本文详细介绍了CLCD土地覆盖数据在ArcGIS中的实战应用,从数据导入到空间分析的完整流程。涵盖坐标系转换、数据质量检查、土地利用变化检测等核心技术,并分享城市扩张模拟和跨数据集融合等高级应用技巧,帮助研究者高效利用这一权威数据集进行环境监测和城市规划。

weixin_29292535的博客 593

IPA 混淆实战 IPA 混淆、IPA 加固、ipa 文件安全与成品包防护全流程指南

本文详解 IPA 混淆实战:为何做 ipa 混淆、Ipa Guard 在成品包加固中的角色、与源码混淆的区别、工具链(MobSF、class-dump、Frida)验证流程,以及灰度发布、白名单与映射表管理等落地经验,面向开发与安全团队。

2501_91373349的博客 1066

轻量级NAS的隐秘战场:比特米盒CumeBox2与CasaOS的生态融合实践

本文探讨了比特米盒CumeBox2轻量级NAS设备与CasaOS操作系统的生态融合实践。通过硬件选型、系统部署、性能优化和应用场景分析,展示了如何将CumeBox2与CasaOS深度整合,打造经济实用的家庭数据管理中心,特别适合入门级用户和小型办公环境。

rl6adventurer的博客 895

iOS 应用加固与苹果软件混淆指南,如何防止 IPA 被反编译与二次打包?

本文从实战角度讲解 iOS 应用加固与苹果软件混淆策略:分析 IPA 反编译路径,介绍 Ipa Guard 无源码混淆方案,涵盖资源扰动、自动签名、CI 集成与安全治理全流程,适合开发与安全工程团队参考。

2501_91510632的博客 588

ardupilot SBUS输入捕获

本节主要记录ardupilot 的sbus 输入捕获功能。ardupilot 默认支持多种无线协议控制输入设备,比如常用的PPM,SBUS,IBUS,DSM,SUMD,SRXL等协议,本节主要讲解ardupilot 如何通过定时器的pwm输入捕获来获取sbus数据。

陌城烟雨 270

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

在 Linux 环境通过命令行上传 IPA 到 App Store,iOS自动化构建与发布

本文围绕 Linux 环境上传 IPA 到 App Store 的实际工程场景,拆解了 IPA 前置条件、上传接口本质以及在 CI 中落地命令行上传的具体方式。在多工具协作的发布流程中,AppUploader 命令行版本可用于在 Linux、Windows 或 macOS 环境下完成 IPA 提交,适合集成到自动化构建与发布流程中,解决非 macOS 场景下的 iOS 应用上传问题。

2501_91380052的博客 682

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

iOS 混淆与 IPA 加固一页式行动手册(多工具组合实战 源码成品运维闭环)

工程化 iOS 混淆行动手册:用 MobSF/class-dump 做静态发现,Swift Shield/obfuscator-llvm 做源码混淆(若可),Ipa Guard 对 IPA 成品混淆并导出映射表,结合 Fastlane/Jenkins 自动化、Frida 动态验证与 KMS 管理,构建可审计、可回滚的 IPA 加固闭环。

2501_91591841的博客 1154

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

iOS 成品包加固,在只有 IPA 的情况下,能做那些操作

本文围绕 iOS 成品包加固展开,从只有IPA文件的实际场景出发,详细说明了对可执行文件、资源与调试信息进行处理的具体流程,并结合 Ipa Guard 的使用方式,展示在不依赖源码的前提下完成成品包加固

2501_91510632的博客 610

iOS 混淆工具链实战,多工具组合完成 IPA 混淆与加固(iOS混淆|IPA加固|无源码混淆|App 防反编译)

本文给出一套工程化 iOS 混淆方案:结合 MobSF/class-dump 静态扫描、Swift Shield/obfuscator-llvm 源码混淆、Ipa Guard 成品混淆、Fastlane/Jenkins 自动化、Frida 动态验证与 KMS 管理映射表,形成可复现、可审计的 IPA 加固闭环,适配有源码与无源码场景。

2501_91600747的博客 726

用多工具组合把 iOS 混淆做成可复用的工程能力(iOS混淆 IPA加固 无源码混淆 Ipa Guard)

本文提出一套工程化 iOS 混淆方案:结合 MobSF/class-dump 静态扫描、Swift Shield/obfuscator-llvm 源码混淆、Ipa Guard 成品混淆与 Fastlane/Jenkins 自动化,映射表用 KMS 管理,并以 Frida/Hopper 做动态验证,构建可审计、可回滚的 IPA 加固闭环。

2501_91380052的博客 1081

iOS 混淆实战 多工具组合完成 IPA 混淆、加固与工程化落地(iOS混淆|IPA加固|无源码混淆|Ipa Guard|Swift Shield)

本文以对话与实战流程还原 iOS 混淆落地:用 MobSF/class-dump 做静态发现,Swift Shield(可选)做源码混淆,Ipa Guard 做成品 IPA 混淆,Fastlane/Jenkins 自动化流水线,Frida/Hopper 动态验证,映射表由 KMS 管理,构建可审计、可回滚的 IPA 加固闭环。

2501_91591841的博客 565
上一篇: 神经网络笔记 - Regularization
下一篇: WebRTC 中的Quality Scaler
volvet
博客等级 码龄18年 129粉丝 83原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值