KISS

Keep It Simple Stupid

My observations from learning electronics

| comments

I’ve wanted to learn electronics for a long time, and it always seemed a huge field where you’d need to know psychics and differential equations well. Then it started two years ago with the Make: Electronics book and I’ve been learning about this very interesting field of hardware. It is also interesting to note the differences between hardware and software — programming has been my job for eight years. The following is how I understand electronics now and may or may not be entirely correct. I welcome your feedback and clarifications.

Cloning TimeMachine backup drive to another disk

| comments

Say, you have an external USB drive for TimeMachine backups on OSX. (You make backups, don’t you?) Now you want to replace it with a larger drive, so the task is to copy all the data to the new disk. There are two ways to do it:

  1. Create an equivalent partition setup on the new disk and copy all the files on each filesystem. Since the default TimeMachine setup is to have one (visible) user’s partition, it shouldn’t be too hard, however you want to make sure all the information is copied, including file timestamps, Access Control Lists, extended attributes, etc. The best tool I know for this job is rsync (install a newer version from brew), however I had issues in the past when copying Time Machine backups because those directories have some special permissions and even sudo didn’t help.

  2. Clone the disk byte-by-byte. This is a lower-level approach, which doesn’t care about which partitions and filesystems you have and you will have an exact copy. It will copy all the disk’s bytes, even if you’re really using little space. Since we’re migrating to a larger disk, all the old bytes will fit.

The latter approach seems to me a better one for the exact duplication of a TimeMachine backup drive. How I did it and a few necessary steps follow.

OSX, TimeMachine and log: too many arguments

| comments

Apple has updated the OSX’s logging system in OSX 10.12. The Console.app for viewing logs was also updated and has become pretty much useless. I couldn’t find TimeMachine logs anywhere, for example. It seems that past messages cannot be seen there at all. Luckily there is still a way to see the proper logs in the terminal. This superuser question has answers for how to do that, using the log utility. However, when I tried it locally I only got:

1
2
$ log show --style syslog --info --last 10m --predicate 'processImagePath contains "backupd" and subsystem beginswith "com.apple.TimeMachine"'
log: too many arguments

Global notification center in iOS is an anti-pattern

| comments

There is the standard class in the Apple’s Foundation framework: NotificationCenter, which is used to deliver global notifications to anyone who subscribes to them. Sounds like a great idea, doesn’t it? I think that it brings more harm than good and is used too much in iOS applications — just like the Singleton pattern. Both have their own use cases and are useful in specific circumstances, but those are quite rare. This article is about how to decrease the dependency on the global notification center.

How I migrated Arch Linux ARM to another Pi architecture

| comments

For a small project of mine, I needed a small computer — I picked a Raspberry Pi 3B+ and setup the Arch Linux ARM there, which worked great. However I only used its Wi-Fi and GPIO ports, so that high-end model was an overkill. I decided to migrate to a smaller and cheaper one — Raspberry Pi Zero W. The 3B+ model uses an armv7 chip (to be precise, that’s an aarm64 (aka armv8), but I couldn’t make the GPIO ports work there a few months ago), and the zero W has an armv6 chip, so cloning the SD card directly doesn’t work (the binaries will be incompatible). My solution is to install the proper Arch Linux ARM for armv6 on the new SD card and then manually transfer the necessary configs/files from the old one. My way of doing that is below.

OSX says, “iCloud Drive may not work properly”. I say, “Who cares?”

| comments

I had to upgrade recently from OSX 10.11.6 to OSX 10.13.3 to be able to run the latest Xcode. The upgrade has broken a few things and also brought a bunch of new system stuff — I found out about a dozen of new daemons because my Little Snitch was popping an alert quite often after the upgrade.

There were some questionable daemons trying to access the internets, for example keyboardservicesd — based on the name only, why would a keyboard-related daemon connect online? I didn’t want to get into the details so I just blocked almost all of them. But why stop at blocking the access? A better way is to actually stop these muddy services, that’s what I did and ended up seeing this “iCloud Drive may not work properly. Please check the iCloud preference pane.” alert every time I opened the Open/Save File dialog in any application — it showed up once per app launch.

"iCloud Drive may not work properly. Please check the iCloud preference pane."

That is very annoying, especially since I don’t care about this iCloud thing at all and I would gladly remove/disable it altogether in an official way, but guess what, Apple doesn’t provide that way (at least, I couldn’t find anything online). I was then searching for this message to figure out what is possible to do to get rid of it — nope, nothing. I had to brush up on my little reverse engineering skills to deal with it myself. The step-by-step story (and guide to repeat it) is below.

IPA export error in Xcode and ruby

| comments

I needed to archive my project and export its .ipa file with Xcode, so I went to “Product” > “Archive”. After building the project a new window opens where you click “Export…”, then select “Development”. And it shows “The data couldn’t be read because it isn’t in the correct format.” error:

"The data couldn’t be read because it isn’t in the correct format." Xcode error

How can it be an incorrect format?! Xcode restarts didn’t help.

OSX: `sudo` with insults

| comments

I’ve had this line in my /etc/sudoers file for years:

1
Defaults insults

It enables the insults option, which prints a funny message instead of boring “Sorry, try again” when you type an incorrect password for sudo. The man page says:

If set, sudo will insult users when they enter an incorrect password. This flag is off by default.

I noticed that it stopped working quite a while ago — I don’t remember seeing the insults in OSX 10.11.6, nor now in 10.13.3.

swift: Functions are more generic `enum`s

| comments

Let’s say you have a structure with two very similar properties and you need to choose one of the two. You don’t know which one at compile time, so you need to have a parameter to change that at runtime. This post shows this in a very simple and contrived example, given the data structures:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct Person {
    let firstName: String
    let lastName: String
    let age: UInt8
}

struct PersonId {
    let name: String
    let age: UInt8
}

let johnDoe = Person(firstName: "John", lastName: "Doe", age: 42)
print("Input: \(johnDoe)")

// Input: Person(firstName: "John", lastName: "Doe", age: 42)

The Person (the input) has two names: firstName and lastName, and when you need to convert it to a PersonId (the output) you need to select one of the names. How do you do that?

An infinite list usage example in swift

| comments

Learning various programming paradigms is very useful to extend your mind and also design approaches in your main language. For example, this post describes a simple example where infinite lists, as in Haskell, allow us to solve a problem in swift more elegantly.

The simple task

Let’s say we have some basic data structure in our domain model:

1
2
3
4
5
6
7
8
9
10
11
public typealias Label = String

public struct ColoredLabel {
    public let label: Label
    public let color: UIColor

    public init(label: Label, color: UIColor) {
        self.label = label
        self.color = color
    }
}

We have a list of Labels, which can be of any length, and we need to add a color to every Label, create a new ColoredLabel and send it to another system. We have a predefined set of colors, let’s say only three of them:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public let labels: [Label] = ["a", "b", "c", "d", "e", "f", "g"]

public let defaultColors: [UIColor] = [.blue, .green, .orange]

public extension UIColor {
    open override var debugDescription: String {
        switch self {
        case UIColor.blue: return "blue"
        case UIColor.green: return "green"
        case UIColor.orange: return "orange"
        case UIColor.black: return "black"
        default: return super.description
        }
    }
}

I’ve also overridden the debugDescription for our set of colors to make the debug output below more readable.

How do you color each label in case when we have more labels than colors, given that the colors should be looped?