Category: Tools

Dealing with “Failed to prepare device for development” Error Message in Xcode

You update your iOS device to the latest version of iOS. Now you try to run your Xcode project on that device. An alert pops up in Xcode with the message Failed to prepare device for development.

Why Are You Getting This Message?

You are getting the Failed to prepare device for development message because the device is running a newer version of iOS than Xcode supports.

Each version of Xcode ships with a version of the iOS SDK. The Xcode Releases site has a list of each version of Xcode along with the iOS SDK. The version of the SDK is the latest version of iOS that version of Xcode supports. You won’t be able to run your Xcode project on a device running a newer version of iOS.

For example Xcode 13.2.1 ships with the iOS 15.2 SDK. If you are running Xcode 13.2.1, you won’t be able to run your project on a device running anything newer than iOS 15.2. If you have a device running iOS 15.4, you won’t be able to run the project on that device with Xcode 13.2.1.

How Do You Fix the Error?

The easiest solution is to install the latest version of Xcode. The latest version of Xcode has the latest version of the iOS SDK so you’ll be able to run and debug your project on a device running the latest version of iOS.

If your Mac is running an older version of macOS, you might not be able to update to the latest version of Xcode. Xcode 13.3 requires macOS 12. If your Mac is running macOS 11 and can’t run macOS 12, you won’t be able to update to Xcode 13.3. What do you do then?

There are two workarounds. The first is to download iOS support files for the newer iOS version and copy them to your Xcode app bundle.

The second workaround is to deselect the Debug executable checkbox in the Run step of the scheme. After the app launches, attach it to the debugger. The following article provides details and screenshots:

Debugging on iOS 15 with Xcode 12

Turn off Automatic Updates on Your Device

Keeping up with the latest version of iOS requires using the latest version of Xcode. Xcode takes a long time to install. If you don’t want to be constantly updating Xcode, turn off automatic updates on your iOS device.

Why Won’t My Xcode Project Build?

It’s frustrating to click the Run button in Xcode and find that your project won’t build and run. Xcode initially shows you a message like Command CompileSwiftSources failed with a nonzero exit code, which really doesn’t help much. How do you find where the error is so you can fix it and run your project?

Get a List of the Errors

The first step to figuring out why your project won’t build is to find the compiler errors in your project. Open Xcode’s issue navigator by pressing Cmd–5.

IssueNavigator

The issue navigator shows the compiler errors in your project. Select an error to show the line where the error is.

Seeing More Detailed Information about an Error

To see more detailed information about a compiler error, open the report navigator by pressing Cmd–9. Select a build from the report navigator to see the build steps and errors for that specific build.

ReportNavigatorHighlighted

Click the Log button (the small button with the horizontal lines) to see a detailed log of that particular build step.

Tips for Fixing Errors

You found the compiler errors in your project. How do you fix them?

I can’t tell you specifically how to fix the errors because I can’t see your code. But I have some general tips to help you fix the compiler errors in your Xcode projects.

Make Sure Argument Types Match

When calling functions, make sure the data types for the function arguments match. When the argument types don’t match, you get a compiler error message like the following:

Where X and Y data types.

If a function takes an integer as the first argument and you pass a string, you’re going to get the Can't convert value compiler error.

Check for Typos

If I make a typographical error in this article, you’ll still be able to read the article. But if you make one small typo in your code, the project won’t build.

Make sure you spell function names correctly when calling them. If you have a function called doSomething and you call it like the following:

You are going to get a compiler error because you made a typo when calling the function. There is no doSomethng function.

Make sure that you spell variable names correctly when accessing them. If you have a player variable in your app and misspell it,

You are going to get a compiler error because there is no playr variable.

Make sure each left brace, bracket, parenthesis, and quotation mark has a matching right one. An extra left or right brace can lead to compiler errors with bizarre messages.

Import Missing Modules

Make sure you import the modules for the frameworks your app uses. If you’re writing an app that works with PDF documents, you must import the PDFKit framework to call its functions in your app.

Edit Swift Files Outside Xcode

Does Xcode’s editor frustrate you? Do you have problems with Xcode’s code completion? Do you wish you could use a different text editor to edit the Swift files in your Xcode projects?

Xcode supports opening and editing Swift files in other text editors, such as BBEdit, Sublime Text, TextMate, and Visual Studio Code. Keep reading to learn how to use your favorite text editor to edit the Swift files in your Xcode projects.

