Xcode 10: Create Global Git Ignore File

January 7th, 2019

Filed under: Version Control, Xcode | Be the first to comment!

Xcode 10 lets you create a global .gitignore file so you don’t have to create a .gitignore file for each project you create. Go to Xcode’s Source Control Preferences and click the Git button in the preferences window.

Xcode10GitIgnoredFilesHighlighted

You most likely have an empty list of ignored files. Click the Add button to add files to ignore. Adding files to ignore from Xcode is a little tedious. You have to add one file at a time. But you only have to enter them once.

If you need to know what files to ignore, read the Generating a Git Ignore File section in the following article:

Telling Git to Ignore Files in Xcode Projects


Using a Ruby Gem in a Mac App

January 6th, 2019

Filed under: Mac Development | Be the first to comment!

I wanted to run a Ruby tool (packaged as a gem) in a Mac app, but I didn’t want people to have to install the Ruby gem to run my app. I knew I wanted to bundle the gem in my app bundle, but I wasn’t sure how to do so. I finally figured it out so I am sharing what I learned with you. There are five main steps to bundling a Ruby gem in a Mac app and running the gem.

  1. Install the gems on your Mac
  2. Add a Copy Files build phase
  3. Find the gems folder in the app bundle
  4. Configure the command to run the gem
  5. Run the gem in your app

Step 1: Install the Gems on Your Mac

Before you can copy Ruby gems to your app bundle, you must install them on your Mac. The standard gem install command installs the gem in a location that’s difficult to find. What you should do is install the gems you want to use in a folder you can find easily, such as a gems folder inside your project folder.

To install the gems into a custom location, use the -i option and supply the path to the destination folder.

gem install -i /path/to/gem/folder gemName

Step 2: Add a Copy Files Build Phase

You must add a Copy Files build phase to your app target that copies the Ruby gem to the app bundle when building the project. Select your project from the project navigator to open the project editor. Select your target from the project editor. Click the Build Phases button at the top of the project editor.

In Xcode choose Editor > Add Build Phase > Add Copy Files Build Phase.

Xcode10CopyFilesBuildPhase

Use the Destination menu to specify where in the app bundle to copy the files. I chose the Resources folder.

If you want to copy the files into a subfolder, enter the name of the folder in the Subpath text field.

Click the Add button to add the gems to the Copy Files build phase. A sheet will open. Click the Add Other button. Navigate to your gem folder location and select the gem folder containing the gems you want to add.

Step 3: Find the gems Folder in the App Bundle

The next step is to locate your gems folder in the app bundle so you can run the gem and set up environment variables to run the gem. You are going to use the Bundle class. The Bundle class has accessors to get to standard parts of the bundle, such as the Resources folder.

Once you get to a standard location in the bundle, you must build a path to the folder containing your gems. The following code locates a gems folder inside the Resources folder:

if let resourceDirectory = Bundle.main.resourceURL {
    let pathString = resourceDirectory.path + "/gems"
    return URL(fileURLWithPath: pathString)
}

The folder containing the gems should have a bin folder containing the executable files. You would build a path to the executable file and use that path as the first argument when running the gem.

Step 4: Configure the Command to Run the Gem

Before you can run the gem, you must configure the command to call it. Use the Process class, formerly called NSTask, to run a command-line program, such as a gem.

Start by creating a Process object.

let taskToRun = Process()

You must set up the following items:

  • The launch path
  • Environment variables
  • The arguments to pass

Use the launchPath property to set the launch path. For Ruby gems the launch path is the path to the Ruby interpreter.

taskToRun.launchPath = "/usr/bin/ruby"

Use the environment property to set environment variables. An environment variable is a dictionary. For Ruby gems the environment variable key is GEM_HOME and its value is the path to your gems folder.

taskToRun.environment = ["GEM_HOME" : gemsPath]

Use the arguments property to pass arguments to the gem. The arguments property is an array of strings. The first argument is the path to the executable file of the gem you want to run. Add any arguments the gem requires.

When supplying options as arguments, make sure you have separate entries for the option and its value. Suppose your gem has a -o option followed by the name of an output file. The -o is one entry. The name of the output file is a separate entry.

let argumentList = [gemExecutablePath, inputURL.path, "-o", outputURL.path]
taskToRun.arguments = argumentList

Step 5: Run the Gem

The final step is to run the gem. On macOS 10.13 and later, call the run function to run the task you configured.

do {
    try taskToRun.run()
} catch {
    fatalError("Error running command line tool.")
}

On earlier versions of macOS, call the launch function to run the task.

taskToRun.launch()

Xcode 10: Subversion Support Removed

December 9th, 2018

Filed under: Version Control, Xcode | Be the first to comment!

Xcode 10 removes support for Subversion. If you want to continue to use Subversion with Xcode, stick with Xcode 9. Alternatively, you can switch to git or use another tool for Subversion.


Making iOS Document-Based Apps

November 12th, 2018

Filed under: iOS Development | Be the first to comment!

I have a two-part tutorial on making document-based iOS apps over at Swift Dev Journal.


Xcode 10: Running Tests in Random Order

November 6th, 2018

Filed under: Xcode | Be the first to comment!

In Xcode 10 you can tell Xcode to run your tests in random order. Open the scheme editor for your project and select the Test step.

Xcode10RandomizeTestOrder

Click the Options button next to the test target to open a popover. Select the Randomize execution order checkbox to run your tests in random order.