Search code examples
iosobjective-cswiftlanguage-interoperability

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


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.


Solution

  • 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)];