Finding Where Your App Crashes in Xcode

March 20th, 2017

Filed under: Xcode | Be the first to comment!

As you’re developing an app, it may crash when you run it. When it crashes you want to know where the crash occurs so you can fix the error that’s causing the crash. Set an exception breakpoint in Xcode to find your project crashes.

Setting an Exception Breakpoint

Go to Xcode’s breakpoint navigator by choosing View > Navigators > Show Breakpoint Navigator. At the bottom of the breakpoint navigator is an Add (+) button. Click the Add button and choose Exception Breakpoint. The exception breakpoint is initially set to fire on all exceptions.

ExceptionBreakpoint

Now when you run your app in Xcode, Xcode will pause the app when it crashes, allowing you to locate the line of code where the crash occurs.

One thing to keep in mind with exceptions is they can fire for reasons other than a crash. As an example Xcode throws an exception every time you save with Core Data, even if there are no problems with the save. Disable the exception breakpoint when it annoys you. Enable the exception breakpoint when your app crashes.

Sharing the Breakpoint

Setting an exception breakpoint is something you want for most projects. Xcode lets you share breakpoints so you don’t have to create them every time you create a new project. Exception breakpoints and test failure breakpoints are the most common breakpoints to share.

There are two ways to share a breakpoint. First, select the breakpoint in the breakpoint navigator, right-click, and choose Share Breakpoint.

Second, you can make a user breakpoint that is available for every project in your Mac user account. Select the breakpoint in the breakpoint navigator, right-click, and choose Move Breakpoint To > User.

Facebooktwittergoogle_plusredditmail

Xcode 8: Core Data Class Generation

March 1st, 2017

Filed under: Xcode | Be the first to comment!

Xcode 8 adds support for automatically creating classes for your Core Data entities. If you look at Xcode’s data model inspector, you will see a Codegen menu.

Xcode8CoreDataCodeGenMenu

The Codegen menu has the following items:

  • Manual/None, which means Xcode does not generate code files for the entity. This is the same behavior that previous versions of Xcode had. You must create the classes for your entities by choosing Editor > Create NSManagedObject Subclass in Xcode.
  • Class Definition, which means Xcode generates the entity’s class files for you. Xcode does the equivalent of you choosing Editor > Create NSManagedObject Subclass. Class Definition is the default option for new projects.
  • Category/Extension, which means Xcode creates an Objective-C category or Swift class extension for the entity.

If you choose Class Definition or Category/Extension for one of your entities, make sure you don’t manually create a NSManagedObject subclass for that entity. Manually creating the subclass creates duplicate class files, and your project won’t build. Remove the manually created subclass files from the project if you have duplicate files.

Where Are the Files?

If you choose Class Definition or Category/Extension from the Codegen menu, you’ll notice there are no files for the NSManagedObject subclasses in your project. Where are the files?

Xcode creates the files when you build the project. The files are in your project’s derived data location. Read my Changing Xcode’s Build Location post for more information on the derived data location. You’re not meant to access and edit the Core Data class files Xcode creates. The point of Xcode creating the class files is to automatically update the files when you make changes to the data model.

What do you do if you want to add methods to your NSManagedObject subclasses? Create a new file for your methods. Add either a Swift class extension or an Objective-C category.

Which Codegen Option Should You Use?

In most cases you should use either the manual or class definition codegen options. The advantage of the class definition codegen option is you don’t have to worry about forgetting to change your classes when you change your data model. Xcode keeps the class and data model in sync. The advantage of manually creating your Core Data class files is you can access them in the project window and edit them.

Facebooktwittergoogle_plusredditmail

Instruments: Call Tree View Is Your Friend

January 23rd, 2017

Filed under: Instruments | Be the first to comment!

On Stack Overflow I see the same question constantly from people who use Instruments. Instruments uncovers a problem with their app. The app could have memory leaks. It could use a lot of memory. The people asking the questions want to know how to find the area of their code that is causing the problem. I have answered questions like this multiple times on Stack Overflow. Rather than repeat myself, I will answer it here.

