PlugRocket

:  ~ 2 min read

It all started with this post by Joe for updating a plug-in from the terminal, which lead to this script for automating the process of updating all plug-ins.

Even though I could have created an Alfred workflow to easily run the script with a single command, I always wanted to start working on Mac apps, so this was a good opportunity to get my feet wet.

I said I'll give open source by default a try, but I also wanted to have it on the MAS for a little while before that, just to have a feel about how the […]


Continue reading →

Manipulating files outside of sandbox

:  ~ 1 min read

First, we need to ask for the user's permission to access the folder, but for that, we need an NSOpenPanel:

let op = NSOpenPanel()
op.message = "Descriptive message here"
op.canCreateDirectories    = false
op.canChooseDirectories    = false
op.showsHiddenFiles        = false
op.prompt                  = "Allow"
op.title                   = "Allow access"
op.extensionHidden         = true
op.directoryURL            = NSURL(string: "/path/to/folder")
// Depending on your purpose, you might need these to true
op.allowsMultipleSelection = false
op.canChooseFiles          = false

We then check if the […]


Continue reading →

Running a script with NSTask and NSPipe

:  ~ 59 seconds read

Say you have a Mac app and you want to run a script, either to perform some action, or to return something, here's one way to do it.

First, we create an NSTask, set the launch path of the handler, in our case ruby (we will use the default one, to be sure it exists), and the required parameters, if required:

let task = NSTask()
task.launchPath = "/usr/bin/ruby"
task.arguments = [
  NSBundle.mainBundle().pathForResource(myScript, ofType: "rb")!,
  parameter1
]

This would be the same as […]


Continue reading →

Different fonts for the same label

:  ~ 2 min read

Been slacking lately, but I hope I can make it up with this one. Let's say you need to display a price, and the currency, but the currency code should have a different font. You could have two labels, but that just complicates code and brings unwanted overhead, so let's use the same label.

This part will be common to all examples:

let priceFont = UIFont(name: "CustomFontBold", size: 15)
// This is the part we will work on in the next steps.
let currencyFont = [...]

let attributedPrice = NSMutableAttributedString(string […]

Continue reading →

Swift going open source

:  ~ 40 sec read

This week, Christmas arrived early for developers. Swift is now open source, it has a package manager, there is a dedicated evolution / roadmap repo for it (the changes for 3.0 look really nice) and Apple already accepted a lot of pull requests.

Can't wait to see what will happen with Swift in the next year or so, but I do know its future looks bright and it looks like others feel the same, even more so than me.

Updating Xcode plug-ins

:  ~ 2 min read

I recently saw Joe's post about updating Xcode plug-ins, but since I'm really lazy, updating them one by one didn't suffice, so here's my take on it. In case you want to skip straight to the desert, here's the gist.

First, we change our script's directory:

# You might need these.
# require 'pathname'
# require 'fileutils'

# In case we want to also print the already updated plug-ins
DISPLAY_ALREADY_UPDATED = false

plugin_path = File.expand_path('~/Library/Application Support/Developer/Shared/Xcode/Plug-ins')

Dir.chdir(plugin_path)
files =  Dir['*.xcplugin']

Then we iterate through the files:

 […]

Continue reading →

Reusing blocks of code

:  ~ 40 sec read

Let's say you have a method which performs some networking actions, which can obviously fail, but in different ways:

func performNetworkStuff() {
  fetchSomething({ condition in
    // success
    if condition {
    }
    // failure due to condition
    else {
      failureAction1()
      failureAction2()
      variable1 = value
      etc...
    }
  }) {
    // failure due to network
    failureAction1()
    failureAction2()
    variable1 = value
    etc...
  }
}

But instead, we could DRY it up a little bit, by storing the failure actions into a block beforehand:

func performNetworkStuff() {
  let handleFailure = {
    failureAction1()
    failureAction2()
    variable1 […]

Continue reading →

Code coverage issues for Swift projects

:  ~ 2 min read

I stumbled upon a problem recently (the full story can be found on Apple Developer Forums) and the short version is: running the app or the tests without code coverage enabled always worked fine, but turning it on caused errors to appear, breaking the build process when trying to test.

Hunting attemp #75. One of the errors raised was Segmentation fault 11, which appeared for several Swift files during the Compile Swift source files phase. This is an error I remembered having in the early days of Swift when writing daring short syntax, like:

// UILabel convenience […]

Continue reading →

Swift and enums #3

:  ~ 25 sec read

In case you haven't already read them, Advanced & Practical Enum usage in Swift and Match Me if you can: Swift Pattern Matching in Detail have to be one of the best posts about Swift enums. I'd say you should really read and bookmark them.

Wrapping up the Pull Request from terminal

:  ~ 2 min read

You might want to read the the first part and the second part, too.

During the weekend I rewrote a lot of the script, covering cases where the Pull Request failed, adding Fastlane automation and all around improvements.

The script has now 2 possible parameters, a different branch than development, and skip_deploy, in case we don't want to auto-run the fastlane command. Comments explaining the flow, as usual:

perform_pull_request() {
  # Default to not skipping deploy.
  skip_deploy=false
  sd="sd"
  # Default to development branch as base.
  branch="development"
  branch_to_push="$( […]

Continue reading →