iOS Development


This document relates to developing iOS applications on macOS Sierra versions 10.12.6 to 10.13.3 using Xcode versions 9.0.1 to 9.2 and iOS 10.3.1 together with Swift 4.

Getting Started


Xcode Concepts

Also, select Help > Xcode help from the Xcode menu, then Xcode overview.

To show line number and a page guide, go to Xcode > Preferences > Text Editing. Select Line numbers and Page guide at column:.

Installing Simulators

To download and install older iOS simulators:

Xcode -> Preferences -> Components -> Simulators

See also:

Removing Redundant Simulators

For help on using the simctl command:

$ xcrun simctl help

For help on the delete subcommand:

$ xcrun simctl help delete

To delete all unavailable devices:

$ xcrun simctl delete unavailable

Initial Learning

  1. Read The Swift Programming Language (Swift 4) also available as a free iBook from the App Store.

  2. Follow the Start Developing iOS Apps (Swift) tutorial

  3. Read the View Controller Programming Guide for iOS

  4. Review the documents listed under the What's next? Where to Go from Here section of the Start Developing iOS Apps (Swift) tutorial

Debugging and Logging

Table Views

TableViews are quite useful for many if not most uses. Note that a table view has content which consists of either Static Cells or Dynamic Prototypes. The Start Developing iOS Apps (Swift) tutorial shows how to use Dynamic Prototypes, but if you know the content of the table view at compile time, it is quite straight-forward to implement in the storyboard. Briefly;

  1. Drag a Table View Controller onto the storyboard from the Object Library.

  2. Use the Attributes Inspector to change the Table View Content to Static Cells.

  3. Consider changing the Style to Grouped

  4. Set the number of rows for the initial section and add elements to match the behviour of the majority of the sections. These wil be duplicated when you create more sections.

  5. Change the number of sections to create the additional sections.

  6. Create a UITableViewController class and assign it to the Custom Class property of the table view in the Identity Inspector.

See also:

Disabling Cell Selection in Dynamic Table

To disable cells being highlighted when selected in a dynamic table view, use the storyboard to select the prototype cell in the Document Outline. It will be a child of the Table View. In the Attributes Inspector, under the Table View Cell properties, beneath the Identifier section, change the Selection option to None.

Returning Data to a Presenting View Controller

Implement the delegate pattern. See the Dismissing a Presented View Controller in the Presenting a View Controller section of the Presentations and Transitions chapter of the View Controller Programming Guide for iOS

  1. Create a simple protocol defining a suitable method to pass the data.

  2. The presented view has an optional delegate property of that protocol type.

  3. The presenting view implements the delegate protocol. It sets the presented view delegate to itself before the view is presented, perhaps in the prepare(for:sender:) method of the presenting view, which will be called when the segue is activated.

  4. When values change on the presented view, it can make appropriate calls to the delegate method(s) to update the presenting view's data model.

Navigation Controller Back Button Behaviour

The back button of a pushed view is actually defined in the presenting parent. The logic seems to be that the pushed view's back is logically the pushing view.

If the presenting view does not have a navigation item, the back button text of the called view will be Back. Add a navigation item by dragging a Navigation Item from the object library to beneath the controller element of scene in the outline view.

Then select the new navigation item in the outline view and set the title for the presenting page. If you want presented pages to show a different text for the back button, enter the values in the navigation item's back button setting in the attributes inspector.

The text for the back button of the pushed view should change appropriately in the interface builder to display either the title of the presenting view or if the back button text has been defined, it'll use that. Note that at run-time, if the text to be displayed for the back button is too long for the device screen size, it is replaced with the localised version of Back.

See also:

Split View Controllers and Navigation

In a split view, in some situations, a detail view navigation controller uses the title of the master navigation controller to name the left back button of the detail view navigation bar. One such scenario is in portrait mode on an iPad Pro (12.9-inch). The title can be set in the storyboard.

To display the left back button on the detail view, in the storyboard, select the Navigation Item in the detail view controller and use the Attributes inspector to set the Left Items Supplement checkbox. Alternatively, set it at runtime with code similar to myViewController.navigationItem.leftItemsSupplementBackButton = true.

How to manually rename view controller

The easiest method is to right click the classname in the class definition file and choose the refactor method. But if you want or need to fix things manually, follow these steps:

  1. Rename it in the project navigator by selecting ViewController.swift and hitting return.

  2. Rename the class and also the header comment

  3. Open Main.storyboard

  4. Select the View Controller by clicking on its scene dock or select the View Controller in the outline view

  5. Open the Object Inspector (Option-Command 3)

  6. Under Custom Class select the renamed Class

