iOS 分享扩展(ShareExtension)指定可以分享的数据类型

可修改info.plist文件中的NSExtensionAttributes .NSExtensionActivationRule 值,例如 <key>NSExtensionAttributes</key> <dict> <key>NSExtensionActivationRule</key> <dict> <key>NSExtensionActivationSupportsImageWithMaxCount</key> <integer>10</integer> <key>NSExtensionActivationSupportsMovieWithMaxCount</key> <integer>1</integer> <key>NSExtensionActivationSupportsWebURLWithMaxCount</key> <integer>1</integer> </dict> </dict> 更多参见 https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/ExtensionScenarios.html#//apple_ref/doc/uid/TP40014214-CH21-SW8

November 5, 2020 · 1 min · holdsky

adb 遍历Android应用包名并删除

adb命令 adb usb ==== 重启 adb的 usb连接 adb shell pm list packages ==== 列举所有应用包名 adb shell am monitor ==== 监控手机上的应用启动 adb shell pm uninstall -k --user 0 包名 ==== 删除包(屏蔽包)

November 5, 2020 · 1 min · holdsky

手动创建一个electron工程

1、创建工程文件夹 并进入 mkdir my-electron-app && cd my-electron-app 2、初始化npm npm init -y 3、安装electron npm i --save-dev electron 自动化脚本 #!/bin/bash # -*- coding:utf-8 -*- import os import sys import json if (len(sys.argv) < 2 ): print("缺少electron工程名字 ; python create-electron-app name") exit(0) CURRENT_PATH = sys.path[0] APP_NAME = sys.argv[1] APP_DIR = os.path.join(CURRENT_PATH,APP_NAME) if os.path.exists( APP_DIR ): print("目录" + APP_NAME + "已存在") exit(0) # 创建工程目录 os.system("cd {} && mkdir {}".format(CURRENT_PATH,APP_NAME)) # 初始化npm os.system("cd {} && npm init -y".format(APP_DIR)) #安装electron os.system("cd {} && npm i --save-dev electron".format(APP_DIR)) #创建主脚本 mainjs = """ const { app, BrowserWindow } = require('electron') function createWindow () { const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true } }) win.loadFile('main.html') win.webContents.openDevTools() } app.whenReady().then(createWindow) app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit() } }) app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) { createWindow() } }) """ fs = open(os.path.join(APP_DIR,"main.js"),"w") fs.write(mainjs) fs.close() #创建主html mainhtml = """ <OCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Hello World!</title> <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" /> </head> <body> <h1>Hello World!</h1> <p>世界你好</p> </body> </html> """ fs = open(os.path.join(APP_DIR,"main.html"),"w") fs.write(mainhtml) fs.close() # 添加快捷启动方式 fs = open(os.path.join(APP_DIR,"package.json"),"r") jsondata = fs.read() fs.close() jsonobj = json.loads(jsondata) jsonobj["scripts"]["start"] = "electron ." jsonobj["main"]= "main.js" jsondata = json.dumps(jsonobj,indent=4) fs = open(os.path.join(APP_DIR,"package.json"),"w") fs.write(jsondata) fs.close() # 启动 os.system("cd {} && npm start".format(APP_DIR)) 参考 https://www.electronjs.org/docs/tutorial/quick-start

October 28, 2020 · 1 min · holdsky

学习笔记:(转)CSS样式选择器优先级

CSS 7 种基础的选择器: ID 选择器, 如 #id{} 类选择器, 如 .class{} 属性选择器, 如 a[href=“segmentfault.com”]{} 伪类选择器, 如 :hover{} 伪元素选择器, 如 ::before{} 标签选择器, 如 span{} 通配选择器, 如 *{} CSS 优先规则3:优先级关系:内联样式 > ID 选择器 > 类选择器 = 属性选择器 = 伪类选择器 > 标签选择器 = 伪元素选择器 参考 https://www.runoob.com/w3cnote/css-style-priority.html

September 30, 2020 · 1 min · holdsky

