はじめに
Swift3に移行したところかなり仕様が変わったものがあったのでまとめておきます。
URL(旧NSURL)
URLのStringを取り出したい時、今まではURLString
プロパティでしたが、Swift3からabsoluteString
になりました(自動コンバートに引っかからないので公式ですが一応念のため)
Alamofire
こちらが
Alamofire.request(.GET, URLの文字列, parameters: nil)
こうなります。
Alamofire.request(URLの文字列)
SDWebImage
細かいところですがSDWebImageDownloaderCompletedBlockの型が自動変換では変えられませんでした。
(UIImage!, NSData!, NSError!, Bool!) -> Void
これが
(UIImage?, NSData?, NSError?, Bool) -> Void
になります。
Realm
allObject
の第一引数名としてofType
、sortedの第一引数としてonProperty
が採用されています。またofType
に指定する型に関しては特別にselfプロパティを渡さなければいけなくなりました。例えばclass DataList: Object
に関してidでソートしたデータを取り出したい場合は
realm.objects(DataList.self).sorted(byProperty: "id")
というように書きます。
RxSwift
結構変わっています。
まず基本的に今までrx_tap
やrx_text
というようになっていましたが、これがすべてrx.tap
やrx.text
のようにrxの子プロパティ(といえば良いんでしょうか...?)に変わっています。
またRxExampleの中のImagePickerを呼び出すサンプルに関して、今までは
extension UIImagePickerController {
static func rx_createWithParent(_ parent: UIViewController?, animated: Bool = true, configureImagePicker: (UIImagePickerController) throws -> () = { variable in }) -> Observable<UIImagePickerController> {
return Observable.create { [weak parent] observer in
let imagePicker = UIImagePickerController()
let dismissDisposable = imagePicker
.rx_didCancel
.subscribeNext({ [weak imagePicker] in
guard let imagePicker = imagePicker else {
return
}
dismissViewController(imagePicker, animated: animated)
})
do {
try configureImagePicker(imagePicker)
} catch let error {
observer.on(.Error(error))
return NopDisposable.instance
}
guard let parent = parent else {
observer.on(.completed)
return NopDisposable.instance
}
parent.present(imagePicker, animated: animated, completion: nil)
observer.on(.next(imagePicker))
return CompositeDisposable(dismissDisposable, AnonymousDisposable {
dismissViewController(imagePicker, animated: animated)
})
}
}
}
このようなExtensionを書き、
UIImagePickerController.rx_createWithParent(self) { picker in
picker.sourceType = .photoLibrary
picker.allowsEditing = true
}
というように呼び出していましたが、これが
extension Reactive where Base: UIImagePickerController {
static func createWithParent(_ parent: UIViewController?, animated: Bool = true, configureImagePicker: @escaping (UIImagePickerController) throws -> () = { x in }) -> Observable<UIImagePickerController> {
return Observable.create { [weak parent] observer in
let imagePicker = UIImagePickerController()
let dismissDisposable = imagePicker.rx
.didCancel
.subscribe(onNext: { [weak imagePicker] in
guard let imagePicker = imagePicker else {
return
}
dismissViewController(imagePicker, animated: animated)
})
do {
try configureImagePicker(imagePicker)
} catch let error {
observer.on(.error(error))
return Disposables.create()
}
guard let parent = parent else {
observer.on(.completed)
return Disposables.create()
}
parent.present(imagePicker, animated: animated, completion: nil)
observer.on(.next(imagePicker))
return Disposables.create(dismissDisposable, Disposables.create {
dismissViewController(imagePicker, animated: animated)
})
}
}
}
と書いて、
Reactive<UIImagePickerController>.createWithParent(self) { picker in
picker.sourceType = .camera
picker.allowsEditing = false
}
このように呼び出すようになりました。これは推奨というわけではなくこう書かなければ自動変換だとここまで直してくれません...汗
Swifter
Twitter関連を作る人には大分使われるものだと思いますが、こちらが大幅に変更されました。最近masterにswift3ブランチがマージされて、今pullしてしまうとこのバージョンになってしまうのでSwift3を使ってない人は注意してください。
こちらは変更点が大きいので少しまとめたいと思います。
① SuccessHandler型, FailureHandler型の導入
全てのsuccessHandlerとfailureHandlerがそれぞれSuccessHandler
型、FailureHandler
型に統一されました。それぞれ(JSON) -> Void
と(Error) -> Void
のtypealiasなのでクロージャーの宣言を変えましょう。
② JSONValueが廃止されJSONに統一
JSONValue
が無くなりすべてJSON
となりました。SuccessHandler
ではすべてこのJSON
型で返ってくるため、今までDictionaryで返ってきていたところはstatus.object
、配列で返ってきていたところはstatus.array
とその中から取り出す形となります。
③ UserTag、ListTagの導入
今までメソッドによって分けられていたIDやスクリーンネームなど二つの指定の仕方があるユーザーやリストに関してこのタグを使うことでメソッドが一元化されました。
例えばIDでユーザーの情報を取りたい場合などは.id(IDの文字列)
というものを引数として渡すことでメソッドが実行できます。
④ 以上の変更を経てメソッド名の大幅変更
①〜③の変更をうけてメソッド名と使い方が変わりました。短く、直感的なものになっています。
用途とメソッド名のみリストにしてもいいのですが、とりあえずどれがどう対応するのかというのも確認しようということで、旧バージョンに関しても載せたいと思います。
用途 | Swift3版 | Swift2版 |
---|---|---|
タイムライン取得 | getHomeTimeline(count: 個数, success: successHandler, failure: failureHandler) |
getStatusesHomeTimelineWithCount(個数, success: successHandler, failure: failureHandler) |
メンション一覧取得 | getMentionsTimlineTweets(count: 個数, success: successHandler, failure: failureHandler) |
getStatusesMentionTimelineWithCount(個数, success: successHandler, failure: failureHandler) |
リストタイムライン取得 | listTweets(for: ListTag, success: successHandler, failure: failureHandler) |
getListsStatusesWithListID(ID文字列, success: successHandler, failure: failureHandler) |
ユーザータイムライン取得 | getTimeline(for: UserTag, count: 個数, success: successHandler, failure: failureHandler) |
getStatusesUserTimelineWithUserID(ID文字列, count: 個数, success: successHandler, failure: failureHandler) |
リスト一覧 | getSubscribedLists(for: UserTag, success: successHandler, failure: failureHandler) |
getListsSubscribedByUserWithScreenName(screenName, success: successHandler, failure: failureHandler) |
ツイート情報取得 | getTweet(forID: ID文字列, success: successHandler, failure: failureHandler) |
getStatusesShowWithID(ID文字列, success: successHandler, failure: failureHandler) |
ユーザー情報取得 | showUser(for: UserTag, success: successHandler, failure: failureHandler) |
getUsersShowWithScreenName(screenName, success: successHandler, failure: failureHandler) |
フォロー | (for: UserTag, success: successHandler, failure: failureHandler) |
postCreateFriendshipWithID(ID文字列, success: successHandler, failure: failureHandler) |
リムーブ | unfollowUser(for: UserTag, success: successHandler, failure: failureHandler) |
postDestroyFriendshipWithID(ID文字列, success: successHandler, failure: failureHandler) |
ツイート | postTweet(status: tweetText!, inReplyToStatusID: replyID, media_ids: mediaIds, success: successHandler, failure: failureHandler) |
postStatusUpdate(tweetText!, media_ids: mediaIds, inReplyToStatusID: replyID, success: successHandler, failure: failureHandler) |
ツイート削除 | destroyTweet(forID: ID文字列, success: successHandler, failure: failureHandler) |
postStatusesDestroyWithID(ID文字列, success: successHandler, failure: failureHandler) |
お気に入り | favouriteTweet(forID: ID文字列, success: successHandler, failure: failureHandler) |
postCreateFavoriteWithID(ID文字列, success: successHandler, failure: failureHandler) |
お気に入り削除 | unfavouriteTweet(forID: ID文字列, success: successHandler, failure: failureHandler) |
postDestroyFavoriteWithID(ID文字列, success: successHandler, failure: failureHandler) |
リツイート | retweetTweet(forID: ID文字列, success: successHandler, failure: failureHandler) |
postStatusRetweetWithID(ID文字列, success: successHandler, failure: failureHandler) |
ブロック | blockUser(for: UserTag, success: successHandler, failure: failureHandler) |
postBlocksCreateWithScreenName(screenName, success: successHandler, failure: failureHandler) |
通報 | reportSpam(for: UserTag, success: successHandler, failure: failureHandler) |
postUsersReportSpamWithScreenName(screenName, success: successHandler, failure: failureHandler) |
以上です。見ていただいて分かる通りSwifterだけでかなりのボリュームなのでそれで記事を作っても良かったのですが、せっかくだということで使っているいくつかのライブラリに関しても紹介させていただきました。
このようにサードパーティのライブラリひとつとってもSwift3への変更はかなり大きいものなのでしっかり対応できるように頑張っていきましょう。