Make Your Text Editor the Default Editor for Swift Files

Start by making your preferred text editor the default editor for Swift files on your Mac. Perform the following steps to change the default editor for Swift files:

  1. Go to the Finder.
  2. Select a Swift file.
  3. Press Cmd-I to open the file’s info panel.
  4. Choose your text editor from the Open with menu.
  5. Click the Change All button.

OpenWithTextEditorPanel

Now when you open a Swift file in the Finder, the file opens in your text editor.

Opening from Xcode

The final step is to open the Swift files in your text editor from Xcode. Select a Swift file in Xcode’s project navigator, right-click, and choose Open with External Editor. The file will open in your text editor.

The changes you make to the text in your text editor will also appear in Xcode. If your project is under version control, an M will appear next to the file in the project navigator, indicating you modified the file.

Xcode Installation Questions

People learning iOS development without prior programming experience have a lot of questions on installing Xcode, Apple’s tool for developing iOS and Mac apps. This post collects these questions and answers them.

Where do I get Xcode?

The easiest way to install Xcode is from the Mac App Store. The Mac App Store has the latest version, which usually requires the latest version of macOS.

If your Mac can’t run the latest version of Xcode, go to Apple’s Xcode Downloads page and install an older version. You can also use the Downloads page to install the latest version if you run into problems with the Mac App Store.

A faster way to find Xcode download links is to go to Xcode Releases, a site that has download links for every version of Xcode. Xcode Releases also lists the minimum version of macOS required for each Xcode version.

Another alternative to the App Store is to use the Xcodes app to install Xcode. I have not used Xcodes, but many people swear by it, saying it installs Xcode much faster than the App Store.

Why does Xcode take forever to install?

Xcode is a huge app. Verifying and expanding it takes a really long time. Even with a fast Internet connection, it will take 1–2 hours to install Xcode.

A Twitter thread explains why expanding takes so much time and provides a tip to speed up the expanding.

If you are installing Xcode from the Mac App Store, you can see the progress of the install from the LaunchPad app.

Why does Apple say I don’t have enough disk space to install Xcode?

Xcode requires a lot of disk space to install. You need 4–5 times the size of the Xcode download to install it. The file you are downloading is a compressed file. You need enough free space to temporarily store both the compressed and expanded files. If you have a Mac with a 128 GB drive, you will have a tough time installing Xcode.

If you get an error message saying there isn’t enough free space to install Xcode, free up more disk space until the error message goes away.

Some ways to free up disk space and work around space limitations include the following:

  • Download Xcode from the Xcode Releases site onto an external drive and expand it there. Copy the expanded file to your main drive.
  • Restarting your Mac can free up disk space if you haven’t restarted the Mac in several days.
  • The Dev Cleaner app can free up space used by Xcode caches and old iOS simulators.
  • Delete existing versions of Xcode before installing a new version.

Can I install Xcode on an external drive?

Xcode must be installed on your Mac’s startup disk. If you make an external drive the startup disk, you can install Xcode on an external drive. Use the System Preferences app (Choose Apple > System Preferences from the menu bar) to set the startup disk.

Can I run Xcode on an iPad?

Xcode currently runs only on Macs. Apple has a Swift Playgrounds app for iPad to learn Swift programming. Version 4, which requires iOS 15, lets you develop iOS apps on an iPad.

Can I run Xcode on a Windows PC?

Not without violating Apple’s license on macOS. Xcode currently runs only on macOS. Apple’s license forbids installing macOS on non-Apple hardware.

Can I have multiple versions of Xcode on my Mac?

Yes you can.

If you are installing Xcode from the Mac App Store, make sure you don’t overwrite your existing Xcode install. When installing from the Mac App Store, Apple adds a file named Xcode in your Applications folder. Change the name of the existing Xcode app on your Mac before installing the new version.

Where are the Single View and Master-Detail App Project Templates?

Prior to Xcode 12 Xcode had the following iOS application project templates:

  • Single View App
  • Master-Detail App
  • Page-Based App
  • Tabbed App

If you create an iOS application project in Xcode 12, you will notice these project templates are missing. In Xcode 12 Apple consolidated these project templates into one template: App. If you are following a tutorial that tells you to choose one of the older templates that no longer exist, choose the App template.

Getting Started with Swift Unit Testing in Xcode

In this article you’ll learn what you need to start unit testing your Swift code in Xcode.

Adding a Unit Test Target to Your Xcode Project

