まえおき
ふたつほど、マイクロライブラリを公開しています。
Notifwift: NSNotificationCenter wrapper for Swift
https://github.com/takasek/Notifwift
ActionClosurable: Extensions which helps to convert objc-style target/action to swifty closures
https://github.com/takasek/ActionClosurable
これらをSwift2.3/3.0に対応させていった手順を、記録に残しておきます。
どう対応するか
branch
ふたつ用意しましょう。
- swift3.0用のbranch(masterでもいい)
- swift2.3用のbranch
ユーザーがどちらのbranch(タグ)も選べるようにしておかないといけないので、必ず並行でbranchを稼働させるようにしましょう。
コーディング
Xcodeで自動的にmigrationできて、コンパイルが通ったからそれでOK…
だなんて、思ってませんか?
Migration Guideを読もう
Swift.org - Migrating to Swift 2.3 or Swift 3 from Swift 2.2
公式のドキュメントをしっかり読んで、適切な実装について理解しましょう。
Notifwiftでは、Notification名をこれまでString型で受けていたAPIを、 Notification.Name
で受けるように変更しました。
後方互換性のためにStringのままにすることもできたのですが、あえて破壊的変更を選びました。
なぜなら、ガイドに次のような記述があったからです。
In Swift 3, many of Foundation’s “stringly-typed” APIs have been changed to use struct “wrapper types”, such as the new Notification.Name type. Since, it’s common for notification names and other string constants to be declared globally or as static members, the best way to take advantage of these new types is usually to construct the wrapper at the point of declaration:
static let MyGreatNotification = Notification.Name("MyGreatNotification")
// Use site (no change)
NotificationCenter.default().post(name: MyController.MyGreatNotification, object: self)'
アクセス修飾子もちゃんとしよう
これも、Xcodeの機械的なmigrationに任せるだけでなく、ちゃんと手を入れたい箇所。
Xcodeのmigrationに任せると、 public
だった修飾子が open
に変更されていまいます。
しかし、継承させたい意図がない場合はopenではなくpublicを使うべき。
同じく、その型の中でだけアクセスできればいいメンバについては、 fileprivate
ではなく private
を使いましょう。
ネーミングルールにこだわろう
Xcodeのmigrationでは、標準のAPIはmigrateできても、ライブラリのAPIはそのままです。
これをSwift3らしくリネームするかどうかは、あなた次第。
でも、かっこいいAPIにしたほうがいいんじゃないかなー。
Swift 3 その基本ルールを眺める #cswift
32ページ以降を読んでおくといいと思います
あるいはmono0926さんの
Swift API Design Guidelinesの紹介(Swift 3版) - Qiita
パッケージ管理対応
Carthage
何も罠がありませんでした。
素晴らしい。
CocoaPods
つらかったです。
CocoaPodsのバージョンは、 1.1.0 rc2
を使う
コマンドラインで案内が出てたので、深く考えずに以下を実行したのだけれど…
それだけだと使えませんでした。
CocoaPods 1.1.0.rc.2 is available.
To update use: `sudo gem install cocoapods --pre`
既にインストールされていたリリース版が優先されてしまったのです。
[Notifwift]@23:09 % pod --version
1.0.1
どうやればRC版を優先できるのか悩んだ結果…
"Quick and Dirty"
なやり方に従うことにしました。
How to use different CocoaPods versions · Bitrise
[Notifwift]@23:41 % gem uninstall --all --executables cocoapods
ERROR: While executing gem ... (Gem::InstallError)
cocoapods is not installed in GEM_HOME, try:
gem uninstall -i /Users/tksk_mba/.rvm/gems/ruby-2.2.1@global cocoapods
[Notifwift]@23:42 % gem uninstall -i /Users/tksk_mba/.rvm/gems/ruby-2.2.1@global cocoapods
Select gem to uninstall:
1. cocoapods-1.0.1
2. cocoapods-1.1.0.rc.2
3. All versions
> 1
Successfully uninstalled cocoapods-1.0.1
[Notifwift]@23:42 % pod --version
1.1.0.rc.2
(2016/10/5追記)
@kishikawakatsumiさんからコメントいただきました。
http://qiita.com/takasek/items/c42641ca1ca03bb2ee39#comment-951c31b3b3b8d49ca985
CocoaPods(に限らずRubyGems一般)のバージョンを使い分けるのはBundlerを使うのが便利です。
詳しい使用法はコメントをご参照ください。
.swift-version
を作る
CocoaPodsのtrunkは、そのライブラリのバージョンを判別する際に .swift-version
というファイルの内容を参照するようです。
これはechoコマンドを使えば、手っ取り早く作れます。
echo "2.3" > .swift-version
あるいは
echo "3.0" > .swift-version
あとはいつもの手順
- 最新のbranchにtagつけて、
-
pod lib lint
して、 pod trunk push
[Notifwift]@0:10 % pod lib lint (git)-[master]
-> Notifwift (1.0.0)
Notifwift passed validation.
[Notifwift]@0:14 % pod trunk push (git)-[master]
[!] Found podspec `Notifwift.podspec`
Updating spec repo `master`
Validating podspec
-> Notifwift (1.0.0)
Updating spec repo `master`
- Data URL: https://raw.githubusercontent.com/CocoaPods/Specs/65608e550b0c28061345a403759ce7cd7a812863/Specs/Notifwift/1.0.0/Notifwift.podspec.json
- Log messages:
- September 23rd, 00:15: Push for `Notifwift 1.0.0' initiated.
- September 23rd, 00:15: Push for `Notifwift 1.0.0' has been pushed (0.387305114 s).
[Notifwift]@0:16 %
Swift Package Manager
そんなに難しくないらしい?
余裕があれば。
自分は余裕なくなったので、またの機会にやります…。
すべて済んだら、
READMEをしっかり書こう
Swift2.3用branch、Swift3.0用branch、それぞれのREADMEに、最適化された形で次の情報があると親切です。
- Swift2.2バージョンからのAPI変更点のまとめ、あるいはmigrationの手順
- Cartfileに記述すべき内容
- Podfileに記述すべき内容
- Swift2.3用branchであれば、Swift3.0用branchへのリンク
- Swift3.0用branchであれば、Swift2.3用branchへのリンク
以上であなたのライブラリのSwift2.3/3.0対応は完了です。
お疲れ様でした。