このページの本文へ

Swift Playgroundsで学ぶiOSプログラミング第58回

最新バージョンでのエラー対処法

Swift 4.0への対応と超簡単なHLSビデオプレーヤーを作成

2017年10月30日 17時00分更新

文● 柴田文彦 編集●吉田ヒロ

  • この記事をはてなブックマークに追加
  • 本文印刷

 突然ですが、現時点で最新のSwift Playgroundsのバージョンは1.6(674.15)です。実際の記事の公開タイミングとは少しずれていますが、原稿執筆のタイミングで言えば、数日前にiOS 11とほぼ同時に登場したばかりです。このバージョンの特徴は、プログラミング言語としてSwift 4.0に、OSとしてはiOS 11に対応したことです。とはいえ、当然、と言えるかどうかわかりませんが、これまでのiOS 10にも対応していて、iOS 10でもSwift 4.0でのプログラミングが可能となっています。というのも、Swift Playgroundsは、コンシューマー向けの特殊なIDEのようなものなので、Swift言語のコンパイラーは自分で持っているからです。

 それはともかく、Swift 4はこれまでのSwift 3と互換性があるのが1つのウリになっています。そこでSwift 4になっても、これまでこの連載で紹介してきたSwift 3のプログラムは、ほとんどそのまま動くのではないかと期待していました。それは「ほとんど」の程度にもよるのですが、だいたい期待どおりのようです。しかし、比較的よく登場するフレーズで、明示的にSwift 4に対応させる必要がある記述もありました。

 今回は、まずその対応方法を解説したあと、驚くほど簡単にできるビデオプレーヤーの作り方を取り上げることにします。

ターゲットのメソッドに「@objc」を付ける

 直近の例として、前回に作成したオーディオプレーヤーを見てみましょう。新しいSwift Playgrounds 1.6で開くと、残念ながらエラーが出てしまいます。

前回のオーディオプレーヤーのプログラムをiOS 11と同時に登場したSwift Playgrounds 1.6で開くと、エラーを示す赤丸があちこちに表示されるのでびっくりするかもしれません。しかし、これらはすべて根が同じ、比較的単純なエラーです

 1つの画面にいくつもエラーが表示されると悲愴な気分になりますが、気を取り直して赤い丸で示されたエラーが出ている行をよく見て見ましょう。すると、どれも基本的に1つのパターンにマッチしていることに気づきます。それは表面的には#selectorというキーワードを含んでいる行です。この意味は、ユーザーがUIKitの部品を操作した際などに、そのアクションとして機能するメソッドの名前を指定している部分です。多くはUIKitの部品のaddTargetオブジェクトですが、先週のプログラムで使っているコアアニメーションのタイマーを設定するCADisplayLinkクラスの初期化部分にも、やはり#selectorがあり、エラーになっています。根は同じです。

 Swift Playgroundsでは、赤い丸の部分をタップすると、エラーの内容をできるだけ詳しく表示し、多くの場合、それを修正するための解決策を示してくれます。

エラー行の先頭にある赤丸をタップしてみると、そのエラーの内容と対処法のヒント、さらには自動的に訂正してくれる「修正」ボタンまで表示されます。これは、セレクターとして指定したターゲットの飛び先のメソッドの定義の先頭に「@objc」を付けろ、というものです

 このエラーの意味は「#selectorを使って指定したメソッドが、Objective-Cからは見えていない」といったものです。わかりにくいかもしれませんが、ということは、つまりこの#selectorを使ってメソッドを指定する部分はObjective-Cの機能を使っていることになります。それに対して、後ろのほうで定義しているメソッドはSwiftのものなので、そこに直接飛ぶことができないと言っているのです。

 Swift 4になっても「まだObjective-Cなのか」と思われるかもしれませんが、このようにプログラムの中で飛び先をダイナミックに指定できるのは、Objective-Cならではの特徴というわけでしょう。「Swiftの世界だけで済ますことはできないのか」とも思われるかもしれません。しかし、AppleのSwift 4の公式ドキュメントを見ても、プログラムでターゲットをセレクターとして指定するには、このような書き方が標準とされています。

 ともあれ、このエラーの説明には「修正」ボタンが用意されているので、ためらわずにタップしましょう。すると、このエラーが表示されていた部分は何も変更されていないのにエラーは消えます。変更されるのは飛び先のほうです。この場合は、pButtonTappedメソッドの定義部分です。

「修正」ボタンをタップして自動的に訂正させてみると、確かに飛び先のメソッドの定義の先頭に「@objc」が付きました。エラーが発生していた行とはかなり離れていますが、これで元の行のエラーも消滅しているはずです

 ここには、メソッドを定義するためのfuncというキーワードの前に、さらに@objcが追加されています。これにより、このメソッドはObjective-Cのメソッド、言い換えればObjective-Cの世界から呼び出すことのできるメソッドとして定義したことになります。このように、#selectorで指定したすべてのメソッドの定義の前に@objcを付ければ、この種のエラーはすべて消滅し、Swift Playgrounds 1.6の上で先週のプログラムを動かすことができます。言うまでもなく、それ以前のプログラムも、ターゲットをセレクターとして設定している部分では、すべて同じエラーが出るので、このようにして修正してください。

 なお、この@objcというコンパイラーに対する指示は、Swift 4になって初めて導入されたわけではありません。実はSwift 3でも、セレクターのメソッドは、厳密にはこのように書くべきだったのです。Swift 3まではチェックが甘く、まあいいか、という状態だったのが、Swift 4になってより厳しくなったと考えるべきでしょう。

この連載の記事

週間ランキングTOP5

ASCII倶楽部会員によく見られてる記事はコレだ!

ASCII倶楽部の新着記事

会員専用動画の紹介も!