如何利用iCloud Drive同步Xcode配置详解

前言

多年以前一位老程序员告诉笔者代码片段(code snippets)是程序员的财富,他有一个U盘,里面装着他的财富。每当他需要切换电脑写代码的时候,他就会把把精心配置的字体、主题、代码片段等部署到新电脑上,然后开始高速编码。每次看他写代码都是一种享受,不过这是另一个故事了。

需求

多年之后,笔者也终于凑够了钱买了自己的Mac,闲暇无事的时候也会写写代码祭奠下逝去的青春。但是某些时候总会觉得很别扭,例如感觉字体和单位的有细小的差距,或者一个代码片段怎么也按不出来——最后发现是没有在这台电脑配置这段代码片段。这种事发生的事情多了之后,就会感觉厌烦,同样的操作为什么得重复两次、三次?或者拿出吃了几年灰的U盘抽插在各地的电脑上人工同步?就不能有什么办法可以一次更改多次应用?笔者稍微一拍脑门,想到了今天的主角——iCloud Drive

1、为什么使用iCloud Drive?

因为这是苹果本家的网盘,嵌入系统中,只要开启我们就无需关心上传下载,正如OneDrive在Windows一样,我们只需要把文件放进去,他就会自动开始上传,并在你的每一台苹果设备上同步。利用这点我们就能方便的做到在不同的设备上同步Xcode配置文件,无需手动同步或者上传下载。

2、其他的替代方案

GitHub之类的大型同性交友网站

目前想来用git应该更好更方便,不过实现起来有点复杂,有能力的朋友可以自己动手

OneDrive/坚果云等网盘

我觉得能有自带的还是用自带的吧

思路

总所周知Xcode的代码片段是保存在~/Library/Developer/Xcode/UserData/CodeSnippets路径下的,附近位置还有主题等配置信息。基于笔者的经验我们只需要备份同级目录下的CodeSnippets、FontAndColorThemes和KeyBindings三个子目录就行了。每当我们修改了代码片段、主题或者快捷键,把对应的文件放在iCloud Drive同步,当在其他电脑上时就使用最新的覆盖到对应目录即可。

脚本

虽说思路如此,但是笔者肯定不敢把这种三岁小孩子就能分析出来的东西发出来糊弄人。所以为了简化这个繁琐而又机械的操作,笔者编写了这样一个脚本:

#!/usr/bin/env bash

set -euo pipefail

################# variable define ##########
now=`date "+%Y%m%d%H%M%S"`

red=`tput setaf 1`
green=`tput setaf 2`
yellow=`tput setaf 3`
reset=`tput sgr0`

xcode_dir="${HOME}/Library/Developer/Xcode/UserData"
cloud_backup_dir="${HOME}/Library/Mobile Documents/com~apple~CloudDocs/XcodeBackup"
local_backup_dir="${HOME}/资源/归档/XcodeBackup"

code_snippets="CodeSnippets"
font_and_color_themes="FontAndColorThemes"
key_bindings="KeyBindings"

########### MAIN ##################
# check directory exist
if [ ! -d "${cloud_backup_dir}" ]; then
 echo "${red}iCloud Drive备份路径不存在!${reset}"
 mkdir -p "${cloud_backup_dir}"
 echo "${green}自动创建iCloud Drive备份路径:${reset}${cloud_backup_dir}"
 else
 echo "${green}iCloud Drive备份路径:${reset}${cloud_backup_dir}"
fi

if [ ! -d "${local_backup_dir}" ]; then
 echo "${red}本地备份路径不存在!${reset}"
 mkdir -p "${local_backup_dir}"
 echo "${green}自动创建本地备份路径:${reset}${local_backup_dir}"
 else
 echo "${green}本地备份路径:${reset}${cloud_backup_dir}"
fi

# zip files
cd "${xcode_dir}"
zip -r "${cloud_backup_dir}/XcodeBackup+${now}.zip" "${code_snippets}" "${font_and_color_themes}" "${key_bindings}" &
zip -r "${local_backup_dir}/XcodeBackup+${now}.zip" "${code_snippets}" "${font_and_color_themes}" "${key_bindings}" &

wait

# delete unnecessary backup files
num=`ls -l "${cloud_backup_dir}" |grep "^-"|wc -l`
if [ ${num} -gt 5 ]; then
 num=`expr ${num} - 5`
 cd "${cloud_backup_dir}"
 ls -tr "${cloud_backup_dir}" | head -${num} | xargs rm
fi

num=`ls -l "${local_backup_dir}" |grep "^-"|wc -l`
if [ ${num} -gt 5 ]; then
 num=`expr ${num} - 5`
 cd "${local_backup_dir}"
 ls -tr "${local_backup_dir}" | head -${num} | xargs rm