Add storyboard controls to stack view

  1. Shift-click each of the controls to select them

  2. Select Editor > Embed In > Stack View


  1. Open the storyboard and select the related navigation controller

  2. In the Attributes inspector, Navigation Controller section, select Shows Toolbar

  3. Within a view controller that displays the toolbar, programmatically create instances of UIBarButtonItem

  4. Assign an array containing the buttons to the view controller's toolbarItems property

  5. In the storyboard, select each view controller that you do not wish to display the toolbar on and select the Hide Bottom Bar on Push in the Attributes inspector

  6. How to show and hide a toolbar inside a UINavigationController

Button Border Colours

Keyboard Navigation with the Next Button

Making the next button move to the next edit field involves giving each UITextField a integer tag, each tag value incrementing from the previous. In the controller handle when the return (next/send/done/etc) key is pressed, get the tag value of the current UITextField, increment it, and find the associated UITextField from the owning super view, (most likely the view of the current controller) and set it to become the first responder.

Your view controller implements the UITextFieldDelegate and defines the textFieldShouldReturn(textField:) method.

The tags can be set for the text fields in the interface builder. The Connections Inspector is used to associate the delegate with the view controller which implements the UITextViewDelegate.

Home Screen Quick Actions

Long Press Gesture Handling


Local files are stored in a directory under ~/Library/Developer/CoreSimulator/Devices. To find out the id of the device, open the Devices and Simulators window in Xcode. Window > Devices and Simulators Select either Simulators or Devices as appropriate, then select the device. The Identifier is displayed under the details of the device at the top of the window.

iCloud in Simulator

Resync simulator with iCloud by selecting Debug > Trigger iCloud Sync from simulator menu.

Type X does not conform to protocol NSObjectProtocol

Implement NSObject protocol.

Launch URL in Safari

Location Manager

See also:

Desired Accuracy

The following observations have been noted in testing on iPhone X with iOS 11:

  • 10 metres - seems to turn on GPS and cause frequent calls to the delegate. Additionally, provides speed and bearing information.
  • 100 metres - infrequent calls to the delegate and doesn't seem to use GPS. Locations are frequently less accurate than 100 metres to the point where obtaining locations with an HDOP of less than 100 metres is unlikely.
  • Setting the distance filter causes the OS not to call the location manager until the distance criteria has been met. This is likely to be an important value in reducing battery usage.

See also:

Deferred Locations

Note: I have been unable to get deferred locations working with iOS 11 on iPhone SE nor on iPhone X.

Simulating Locations

The Xcode Debug has a Simulate Location option, which is disabled unless the app is running in a simulator with the debugger attached to the running app process. However, it seems to be broken in Xcode 9.2. At best it will provide one point per LocationManager session then stop.

However, in the simulator menu Debug -> Location there are options to choose between a City Run, City Bicycle Ride or Freeway Drive that simulate real trips. Note: This is in the simulator application, not Xcode.


Attributed Strings

Share Sheet (UIActivityViewController)

Core Data and CloudKit

Watch WWDC 2017 - What's New in Core Data. Covers topics such as query optimisation with indexes and persistent history tracking. That latter is probably the most effective technique to use for updating offline changes etc. to the cloud.

To handle when records have been deleted, you probably need to preserve the primary key value in order to delete the same record on the Apple Watch. You do this by defining the relevant attribute as one to Preserve After Deletion.

In the XCode model editor, Selec the attribute and open the Data Model inspector panel. In the Advanced sub-section of the Attribute section, there is the option to Preserve After Deletion.

iCloud File Management



Install the ImageMagick package from MacPorts. See InstallingMacPorts.

Artwork can then be created from a larger original (e.g. 2048x2048) with:

$ convert $FILENAME -resize '40x40' converted_file.png

See also:

Generating App Icons



Free Developer Account

Note: apps distributed using ad-hoc distribution with a free developer account will not run on a device after the provisioning profile expires. The certificate for the provisioning profile expires after a maximum of seven days.

Provisioning Profiles

Ad-hoc Distribution

Ad-hoc distribution allows you to distribute and install builds on internal test devices. The device IDs need to be included in your developer account and your provisioning profile certificate needs to include these device IDs, otherwise, they either fail to install, or simply fail/crash on startup.