If you want to find the problem areas in your code with Instruments, switch to the call tree view. Select the Invert Call Tree and Hide System Libraries checkboxes to show your code in the call tree view. Double-click a function in the call tree view to find problem lines of code. More detailed information on switching to the call tree view can be found in the Allocations Instrument Call Tree section of the following article:

Getting Started with Instruments

Facebooktwittergoogle_plusredditmail

Limiting Device Orientations in an iOS App

January 8th, 2017

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

I’ve been developing an iOS Game that is meant to be played in landscape orientation. I had problems forcing the game to be played in landscape orientation, causing the game to be rejected by Apple the first time I submitted it.

Limiting an iOS app’s device orientations is trickier than you would expect. I didn’t find much information about this online so I’m writing about what I learned.

Setting Supported Device Orientations

The first step is to set the supported device orientations for your target in Xcode. Select the project from Xcode’s project navigator to open the project editor. Select the target in the project editor.

XcodeDeviceOrientation

In the Deployment Info section there’s a series of Device Orientation checkboxes. Select the checkboxes of the device orientations you want to support. My game is meant to be played in landscape orientation so I selected the two landscape checkboxes.

Supported iPad Orientations

When you set the supported device orientations for your app and test the app, you’ll notice something. On the iPhone the app will respect your supported device orientations. But on the iPad the app will support all four possible orientations. Why does the iPad do this?

The Info.plist file has a separate entry for supported iPad device orientations. Click the Info button at the top of the project editor to access the Info.plist file properties.

SupportediPadOrientations

When you examine the Supported interface orientations (iPad) entry, you will see the iPad initially supports all four device orientations. Remove the items for the orientations you don’t want to support. In my case this means removing the two portrait items.

Disabling iPad Multitasking Support

When you set the supported iPad orientations and test your app, it should respect your supported device orientations. But when you try to upload your app to the App Store, the app will be rejected because iPad multitasking requires your app to support all four device orientations.

The fix is to disable iPad multitasking support for your app. In the Deployment Info section for the target (Look at the first image in this article), there is a Requires full screen checkbox. Select that checkbox to disable iPad multitasking. With iPad multitasking support disabled you can upload your app to the App Store without having to support all four device orientations.

Facebooktwittergoogle_plusredditmail

Adding Markers to Text Lists when Pressing the Return Key

December 12th, 2016

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

I tried using Apple’s NSTextList class for creating ordered and unordered lists in an application I’m developing. I was able to create lists, but when I pressed the Return key inside an unordered list, no bullet was added.

Because of this flaw in NSTextList I decided to implement my own class for lists. But I still needed to insert markers when pressing the Return key inside the list. There is very little information available on how to insert list markers when pressing the Return key so I’m sharing what I’ve learned.

Perform the following steps to insert list markers when the Return key is pressed:

  1. Create a subclass of NSTextView.
  2. Override the function insertNewline in your NSTextView subclass. This function gets called when someone presses the Return key.
  3. Use the text view’s selectedRange property to determine if you’re inside a list. The selectedRange property’s location field is the text view’s insertion point.
  4. If you’re inside a list, add the marker to the text view’s text storage at the insertion point.

The following Swift code shows a simple example of overriding insertNewline to insert a bullet when someone presses the Return key inside an unordered list:

override func insertNewline(_ sender: Any?) {
    // Choose Edit > Emoji & Symbols in Xcode to enter the bullet character.
    let bullet = "•\t"
    let bulletToAdd = NSAttributedString(string: bullet)
    super.insertNewline(sender)
    if insideAList() {
        addMarker(marker: bulletToAdd, point: (selectedRange().location))
    }  
}

func addMarker(marker: NSAttributedString, point: Int) {
    textStorage!.insert(marker, at: point)
}

You’ll notice I didn’t provide the code for the insideAList function. That code depends on your application and how you store lists in the application. You have to get the ranges for the lists in your document. Check if the text view’s insertion point is in one of the ranges.

Facebooktwittergoogle_plusredditmail