To unit test your app, your Xcode project must have a unit test target. The easiest way to add a unit test target to your project is to select the Include Tests checkbox when you create the project. Selecting the checkbox creates targets for unit tests and UI tests.

To add a unit test target to an existing Xcode project, choose File > New > Target.

AddUnitTestingTarget

Select your app platform (iOS, macOS, watchOS, tvOS) from the top of the New Target Assistant. Select the Unit Testing Bundle target from the list of targets. You will have to scroll through a long list of application extension targets to find the test targets.

Adding a Unit Test Class to Your Xcode Project

When you create the unit test target, Xcode includes a unit test class file. It has the name AppNameTests.swift, where AppName is the name of your project. Unless you have a really small project, you will have multiple unit test classes.

Choose File > New > File to add a new file to your project.

AddUnitTestClass

Select Unit Test Case Class from the list of file templates. Click the Next button.

Enter the name of the class in the Class text field. The subclass should be set to XCTestCase, and the language should be set to Swift. Click the Next button.

Save the file inside the Tests folder. Make sure to select the checkbox for the unit test target.

AddUnitTestClassToTarget

Click the Create button to finish creating the unit test class.

The Initial Unit Test Class

Select the unit test class’s Swift file to open it. It should look similar to the following code:

The first two lines of code import the XCTest framework, which is the framework Xcode uses for unit testing Swift code, and your app. You must use the @testable import statement to give the unit test class access to your app’s code. If your app name has spaces in it, use the underscore character instead of spaces in the @testable import call.

Next comes the declaration of the unit test class. It inherits from XCTestCase, the base class for Xcode’s unit test classes.

Finally comes the four empty test methods.

  • The setUpWithError method gets called before running each test in the class. Put any setup code you need to run before each test in this method.
  • The tearDownWithError method gets called after each test runs.
  • The testExample method provides a shell for a unit test. You can delete this method.
  • The textPerformanceExample method provides a shell for a performance unit test. You can delete this method.

The throws keyword means the test method throws an exception if the test fails.

Older versions of Xcode may not have the throws keyword in the test methods. The setup and teardown methods may not have the WithError part at the end.

XCTest Test Methods

Each unit test requires you to write a method for it. A unit test method has the following requirements:

  • It must start with the word test.
  • It takes no arguments.
  • It returns no value.

The following code shows the definition of a unit test method:

In the test start by calling the code in your app that you want to test. Then make an assertion, which I talk about next.

XCTest Assertions

Each test needs at least one assertion, which determines whether or not the test passes. XCTest assertions start with XCTAssert. If you start typing XCTAssert, Xcode’s code completion should show you a list of all the available assertions, but the following are the most widely-used assertions:

  • XCTAssertNotNil asserts a variable is not nil.
  • XCTAssertTrue asserts a condition is true.
  • XCTAssertFalse asserts a condition is false.
  • XCTAssertEqual asserts two values are equal.

The simplest way to write an assertion is to supply an expression.

But when you supply only the expression, all you get when a test fails is a message that the test failed. In this assertion example, when the assertion fails, you would like to know what the value of temperature is. Supply an error message to report as the final argument in the assertion. Wrap the variable whose value you want to report using the following syntax:

The following shows an improved assertion that the temperature is above 0.

Running Unit Tests

Xcode provides multiple ways to run your tests.

  • Press Cmd-U to run all your tests.
  • Run a unit test class’s tests from the Xcode editor by clicking the diamond-shaped button on the left side of the editor next to the test class name.
  • Run a single test from Xcode’s editor by clicking the diamond-shaped button next to the test method.
  • Press Cmd–6 to open the test navigator. Selecting the test target, a test class, or a test will make a small button appear on the right side of the navigator. Click the button to run the target’s tests, the class’s tests, or the single test, depending on what you selected.

Unit Testing Checklist

Use the following checklist to start unit testing your Swift code in Xcode:

  • Create a unit test target by selecting the Include Tests checkbox when creating your Xcode project.
  • Add unit test classes to the test target by choosing File > New > File.
  • Import the XCTest framework in your unit test classes.
  • Use the @testable import statement to give your unit test classes access to your app’s code.
  • Add test methods to your unit test classes.
  • Test methods start with test, take no arguments, and return no value.
  • Add at least one XCTest assertion in your test methods.
  • Press Cmd-U to run the tests.

Renaming Xcode Projects

