CocoaPod 指定动态或者静态链接framework

当在 podfile 文件中使用 use_frameworks! 指令时,CocoaPod在安装Pod时,会用framework方式组织资源(默认使用lib方式),同时该指令还提供扩展选项,指定动态framework或者静态framework use_frameworks! #使用默认值,根据pod类型自行设置static或者dynamic use_frameworks! :linkage => :static # 使用静态链接 use_frameworks! :linkage => :dynamic #使用动态链接 如果在 podfile 中设置 use_frameworks! ,又没有指定 linkage => :static 或 linkage => :dynamic 时,则会根据 podspec 文件中的根配置 static_framework = true/false 来设置。 另外, linkage => :static 或 linkage => :dynamic 只对源码Pod有效,对已经是framework的pod不起作用。而且,如果pod中的framework是动态库,那么在 pod install 后,会在相应的target的 Build Phases 设置中添加 [cp] Embed Pods Frameworks 脚本,以动态库的方式将framework输出到最终产物中。

March 29, 2021 · 1 min · holdsky

ios 判断framework是动态库还是静态库

framework是一种头文件和链接库的组织形式,可以通过file命令查看相关信息来判断该链接库是动态库还是静态库,如果输出信息中含有 dynamically linked,则是动态库 file ~/ZipArchive.framework/ZipArchive ~/ZipArchive.framework/ZipArchive: Mach-O universal binary with 3 architectures: [arm_v7:Mach-O dynamically linked shared library arm_v7] [x86_64:Mach-O 64-bit dynamically linked shared library x86_64] [arm64:Mach-O 64-bit dynamically linked shared library arm64] ~/ZipArchive.framework/ZipArchive (for architecture armv7): Mach-O dynamically linked shared library arm_v7 ~/ZipArchive.framework/ZipArchive (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64 ~/ZipArchive.framework/ZipArchive (for architecture arm64): Mach-O 64-bit dynamically linked shared library arm64

March 29, 2021 · 1 min · holdsky

Android gradle build 用R8而不使用Proguard

com.android.tools.build:gradle:3.4.0 3.4.0以后,默认使用R8编译。 可以在 gradle.properties 添加属性,指定R8是否启用 android.enableR8=true ;// true 启用R8 有时候上述配置并不一定生效,在编译时有可能还是使用 Proguard,这时候可以在App 的 build.gradle 中配置 useProguard false,强制关闭Proguard而启用R8 android { buildTypes { release { minifyEnabled true useProguard false //强制关闭Proguard而启用R8,这时将忽略gradle.properties里关于android.enableR8的设置 } } }

March 22, 2021 · 1 min · holdsky

引入私有CocoaPod编译报错include of non-modular header inside framework module

原因是引入的CocoaPod仓库,编译后缺少 module.modulemap 文件;通常是因为私有CocoaPod仓库只有声明文件,没有定义实现文件—–只有 .h 文件,没有 .m .mm 等文件。 简单的解决办法是在私有仓库添加一个空的 .m 文件,例如添加 cocoapod.m 文件(名字随意) /// cocoapod.m #import 然后在 podspec 文件中,将这个文件添加到 source_files 属性里 s.public_header_files = '公开的头文件' s.source_files = '已有的源文件','cocoapod.m' #也可使用通配符写法 ,如 **/*.{h,m} 再次 pod install 即可生成 module.modulemap 文件

January 27, 2021 · 1 min · holdsky

VSCode插件开发--一些API

VSCode 打开本地目录或工作空间 命令ID vscode.openFolder ,打开一个目录或者工作空间。可以在当前窗口打开,或者新建窗口打开。 参数 uri ,Uri类型,可选,目录(工作空间)路径。如果不提供,那么将会弹出一个原生的目录选择对话框 newWindow,可选,是否打开一个新的窗口 // 在新窗口打开/some/path/to/folder let uri = vscode.Uri.file("/some/path/to/folder"); vscode.commands.executeCommand("vscode.openFolder",uri,true); 当前活动的Terminal(Shell终端) 内置方法 vscode.window.activeTerminal 创建Terminal(Shell终端) 使用内置方法 vscode.window.createTerminal,它有三个重载函数, 返回值均为 vscode.Terminal createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string): Terminal 参数解释name可选 ,终端创建后显示在UI上的名字shellPath可选,自定义shell终端的执行路径shellArgs可选 ,传递给自定义终端的执行参数。 只对Windows生效 shellArgs 详细格式参见https://msdn.microsoft.com/en-au/08dfcab2-eb6e-49a4-80eb-87d4076c98c6 createTerminal(options: TerminalOptions): Terminal 参数解释options必选 ,TerminalOptions配置参数 TerminalOptions 可用的值 参数解释占位占位占位占位占位占位占位占位占位占位占位占位占位cwd可选 ,string 或 Uri ,终端的工作目录env可选 ,object ,添加到终端中的环境变量hideFromUser可选 ,boolean ,如果设置为true,终端将正常运行,但直到调用Terminal.show时,才会对用户公开。 通常的用法是在需要运行可能需要交互性,但只想在需要交互时对用户公开name可选 ,string ,终端创建后显示在UI上的名字shellArgs可选 , string[] 或 string ,传递给自定义终端的执行参数 只对Windows生效shellPath可选 , string ,自定义shell终端的执行路径strictEnv可选 , boolean ,终端环境是否应完全与TerminalOptions.env中提供的一致。 如果为false(默认),则环境将基于窗口的环境,并且还会在顶部应用配置的平台设置,例如terminal.integrated.windows.env。 如果true,则必须提供完整的环境。 createTerminal(options: ExtensionTerminalOptions): Terminal 此方法将创建一个由插件(扩展)控制输入输出的终端环境 参数解释options必选 ,ExtensionTerminalOptions配置参数 ...

January 7, 2021 · 1 min · holdsky

VSCode插件开发--添加侧边栏入口和面板

先看一张图 在VSCode的文档中,侧边栏按钮入口称之为 Tree View Container,侧边栏面板称之为 Tree View,本文涉及的就是这两个区域。 创建工程 使用 yo code 脚手架创建一个插件工程,语言选择 TypeScript。具体过程略 配置侧边栏按钮(Tree View Container)和面板视图(Tree View) 侧边栏按钮(Tree View Container)和面板视图(Tree View)要同时配置,否则不生效。 打开 package.json,添加以下内容 "contributes": { "viewsContainers": { "activitybar": [ { "id":"sidebar_test", "title": "侧边栏测试", "icon": "入口.svg" } ] }, "views": { "sidebar_test":[ { "id":"sidebar_test_id1", "name":"面板区块名称1" }, { "id":"sidebar_test_id2", "name":"面板区块名称2" } ] } } 按钮图片格式,需要使用svg格式。views中key要和activitybar中的属性id保持一致,如sidebar_test在两者中是一致的。 以上配置了一个 sidebar_test 的侧边栏按钮,点击按钮,会出现 面板区块名称1 和 面板区块名称2 两个区块。 ...

December 15, 2020 · 2 min · holdsky

iOS UIBarButtonItem.initWithCustomView 导航按钮在不同版本的表现不一致

方法 [[UIBarButtonItem alloc] initWithCustomView:view] 在iOS 高版上如(iOS11,12,13,14),可以自动调整view的大小 在iOS底版本上如(iOS10,9),则采用view自身的大小。 也就是说,如果view的frame不指定,有可能在导航栏上不可见。 例如 // sendButton 默认大小为0 UIButton *sendButton = [UIButton buttonWithType:UIButtonTypeCustom]; [sendButton setBackgroundImage:背景图 forState:UIControlStateDisabled]; // 实测在iOS9.3上,sendButton不显示 self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:sendButton];

December 4, 2020 · 1 min · holdsky

macos 配置 git ssh访问方式

生成 ssh key $ ssh-keygen -t rsa -C "git服务端留存的邮箱地址" Generating public/private rsa key pair. Enter file in which to save the key (~/.ssh/id_rsa): "这里输入ssh key保存路径,不建议使用默认地址" Enter passphrase (empty for no passphrase): "这里输入密码,建议输入空(方便后续配置)" Enter same passphrase again: "再输入一遍密码,建议输入空(方便后续配置)" 应生成两个文件,公钥和私钥,文件名形式为 xxx(私钥), xxx_pub 或者 xxx.pub(公钥)。记住ssh key生成的文件路径。 默认情况下,ssh会使用 ~/.ssh/id_rsa 这个私钥,但无法处理访问多个ssh远端的场景。 配置本地ssh访问git使用的私钥 打开 ~/.ssh/config 文件,如果没有则创建一个文本文件,添加如下内容 # 请保证 Host 和 HostName 的值相同 (macos11 实测不相同时,git ssh 访问失败) # 远端ssh主机别名 Host bitbucket.cmbc.com.cn # 远端ssh主机名(域名或者ip都可以) HostName bitbucket.cmbc.com.cn # 鉴权文件 ,这填写ssh私钥文件路径 IdentityFile "ssh 私钥文件路径" # 使用公钥算法进行鉴权 PreferredAuthentications publickey 关于 ssh config 更多细节参考 https://linux.die.net/man/5/ssh_config ...

November 27, 2020 · 1 min · holdsky

判断苹果app是否以转译模式运行(Rosetta translation)

苹果app的进程是否运行在转译模式(Rosetta translation),通过调用 sysctlbyname 函数,传入 sysctl.proc_translated 标识来判断 /// 返回 1 表示在Rosetta translation模式 ;返回 0 表示在Native Code模式;返回 -1,表示发生错误 int processIsTranslated() { int ret = 0; size_t size = sizeof(ret); if (sysctlbyname("sysctl.proc_translated", &ret, &size, NULL, 0) == -1) { if (errno == ENOENT) return 0; return -1; } return ret; } 参考地址https://developer.apple.com/documentation/apple_silicon/about_the_rosetta_translation_environment#3616845

November 20, 2020 · 1 min · holdsky

iOS shouldAutorotate , supportedInterfaceOrientations , viewWillTransitionToSize不调用问题

除非只支持单个屏幕方向,否侧shouldAutorotate,viewWillTransitionToSize等方法应被调用。 不被调用的原因,可能是配置文件错误(info.plist),也可能是被Appdelegate或父ViewController拦截了。 1、info.plist配置错误 IPad 上的相关旋转方法都不执行,可能是info中的Supported interface orientations (iPad)项与General->Deployment Info下的Device Orientation配置不一致导致的。 删除不一致项应可以解决问题。 2、被Appdelegate或父ViewController拦截 有点类似触摸事件传递,屏幕旋转也是一层一层的询问。 Appdelegate ---> UIWindow.rootViewController ----> rootViewController的子ViewController 父子ViewController的概念,可以参考 UIViewController.addChildViewController 相关方法。 具体来说 Appdelegate关于旋转的方法 - (UIInterfaceOrientationMask)supportedInterfaceOrientationsForWindow:(nullable UIWindow *)window; - (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(nullable UIWindow *)window; rootViewController关于旋转的方法 # rootViewController 是UINavigationController -(UIInterfaceOrientationMask)navigationControllerSupportedInterfaceOrientations:(UINavigationController *)navigationController; - (BOOL)shouldAutorotate; 子ViewController - (BOOL) shouldAutorotate; -(UIInterfaceOrientationMask)supportedInterfaceOrientations; - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration; - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation; - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator; 参考 https://www.jianshu.com/p/b1ebaad87a80 参考https://www.jianshu.com/p/7c1d214adcbd 参考https://www.jianshu.com/p/73be6d0e152f

November 5, 2020 · 1 min · holdsky