LoginSignup
3
0

More than 5 years have passed since last update.

NYTPhotoViewerの1.2→2.0で遭遇したエラーの解決方法

Last updated at Posted at 2018-02-09

はじめに

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では、

NYTPhotosViewController.m
- (instancetype)initWithPhotos:(NSArray *)photos {
    return [self initWithPhotos:photos initialPhoto:photos.firstObject delegate:nil];

というメソッドだったものが、新しい方ではこのメソッドにリプレースされていました。

NYTPhotosViewController.m
- (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は割愛できるので、ここでは省略して進みます。)

PhotoViewerCoordinator.swift
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)

と書き換えてあげれば、今までのように使えますね。

3
0
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
0