はじめに
NYTimesの画像ビュワーOSS、NYTPhotoViewerを使っています。
バージョンを1.2.0→2.0.0に上げたところ、やっぱりひっかかったので、その解決方法をメモします。
要点
古いNYTPhotoViewerでは、直接NYTPhotoプロトコルを採用したクラスの配列をデータソースに使えた。しかし、新しいバージョンでは、
NYTPhotoViewerDataSourceプロトコルを採用したcoordinatorにNYTPhotoのデータをセットする考え方に変わった。このため、coordinatorを使う方式に書き換える必要がある。
遭遇したエラー
let photo = MyPhoto()
photo.image = image
let vc = NYTPhotosViewController(photos: [photo])
present(vc, animated: true, completion: nil)
という感じの3行目のNYTPhotosViewController()の箇所で
Argument labels ‘(photos:)’ do not match any available overloads
というエラーが発生しました。
インターフェース仕様が変更されたということですが、単なるリネームではなさそうです。
(ちなみに、MyPhotoはNYTPhotoプロトコルを採用している画像のデータソースです。)
解決
エラーが発生したメソッドをたどると、古いほうのNYTphotosViewController.mでは、
- (instancetype)initWithPhotos:(NSArray *)photos {
return [self initWithPhotos:photos initialPhoto:photos.firstObject delegate:nil];
というメソッドだったものが、新しい方ではこのメソッドにリプレースされていました。
- (instancetype)initWithDataSource:(id <NYTPhotoViewerDataSource>)dataSource {
return [self initWithDataSource:dataSource initialPhoto:nil delegate:nil];
}
従来は直接NYTPhotoプロトコルを採用したクラスの配列をデータソースに使えたのですが、新しいNYTPhotoViewerでは、
NYTPhotoViewerDataSourceプロトコルを採用したcoordinatorにNYTPhotoのデータをセットして、coordinatorを渡す発想になっています。
ですので、今までなかったcoordinatorを作れば、解決です。(公式Sampleにいう、PhotoViewerCoordinator.swift)
キモは、NYTPhotoViewerDataSourceプロトコルを採用すること。
要点を示すために、NYTPhoto一枚分を表示することに特化したcoordinatorを示します。
(なお、公式Sampleでは、NYTPhotoBoxというクラスも登場しますが、画像を1枚だけ見せたいという簡易な場合はNYTPhotoBoxは割愛できるので、ここでは省略して進みます。)
class PhotoViewerCoordinator: NYTPhotoViewerDataSource {
private var photos: [NYTPhoto]?
lazy var photoViewer: NYTPhotosViewController = {
return NYTPhotosViewController(dataSource: self)
}()
init(photos: [NYTPhoto]?) {
self.photos = photos
}
@objc
var numberOfPhotos: NSNumber? {
return NSNumber(integerLiteral: 1)
}
@objc
func index(of photo: NYTPhoto) -> Int {
return 0
}
@objc
func photo(at index: Int) -> NYTPhoto? {
return photos?.first
}
}
使うところでは、
let photo = MyPhoto()
photo.image = image
let coordinator = PhotoViewerCoordinator(photos: [photo])
let vc = NYTPhotosViewController(dataSource: coordinator)
present(vc, animated: true, completion: nil)
と書き換えてあげれば、今までのように使えますね。