There are instructions in Xcode Help under Xcode Help > Archive, distribute, and test > Test a beta version > Distribute to registered devices (iOS, tvOS, watchOS).

Create the build in XCode 9.2 by selecting the build target as Generic iOS Device in XCode's toolbar. Then select Product > Archive from the main menu. This will build the app, then display the Organizer window containing this and previous builds. You can display this window in the future by selecting Window > Organizer from the main menu.

XCode 10 introduces a new build system. It can be changed by selecting your project, then File > Project settings from the main menu. Then under Shared Project Settings:, Build System: you can switch to Legacy Build System.

To export the build for distribution:

  1. Click the Export... button in the Organizer window.

  2. Select a method of distribution.

  3. Choose an appropriate value for the App Thinning option, None creates a single universal app that runs on all supported devices. Note that in XCode 10.1, thinned apps won't install via ad-hoc distribution, so leave this option as None in that situation.

  4. Uncheck Rebuild from Bitcode - there doesn't seem to be a way to analyse crash logs when apps are distributed with this option set.

  5. Optionally, choose to Strip Swift symbols

  6. If you want to distribute the app so it can be installed by users using Safari, choose the Include manifest for over-the-air installation

  7. Click Next.

  8. If you chose to create a manifest, fill in the Distribution manifest information. This is information is not remembered by XCode, so store the details somewhere else for future reuse.

  9. Click Next.

  10. Choose the Automatically manage signing option. This should work in most cases. Xcode 10 doesn't seem to create a new ad-hoc provisioning profile after an old one expires, so it is necessary to create one within iTunes Connect, download and import it into XCode. Also, when you start using a new device for internal testing, you will need to update the certificates within iTunes Connect to include the new device and manage signing manually. You need to create an ad-hoc provisioning profile that includes the devices registered for ad-hoc distribution.

  11. Click Next. The artefacts are created and signed.

  12. Click Export and choose a target location for the exported files to be saved.

  13. If distributing for installation via Safari, upload manifest.plist and all the .ipa archives to a single directory on your website. Create an HTML page containing an href link of the following format:

    <a href="itms-services://?action=download-manifest&url=https://HOST/PATH_TO_FOLDER/manifest.plist">Click here to install</a>

If installation fails, there is unlikely to be an error message to analyse. When you click the link, you should immediately see a dialog asking if you would like to install the app. If it fails before that point, it may be because the app is already installed and was installed from another source, most likely the official app store. Either install using Xcode, or uninstall the old version first.

The website's log should see some GET requests. One should be for the manifest.plist file. That GET request should show the model that it looks up in the manifest file, e.g. iPhone10,6. The next GET request should be for the IPA file listed for that model in the manifest.plist file.

If the install starts but fails after it appears to have downloaded the IPA file, it is most likely a problem with the signing certificate, or the device not having been registered in the developer account. See Register a single device in the Developer Account Help, under Register Devices > Register a single Device.

You may also need to 'reset' your registered devices after commencing a new developer membership year, otherwise the ad-hoc app will fail to properly install on the device.

  1. To install using XCode;

    1. connect your device to the build machine, e.g. via a lightening cable

    2. Open the Devices and Simulators window (Window > Devices and Simulators from the main menu)

    3. Select the Devices tab

    4. Select the device under Connected in the left sidebar

    5. Click the + symbol underneath the list of INSTALLED APPS

    6. Browse to and select the relevant .ipa archive file

    7. The application installs on the target device

See also:

Beta Testing with TestFlight

App Store Release Process

Crash Logs

U.S. Export Regulations

Screen Recording

Identifying iPad Models

Root Certificates


Warning once only: Detected a case where constraints ambiguously suggest a height of zero for a tableview cell's content view. We're considering the collapse unintentional and using standard height instead.

In the storyboard, enter a rowHeight of 44 for the table view, instead of leaving it at automatic.


Force reboot iPhone X

  1. Press and quickly release volume up button

  2. Press and quickly release volume down button

  3. Press and hold the side/power button until the Apple logo is displayed. Can take 10 seconds or longer.

Compiler Error Messages

Type 'MyClass' does not conform to protocol 'NSObjectProtocol'

Make MyClass extend NSObject and all the methods required by NSObjectProtocol are provided with a default implementation.

Other information

-- Frank Dean - 23 Dec 2017

Related Topics: iOSTips, MacOSXTips,, watchOSDevelopment