iOS开发如何浏览模拟器中的coredata数据

在后端开发使用go语言时,网络包的使用经历了beego,fasthttp等包,最终又用回了go的官方http包(当然这个包最近各种升级例如支持了优雅退出啊等等就算是另一说了),发现还是尽量用官方的东西更好一些。

iOS开发也是这样,iOS开发中本地数据库操作也有不少的解决方案,从iOS自带的coredata,到FMDB,再到完全不依赖sqlite的Realm,我原本也使用了一段时间的realm,但有两点让我很不爽

  1. 毕竟是第三方项目,总是要更新,如果你是使用OC语言的,那么还好,但如果你是像我一样使用swift语言的,那么swift的更新外加realm自身的更新能够把你烦死
  2. realm对于字段变更的操作非常不友好,如果还没生成数据还则罢了,如果已经生成了数据,那么不好意思,请按照realm提供的反人类一样的方法一步一步执行,而且你还得关注当前的字段版本,比如最老的版本是1.0,之后你又推出了1.0.1和1.0.2的更新,那么你就至少得写下1.0到1.0.2和1.0.1到1.0.2的两个版本迁移的代码块,因为我们是在面向C端的,你永远不知道你的用户什么时候更新你的APP,所以你得提供所有老版本到最新版本的转化方式。

综上,最终我还是决定用回coredata,至少官方的支持还是可以的,swift版本也不用像OC一样需要几个步骤生成连接代码等等,直接在model文件里操作好,背后的一切工作swift都已经帮你完成了,当然,这里我要强调一点,那就是本地数据库并不应该存储多么巨大复杂的数据,如果一个用户一天在你的APP里生成10条数据,一年也不到4000条,完全到不了需要拼速度和优化的时候。

终于说到正题,既然使用了coredata,那么调试的时候免不了会想要查看一下数据或者手动更改数据,可是模拟器的数据一是藏得深,二是并没有直接浏览更改的方式,我们分别解决一下。

获取数据路径

在AppDelegate文件的didfinishlaunch中加入下面这一行代码

print(FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask))

这样会把当前模拟器的文件路径打印出来,有了路径,就好办了,比如可以在terminal里直接open,然后应该会看到一个名为“Application Support”的文件夹,里面就是对应的.sqlite文件

查看.sqlite文件

有了文件,如何查看又是个问题,下面提供以下几个方法,可以根据自身情况自由选择

  • (推荐)使用sqlite3直接在terminal里查看
    • 对于习惯于用命令行操纵MySQL的人来说,sqlite3的操作应该没有什么入门难度,也是比较推荐的方法,Mac又是自带Python和sqlite3的,如果找不到,那么可以从如下网站来进行安装:https://www.sqlite.org/download.html
  • (推荐)可视化方案:DB Browser for SQLite
    • 对于习惯于可视化管理的人来说,我推荐这个方案,本身是一个在GitHub上的开源项目,马上要突破1万星,安全和可靠性都有保障,还是免费的,只要把.sqlite文件拖到这个APP内就可以自动打开,当然coredata自动命名的表名和你自己命名的略有区别,比如我创建了一个Objectives的Enity,在这里看到就是ZOBJECTIVES,自己找一下就可以了
    • GitHub地址:https://github.com/sqlitebrowser/sqlitebrowser
    • 官方网页直接下载打包好的版本:https://sqlitebrowser.org
  • 可视化方案:Base 2
    • 功能更完善,界面更好看,但没有优先推荐的原因是其是收费的,20欧的售价其实并不算高,不过没有特别专业复杂的需求,用上面的就足够了
    • 官网地址:https://menial.co.uk/base/
  • 可视化方案:Firefox sqlite插件
    • 这个大概就是特定适合使用火狐浏览器的人群了吧,我本身不用火狐,所以各位如果用的也可以测试了给我反馈一下
  • (不推荐尝试)可视化方案:Core-Data-Editor
    • 同样是GitHub上的一个开源方案,但由OC写成,同时也只支持OC,同时需要有一个初始的适配过程,并且不能直接打开.sqlite文件
    • GitHub地址:https://github.com/ChristianKienle/Core-Data-Editor

在kubernetes集群中使用私有镜像源

最近公司迁移到了新集群,为了确保服务上线后的稳定性,所有的应用上线之前都要在本地的minikube上跑一下,但原本在集群上用得正常的yaml,在minikube里就无法正常拉取docker镜像,Google一番之后被kubernetes的官方文档搞得一头雾水,拉到最下面才找到了原因,其实好好研究一下yaml就能发现不同的点,即yaml里有这样一行

imagePullSecrets

当deployment指定了特定的secret之后,其便会遵循这个secret中的docker镜像源的信息来拉取镜像,创建非常简单,只要

$ kubectl create secret docker-registry myregistrykey --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
secret "myregistrykey" created.

其中email是选填的

在yaml里就可以直接这样写:

apiVersion: v1
kind: Pod
metadata:
  name: foo
  namespace: awesomeapps
spec:
  containers:
    - name: foo
      image: janedoe/awesomeapp:v1
  imagePullSecrets:
    - name: myregistrykey

参考资料:
https://kubernetes.io/docs/concepts/containers/images/#using-a-private-registry

Mysql更新排名的取巧实现

最近的项目连续遇到了对用户排名的需求,一个要求不用并列,一个要求同分并列,因为用户体量的考虑,拒绝了实时更新(即每个用户查询排名时获取排名),改为定时更新,在网上查了大量的MySQL排名算法之后,发现大部分的文章是以查询时获取来实现,而非定时更新所有人的排名,所以经过一番研究之后自己写了一个算法,欢迎斧正

首先我们假设有一张user表,其中有四个字段,score,rank,score_rank,join_time分别代表用户的分数,排名,获取排名时的分数,及用户加入时间

