古いOS対応アプリを最新Xcodeで作る

少数派のお話ですが、古いOS(OS X 10.4とかOS X 10.5とか)にも対応し、最新のOSにも対応するというような幅広い対応が必要なアプリやプログラム、ライブラリを作らなければいけないときに、気をつけるべきポイントを紹介します。OS Xでの話ですが、iOSでも同様です。古いXcodeを使うという場合も多いかもしれませんが、気をつければ最新環境でも古いOS対応アプリが実装可能です。最新環境の方が色々と便利になっていたり、Xcode以外のアプリも最新が使えるという利点があります。それに、古いOS環境、新しいOS環境と複数環境を整備し続けるのは色々手間がかかります。

SDK

SDKの設定は最新のSDKを使う設定でOKです。「Latest」を選択しましょう。

Deployment Target

Deployment Targetは、ビルドしたバイナリが実行可能な最低OSを定義する情報です。これによって、フレームワークやライブラリとのリンク方法が変わります。例えば、古いOSには無いかもしれないフレームワークはウィークリンクになります。
151116-0001
また、同時にこの情報はOSが実行可能なバイナリかどうかを判定するのにも使われます。対応していないOS上ではアプリのアイコンにバツ印が現れて、起動しようとするとOSがエラーメッセージを表示してくれます。

標準C++ライブラリの選択

使用する標準C++ライブラリを「libstdc++ (GNU C++ standard library)」にします。デフォルトで選択されている「libc++ (LLVM C++ standard library with C++11 support)」は古いOSでは使えない可能性が高いです。また、「C++ Language Dialect」の設定はそれに合わせて「GNU++98 [-std=gnu++98]」などに変更しましょう。
これによってC++11のコードは使えなくなるので、C++ 11で導入された構文やクラスを使わずに機能を実装しましょう。
151116-0002

ARCはオフにする

ARC (Automatic Reference Counting)はオフにしましょう。OS X 10.6未満のOSでは使えません。また、OS X 10.6ではweakが使えないケースがあるなど制限があるので、ARCはオフにしましょう。もちろん、OS X 10.7以降に対応すれば良いという場合はARCも使用可能です。
151116-0003

ブロックは使わない

OS X 10.6未満に対応するときは、ブロックは使わないようにしましょう。「__block」がついた変数があるだけでも、OS X 10.6未満では起動しなくなります。

クラスメソッドの呼び出し

Objective-Cのクラスメソッドを呼ぶときは、そのクラスがDeployment Targetで指定したOSで使えるかどうかを確認した上で使いましょう。例えば、「NSRunningApplication」クラスはOS X 10.6以降で使用可能です。Deployment Targetの設定がOS X 10.5のとき、これを「NSRunningApplication」クラスのクラスメソッドを単純に呼んでいると、シンボル無しでOS X 10.5では起動しなくなります。
しかし、OS X 10.6以降では使わないといけない、OS X 10.11以降ではまた別の処理が必要などとなるときは、「NSClassFromString」関数経由で使用します。「NSClassFromString」関数に文字列でクラス名を渡せば、実行時に使用可能ならば有効なClassが返るので、それを使ってクラスメソッドを呼びます。使えないときはnilが返ります。

メソッドの呼び出し

実行時に使用可能なメソッドかをチェックして呼びます。全てのメソッドでチェックが必要なのではなく、通常はどのOSでも使用可能なメソッドを使用し、特定のバージョン以降ではメソッドを切り替えるというときに、「respondsToSelector」メソッドを使って、呼び出すメソッドが実装されていれば使うというようにします。途中で無くなったときにも有効です(サードパーティのライブラリではたまにあります)。

Swiftは使えない

Swiftは古いOSでは使えません。ランタイムが無いので。もちろん、Swiftが登場した以降のOSであれば、Swiftを使っても大丈夫です。

POSIXやBSDの関数も利用する

CocoaやCocoa touchで提供されるクラスだけで完結できる処理は簡単ですが、古いOSでは使えないというときや、古いOSでも最新OSでもコードを変更しないようしたいときは、POSIXやBSDの関数を使って実装するのも有効です。特にアルゴリズムやライブラリを実装するときは移植性が高くなり、iOSやOS Xだけではなく、AndroidやWindows、Linuxに対しても移植性が高くなります。

テスト環境

最終的な動作テストは実マシンを用意するのがベストですが、実装作業中やデバッグ中はVMwareなどの仮想環境を使うのが効率的です。OS Xであれば、OS X 10.5以降は仮想化かのうです。(OS X 10.5とOS X 10.6はサーバー版のみ)
iOSについては仮想環境では試せませんが、iOS シミュレータである程度は確認できます。それよりも古いものが必要なときはデバイスを用意するか、古いXcodeを使いましょう。(この場合は古いOS Xが別途必要です)
 

関連記事

  1. Xcodeでのリモートデバッグ

  2. Snow Leopard ServerとWindowsのファイル共有

  3. ObjcのNSDictionaryとCppのmapはどっちが早いか

  4. Arduinoとkonashiを接続する

  5. Safariのタブのタイトルが更新されない問題解決

  6. サーバー再構成しました

最近の著書

  1. 基礎から学ぶ SwiftUI

最近の記事

  1. 2020.10.21

    GitLabへの移行
  2. 基礎から学ぶ SwiftUI
  3. 基礎から学ぶ SwiftUI