4

I have a library class wrote in swift which should be used in my existing objective-c code. I have created the bridging-header and have define @class MySwiftClass in .h and import "-Swift.h" in .m

a swift class is something similar to this

@objc class MySwiftClass: NSObject {
    var firstName : String
    var lastName: String

    public init(firstName: String, lastName: String) throws {
        guard !firstName.isEmpty && !lastName.isEmpty else { throw SOME_ERROR }
        self.firstName = firstName
        self.lastName = lastName
        super.init()
    }


func methodWithParams(city: String, suburb: String) throws -> String {
        return city + suburb
    }

I have faced two problems.

  1. Don't know how to call swift init function on the objective-c class. I have tried MySwiftClass *myClass = [MySwiftClass init];. Up to this, the app can compile. But don't know how to pass the parameters.

  2. I also want to access myClass.methodWithParams(city:"My city", suburb:"My country") in objective-c class.

Appreciate the help!

1
  • The first thing you need is to add @objc to the methods which should be visible from Objective-C. Commented Oct 3, 2018 at 8:00

2 Answers 2

7
  1. You must call alloc before init call.

    MySwiftClass* instance = [[MySwiftClass alloc] initWithFirstName: @"John" lastName: @"Doe"];
    
  2. Mark method with @objc or use @objcMembers to make your method exposable from Objective-C code. And unfortunately you can't user throwable initializers in Objective-C.

    @objcMembers class MySwiftClass: NSObject {
        var firstName : String
        var lastName: String
    
        public init(firstName: String, lastName: String) throws {
            guard !firstName.isEmpty && !lastName.isEmpty else { throw SOME_ERROR }
            self.firstName = firstName
            self.lastName = lastName
            super.init()
        }
    
        func methodWithParams(city: String, suburb: String) throws -> String {
            return city + suburb
        }
    }
    
Sign up to request clarification or add additional context in comments.

2 Comments

You can use throwable initialisers from Objective-C - the signature just has an extra NSError ** error parameter
@lgzar Thanks a lot for the detailed answer. Keep it up.
1

To instantiate an object in Objective-C…

NSError *error = NULL;
MySwiftClass *class = [[MySwiftClass alloc] initWithFirstName: @"John"
                                                     lastName: @"Smith" 
                                                        error: &error]

to call the method

[class methodWithParamsWithCity: @"My CIty" suburb: @"My suburb" error: &error];

throws in Swift appends an NSError ** error parameter in Objective-C

3 Comments

Here it would be [[MySwiftClass alloc] initWithFirstName:@"first" lastName:@"last" error:&error] since the init method throws as well.
This is me digging back into my 4 years old Objective-C memory - I knew that, but thought I was going crazy when testing it out it wasn't compiling. I thought maybe something had changed in the Obj-c world that had passed me by. It was the missing @objc
I have accepted lgzar's answer only because of @objcMembers.Sice I cannot accept two answers, I have given +1 to your's since both help me to resolve the problem. Thanks a lot

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.