profile for monkeydom at Stack Overflow, Q&A for professional and enthusiast programmers


coding bits I use, come across, like, hate, the whole shebang.

twitter | github | mastodon     rant-dom     rss | archive

TCMPortMapper 2018 Edition

About 10 years ago, I released one of my first pieces of open source software. For the collaboration part of SubEthaEdit we needed a way to make the app's network service available to the outside world, so you could invite people to documents without any additional setup.

To achieve this without any other additional central service to communicate over, one way is to leverage the port mapping services of your router to open up to the outside world. And for this reason, I created TCMPortMapper.framework with its companion example and in itself useful Port

Port Map App Icon

Since this piece of software was more or less just working after its inception, I left it quite unmaintained for a long time. This is also signified by the fact, that the original repo was on google code, and it didn't even make it over to another hoster when it got shutdown, so the commit history was lost.

So I took some time to revive it, clean it up, get the original commit history and update the libraries it leverages.

The funny thing is, that 10 years ago the thought was, when IPv6 will be here, port mapping would be obsolete. Sadly, that is not the case. Both IPv6 is not available everywhere yet, and as it turns out, the default IPv6 behaviour of routers is to close you off from the outside world too. With most routers it is not an easy feat to open it up again for the layperson. With that in mind I'll probably look into what kind of information/help for IPv6 connectivity TCMPortMapper.framework can give you, now that the codebase is cleaned up again and fit for the next few years.

Until then, the existing Port can be helpful for you in some of the following scenarios:

  • make your SSH avaialable temporarily, or permanently e.g. if you use dyn-dns for your home router.
  • temporarily expose some services to others. E.g. I use it so show my local web development things by turning on Port Map for e.g. 4000 and copy the link to others in a chat.
  • know your external IPv4 address, if any.
  • looking up what ports are currently mapped in your UPnP enabled router.

Port Map Screenshot

Command line utilities: exa and bat

While surfing through the rust ecosystem, I stumbled across a few excellent command line utilities I enjoy using and installed on all my systems. I'm going to post about them for my own reference and in case they might be useful to you too.


exa is a modern replacement for ls. Apart from great coloring I use it mostly for its tree based view and git and extended attributes integration.

dom@dreizehn:/usr/local/etc$ exa -lTF
drwxrwxr-x     - dom  3 Jul 13:02 ./
drwxr-xr-x     - dom  3 Jul 13:02 ├── bash_completion.d/
lrwxr-xr-x    36 dom 29 Jun  2017 │  ├── brew -> ../../Homebrew/completions/bash/brew
lrwxr-xr-x    48 dom  5 Oct  2017 │  ├── exa -> ../../Cellar/exa/0.8.0/etc/bash_completion.d/exa
lrwxr-xr-x    51 dom 29 Apr  4:36 │  ├── fd.bash -> ../../Cellar/fd/7.0.0/etc/bash_completion.d/fd.bash
lrwxr-xr-x    65 dom 22 Jun 16:38 │  ├── git-completion.bash -> ../../Cellar/git/2.18.0/etc/bash_completion.d/git-completion.bash
lrwxr-xr-x    59 dom 22 Jun 16:38 │  ├── -> ../../Cellar/git/2.18.0/etc/bash_completion.d/


bat to me is a great less/cat combination that adds syntax highlighting and line numbers. Especially useful on remote servers.

dom@dreizehn:/etc$ bat hosts
       │ File: hosts
   1   │ ##
   2   │ # Host Database
   3   │ #
   4   │ # localhost is used to configure the loopback interface
   5   │ # when the system is booting.  Do not change this entry.
   6   │ ##
   7   │       localhost
   8   │ broadcasthost
   9   │ ::1             localhost

Swift Library naming warts

