Category: Programming & Tech

History Repeating Itself

At my last job, I wanted to take some private company CocoaPods and merge them into the main company codebase. That way, I could make changes to interrelated classes with a single commit.

But the pods and the main codebase were all in different GitHub repositories.

The naive way to do this would just be to take all the pod doors files and copy them over to the main repository, and check them in as a new commit. But that would lose all the history of those files, which I didn’t want.

Instead, I decided to copy the GitHub history of the pod repositories over. Yup, you can combine completely unrelated GitHub repositories and retain all their histories, together, without mucking about in git internals. Thanks to Jens Ayton for telling me about the necessary steps.

I’ve created an extremely simple set of three GitHub repositories to show how it works.

WhiteProject and BlueProject are the stand-ins for the CocoaPods projects. They have but a single file in them, White.swift and Blue.swift, respectively.

RainbowProject is the stand-in for the main codebase. It’s a regular sample Xcode project, in this case a macOS command-line app.

You can see that color projects each have a commit history, for the creation of their Swift files and for the addition of some comments.

First thing I did was clone all three repositories locally, in the same parent directory.

Then, I created a branch in RainbowProject called add-white-project, so I could make a pull request of it later.

After that, I added a remote reference to the WhiteProject repository to RainbowProject, like this:

git remote add WhiteProject ../WhiteProject/

I make the connection via the two local copies of the repositories. I don’t know if there’s a way to accomplish this without using local copies.

Here’s what it looks like to have that remote reference, in SourceTree:

Table with header Remotes and two rows, first row WhiteProject and second row origin

Next, I went ahead and merged the remote repository into the local repository with this command:

git merge --allow-unrelated-histories -m 'Merge history from WhiteProject' WhiteProject/master

Note the following:

  • The --allow-unrelated-histories argument is needed by git 2.9 and higher according to this Stack Overflow answer and my own experience. I’ve got git 2.10 installed on my machine. Is that from an Xcode install or my own separate install? What version of git does come with Xcode? I can’t answer these questions, so your mileage may vary.
  • You need to specify both the remote repository and the branch in the remote repository, or it won’t work.

Here’s what it looks like in SourceTree after that merge:

Tree with root add-white-project and two branches, first branch from the RainbowProject repository with one commit, and second branch from the WhiteProject repository with two commits

Note the separate WhiteProject repository history is all there (all two commits, in our extremely simple example), and it’s hanging off of that merge commit we just made, all without obliterating the previous RainbowProject history, either. That’s what we want.

From here, I made a pull request, as you would do for a Real Project at Work. Here’s what that looks like on the GitHub website:

Screenshot of GitHub pull request user interface including PR text and list of commits.

I merged that, and then removed the remote reference, which was no longer needed:

git remote remove WhiteProject

At that point, I was done with the WhiteProject merge, and ready to perform the same steps for the BlueProject.

Now, the steps I followed for the merge at work were much more complicated than this simple example. In particular, I had to take what used to be separate static libraries whose files were managed by CocoaPods, and add them to my main Xcode project directly.

From that more complex scenario, I have a bunch of tips:

  • Make sure the files you’re merging in are all in different locations than the existing files, otherwise there’ll be conflicts.
  • Image and other resource files that couldn’t be in asset catalogs as long as they were in a pod can now be put into the asset catalog of the main app (and should be).
  • Your pod source code file might use [NSBundle bundleForClass:[MyPodClass class]] to get the bundle to load a resource from. You should change that to the main bundle, [NSBundle mainBundle], where you can’t just replace it with nil, like in [UIStoryboard storyboardWithName:bundle:].
  • Check whether you’re loading the pod bundle explicitly for anything and change your code to use other mechanisms.

That’s it! Let me know if you have any questions.

Attack the Block

How many readers of this blog know that Objective-C blocks are initially created on the stack, unlike every other type of Objective-C object? I believe this is for performance reasons.

It used to be a bigger deal, before ARC. Why? Because those stack-based blocks would be deallocated once their scope ended. If you tried to reference a stack-based block outside its enclosing scope, your app would crash and burn.

To get around this, you had to send a copy message to the block, which would perform a special sort of copy to copy it to the heap instead, like every other Objective-C object. Then it could be passed around, because it wasn’t tied to the stack’s scope anymore. Of course, then you’d also be on the hook for sending it a release message, or you’d have a memory leak.

That’s why, if you have a block property, you’re supposed to use the copy attribute, not the retain (now strong) attribute:

typedef void (^MyBlock)();

@interface MyClass : NSObject

@property (nonatomic, copy) MyBlock myBlock;

@end

All that’s water under the bridge with ARC, however.

ARC adds those copy calls for you, in the same way that it adds retain and release calls for regular Objective-C objects. You’ll never have to worry about using a stack-based block outside of its scope accidentally, because ARC will never let you do that.

The result? Now, when I mention the dangers of stack-based blocks to my younger coworkers, they have no idea what I’m talking about.

Interview Ballyhoo