UITablView Reload会是TextView失去焦点,可使用beginUpdates/endUpdates替代

如题 如果cell中有TextView或者TextField,tableview reload后会是TextView/TextField失去焦点。使用beginUpdates/endUpdates,则会保持焦点

September 14, 2020 · 1 min · holdsky

判断Unicode码是否落在了中文区间

static inline BOOL isChineseC(u_long ch) { /// https://www.qqxiuzi.cn/zh/hanzi-unicode-bianma.php return ( (/ 基本汉字/ ch >= 0x4E00 && ch <= 0x9FA5) || (/ 基本汉字补充/ ch >= 0x9FA6 && ch <= 0x9FEF) || (/ 扩展A/ ch >= 0x3400 && ch <= 0x4DB5) || (/ 扩展B/ ch >= 0x20000 && ch <= 0x2A6D6) || (/ 扩展C/ ch >= 0x2A700 && ch <= 0x2B734) || (/ 扩展D/ ch >= 0x2B740 && ch <= 0x2B81D) || (/ 扩展E/ ch >= 0x2B820 && ch <= 0x2CEA1) || (/ 扩展F/ ch >= 0x2CEB0 && ch <= 0x2EBE0) || (/ 扩展G/ ch >= 0x30000 && ch <= 0x3134A) || (/ 康熙部首/ ch >= 0x2F00 && ch <= 0x2FD5) || (/ 部首扩展/ ch >= 0x2E80 && ch <= 0x2EF3) || (/ 兼容汉/ ch >= 0xF900 && ch <= 0xFAD9) || (/ 兼容扩展/ ch >= 0x2F800 && ch <= 0x2FA1D) || (/ PUA(GBK)部件/ ch >= 0xE815 && ch <= 0xE86F) || (/ 部件扩展/ ch >= 0xE400 && ch <= 0xE5E8) || (/ PUA增补/ ch >= 0xE600 && ch <= 0xE6CF) || (/ 汉字笔画/ ch >= 0x31C0 && ch <= 0x31E3) || (/ 汉字结构/ ch >= 0x2FF0 && ch <= 0x2FFB) || (/ 汉语注音/ ch >= 0x3105 && ch <= 0x312F) || (/ 注音扩展/ ch >= 0x31A0 && ch <= 0x31BA) || (/ 〇/ ch == 0x3007) ); }

September 4, 2020 · 2 min · holdsky

UICollectionView (UICollectionViewFlowLayout)添加元素时保持屏幕定位不变

默认情况下,使用UICollectionViewFlowLayout布局的UICollectionView 的 添加元素,没多一行就会会有自动向上滚动。UITableView的效果也是类似的。 (相对于用户来说)为了保持屏幕定位不变,也就是用户操作的某个cell在屏幕上的位置不变,可以这样做: 获取一行的高度,设置UICollectionView的contentOffset,使向反方向滚动一行,然后立即添加元素 示意代码 //在performBatchUpdates中批量执行 [collectionView performBatchUpdates:^{ // 禁用动画效果 [UIView setAnimationsEnabled:NO]; //添加元素 [collectionView insertItemsAtIndexPaths:@[addIndp]]; if (新增一行) { // 计算一行高度 CGFloat oneLineHeight= 1000; CGFloat oneTop = 0; for (UICollectionViewCell * cell in _collectionView.visibleCells) { if (oneTop <= 0 ) { oneTop = cell.top; } else if (oneTop != cell.top) { CGFloat tmp = (cell.top - oneTop); tmp = ABS(tmp); if (tmp > 1 && oneLineHeight > tmp ) { oneLineHeight = tmp; } } } //向上滚动一行 CGPoint offset = collectionView.contentOffset; offset.y += oneLineHeight; collectionView.contentOffset = offset; } } completion:^(BOOL finished) { //开启动画效果 [UIView setAnimationsEnabled:YES]; }];

July 17, 2020 · 1 min · holdsky

git patch 文件冲突时的解决办法

生成patch 1、生成当前分支的patch 生成当前分支指定节点之后的所有patch 生成的patch,会根据节点顺序自动编号,一个commit生成一个patch文件 git format-patch 404777e8586393d5eb6581485fc1bb2bf2e8eb2a //这里长短commit id都可以 2、生成两个节点之间的patch git format-patch 节点开始..节点结束 //这里长短commit id都可以 //例如 git format-patch aed12..ecf3a 更多详细 https://blog.csdn.net/sunnylgz/article/details/7661920 使用patch 生成patch相对容易,使用时却有些麻烦,尤其是有冲突的时候。 对于有冲突的patch,用搜索引擎搜索出的结果大都是 git apply --reject patch文件 //对于冲突,会生成.rej文件,然后手动解决所有冲突 这种办法在有冲突时,并不好用(因为根据.rej文件手动解决冲突比较麻烦) 我尝试的一个简单方法是 git am --3way patch文件 //解决冲突后 git am --continue --3way,会尝试合并冲突到目标文件,而不是另生成.rej文件,这样的好处是可以使用成熟的冲突解决工具

July 6, 2020 · 1 min · holdsky

【转】ssh访问控制,多次失败登录即封掉IP,防止暴力破解

读取/var/log/secure,查找关键字 Failed,例如: Sep 17 09:08:09 localhost sshd[29087]: Failed password for root from 13.7.3.6 port 44367 ssh2 Sep 17 09:08:20 localhost sshd[29087]: Failed password for root from 13.7.3.6 port 44367 ssh2 Sep 17 09:10:02 localhost sshd[29223]: Failed password for root from 13.7.3.6 port 56482 ssh2 Sep 17 09:10:14 localhost sshd[29223]: Failed password for root from 13.7.3.6 port 56482 ssh2 从这些行中提取IP地址,如果次数达到10次(脚本中判断次数字符长度是否大于1)则将该IP写到 /etc/hosts.deny 中。 步骤: 1、先把始终允许的IP填入 /etc/hosts.allow ,这很重要!比如: sshd:19.16.18.1:allow sshd:19.16.18.2:allow 2、脚本 /usr/local/bin/secure_ssh.sh #! /bin/bash cat /var/log/secure|awk '/Failed/{print $(NF-3)}'|sort|uniq -c|awk '{print $2"="$1;}' > /usr/local/bin/black.list for i in <code>cat /usr/local/bin/black.list</code> do IP=<code>echo $i |awk -F= '{print $1}'</code> NUM=<code>echo $i|awk -F= '{print $2}'</code> if [ ${#NUM} -gt 1 ]; then grep $IP /etc/hosts.deny > /dev/null if [ $? -gt 0 ];then echo "sshd:$IP:deny" >> /etc/hosts.deny fi fi done 3、将secure_ssh.sh脚本放入cron计划任务,每1分钟执行一次。 ...

June 27, 2020 · 1 min · holdsky

Ubuntu18上从源码部署禅道项目管理系统

安装环境: Ubuntu MySql Php Nginx 如果没有安装mysql、PHP、Nginx(或Apache)还是直接使用官方提供的一键安装包吧https://www.zentao.net/book/zentaopmshelp/90.html 相比一键安装包,源码安装也挺简单的。 下载开源版源码: https://www.zentao.net/download/zentaopms12.3.2-80227.html 然后解压缩到服务器上的某个目录,假设目录为 ~/zentaopms 配置nginx,新建一个配置文件 /etc/nginx/sites-available/zentaopms.conf,内容如下 server { server_tokens off; server_name zentaopms.你的域名; listen 80; listen [::]:80; root ~/zentaopms/www; //这里的目录参考禅道源码解压目录 index index.php index.html index.htm; client_max_body_size 5M; location / { try_files $uri $uri/ /index.php?$args; } location ~ \.php$ { include snippets/fastcgi-php.conf; #unix socket 路径参见 /etc/php/7.3/fpm/pool.d/www.conf fastcgi_pass unix:/run/php/php7.3-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } 创建软链接,重启nginx ...

June 25, 2020 · 1 min · holdsky