Renaming Xcode projects is not intuitive or obvious. If you do it wrong, you can mess up your project. In this article you will learn how to safely rename your app and your project.

Rename the Target to Rename the App

Most of the time when people want to rename their project, what they really want to do is rename their app. By renaming the app target, you can rename the app without having to rename the project.

Select the project from the project navigator to open the project editor and see a list of the app’s targets.

TargetList

To rename a target, select it, press the Return key, and enter the new name. If all you want to do is rename the app, you’re finished.

Renaming the Project

Continue reading if you really want to rename the project. If you look at the screenshot from the previous section, you might think you could rename the project by selecting it and pressing the Return key. But you’ll discover that you can’t change the project name from the project editor.

Use the project navigator to change the project name.

ChangeXcodeProjectName

Select the project file and press Return to change the name. A sheet will open.

RenameProjectSheet

Xcode is initially set to rename all the project’s targets to reflect the new name of the project. Deselect a checkbox next to any item you don’t want to rename. Click the Rename button to rename the project.

Clicking the Don’t Rename button will rename the project file but won’t rename anything else.

Xcode Breakpoint Actions

Xcode’s breakpoints pause your program so you can step through your code line by line and examine the values of your variables. But sometimes you don’t want to pause your program. You want to do something like print the value of a variable to the console. Xcode has breakpoint actions that let you do things like print a variable’s value, run debugger commands, and run scripts.

If you’re unfamiliar with Xcode breakpoints, read Introduction to Xcode’s Debugger.

Creating a Breakpoint Action

Right-click on a breakpoint in Xcode’s editor or in Xcode’s breakpoint navigator (Press Cmd–8) and choose Edit Breakpoint. A popover opens to edit the breakpoint.

XcodeBreakpointEditor

Click the Add Action button to create a breakpoint action.

Breakpoint Actions

When you click the Add Action button, the popover looks similar to the following screenshot:

XcodeBreakpointActionEditor

Xcode provides the following breakpoint actions:

  • AppleScript
  • Capture GPU Frame
  • Debugger Command
  • Log Message
  • Shell Command
  • Sound

A breakpoint can have multiple actions. For example you can run a debugger command and play a sound when reaching a breakpoint.

AppleScript

The AppleScript breakpoint action runs an AppleScript script.

XcodeAppleScriptAction

Enter the script text in the text view. Most of you using the AppleScript action will write the script in a text editor and paste it into the text view. Click the Compile button to make sure the script works.

Capture GPU Frame

The Capture GPU Frame action captures a frame from the graphics card. This action helps most with apps that work with graphics, such as games, image editors, and video editing apps.

Debugger Command

The Debugger Command action runs an LLDB debugger command. The LLDB site has information on all the LLDB commands.

Enter the command in the text field.

Log Message

The Log Message breakpoint action logs a message to Xcode’s debug console. A common use of message logging is to write the value of a variable to the console. Use this action as an alternative to littering your code with print statements for debugging purposes.

Most text that you enter in the text field will appear that way in the console. Wrap variable names with the @ character. Suppose you have a game and want to display the player’s x position. The following log message:

Prints the following in the console if the x position is 12:

Shell Command

The Shell Command action runs a shell script. You can use this action to run command-line programs as well as shell scripts.

XcodeShellCommandAction

Enter the command in the top text field, or click the Choose button to locate a shell script on your Mac. Enter any arguments in the bottom text field. Selecting the Wait until done checkbox tells Xcode to wait until the shell script finishes to continue.

Sound

The Sound action plays a sound. Playing a sound lets you know you hit the breakpoint. Normally you mix the Sound action with other breakpoint actions.

XcodeSoundAction

Choose a sound from the menu.

Automatically Continue

At the bottom of the breakpoint editor popover is a checkbox to automatically continue after running the breakpoint actions. If you’re using breakpoint actions, you should select the checkbox so you don’t have to click the Resume button to resume running your app.

Creating Custom Elements and Attributes in the Plot HTML Framework

Plot is a framework for creating HTML and XML documents in Swift. The Plot framework supports the most common HTML elements and attributes. But if you want to do something Plot doesn’t natively support, such as create an EPUB book, you must create custom elements and attributes. In this article I share what I’ve learned about creating custom elements and attributes.

Custom Elements

You can think of an element as a tag. Examples of HTML elements include p for paragraphs, h1 for heading 1, and li for a list item. Create a custom element if there is an element you need that Plot does not have. You are more likely to create custom elements for XML than HTML.

