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

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