fi

简化了这个繁琐的操作,仅需在开机的时候跑一下,就能达到自动备份的效果。功能也是十分的简单:

  • 首先创建了两个备份Xcode配置文件的路径,一个在云端,一个在本地(本地路径大家可以自行配置,一般也不会用上)。
  • 然后把Xcode归档到这两处各一份,笔者这里选用zip包而不是更高压缩比的7zip等是因为想做通用一点便于大家开箱即用,不需要额外安装其他软件。
  • 最后将多次运行后生成的老包删除,只保留最新的5个,以便节约宝贵的空间(毕竟笔者比较穷只舍得用免费的5g版)

有了这个脚本之后,大家只需要坚持开机的时候跑一跑就行了。笔者喜欢每天开机就更新下cocoapods、brew、brew cask这类的,所以就写了个脚本,刚好顺便也就备份一下。脚本思路大致如下,因为和主题无关就不细说了。

#!/usr/bin/env bash

open 自用魔法丝袜之影

wait

pod repo update --verbose &
更新Homebrew cask &
备份各种币钱包 &

备份Xcode等IDE配置文件 &

wait

killall 自用魔法丝袜之影

不过这样其实也不是很方便,毕竟打开terminal输入指令都很烦了,难道还要手动计算这台电脑的配置是否是最新的?然后再考虑是不是需要把云盘里面的配置解压到指定的位置覆盖?而且很有可能在做这些前已经把这台电脑的配置当最新版上传到云盘里了。

让所有的电脑用同一个版本的配置

笔者再次进行了思考。如果可以根据这些文件的最后修改日期和备份的文件进行比较,谁新就用哪个版本,那么不就实现了吗?只要我们确保每次修改都跑一次脚本,每次开机都跑一次,就能达到我们想要的效果了。至于如何判断文件的最后修改时间,笔者认为只需要一个根据文件名生成的key和一个对应的文件的最后修改时间做value的数据结构就行了(虽说也可以把备份的文件展开比较,但是因为笔者才疏学浅,尚不知如何操作,就只能通过键值对来判断了)

不过实际操作起来,再次彰显了笔者的才疏学浅,笔者也不知道如何在bash中创建一个高效并能持久化的键值对,如果哪位大佬知道请务必告诉笔者。

最后笔者想到Mac自带的SQLite3,虽说这样一个小小的功能上数据库是有一点高射炮打蚊子,但是能跑就行吧。脚本如下;

#!/usr/bin/env bash

set -euo pipefail

################# variable define ##########
now=`date "+%Y%m%d%H%M%S"`

red=`tput setaf 1`
green=`tput setaf 2`
yellow=`tput setaf 3`
reset=`tput sgr0`

xcode_dir="${HOME}/Library/Developer/Xcode/UserData"
cloud_backup_dir="${HOME}/Library/Mobile Documents/com~apple~CloudDocs/XcodeBackup"
local_backup_dir="${HOME}/资源/归档/XcodeBackup"

xcode_backup_database="${HOME}/Library/Mobile Documents/com~apple~CloudDocs/.BackupDatabase"

code_snippets="CodeSnippets"
font_and_color_themes="FontAndColorThemes"
key_bindings="KeyBindings"

temp="DoNotModify"
database="${xcode_backup_database}/${temp}"

########### MAIN ##################
# check directory exist
if [ ! -d "${cloud_backup_dir}" ]; then
 echo "${red}iCloud Drive备份路径不存在!${reset}"
 mkdir -p "${cloud_backup_dir}"
 echo "${green}自动创建iCloud Drive备份路径:${reset}${cloud_backup_dir}"
else
 echo "${green}iCloud Drive备份路径:${reset}${cloud_backup_dir}"
fi

if [ ! -d "${local_backup_dir}" ]; then
 echo "${red}本地备份路径不存在!${reset}"
 mkdir -p "${local_backup_dir}"
 echo "${green}自动创建本地备份路径:${reset}${local_backup_dir}"
else
 echo "${green}本地备份路径:${reset}${cloud_backup_dir}"
fi

if [ ! -d "${xcode_backup_database}" ]; then
 echo "${red}同步数据库路径不存在!${reset}"
 mkdir -p "${xcode_backup_database}"
 echo "${green}自动创建数据库路径:${reset}${local_backup_dir}"
else
 echo "${green}数据库路径:${reset}${cloud_backup_dir}"
fi

sqlite3 "${database}" 'create table if not exists backupXcode(id integer primary key not NULL,key integer unique not NULL,value integer not NULL);'

