Tech

Manipulating files outside of sandbox

2 min read

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

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

Running a script with NSTask and NSPipe

2 min 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 = Process()
task.launchPath = "/usr/bin/ruby"
task.arguments = [
  Bundle.main.path(forResource: myScript, ofType: "rb")!,
  parameter1
]

This would be the same as running in the terminal:

ruby /path/to/myScript parameter1

All good, but what if the script returns something and we want to use that? NSPipe to the rescue:

Continue reading →

Different fonts for the same label

3 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: price,
  attributes: [
    .font: priceFont,
    .foregroundColor: UIColor.darkText
  ]
)
Continue reading →

Updating Xcode plug-ins

5 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'
Continue reading →

Reusing blocks of code

1 min read

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

func performNetworkStuff() {
  fetchSomething(then: { condition in
    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:

Continue reading →

Code coverage issues for Swift projects

3 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 init
convenience init(text: String, font: UIFont)
Continue reading →

Wrapping up the Pull Request from terminal

4 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:

Continue reading →

Improving the Pull Request from terminal

2 min read

Just a slight improvement for last post: sometimes I don't have the branch pushed on GitHub, so why not automate that too?

perform_pull_request() {
  branch="development"
  branch_to_push="$(parse_git_branch)"
  git push origin "$branch_to_push":"$branch_to_push"
 
  if [ -n "$1" ]; then
    branch=$1
  fi
 
  pr_url=$(hub pull-request -b "$branch" -m "$(formatted_git_branch)")
 
  if [ $? -eq 0 ]; then
    open "$pr_url"
  fi
}
 

I also found some nice helpers for easier color printing:

Continue reading →