Custom Attributes

An attribute is a value that appears inside an HTML or XML element. HTML links have a href attribute with the link destination.

Like elements, you are more likely to create custom attributes for XML than HTML. Custom elements are likely to require custom attributes.

Creating a Custom Element

Call the .element function to create a custom element. There are multiple ways to call the .element function. A simple way to call it is to supply a text value for the element. The following call:

Creates the following XML tag:

You normally write a static function to create a custom element that makes a call to .element. The following function creates a custom element for a country:

Supplying Attributes

Another way to call .element is to supply a list of attributes. The following call:

Creates the following tag:

Supplying a List of Nodes

The final way to call .element is to supply a list of nodes. Supplying a list of nodes helps when creating nested tags. Normally when you have nested tags, the child nodes are nodes of a custom context.

I explain custom contexts later in this article.

Another situation to supply a list of nodes is to create a custom element that includes both a text value and attributes. The following function creates a custom modified date element:

Calling modifiedDate creates an element that looks like the following:

The exact value depends on the date string.

Creating a Custom Attribute

Call the .attribute function to create a custom attribute. Supply the name of the attribute and its value. The following call:

Creates the following attribute:

Like with custom elements, you normally write a static function to create a custom attribute. The following function creates a custom attribute for the language of an XML document:

Example: Create a Spine for an EPUB Book

Now it’s time for a real example, creating the spine for an EPUB book. The spine contains a list of files in the order they appear in the book. The following code shows the XML of a sample spine:

Building the spine in Plot requires two custom elements: one for the spine and one for the item references. The spine element requires a custom attribute for the table of contents (toc). The item reference element requires a custom attribute for the ID reference.

Create New Contexts

A context is a section of an HTML or XML document where elements and attributes reside. Plot has a BodyContext for HTML documents that corresponds to the body tag in the document. Most HTML elements reside in the body context.

Custom attributes usually require you to create a custom context. Sometimes custom elements also require a custom context.

To create the spine, create new XML contexts for the spine and spine item.

The SpineContext context contains anything inside a spine tag, which is going to be the spine items and the spine element’s custom attribute. The SpineItemContext context contains anything inside an itemref tag, which is each item’s ID reference.

Create the Spine Custom Element

The next step is to create the spine custom element, which you can see in the following code:

The code creates an element named spine with a list of child nodes. The child nodes include the spine’s custom attributes and the item reference elements. The child nodes must be in the spine context.

Create the Spine Custom Attribute

Now let’s create the spine’s custom attribute, which you can see in the following code:

Notice the class extension for the spineTOC function applies to the spine context so the attribute appears inside the spine tag.

Create the Item Reference Element

The next task is to write the code to create the item reference element.

The item function must be inside the spine context for the item reference elements to appear inside the spine tag.

The nodes are going to be the ID references.

Create the ID Reference Attribute

There’s one more custom attribute to write, the item’s ID reference.

The itemID function must be inside the spine item context for the attributes to appear inside the item reference tag.

Creating the Spine

The last step is to write a function to build the spine using the custom elements and attributes. Assume there is a Book struct that contains a list of chapters. Each chapter has a title.

The first line of code in the buildSpine function creates the spine custom element. The second line creates the spine element’s custom attribute.

For each chapter in the book, the code creates a spine item custom element and an item ID (idref) custom attribute for the spine item. The item ID’s value is the chapter’s title.

Once you do the work of writing functions for the custom elements and attributes, it doesn’t take much code to do something like build the spine for an EPUB book.

Cherry Picking a Git Commit in Xcode

Xcode 11 adds support for cherry picking commits. Cherry picking involves taking a commit from one git branch and applying it to another branch. Cherry picking lets you apply a commit to a branch without having to merge all your recent commits into that branch.

Take the following steps to cherry pick a commit in Xcode.

  1. Open the source control navigator by pressing Cmd–2.
  2. Checkout the destination branch, the branch that will receive the cherry picked commit.
  3. Select the branch with the commit to cherry pick. Xcode’s editor will show all the commits for that branch.
  4. Select the commit.
  5. Right-click and choose Cherry-Pick.
  6. An alert will open asking if you want to cherry pick. Click the Cherry-Pick button.

Want to Learn More About Version Control?

Check out my version control book. It shows you how to do the most common git tasks without leaving Xcode. Some of the material covered in the book includes seeing the changes you made to your code, branching, and going back to earlier versions of your project.