I did quite a bit of interviewing recently before I got my new job.

I’ve come to believe your success depends much more on the attitude of the interviewer than how much you prepare. Anyone can find a gotcha question you can’t answer. Anyone can twist your lack of instant recall of a topic into an irrecoverable failure. You simply can’t know everything off the top of your head.

And on the flip side, anyone could talk you through your nervousness or your sudden blanking on things-you-knew-an-hour-ago, if they really wanted to. Anyone could connect with you and get you to open up about what you understand.

Could, but often won’t.

So while you should definitely do the preparations that they advise you to do — many companies give you fairly detailed lists of things to study — you shouldn’t kick yourself when you get rejection emails.

And you will get them, and they’ll almost never give you very helpful feedback. That just seems to be the way it is, however frustrating.

Like a Beacon in the Dark

This might be old news to my readers, but…I recently had to test beacon support for an iOS application.

I learned that you can do so without actually buying separate beacon hardware, by taking an iPhone and making it broadcast like a beacon.

I did this by installing a freeware application called GemTot SDK. It’s from a company called PassKit which sells GemTot Beacons.

You can also follow their blog post’s instructions for building their Xcode project yourself and running it on your phone.

But I figured, absent taking the time to inspect the code thoroughly myself, it was safer to use the version that had already been through App Store review.

Here are the steps:

  1. Search for “GemTot SDK” on the iOS App Store, download it, install, run. (There are separate iPad and iPhone versions.)
  2. In the iPhone version, tap the “Beacon” tab all the way to the right.
  3. Set the “Broadcast Signal” switch to On.

That’s it! You have a functioning beacon.

In the tests I did, I believe I needed to set either the Major Value or the Minor Value to something other than zero. So if things aren’t working, you could try that, though that doesn’t appear to be necessary in general.

If you need the UUID of the beacon, you can tap on the tiny beacon text near the bottom of the screen, and an alert will pop up to tell you it’s been copied to the clipboard.

If you want a quick and dirty way to tell that the beacon is broadcasting, take a look at https://github.com/mlwelles/BeaconScanner, which has a pre-built binary in addition to buildable source code (and a nicely informative README with a bunch of links).

(Build and) run that Mac app, and check the window to see if your beacon’s there.

If you want to test your iOS app, though, you’ll need a second phone (or other iOS device).

Hands-Off Managers

In my last post, I included links from Cate’s blog on how to be a good “hands-on” manager.

For example, a good “hands-on” manager:

  • Actively tracks direct reports’ progress.
  • Holds regular one-on-ones.
  • Advises on career path.
  • Intervenes to help with personal conflicts and organizational changes.

That’s really hard, and I don’t think I’ve ever seen the full package in my long employment experience. (Sometimes that that’s just because the team is too large.)

What I have seen frequently is the “hands-off” manager.

For example, a “hands-off” manager:

  • Talks to you only if there’s an issue or problem.
  • Provides little to no oversight.
  • Delivers bare minimum of a performance review.

The negative side of this kind of manager is that you get no support when things go wrong: you’re on your own to find solutions to your problems.

But that’s also the positive side. When you do something right, it’s not because of someone else’s input. It’s all you.

And “leave everybody alone unless something goes really wrong” is a lot easier than the first set of bullet points above, so you’re a lot more likely to find bearable “hands-off” managers than bearable “hands-on” managers: if there are fewer interactions overall, there’s less chance of bad interactions.

If you can’t have good managers, would you rather have a career full of so-so “hands-on” managers, or full of of so-so “hands-off” managers?

Advice for New Managers

Cate in the blog “Accidentally in Code” has a 5-part series on “Things to Figure Out as a New Manager”:

Part 1: Your Schedule

Part 2: Social Support

Part 3: Communication

Part 4: Feedback

Part 5: Trust

I could have used this earlier in my career.

I don’t see a lot of advice about managing in the tech industry in the weblogs I read. I’d like to see more. This is a good start.

A taste:

Because people are less likely to give their boss feedback, it becomes all the more important for you to give yourself that feedback to them. To own when you screwed up, and apologise. To acknowledge what you learned and what you would do differently. To recognize implicit feedback, and make it explicit between you.

Boom Boom Enum

To quote a fairly awful movie: “We were so, so wrong.” — me

Remember I said you couldn’t use Swift value types for a linked list? The real reason is because you can’t have references to other value instances, just copies (thus making bi-directional linked lists a recursion nightmare), but the compiler error was “a value type can’t refer to itself”.

Turns out, one Swift value type can refer to itself: enumerations. By adding the indirect keyword, you can use Swift enums to, for example, represent a binary tree structure:

indirect enum Tree {
	 case node(Int, left: Tree?, right: Tree?)
}

And it works! But is it a good idea? Hell, no!

Why not? Because accessing the “properties” of your data structure is a pain in the ass:

switch node {
case let .node (data, left, right):
	// Do something with data, left, and right
}

