Xcode构建关于Bitcode的说明

启用/关闭Bitcode Xcode设置路径为 Build Settings -> Build Options -> Enable Bitcode 设置后,改变的是构建过程中环境变量 ENABLE_BITCODE 的值。 需要注意的是,这个设置在不同的构建中表现不一样 平时用于调试、部署的构建,启用Bitcode后,仅进行Bitcode依赖检测,不会生成Bitcode符号到产物中。(项目中即使有非Bitcode库,也不影响调试、部署) 当进行Archive打包时,启用Bitcode后,则要求项目的所有依赖库均启用Bitcode(所有库均要有Bitcode符号) 另外,Xcode构建时也会读取环境变量 HIDE_BITCODE_SYMBOLS,这个变量默认YES。当 HIDE_BITCODE_SYMBOL=NO 且 ENABLE_BITCODE=YES 时,则要求项目的所有依赖库均要有Bitcode符号 强制所有构建启用Bitcode 添加 -fembed-bitcode 编译标识。设置路径为 Build Settings -> Apple Clang - Custom Compiler Flags -> Other C Flags 添加后,无论哪种构建,均会强制启用Bitcode。 而通过 Build Settings -> Build Options -> Enable Bitcode 路径启用Bitcode,本质是添加了编译标识 -fembed-bitcode-marker,区别如下 -fembed-bitcode ,任何类型的Build都会带上Bitcode符号 -fembed-bitcode-marker, 只是在产物中做标记,表示可以支持Bitcode;而在Archive打包时,才会生成Bitcode符号 XcodeBuild构建如何启用BitCode Shell环境中构建SDK(静态库、动态库)的场景,此时没有Archive构建,那么可以设置 BITCODE_GENERATION_MODE=bitcode 解决。 BITCODE_GENERATION_MODE可以是 marker,也可以是 bitcode,默认取 marker 例如: xcodebuild BITCODE_GENERATION_MODE=bitcode ..... 如何查看SDK中是否含有Bitcode符号 可以通过 Mach-O View 工具查看,是否含有 Section (__LLVM ,__bitcode ). ...

July 1, 2021 · 1 min · holdsky

设置环境变量关闭react-scripts的sourceMap生成

关于 GENERATE_SOURCEMAP 的作用原理在这篇文章中介绍过。 http://139.155.43.7/2019/10/15/create-react-app-%ef%bc%9a%e4%b8%8d%e4%ba%a7%e7%94%9fsource-map%e6%9d%a5%e7%bc%a9%e5%87%8f%e6%89%93%e5%8c%85%e6%96%87%e4%bb%b6%e4%bd%93%e7%a7%af/ 可以通过创建 .env 环境变量文件影响 react-scripts start/build 等命令。其实还有另一种更灵活的方式设置环境变量,使用 export 可以对不同的命令设置不同的环境变量. 打开 package.json,找到 scripts 配置项 "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, 添加 export GENERATE_SOURCEMAP=true/false 修改为以下配置 "scripts": { "start": "export GENERATE_SOURCEMAP=true && react-scripts start", "build": "export GENERATE_SOURCEMAP=false && react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, 这样,在运行start调试时,产生sourceMap方便调试;运行build命令时,关闭sourceMap减少产物文件大小。

June 15, 2021 · 1 min · holdsky

React-ZLView 使用 x-y-width-height坐标布局

https://github.com/gm958spanda/React-ZLView https://gitee.com/gm958spanda/React-ZLView ZLView ZLView base react , super and sub , coordinate by x-y-width-height;基于react的视图,使用x-y-width-height坐标系 示例 使用多个div节点绘制正弦曲线 import React from 'react'; import * as zl from 'react-zlview' class App extends React.Component { private appView : zl.View | undefined; render() { if(this.appView === undefined) { this.appView = new zl.View(); this.appView.x = 200; this.appView.y = 100; this.appView.width = 1000; this.appView.height = 50; this.appView.backgroudColor = "white"; let colors = ["red","blue","gredd"]; for (let i = 0 ; 999 > i ; i ++) { let sub = new zl.View(); sub.x = i; sub.y = Math.sin(i / 3.14) * 15 + this.appView.height / 2; sub.width = 3; sub.height = 3; sub.backgroudColor = colors[i %3]; this.appView.addSubview(sub); } } // 也可以直接返回 this.appView.reactElement(); // return this.appView.reactElement(); return ( {this.appView.reactElement()} ); } } ZLView的坐标系统 一个ZLView对应一个 React Component,也可说是对 React Component 的封装;ZLView采用固定CSS样式,将 position 设置为 absolute,然后设置 left/right/widht/height。当然ZLView对此作了封装: ...

