15

For example I have this method in swift:

@objc class MyClass: NSObject
....
@objc class func viewWithIndex(index: Int, str: String) {
    println(index, str)
}

then i wanna call that method in my objective-c class, and i was expecting as simple as this call [MyClass viewWithIndex:10 str:@"string"]; but it doesn't work.

How do i call it? Please help.

Note: I have already a working swift function call to objective-c [MyClass showSomething]; so that means i have successfully setup necessary settings to bridge classes. Only the function that has two of more parameters is my problem. :)

Solved:

I dont know what i happened but i just restarted my mac and removed objc and it worked with the call [MyClass viewWithIndex:10 str:@"string"];. I remember reading in documentation.

Migrating Your Objective-C Code to Swift

  • To be accessible and usable in Objective-C, a Swift class must be a descendant of an Objective-C class or it must be marked @objc.
6
  • What doesn't work? Do you have a compile-time error or a runtime error? Commented Sep 17, 2014 at 9:48
  • Is your Swift class a subclass of NSObject? Compare stackoverflow.com/questions/25605677/…. Commented Sep 17, 2014 at 9:51
  • I have a working swift function call to objective-c class already but without a parameter or just one parameter. now i want to try two or more parameter. the error it make is No Known class method for selector viewWithIndex:str Commented Sep 17, 2014 at 9:59
  • Did you do #import YOUR_PROJECT_NAME-Swift.h ? Commented Sep 17, 2014 at 11:01
  • i already did import that and made the bridge header file. Commented Sep 18, 2014 at 0:58

3 Answers 3

17

This worked for me in Swift 3.0

public class func viewWithIndex(_ index: Int, str: String) {
    println(index, str)
}

Adding the underscore before the first parameter in the Swift declaration allowed me to call from objective c without naming the first parameter, like this:

[MyClass viewWithIndex:10 str:@"string"]
Sign up to request clarification or add additional context in comments.

3 Comments

What does the underscore at the start of the method's parameters list actually do? ..viewWithIndex(_ index... I can confirm this works for me too, but what's going on here? Does this token have a name in this context?
@JamesTSnell The _ determines whether or not the parameter name should be used when calling the method. In the example above, even calling that method from swift would look something like this: className.viewWithIndex(10, str: "test"). If the method definition had the _ before both index and str, then the method call would look like this: className.viewWithIndex(10,"test")
Is it not possible to call a swift function where all parameters are named?
4

I believe you'll need to mark the function as either public (makes sense) or dynamic. Otherwise it will be a candidate for Swift's optimization (inline or vtable the method) which will make it invisible to Objective-C.

Try this:

public class func viewWithIndex(index: Int, str: String) {
    println(index, str)
}

Or this: (doesn't really make sense, but should also work)

private dynamic class func viewWithIndex(index: Int, str: String) {
    println(index, str)
}

4 Comments

i dont know what happened but when i turned on my mac this morning and removed @objc it just work properly with the call [MyClass viewWithIndex:10 str:@"string"];
OK, it must be the method is already using dynamic dispatch. When its not, I've found the above approach works. . the same rules for the guide on working with KVO in Swift should apply.
i guess i dont need public or dynamic or etc coz i have my class subclass to NSObject.
As of Xcode6 beta 6, Swift can still inline/vtable methods/vars on NSObject subclasses. This definitely applies to private vars (which makes sense), but if you have a case where you want it to be private except to the Objective-C runtime, you can add the 'dynamic' modifier.
1

forward declaration of your class in .h file of objective-c

@class <MySwiftClass>

import "Productname-swift.h" in obj-c .m class use

[SwiftClass storeWithData:@"Hi" password:@"secret"];

SwiftClass.swift

@objcMembers class SwiftClass{
   public class func store(data: String,password:String)->Bool{
    let saveSuccessful: Bool = KeychainWrapper.standard.set(data, forKey: password)
    return saveSuccessful;
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.