From time to time it happens to all of us: An app crashes with the not really helpful message “terminating with uncaught exception of type NSException”. Great.
This can happen when an assertion in a framework you are using fails (among other reasons). When this happens Xcode is not very helpful and just shows you that an exception was thrown. It does not show the reason nor the location where the exception was thrown.
Not very helpful.
To find our more about the exception you can use an Exception Breakpoint:
1. Open the breakpoint navigator (⌘8)
2. Press “+” in the footer
3. Choose “Exception Breakpoint…”
4. Leave all default values. Only change “Action” to “Debugger Command”
5. Enter po $arg1 into the text field
That’s it! Your shiny new Exception Breakpoint should look like this:
Now, when you try to start your app again, it still crashes (obviously), but you’ll see the exception’s message in the Debug area and Xcode shows you the code where the exception was thrown:
When your are writing UITests for a multi language app you need access to your Localizable.strings. For example when you need to press a “Save” Button in your test. Because your app is localized the text “Save” is part of your Localizable.strings file.
In your app you set the title of your “Save” Button like this:
You can use any class from your UITests to access the UITest bundle. When you are not explicitly asking to use the UITest bundle when initializing the NSLocalizedString the default value Bundle.main will be used. Using Bundle.main does not work when running UITests because it gives you the bundle of the UITest Runner App instead of the UITest bundle.
Voilà! You can now use your localized strings in your UITests:
A simple scenario: You are writing a UITest that should check if a UISwitch is switched on.
In a UnitTest you would simply do this:
When you are running a UITest you cannot do that, because during a running UITest you cannot access the UISwitch directly. Xcode only gives you access to your app’s UI elements via the XCUIElement class. That class is used for all accessible UI elements so it does not have a isOn property like UISwitch has.
So how do you test that the UISwitch is on?
It’s actually pretty easy, but not really obvious. XCUIElement conforms to XCUIElementAttributes which gives you access to a value property of type Any?
So, as value can literally be Any(thing) I tried to cast it to a Bool, because isOn also is a Bool, right?
Not working! Turns out that when you access a UISwitch in your UITest its value property is of type NSTaggedPointerString. Which is a subclass of NSString and can be cast to String (when you are using Swift). So the BoolisOn value has been mapped to a “0” or “1” String.
To test if the first UISwitch in your current view has been switched on, you can do this in a UITest:
In an older blog post I described how to simulate a custom location in the Simulator by using a GPX file. During my current project I have to use simulated locations a lot. But every time I ran my app in the simulator Xcode deactivated the location simulation. So I had to manually select it again with every start of the app. Really annoying.
As it turns out there is way to permanently enable location simulation in the Simulator. It’s just a bit hidden. To always enable location simulation open Edit Scheme for the scheme you are running and then under Run > Options select one of the available locations as Default Location because otherwise the default is None and no location is simulated.
Voilá, once you select a default location for your scheme the Simulator keeps simulating the location everytime you start it.
Xcode has a neat built in feature that let’s you simulate a (GPS) location in the iOS Simulator. To switch it on you just need to run your app in the Simulator and then click on the location arrow on top of the debug area. Xcode offers a handful of default locations from Moscow to Honolulu that you can use if you just need any location.
But sometimes you need to simulate a certain location that is not part of that default set. For example, let’s say you are developing an app that shows all the cool bars in your hometown. Then being able to simulate the location “Honolulu” won’t be of much use to you (unless your hometown in Honolulu).
Luckily Xcode offers the possibility to add a GPX file to your project that defines the location you would like to simulate. GPX is a XML Format for GPS data. It has a large set of datatypes but to simulate a location we only need the wpt (waypoint) datatype:
To add your custom location to the Simulator you have to add a GPX file to your project. Xcode offers this file type in its New File dialog (File -> New -> File… -> Resources -> GPX File) but it is just a plain XML file so you can create it somewhere else and just add it to your project (just make sure it has a “.gpx” file ending).
So to simulate the location add the following GPX file to your project:
Now if you run your app in the Simulator and click on the location arrow on top of the debug area, you will find your custom location on top of the default locations (Xcode displays the file name of your GPX file as the name of your custom location). Select it and the Simulator pretends to be at that location.
But it gets better! What if a static location is still not enough for you? Say, you want to add a feature to your “Best Bars in my Hometown”-App that allows the user to track his way home after his visit to the bar (So he can see the next day how he got home in case he can’t remember…). To test that feature you would have to make the Simulator pretend to be moving from one location to another.
This is where a second GPX datatype comes into play: the time data type. When you add a time element to a waypoint element and you have multiple waypoint elements Xcode simulates a movement between those waypoints:
When you select this GPX file from the list of locations Xcode starts to simulate a movement from the first waypoint to the second waypoint and then to the third.
The speed of this movement is determined by the value of the time elements. The absolute time does not matter. Xcode only uses the time difference between the waypoints to calculate a speed. So in my example it takes the Simulator 1 minute to “move” from the first waypoint to the second waypoint and then another minute before it reaches the third waypoint.
After switching to Xcode 6 and the iOS8 SDK I was confronted with a strange error message when trying to test my app on a device. The app was built and deployed to the device but Xcode did not run it. Instead it showed an alert with the following error message:
Could notlaunch"APP_NAME",process launch failed:Security
The only thing you can do is to press “OK”, but the app still does not run. When you try to run it again from Xcode you just get the same alert.
The solution to this problem is quite simple:
Run the App from Xcode
When the alert shows, press “OK”
Open the app on the device
An alert will be shown, asking you if you want to trust this app. Press “Trust”.
Sometimes when you transfer your project to another computer and especially when you create a new developer certificate in the progress, you’ll run into difficulties. When you try to run your app on a device, Xcode will throw the following error:
The problem is that in your project’s project.pbxproj file the old provisioning profile identifiers are still lingering. You need to clean up that file so that Xcode can build your project without errors.
Here’s how you do that:
1. Close Xcode
2. Right click on your project’s .xcodeproj bundle to show it’s contents.
3. Open the .pbxproj file in a text editor of your choice (make a backup copy first if you feel paranoid)
4. Find all lines in that file that include the word PROVISIONING_PROFILE and delete them.
5. Open Xcode and clean your project
6. Build your project
1. In Xcode’s project navigator (left column) klick on the blue project icon.
2. Select the “Build Phases” tab in the main window
3. Open the “Compile Sources” section
5. Open the “Copy Bundle Resources” section
warning:no rule toprocess file'*FILEPATH*'of type
So the problem is easier to spot now. You still have to fix it manually as I described above.
When I started to play around with CoreData for the first time, I came across a strange error. The error description said “The model used to open the store is incompatible with the one used to create the store”. At first I just couldn’t figure out what the problem was. As soon as I tried to access the NSManagedObjectContext the app crashed.
The solution is really simple: Whenever you change something your CoreData data model, you have to delete the old compiled app from the simulator or device. CoreData uses SQLite3 which is nothing more than a file in your app’s filesystem. If you do not delete the old version of your app the file remains in the file system and does not reflect the changes that you made in the data model. The SQLite file will only be deleted when you delete the whole app.
So the golden rule is: Whenever you change something in the data model of your CoreData driven App, make sure to delete the old version of the app before compiling and running the new one.