"No known class method for selector" when using static Swift method on Objective-c

Miguel Guerreiro picture Miguel Guerreiro · Aug 29, 2016 · Viewed 10k times · Source

I have been given Objective C code and I need to add extra functionalities to it. I am very unfamiliar with Objective C so doing the most I possibly could on Swift would be very optimal for me.

This is my Swift file/class:

import Foundation
import UIKit

@objc class ImageBarSize: NSObject{

  static func changeContadorImageSize(img:UIImage, newSize:CGSize) -> UIImage{
    UIGraphicsBeginImageContextWithOptions(newSize, true, 0.0)
    let x:CGFloat = 0
    let y:CGFloat = 0
    img.draw(in: CGRect(x:x,y:y,width:newSize.width,height:newSize.height))
    let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    return newImage;
  }
}

And this is the code on my Objective C .m file:

 imgBarCounter = [UIImage imageNamed:@"bar-counter-pd.png"]; 

 self.image = [ImageBarSize changeContadorImageSize:imgBarCounter newSize:CGSizeMake(300, 300)];

I get the Error "No known class method for selector 'changeContadorImageSize:newSize:'".

I did the whole bridging process and I have

 #import <WHS_Live_2-Swift.h>

At the beginning of the file, and it all seems to be working fine. I've looked through what seemed like similar error threads here on SO, but to no avail.

Answer

OOPer picture OOPer · Aug 30, 2016

Seeing this line, you are using Swift 3.

img.draw(in: CGRect(x:x,y:y,width:newSize.width,height:newSize.height))

In Swift 3, the first parameter is also treated as having argument label.

Establish consistent label behavior across all parameters including first labels (SE-0046)

You can check how they are exported to Objective-C by Command-clicking on #import <YourProjectName-Swift.h>. (You may need to wait till Xcode finishes Indexing.)

Tested in Xcode 8 beta 6, your class method becomes like this:

+ (UIImage * _Nonnull)changeContadorImageSizeWithImg:(UIImage * _Nonnull)img newSize:(CGSize)newSize;

So, you may need to call it like this:

self.image = [ImageBarSize changeContadorImageSizeWithImg:imgBarCounter newSize:CGSizeMake(300, 300)];

Or, you can change the Swift method as:

static func changeContadorImageSize(_ img:UIImage, newSize:CGSize) -> UIImage{

Then you can call it as in the original form:

self.image = [ImageBarSize changeContadorImageSize:imgBarCounter newSize:CGSizeMake(300, 300)];