28

I am making the following call using SDWebImage on my imageView, which works fine with Swift 2 but gives an error with XCode 8 beta 5 compiling with Swift 3:

 imageView.sd_setImage(with:url, placeholderImage:placeholder, completed: {
    (image: UIImage?, error: Error?, cacheType: SDImageCacheType, imageURL: URL?) in
            ...
    });

The error is:

Ambiguous use of 'sd_setImage(with:placeholderImage:completed:)'

I suspect I have something wrong in the signature for the completed handler, but I can't figure out what the syntax should be. What am I missing?

Ronak Chaniyara
  • 5,335
  • 3
  • 24
  • 51
carloshwa
  • 1,254
  • 2
  • 11
  • 12

2 Answers2

58

The Swift compiler translates the ObjC headers into Swift which leads to naming collisions:

UIImageView+WebCache.h:

o1) - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock;

o2) - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock;

Their only difference is the additional optionsparameter in o2.

Generated Swift declaration:

s1) open func sd_setImage(with url: URL!, placeholderImage placeholder: UIImage!, completed completedBlock: SDWebImage.SDWebImageCompletionBlock!)

s2) open func sd_setImage(with url: URL!, placeholderImage placeholder: UIImage!, options: SDWebImageOptions = [], completed completedBlock: SDWebImage.SDWebImageCompletionBlock!)

Because options was translated into an optional parameter (default assigned an empty array) calling s1 in Swift leads to an ambiguous use. Calling s2 could simply have the same implementation. When providing such methods in Swift code one would add the options parameter as optional in a single function implementation.

Workaround

As a workaround the options parameter could be set or o1 or o2 could be renamed temporarily until SDWebImage will be translated into Swift.

M_G
  • 1,208
  • 1
  • 11
  • 16
  • 11
    Good spot. Thank you. In addition here is the lien, that fixes temporary the collision issue: yourImageView.sd_setImage(with: yourUrl, placeholderImage: yourPlaceholderImage, options: SDWebImageOptions(), completed: yourImageTransitionCompletitionBlock) – dzensik Sep 26 '16 at 14:47
19

Adding SDWebImageOptions to the method call fixes the issue:

imageView.sd_setImage(with: someUrl,
          placeholderImage: someImage,
                   options: [], 
                 completed: someCompletitionBlock)
budiDino
  • 13,044
  • 8
  • 95
  • 91
  • 1
    I was using Swift inside objective-c project. Renaming stuff was not at all a option as previous Objective-C code was also using those methods. Your solution is perfect for my type of scenario – Rohan Sanap Mar 15 '18 at 10:51