LoginSignup
3
2

More than 5 years have passed since last update.

TodayExtension を objective-c から Swift 3.0 へ移行するときにやったこと

Posted at

全てのソースを Swift へ移行したいと思いつつも時間はかかるし、まずは核となる機能よりも周辺から段階的に進めたいと、みなさん考えると思います。私もそうでした。

そこで、まずは TodayExtension を objective-c から Swift 3.0 へ移行することにしました。そして、つい最近移行が完了しました。ネット上の TodayExtension の情報は古いものが多く、いろいろ調べたので、誰かの参考になればと思い、Qiitaに投稿する。

移行前

  • TodayExtensionは objective-c のみ使用している
  • 本体アプリは objective-c と Swift 3.0 の両方を使ってる
  • 本体アプリは -Prefix.pch を作成して共通で使い回すクラスのヘッダーファイルをまとめてある
  • objective-c から Swift を利用するとき、いちいち -Swift.h を import するのが面倒なので -Prefix.pch に書いている

移行後

  • TodayExtensionは全て Swift 3.0 になった :tada:
  • TodayExtensionは本体アプリの -Prefix.pch-Swift.h-Bridging-Header.h を参照している :tada:
  • 本体アプリは objective-c と Swift 3.0 の両方を使用中

移行完了までにやったこと

1. TodayExtension の -Prefix.pch を作成

  • TodayExtensionでも -Prefix.pch を作成する。そして、本体アプリで使用しており、かつ TodayExtension でも使用したい objective-c のヘッダーファイルを書いておく
  • 次に TodayExtension でも使用したい objective-c のクラスを、本体だけでなく TodayExtension でもビルドの対象にする。
  • このとき Target Membership にチェックを入れるのは実装ファイル(.m)のみでOK
実装ファイル(.m) の Target Membership にチェック

2. TodayExtension の -Bridging-Header.h を作成

  • 全てのファイルを一度に Swift へ移行するとバグやデグレする可能性が高いので、一つ一つ順番に Swift へ移行していく
  • -Bridging-Header.h を作成して TodayExtension の全てのヘッダーファイルを -Bridging-Header.h に書いておく
  • Swift にしたものから順にコメントアウトして、最後に -Bridging-Header.h ごと削除すれば安全に移行できる

3. Swiftにする

  • 黙々と TodayExtension のソースを Swift に書き換える
  • -Swift.h-Prefix.pch に書いておき、objective-c のクラスに import する手間を省く

4. -Prefix.pch-Bridging-Header.h-Swift.h の参照先を変更

  • TodayExtension を Swift に書き換えた後、-Prefix.pch-Bridging-Header.h-Swift.h の参照先を本体アプリのものに変更する
  • 参照先の変更は TARGETS の TodayExtension > Build Settings > Basic > Combined から検索すれば、下記の項目がヒットする
-Prefix.pchの参照先 -Bridging-Header.h と -Swift.h の参照先
  • これで本体アプリと TodayExtension が共通して同じファイルを参照するため、TodayExtension の -Prefix.pch-Bridging-Header.h-Swift.h は不要になる
  • これで無事移行完了、お疲れ様でした

番外編:TodayExtension の Cell に View がうまく表示されない

Swiftへの移行とは関係ないけど、TodayExtension で少し困ったことがあった。本体アプリで表示したいグラフを TodayExtension の Cell に表示しようとするが、動作が不安定でうまく Cell に表示されない (たまに、うまく表示されたりもするから、やっかいだった)。

TodayExtension のメモリは限られたものしか割り当てられないので、重い処理などは推奨されていない。けど、TodayExtension にグラフを表示したい。そこで、直接グラフのカスタムViewを Cell に利用するのではなく、 UIGraphicsBeginImageContextWithOptionsUIImage に書き出して、それを TodayExtension の cell.imageView?.image に利用することでうまくいった。

GraphView
func image() -> UIImage? {

    self.backgroundColor = .clear
    UIGraphicsBeginImageContextWithOptions(self.frame.size, false, UIScreen.main.scale)
    let context = UIGraphicsGetCurrentContext()
    self.layer.render(in: context!)
    let image:UIImage = UIGraphicsGetImageFromCurrentImageContext()!

    return image
}
TodayExtensionのUITableViewCell
self.imageView?.image = graphView.image()

最初は UIGraphicsBeginImageContextWithOptions の処理が重かったりして上手くいかないかもと思い、UserDefault にグラフの画像を保存しておき、 TodayExtension ではそれを利用する方法をとってみたが、そこまでしなくても、直接Viewから、UImage を作成して TodayExtension 側に渡すだけでうまく表示できた。

グラフなどの複雑なカスタムViewを TodayExtension に表示したいけど、うまく表示できない場合、UIGraphicsBeginImageContextWithOptionsUImage にして利用すれば上手くいくかもしれません。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2