肇鑫的技术博客

业精于勤,荒于嬉

脱离CocoaPods 1.8.0的trunk

今早升级pods的时候,看到1.8.0的CocoaPods正式版出了。于是升级了。之后pod install的时候,被强制安装了新的源trunk.

使用时,我发现,pod repo update的界面变了,不仅没有了之前的进度和速度,还变慢了。我搜索了一下trunk,都是说和个人建立自己的源有关,于是我迅速提交了一个故障报告。CocoaPods 1.8.0 added 'trunk' to my repo though I don't use 'trunk' #9190

很快收到了回复,说这个是1.8.0的新功能,采用cdn替换了原本的master。通俗说,就是用分布各地的服务器来替换了原本的GitHub的源。理论上讲,使用了cdn之后,如果你的附近有源服务器,就会加速你更新pods的速度。

但实际上我这里反而重回龟速了。

CocoaPods 1.8希望你这么做

删除掉原本的master

千万别这么做!

pod repo remove master

只要你这么做了,以后的操作就都是基于trunk的了。

如何脱离trunk

如果你已经有了trunk

pod repo remove trunk

如果你已经删掉了master,采用此命令恢复

git clone https://github.com/CocoaPods/Specs.git ~/.cocoapods/repos/master

最重要的一步

打开你每个项目的Podfile,在最顶部添加

source 'https://github.com/CocoaPods/Specs.git'

trunk的方式已经成为了新的默认。如果还想使用旧的方式,就必须每个Podfile顶部都指定源。

两个脚本

为已有的Podfile添加源

#!/bin/bash
echo -e "source 'https://github.com/CocoaPods/Specs.git'\n" | cat - Podfile > temp && mv temp Podfile

新建Podfile

#!/bin/bash
pod init
echo -e "source 'https://github.com/CocoaPods/Specs.git'\n" | cat - Podfile > temp && mv temp Podfile

此外

如果你对于自己的网络有信心,可以测试一下使用cdn的网速。满意的话,也可以按照官方的指导做,删掉master。这样的好处就是不用每个Podfile都需要指定源了。

在终端使用代理

如果你的代理包含socks5,可以在~/.bashrc文件中添加两行。

alias proxy='export all_proxy=socks5://127.0.0.1:1086'
alias unproxy='unset all_proxy'

这样就可以在终端中使用proxy开启代理,可以极大地加速终端下访问GitHub的速度。

参考资料

Ubuntu服务器Livepatch安装及问题解决

Ubuntu在14.04以后,支持更新内核之后动态更新的技术。但是需要激活。步骤如下:

  1. https://auth.livepatch.canonical.com申请一个token。
  2. 然后安装命令操作。

问题

执行第二行命令的时候,遇到了错误。

2019/08/30 01:46:55 error executing enable: cannot enable machine: this machine ID is already enabled with a different key or is non-unique. Either "sudo canonical-livepatch disable" on the other machine, or regenerate a unique /etc/machine-id on this machine with "sudo rm /etc/machine-id /var/lib/dbus/machine-id && sudo systemd-machine-id-setup": {"error": "Conflicting machine-id"}

解决

rm -f /etc/machine-id
rm /var/lib/dbus/machine-id
dbus-uuidgen --ensure=/etc/machine-id
dbus-uuidgen --ensure

> 注意:上面的操作有风险,需要先备份你的系统。

然后再执行第二行的命令。

参考资料

开发者备份和恢复Realm数据库

最近在研究带参数的捷径。因为是SiriKit相关,需要把Realm放在应用组里。这样就不能通过Xcode下载容器了。几天时间里,已经有了两次不小心删除掉数据库,而不得不通过备份恢复手机的经历。我开始研究一下如何导出和恢复数据。

思路

因为目的只是为了方便开发,而不是交给用户操作,过程简便,代码容易是重点。

首先想到的是通过长按某个按钮实现导出,然后出了问题就将导出的数据库放在应用里,应用启动时检测是否有数据,如果有,就替换,然后再正常启动。

实现

具体实现的时候,遇到了一个问题,分享出来的URL,并没有写成文件,而是写成了纯文本。

@objc private func exportRealm(_ sender:Any) {
    let sourceURL = Realm.Configuration.defaultConfiguration.fileURL!
    
    // copy realm to cache and rename it to current date and time
    let fm = FileManager.default
    let filename = { () -> String in
        let df = DateFormatter()
        df.dateFormat = "yyyy.MM.dd_HH.mm.ss"
        return "any_counter_2.backup.at.\(df.string(from: Date())).realm"
    }()
    let cacheFolderURL = fm.urls(for: .cachesDirectory, in: .userDomainMask).first!
    let destinationURL = URL(fileURLWithPath: filename, isDirectory: false, relativeTo: cacheFolderURL)
    
    do {
        try fm.copyItem(at: sourceURL, to: destinationURL)
    } catch {
        return
    }

    // export
    let activityViewController = UIActivityViewController(activityItems: [destinationURL], applicationActivities: nil)
    activityViewController.completionWithItemsHandler = { (_, isCompleted, _, activityError) -> Void in
        guard activityError == nil || (activityError! as NSError).code == 3072 else { // Error Domain=NSCocoaErrorDomain Code=3072 \"操作已被取消。\"
            fatalError("\(activityError!)")
        }

        // clear cache after success
        try? fm.removeItem(at: destinationURL)
    }
    present(activityViewController, animated: true, completion: nil)
}

这个问题花费了我不少时间去寻找解决方案。最后我突发奇想解决了。实际上,就是和URL有关。将12行

let destinationURL = URL(fileURLWithPath: filename, isDirectory: false, relativeTo: cacheFolderURL)

替换为

let destinationURL = URL(fileURLWithPath: cacheFolderURL.path + "/" + filename, isDirectory: false)

,问题解决。

类似的事情很早就遇到过,比如

import Foundation

let folder = "/foo"
let file = "bar"

let folderURL = URL(fileURLWithPath: folder, isDirectory: true)
let u1 = URL(fileURLWithPath: file, isDirectory: false, relativeTo: folderURL)
print(u1.path) // /foo/bar

let u2 = URL(fileURLWithPath: folder + "/" + file, isDirectory: false)
print(u2.path) // /foo/bar

print(u1 == u2) // false
print(u1.path == u2.path) // true

即两个path相同的URL,仅仅是因为构造方法的不同,它们就不相等。这其实是很不直观的,人们在没遇到之前,可能就会认为path相等的两个URL就是相等的,但是实际上系统认为不是。

这里也是这样,通过relativeTo构造的URL,iOS系统仅能将它存成一个纯文本。但是直接构造的URL就没有这个问题。

我虽然不认同,但是只能记住。