This is just a collection of oddities / naming choices that I ran across while playing with Swift. This list isn't exhaustive, nor do I have a good solution for all of them. It's just an observational piece on things that produced a negative gut reaction.

  • the func keyword
    somehow that one really doesn't sit well with me. I'd much more preferred it if the keyword would have called function. However It has been pointed out that other abbreviations are used as well in standard keywords. Most notably: enum, var
  • succ(), pred()
    The ForwardIndex and BidirectionalIndex use these methods to move forward and backward. I'd much rather have seen successor() and predecessor() there. Or nextIndex() and previousIndex() since these methods are tied to Indexes. Or succedingIndex() and precedingIndex(). Actually this hits a sore point in the current Swift Library quite on the mark: how general or specific should the naming of methods and global functions be? And how can this be as consistent as possible to give future code writers the right idea and direction to make these in a way they fit in the language? Something that is very established in Cocoa and imho needs to be established in Swift as soon as possible.

  • advance()
    This is used to move an index forward by a distance. So why not advanceIndex()? And also what is the inverse? I found no good one in the english language, but I'm foreign. There is no inverse because you are supposed to use advance with a negative distance to move backward. I like that the name includes the direction, so you know your moving forwards with a positive distance and backwards with a negative index. However, I don't like the impetus of advance, suggesting to me going forward is the only way. 
    Interestingly enough it hits another point: mutability. Does advance() change the index given or not? This is not clear by the naming, but I think it should be.

  • join(a,b) and <Type>.join(b)
    These behave consistent but are confusing to me as hell. Compared to cocoa's [NSArray componentsJoinedByString:] which is clear to me. So to join ["c","d","e"] with "-" as glue you have to do either join("-",["c","d","e"]) or "-".join(["c","d","e"]). I think the more intuitive version would be something like ["c","d","e"].joinBy("-") - I also don't get exactly why it is both a global function and a method. I would prefer the function to be defined as join(a, by: b) with the semantics reversed. Everything would be much clearer and visible to the first time reader at a glance. However, the swift library does not make use of named parameters on a function level.

  • Array.append(), Array.extend(), Array.filter(), Array.sort()
    This again hits my sore spot on mutablity. Which of these methods return a new, changed array, which do mutate the array? Without consulting the documentation or Xcode there isn't a clear indication. It turns out sort() sorts in place while filter() returns a filtered array. We need a consistent way of expressing this in the naming.

  • contains(a,b)
    Does this test if a contains b, or if a is contained in b? You can't be sure without looking at the signature. I would much rather prefer this to be something like does(a, contain: b). and for it's brethren with the predicate doesAnyElementOf(a, satisfyPredicate: b). However, with trailing closures being able to lose the last parameter name and just putting the closure at the end that might look awkward. But I sure as hell don't get why one should name basic functions in a short way, if there is a possible improvement in readability and less ambiguity by writing a longer signature.

Autolayout and Complexity

I recently dipped my toes into some autolayout on both iOS and OS X. Short term verdict: powerful, but too complex for daily use. And that's an issue.

Remember the times of handling touches before there were UIGestureRecognizers? That is exactly the state autolayout is in. The underlying technology is great but it is in desperate need of a good abstraction layer on top of it that makes the standard use cases easy and maintainable. I'm looking forward to this year's WWDC to see some of these aspects to be addressed.

Blocks need considering

While I don't agree with this post in most respects, it still alerted me to a crucial thing when using blocks: Be sure the Macros you use in them don't reference self directly. And if they do and you need to be sure to not create a retain cycle, use either @weakify and @strongify from libextobjc or do shadow self yourself this way:

__weak typeof(self) weakSelf = self; 

// some api that takes blocks, when you give the block do 
    __strong typeof(weakSelf) self = weakSelf; 

So thanks for ranting so much to alert me to the fact that NSAssert() does reference self directly, and as such make the block retain self.

Update: ZAssert seems to be a reasonable replacement for NSAssert() in blocks which is mentioned in the comments of the Article.

Update 2: Since this is such a common pattern, I've seen people using welf instead of weakSelf, which makes me chuckle. Also the __typeof__ can be replaced by typeof, which makes it less atrocious.