May 28, 2021 · 3 min · holdsky

【转载】使用TypeScript开发项目打包发布到npm

初始化项目 npm init 通过 npm init 初始化项目来创建用户 package.json 文件 也可以 npm init -y 这个是使用的默认的配置,我个人使用的是 npm init 创建tsconfig.json文件 tsc --init 就会生成一个tsconfig.json文件 修改tsconfig.json默认文件 把这两个注释打开 { "compilerOptions": { "declaration": true, //打包之后是否生成声明文件 "outDir": "./dist", //输出文件 } } 添加exclude,忽略dist文件 在打包的时候会排除这里面指定的路径文件 { "compilerOptions": { }, "exclude": [ "./dist" ] } 安装typescript依赖 npm install typescript -D 开始编码 创建xxxxx.ts文件,写入typescript代码 例如 const arrayMap = (array: [], callback:(item: any,index: number, arr: any[]) => any): any => { let i = -1 const len = array.length let resArray = [] while (++i < len){ resArray.push(callback(array[i],i,array)) } return resArray } export = arrayMap 对代码进行编译 tsc 此时我们的项目就会多了一个dist目录 ...

May 28, 2021 · 1 min · holdsky

typescript 导出 d.ts声明文件

需要在 tsconfig.json 中配置以下参数 { "noEmit": false, "declaration": true, "declarationDir": "dist/declaration", "outDir": "dist" } noEmit , 若要导出 d.ts 文件,必须为false。否则会忽略 declaration 相关参数 declaration,是否导出 d.ts 文件,当为true时且 noEmit 为true时才会进行导出操作. declarationDir, d.ts 文件存放的目录路径。当不设置改参数时,将使用 outDir 的值 outDir,将typescript 转换成js文件、以及 d.ts 文件的存放目录 配置完成后,运行 tsc --build tsconfig.json 即可

May 24, 2021 · 1 min · holdsky

iOS 编译宏与指令

版本依赖宏 当前系统支持的最小版本 __IPHONE_OS_VERSION_MIN_REQUIRED 当前系统支持的最大版本 __IPHONE_OS_VERSION_MAX_ALLOWED @interface ViewA : UIView #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_9_0 。。。 。。。 。。。 #endif @end @available 和版本依赖宏的功能类似,不过是一个编译指令,在运行时失效,用来判断当前运行的版本环境 if (@available(iOS 9.0,*)) { //iOS 9.0版本及以上系统环境执行此代码块 ..... } DEBUG 和 __DEBUG 用来判断是Release还是Debug运行模式。DEBUG定义为1或者TRUE #if DEBUG NSLog(Debug模式) #endi API版本宏 API_AVAILABLE 指定API在最小系统版本中可用 // 在 iOS 10.0版本及以后可用 API_AVAILABLE(ios(10.0)) @interface StepSlider : UIControl @end // 在 iOS 14.0版本及以后可用 - (instancetype)initWithFrame:(CGRect)frame primaryAction:(nullable UIAction *)primaryAction API_AVAILABLE(ios(14.0)); API降级宏 API_DEPRECATED 指定API在相应版本后不推荐使用 // 9.0之后,不推荐使用UIAlertView,应使用UIAlertController替换 UIKIT_EXTERN API_DEPRECATED(UIAlertView is deprecated. Use UIAlertController with a preferredStyle of UIAlertControllerStyleAlert instead, ios(2.0, 9.0)) API_UNAVAILABLE(tvos) @interface UIAlertView : UIView @end API不可用宏 API_UNAVAILABLE / OBJC_UNAVAILABLE / NS_UNAVAILABLE // tvos ,watchos平台不可用 @property (nonatomic, readwrite, nullable, copy) NSString *testabcd API_UNAVAILABLE(tvos, watchos); // 方法被删除,不再使用 -(void)funcA API_UNAVAILABLE(unavailable since now) // 方法不可用 -(void)funcB NS_UNAVAILABLE; C/C++ extern 宏 __BEGIN_DECLS 一般在头文件中使用,用来适配 .c 和 .cpp 的不同语法(也就是c/c++的语法差异) ...

April 27, 2021 · 1 min · holdsky

ImageOptim CLI(命令行)

ImageOptim 是macOS系统下的图像二次压缩工具集合,支持GUI模式和CLI模式。源码在https://github.com/ImageOptim/ImageOptim CLI模式可参考 https://imageoptim.com/command-line.html 例如 非阻塞模式,异步将当前文件夹下的所有图片进行二次压缩 open -a ImageOptim . 阻塞模式,同步将当前文件夹下所有png图片进行二次压缩 /Applications/ImageOptim.app/Contents/MacOS/ImageOptim *.png

April 22, 2021 · 1 min · holdsky

macOS App使用WKWebView

和iOS上的使用方式大致相同 #import "ViewController.h" #import @interface ViewController() @property (nonatomic,strong) WKWebView *webView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init]; self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:config]; [self.view addSubview:self.webView]; [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]]]; } @end 另外,还需要配置下工程文件,以允许WKWebView访问网络。需要配置的地方有两处

April 8, 2021 · 1 min · holdsky

Error: Your Xcode does not support macOS 11.2.

使用brew安装telnet时,报错 Error: Your Xcode does not support macOS 11.2. It is either outdated or was modified. Please update your Xcode or delete it if no updates are available. brew install telnet Updating Homebrew... Warning: You are using macOS 11.2. We do not provide support for this pre-release version. You will encounter build failures with some formulae. Please create pull requests instead of asking for help on Homebrew's GitHub, Twitter or any other official channels. You are responsible for resolving any issues you experience while you are running this pre-release version. ==> Downloading https://opensource.apple.com/tarballs/libtelnet/libtelnet-13.tar Already downloaded: /Users/zxs.zl/Library/Caches/Homebrew/downloads/4fe26613ac3f91bd2fa2ed4e9ca39a043c6fd5960c4e0a3f063c672911900665--libtelnet-13.tar.gz ==> Downloading https://opensource.apple.com/tarballs/remote_cmds/remote_cmds-63 Already downloaded: /Users/zxs.zl/Library/Caches/Homebrew/downloads/557d5b69c452e48e5337f6d80e827514cd2218e1c02dcd42f893bd2cafe7d141--remote_cmds-63.tar.gz Error: Your Xcode does not support macOS 11.2. It is either outdated or was modified. Please update your Xcode or delete it if no updates are available. 将Xcode.app先移动到其他位置,然后在运行 brew install telnet,最后把Xcode.app移动回来 ...

April 8, 2021 · 1 min · holdsky

otool 工具分析可能没有使用的Objective-C类

基本原理 Contents of (__DATA,__objc_classrefs) section 和 Contents of (__DATA,__objc_superrefs) section 中的类是已经被引用的类, Contents of (__DATA,__objc_classlist) section 中的类是整个应用未启动时已经定义好的类列表,那么从后者剔除前者而剩余的类就是应用未启动时没有使用的类;同时考虑到Objective-C的运行时特性,所以还需要人工确认下。 基本过程如下: 解压ipa包 本质是zip包,修改后缀解压就可以了 otool 符号格式化 在mac os shell中运行命令(otool 为Xcode工具包中的工具) otool -arch armv7 -ov 应用解压后的目录/Payload/应用名/应用二进制文件 > otool.txt 上述命令中指定 armv7 架构,其假设是ipa包一定会有 armv7 的二进制文件 解析获取 __objc_classlist 类列表 打开 otool.txt 文件,搜索 __objc_classlist ,找到一个class数据,其基本格式如下 025afc00 0x28b2a24 # 第二个,地址0x28b2a24,是class的唯一地址 isa 0x28b2a38 superclass 0x28b4194 # 父类的地址 cache 0x0 __objc_empty_cache vtable 0x0 data 0x25b5e0c flags 0x194 RO_HAS_CXX_STRUCTORS instanceStart 4 instanceSize 20 ivarLayout 0x2123649 layout map 0x13 name 0x2123610 BCCallMultiVideoController #类名字 baseMethods 0x25b5a88 。。。 我们需要重点关注 类地址、 superclass 父类地址, name 类名,按照这样的格式解析所有的 __objc_classlist 从而获得所有定义好的类集合。 ...

April 1, 2021 · 1 min · holdsky