#获取最后修改时间
cd "${xcode_dir}"
find "./${code_snippets}" "./${font_and_color_themes}" "./${key_bindings}" -type f >> ${temp}

while read path; do
 key=`md5 -q -s "${path}"`
 value=`stat -f "%m" "${path}"`
 isModify=`sqlite3 "${database}" "select value from backupXcode where key == '${key}';"`
 if [ -z ${isModify} ]; then
  echo "${yellow}本地Xcode配置尚未同步${reset}!"
  num=`ls -l "${cloud_backup_dir}" |grep "^-"|wc -l`
  if [ ${num} -ge 1 ]; then
   echo "${green}找到最新的Xcode配置,开始自动替换${reset}!"

   cd "${xcode_dir}"
   ## backup before
   zip -r "XcodeBackup.zip" "${code_snippets}" "${font_and_color_themes}" "${key_bindings}" &
   wait

   cd "${cloud_backup_dir}"
   newBackup=`ls -t | head -1`

   unzip -u "${newBackup}" -d "${xcode_dir}" &
   wait

   cd "${xcode_dir}"
   rm ${temp}
   find "./${code_snippets}" "./${font_and_color_themes}" "./${key_bindings}" -type f >> ${temp}
   echo 更新数据库...
   while read path; do
    key=`md5 -q -s "${path}"`
    value=`stat -f "%m" "${path}"`
    sqlite3 "${database}" "insert or replace into backupXcode values(NULL,'${key}',${value});" &
   done < ${temp}
  fi
  break
 fi
 if [ ${isModify} != ${value} ]; then
  if [ ${isModify} -lt ${value} ]; then
   echo "${yellow}本地Xcode配置超前${reset}!"
  else
   echo "${yellow}本地Xcode配置已经过期${reset}!"

   num=`ls -l "${cloud_backup_dir}" |grep "^-"|wc -l`
   if [ ${num} -ge 1 ]; then
    echo "${green}找到最新的Xcode配置,开始自动替换${reset}!"

    cd "${xcode_dir}"
    ## backup before
    zip -r "XcodeBackup.zip" "${code_snippets}" "${font_and_color_themes}" "${key_bindings}" &
    wait

    cd "${cloud_backup_dir}"
    newBackup=`ls -t | head -1`

    unzip -o "${newBackup}" -d "${xcode_dir}" &
    wait
   fi
  fi
  cd "${xcode_dir}"
  rm ${temp}
  find "./${code_snippets}" "./${font_and_color_themes}" "./${key_bindings}" -type f >> ${temp}
  echo 更新数据库...
  while read path; do
   key=`md5 -q -s "${path}"`
   value=`stat -f "%m" "${path}"`
   sqlite3 "${database}" "insert or replace into backupXcode values(NULL,'${key}',${value});"
  done < ${temp}
  break
 fi
done < ${temp}

wait
rm ${temp}

# zip files
cd "${xcode_dir}"
zip -r "${cloud_backup_dir}/XcodeBackup+${now}.zip" "${code_snippets}" "${font_and_color_themes}" "${key_bindings}" &
zip -r "${local_backup_dir}/XcodeBackup+${now}.zip" "${code_snippets}" "${font_and_color_themes}" "${key_bindings}" &

wait

# delete unnecessary backup files
num=`ls -l "${cloud_backup_dir}" |grep "^-"|wc -l`
if [ ${num} -gt 5 ]; then
 num=`expr ${num} - 5`
 cd "${cloud_backup_dir}"
 ls -tr "${cloud_backup_dir}" | head -${num} | xargs rm
fi

num=`ls -l "${local_backup_dir}" |grep "^-"|wc -l`
if [ ${num} -gt 5 ]; then
 num=`expr ${num} - 5`
 cd "${local_backup_dir}"
 ls -tr "${local_backup_dir}" | head -${num} | xargs rm
fi

后记

