Overview

Unsafe API Resolver Tools

INFO

The current iOS developer tools (Xcode/Clang) provided by Apple lack the functionality to point out APIs that are available on only a subset of the OS versions the developer intends to support. This work aims to point out these APIs in an application’s source code (detection phase) and resolve conflicts automatically, if possible (resolution phase).

The detection phase is based on a modification of the Clang compiler, whereas the resolution phase is implemented in an Objective-C command line tool, with a little help from AppleScript and Python. It relates to concepts known from Aspect-Oriented Programming to inject conditional code transparently and without scattering an application’s codebase.

For Objective-C methods,resolveInstanceMethod: and resolveClassMethod: are used to catch and resolve incompatibilities at runtime by adding the missing implementation from a fallback library. For critical classes and C functions, the forwarding to the fallback library must be done in the application's source code at compile time, but the modified compiler will provide FixIts to lead into the right direction. The idea is to change as few lines of existing code as possible, and to put all the fallback functionality into a single library. This library and code stubs are generated automatically by the toolchain provided by this project.

Related Repositories:

Tools/Projects:

  • Clang (modified): The compiler has been modified to flag all symbols that were introduced after the deployment target. These symbols are referred to as critical symbols or critical APIs. A more detailed description can be found in the source repository, this repository only includes a binary.
    Repository

  • Unsafe API Resolver: This command line tool automatically resolved conflicts by creating code/stubs for fallback functionality. It depends on a number of resource directories and tools, so the easiest way is to use the installer that can be found in /Installer. You can provide custom snippets that will be used to resolve specific APIs. See this repository for examples.

  • XcodeProjectCheck: This command line tool detects problems in files that Clang does not process. Currently, it only scans the project file for frameworks that should be weak-linked. Support for XIBs, Storyboards (Auto Layout!) and CoreData models is planned.
    Project Location: /Tools/XcodeProjectCheck

  • Installer: The above-mentioned tools can be integrated into any iOS project via custom build phases and flags. The installer app does that for you. Before any changes are made, you can read detailed descriptions of what the installer will change. A binary of the installer is located in the root directory.
    Project Location: /Installer

Directory Structure:

  • /Installer: The source code of the installer app.
  • /Resources: Resources the installer and other tools depend on. Changes to this folder may break these tools.
  • /FrameworkVersionInfo: It is not possible to detect the minimum version of a framework programmatically, e.g., from header files. Therefore, a PLIST has been created with availability information for all currently available iOS frameworks. The xcodeprojectcheck tool depends on this.
  • /Scripts: These scripts are used by the unsafeApiResolver tool to modify Xcode projects and to restart the build process, if necessary.
  • /Templates: The templates are used by the unsafeApiResolver tool to generate code.
  • /Tools: Binaries and their dependencies that the installer copies to the target project.
  • /Tools: Additional tools to help detecting or resolving critical APIs. Currently includes the xcodeprojectcheck tool's project only.
  • /Unsafe API Resolver: Contains the sources of the unsafeApiResolver tool.

All the tools should be considered beta. Feedback is very welcome. Extensions are planned and will be implemented according to the level of feedback, and my spare time, of course.

Runs on: Mac OS X 10.7+
IDE used: Xcode 4.6 (requires Xcode 4.5)
Useful for: iOS app projects (and, partly, Mac OS X apps)

Current Limitations:

These are limitations for the app project you want to make backwards-compatible. For development requirements, see notice above.

  • No workspaces allowed (resolution phase).
  • Xcode 4.5 (you can try down to 4.3, as long as it's a single bundle distribution, so no installer was used).
  • Your project must have a configuration named Debug.
  • If you use configuration files in your project, you must inherit all values from these options: OTHER_LDFLAGS, OTHER_CFLAGS (resolution phase), and you must not overwrite CC in your debug configuration.
  • No support for multiple application targets: Only the first is considered by the installer. Targets of other types (Static Libraries, Bundles,...) are not a problem.
  • You must not have a directory /Resources in your root directory.
  • Problems in XIB files (Auto Layout!) are currently not detected, but I'm working on it.

Please see LICENSE.md for the open source license used for this project and the software it includes/uses, and a warranty notice.