首先是不考虑并列的情况

SET @r = 0
UPDATE user
SET `rank` = @r := (@r + 1), `score_rank` = `score`
WHERE `score` != 0
ORDER BY `score` DESC, `join_time` DESC // 因为没有并列,所以增加一个排序

然后是考虑并列的情况

SET @r = 0;
SET @l = 0;
SET @s = 1;
UPDATE `user` SET `rank` = (
CASE
WHEN `score` = @l THEN @r := @r + (@s := @s + 1) - @s
ELSE @r := (@r + @s) + (@s := 1) - 1 END), `score_rank` = @l := (`score`)
WHERE `score` != 0
ORDER BY `score` DESC

这里唯一需要注意的事情就是MySQL中的变量问题,变量只能在两个地方赋值,SET或SELECT时,其余的地方只允许在变量赋值给其他字段时才允许被修改,所以就是在这里我们开始取巧,来解释一下并列时的思想:

r,l,s分别是当前排名,当前排名的分数,和当前同分的人数

当某一行的数据与上一行的分数相同时,即 score = @l,那么这时应该给rank赋值为当前的排名,但同时应该更新同分人数,所以我们这样来实现:@r := @r + (@s := @s + 1) – @s,这样s实现了自增,但对返回结果r没有影响

当某一行的数据与上一行的分数不同时,则应该给rank赋值r+1,但同时我们希望给l赋值当前的分数,并把同分人数s归为1,则选择这样实现:@r := (@r + @s) + (@s := 1) – 1

关于速度

这个算法在我这边的模拟测试中,三万条的数据排序用时0.4秒,所以肯定不能作为实时处理,计划是每天定时更新一回,操作时间也算是可以接受了。不知道其他算法的时间是会是多少,欢迎提供下对比。

Golang生产环境中time包的zonefile.zip问题

前段时间给程序加了个功能,打印时间按照时区打印,具体看起来是这样

    loc, _ := time.LoadLocation("Asia/Chongqing")
    return time.Now().In(loc).Format("2006-01-02 15:04:05")

在本地运行没有丝毫问题,于是就想当然的推到了线上,结果线上的环境在进行到这步的时候直接panic了,嗯,看来是过于的自信导致了问题,明显loc是nil了,那么打印下错误吧,结果看到了这么一行:

open /usr/local/go/lib/time/zoneinfo.zip: no such file or directory

于是瞬间就明白了,我们线上使用的是docker镜像,复制到容器里的go程序也是编译好的二进制文件,所以容器里没有go环境,导致在本地能正常运行的程序在线上因为缺少对应文件而panic。

知道了问题,就好解决了,当然这里可以直接换加了go环境的镜像,但是明显这样违背了docker作为线上生产环境的初衷,即最小可用,加入了go环境会直接把大量的冗余数据加入到容器中,使单个容器的体积直接倍增,所以我们只需要把这个特定依赖的文件复制到容器中即可,在Dockerfile中加入这样一段:

    COPY ./zoneinfo.zip /usr/local/go/lib/time/zoneinfo.zip
    // 这里我把这个文件也在本地复制到了我的项目中,因为我们的打包上线工作由线上的CI服务来完成,如果是在本地打包,那么可以直接复制原文件
    COPY /usr/local/go/lib/time/zoneinfo.zip /usr/local/go/lib/time/zoneinfo.zip

最后说一句,下划线无视error什么的,是真不可取啊,吸取教训把上面的代码也换成了

     loc, err := time.LoadLocation("Asia/Chongqing")

	if err != nil {
		LogError("parse location err:", err)
		loc = time.Local
	}

	return time.Now().In(loc).Format("2006-01-02 15:04:05")

升级MacOS10.13 High Sierra导致PHPMyAdmin无法正常显示的问题

升级了新的版本之后,一切介正常,唯独发现pma打不开了,变成了一堆php代码,猜想是自带的Apache出了问题,参考网上其他教程,打开了httpd.conf,发现果然和php有关的那个loadmodule被注释掉了,打开,重启Apache,无果。继续Google,发现还要加上AddType和AddHandler,加上,重启Apache,仍然无果,但发现php info检测的代码可以正常打开了,遂怀疑是自带的PHP升级了,不再兼容当前版本的pma了,于是按照官方流程升级pma,重新打开,正常工作,解决战斗。

以下是详细三部曲:

  • 修改httpd.conf, 开启PHP loadmodule

打开Terminal,输入:sudo nano /etc/apache2/httpd.conf, 对httpd.conf进行编辑,按ctrl+W,搜索php7_module,找到:#LoadModule php7_module libexec/apache2/libphp7.so,将此行前的#号去掉,ctrl+O保存(此处可能弹出finder,关掉即可),ctrl+X退出

参考文献: PHP精通 mac本地安装php环境 找不到webserver 更改php文件目录 运行

  •  修改httpd.conf,增加php文件支持

同上,搜索IfModule,在任意位置添加如下代码:

<IfModule php7_module>
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps

<IfModule dir_module>
DirectoryIndex index.html index.php
</IfModule>
</IfModule>

参考文献:PHPMyAdmin showing code instead of webpage

  • 升级到最新版本的pma

    1. 从以下网址下载最新版本的PHPmyadmin:https://www.phpmyadmin.net/downloads/
    2. 重命名旧的pma文件夹(例如:phpmyadmin-old)
    3. 解压并复制并重命名刚刚下载好的新版本pma到需要的位置(例如:phpmyadmin)
    4. 从旧的文件夹中拷贝config.inc.php文件到新文件夹中
    5. 测试是否一切正常工作
    6. 删除旧文件夹

翻译自官方文档:phpMyAdmin-Docs-安装-从旧版本更新

PS:Reference websites may require ladders.