笔者简单测试了一下,基本上能用。以此思路,应该也可用在Alfred、vimrc等配置文件。不过依旧不是很方便,不过笔者才疏学浅,目前也就这个水平了,希望能对大家有所帮助,不知道大家有没有什么好的建议?笔者认为可以在Xcode关闭时自动运行本脚本,但是尚未找到好的胡克点(:」∠)_,如果大家有什么好的建议,欢迎PR

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • 如何利用iCloud Drive同步Xcode配置详解

    前言 多年以前一位老程序员告诉笔者代码片段(code snippets)是程序员的财富,他有一个U盘,里面装着他的财富.每当他需要切换电脑写代码的时候,他就会把把精心配置的字体.主题.代码片段等部署到新电脑上,然后开始高速编码.每次看他写代码都是一种享受,不过这是另一个故事了. 需求 多年之后,笔者也终于凑够了钱买了自己的Mac,闲暇无事的时候也会写写代码祭奠下逝去的青春.但是某些时候总会觉得很别扭,例如感觉字体和单位的有细小的差距,或者一个代码片段怎么也按不出来--最后发现是没有在这台电脑配置

  • RSync实现文件同步备份配置详解

    一.什么是rsync rsync,remote synchronize顾名思意就知道它是一款实现远程同步功能的软件,它在同步文件的同时,可以保持原来文件的权限.时间.软硬链接等附加信息. rsync是用 "rsync 算法"提供了一个客户机和远程文件服务器的文件同步的快速方法,而且可以通过ssh方式来传输文件,这样其保密性也非常好,另外它还是免费的软件. rsync 包括如下的一些特性: 能更新整个目录和树和文件系统: 有选择性的保持符号链链.硬链接.文件属于.权限.设备以及时间等:

  • mariadb的主从复制、主主复制、半同步复制配置详解

    主从服务器的时间要同步,数据库版本最好是一致的,以免造成函数处理.日志读取.日志解析等发生异常. 以下三个主从复制的设置是独立的. 注意防火墙和selinux的影响. 1.简单主从复制的实现 (1)主服务器的配置 1)安装mariadb-server [root@localhost ~]# yum -y install mariadb-server 2)编辑/etc/my.cnf文件 [root@localhost ~]# vim /etc/my.cnf 在[mysqld]段的最后添加以下内容

  • MySQL5.6 数据库主从同步安装与配置详解(Master/Slave)

    MySQL5.6 数据库主从同步安装与配置详解(Master/Slave) 本篇文章主要介绍了MySQL5.6 数据库主从同步安装与配置详解,具有一定的参考价值,有兴趣的可以了解一下. 安装环境 操作系统 :CentOS 6.5 数据库版本:MySQL 5.6.27 主机A:192.168.1.1 (Master) 主机B:192.168.1.2 (Slave) 这里强调的数据库的版本,是因为MySQL在5.6之前和之后的安装方式是不一样的. 本人在进行配置的时候,也遇到了这个坑,这里提前说明,

  • springcloud微服务之Eureka配置详解

    Eureka注册中心/服务发现框架 Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的.SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能. Eureka包含两个组件:Eureka Server和Eureka Client. Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Serve

  • redis配置文件中常用配置详解

    此次安装的版本为: 5.0.3 [root@localhost local]# redis-server --version Redis server v=5.0.3 sha=00000000:0 malloc=jemalloc-5.1.0 bits=64 build=afabdecde61000c3 打开redis.cof NETWORK # 指定 redis 只接收来自于该IP地址的请求,如果不进行设置,那么将处理所有请求 bind 127.0.0.1 #是否开启保护模式,默认开启.要是配置

  • Redis 对比 Memcached 并在 CentOS 下进行安装配置详解

    Redis 是一个开源.支持网络.基于内存.键值对的 Key-Value 数据库,本篇文章主要介绍了Redis 对比 Memcached 并在 CentOS 下进行安装配置详解,有兴趣的可以了解一下. 了解一下 Redis Redis 是一个开源.支持网络.基于内存.键值对的 Key-Value 数据库,使用 ANSI C 编写,并提供多种语言的 API ,它几乎没有上手难度,只需要几分钟我们就能完成安装工作,并让它开始与应用程序顺畅协作.换句话来说,只需投入一小部分时间与精力,大家就能获得立竿

  • Mybatis中 XML配置详解

    Mybatis常用带有禁用缓存的XML配置 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd" > <configuration> <

  • Nginx配置文件(nginx.conf)配置详解(总结)

    现在经常碰到有新用户问一些很基本的问题,最近整理了一下,Nginx的配置文件nginx.conf配置详解如下: user nginx nginx ; Nginx用户及组:用户 组.window下不指定 worker_processes 8; 工作进程:数目.根据硬件调整,通常等于CPU数量或者2倍于CPU. error_log logs/error.log; error_log logs/error.log notice; error_log logs/error.log info; 错误日志:

  • 利用二进制文件安装etcd的教程详解

    etcd组件作为一个高可用强一致性的服务发现存储仓库. etcd作为一个受到ZooKeeper与doozer启发而催生的项目,除了拥有与之类似的功能外,更专注于以下四点. 简单:基于HTTP+JSON的API让你用curl就可以轻松使用. 安全:可选SSL客户认证机制. 快速:每个实例每秒支持一千次写操作. 可信:使用Raft算法充分实现了分布式. 场景一:服务发现(Service Discovery)一个强一致性.高可用的服务存储目录.基于Raft算法的etcd天生就是这样一个强一致性高可用的

随机推荐