As far as I know, you need an otherwise extraneous switch statement, a case statement, and an extra set of local variables just to access the values. (Whereas for a class all you need is dot syntax.) And you need to do that everywhere you want to access them, every method.

And the compiler will complain if you don’t use all of the enumeration values, so you have to remember to use _ for those:

switch node {
case let .node (_, left, _):
	// Do something with left
}

I tried writing a full tree traversal implementation in Swift with enum-based trees and it was an unholy mess that I would not repeat.

Learn from me. Don’t use cool language features at the expense of maintainability.

Interview Hullabaloo

I have one major piece of advice, if you’re interviewing for a developer job, or really if you’re interviewing for any job.

If you get the sense that the interviewer is dissatisfied with how you did, don’t hesitate to ask what they’re dissatisfied about.

For example: “It feels like I didn’t completely answer your question. Is there anything I could expand on for you?”

Or: “Did my solution to the exercise cover everything you wanted me to cover?”

If they just say yes, but they still seem dissatisfied, well, then there’s nothing you can do.

But I’ve often found that this will bring forward whatever reservations they have, and give you a second crack at them.

Dictionary Fictionary

See update below: it’s more complicated than I thought.

Over the last, what, decade or so? maybe more? people have been using the word “literally” to mean…not literally.

“Literally a monster.”

“Literally the worst thing ever.”

They don’t mean literally literally. They’re using it because it feels right, regardless of its actual definition. It can lead to some amusing results.

I’ve seen something similar in Objective-C.1

When array, dictionary, and number literals and object subscripting were introduced in Objective-C in 2012, people really liked them. Me too! They were literally mostly just compiler syntactic sugar, but they derived their usefulness in part from being vastly more compact and readable.

Because the new syntax is so nifty, people want to use it everywhere.

NSMutableDictionary *foo = @{}.mutableCopy;

instead of

NSMutableDictionary *foo = [NSMutableDictionary new];

for example. Are they equivalent? Well, this is what the first sample is generating:

NSMutableDictionary *foo = [NSDictionary new].mutableCopy;

Making two dictionary instances, only to throw one away immediately, just because you want to use shiny syntax, doesn’t seem like the best idea to me.

Array and dictionary literals derive the rest of their useful from not having quite the same rules as the old syntax.

Unlike for the old creation APIs, now nil is no longer used as the ending sentinel for the list of input values. So because they could, the designers of the new syntax disallowed it completely.

The amusing part? Recently, I had a coworker who swore you couldn’t set a dictionary value to nil, like this:

foo[@"key"] = nil;

What he was doing was confusing the new literal syntax rules with plain old NSDictionary APIs. It’s an easy mistake to make. The only reason I didn’t is because I have years and years of experience with the old APIs, which didn’t have the same hangups about nil.

So I could compartmentalize the new nil rules to just the new literal syntax, where they belong.

I literally needed to run example code for him to convince him that the above line wouldn’t assert.

Update: Looks like I was right for the wrong reasons.

Instead of it always working the way I thought, the current behavior is a recent addition. See Foundation Release Notes for OS X v10.11 and iOS 9, specifically this part:

NSMutableDictionary subscript syntax change
In OS X 10.11 and iOS 9, NSMutableDictionary now allows you to use its subscript syntax to assign nil for a key. Like Swift’s Dictionary type, doing so will remove an existing object for that key from the dictionary. In effect, the following lines of code are now equivalent:

[dictionary removeObjectForKey:@"Key"];
dictionary[@"Key"] = nil;

These new semantics exist only when building with the OS X 10.11 or iOS 9 SDKs. If your application’s deployment target is earlier operating system, then runtime support will be implicitly linked into your binary by Xcode to ensure the behavior works on any targeted operation system.

My mistake was assuming the subscript setter syntax was an unmodified usage of NSMutableDictionary’s setObject:forKey:, which in my recollection always allowed nil, but of course there’s no reason it would have to be.

And now, with nullability annotations, setObject:forKey: no longer allows nil at all! (Plus, on reflection, I think I was wrong about it allowing nil in the past.)

Thanks to Jordan Rose and others for the correction.


1. Somebody get me a storyboard, cuz I just made a killer segue! ↩︎

Link or Swim

I learned today that you can’t make a linked list in Swift using value types. The reason why ties into the pointers issue I was recently discussing.

Here’s how a linked list struct might look in C:

struct LinkedList {
	struct LinkedList *next;
	int data;
};

And here’s how you would do it in Swift:

struct LinkedList {
	var next: LinkedList?
	var data: Int
}

The difference is, in C, you can have a reference to a struct without making a copy — without it being the thing itself. By adding an asterisk and making it a pointer.

In Swift, you can’t do that. So a reference to another struct might as well be that other struct, even if it isn’t always, under the hood.

If I try to compile that Swift, I get the error “value type ‘LinkedList’ cannot have a stored property that references itself”.

If I change the declaration from struct to class, then it compiles fine, because the property representing the “next” instance is now a reference to it.

I wasn’t expecting this issue to come up again so soon in my work.