0

Goal: To use Swift Package within Objective-C.
All I'm trying to do is to have a simple, rudimentary understanding of the correct syntax of access Swift vars & func() from ObjC.

This is the second part of questions about using Objective-C with a Swift package.

enter image description here

Here's my Swift Package file that I'm trying to access...
I'm concentrating on the Swift class access.
But I would also like to know how to access the struct.

import Foundation

public struct RicStruct {
    public private(set) var text = "Hello, World!"

    public init() {
    }
    
    public func sayHello() -> String {
        "Hello Ric!"
    }
}

public class RicClass: NSObject {
    @objc public var msg = "Mother has a feeling, I might be too appealing."
    @objc public let text = "Hello Everybody!"
    
    public override init() {}
    
    public func sayHello() {
            print(text)
        }
    
    public func doSomething() {
        print("Inside doSomething()")
    }
}

This is the Objective-C parent attempting to access the Swift-Package vars & func:

enter image description here

Question: What's the proper syntax of accessing:

  1. the Swift class & struct functions,
  2. the Swift var/let?
Frederick C. Lee
  • 9,019
  • 17
  • 64
  • 105
  • 1
    Swift structs cannot be accessed from Objective-C. You need to convert them to classes, or create a bridging class. Classes must be marked with `@objc`. And in Obj C `....m` file, you need to `#import ` – timbre timbre Jul 31 '21 at 17:01
  • Good to know. Accessing Swift struct is purely academic, not needed. – Frederick C. Lee Jul 31 '21 at 17:03
  • have a look at this useless project that does some in and out to swift, from swift, calling cpp, objC etc.. its a mess but it shows what is needed.. in particular all in this folder https://github.com/designerfuzzi/CombineCppSwiftObjcInStaticLib/tree/main/CombineCppSwiftObjcInStaticLib/Hub_lib – Ol Sen Jul 31 '21 at 17:04
  • Have you tried to use Xcode's autocompletion? It might suggest something and if it doesn't, then something's wrong somewhere else. – mojuba Jul 31 '21 at 17:04
  • I've tried autocompletion which didn't show anything. Hence the query. I'm trying to create an elementary ObjC->Swift Package scenario for posterity/reference. – Frederick C. Lee Jul 31 '21 at 17:07
  • Also generally, I suggest to just follow apple's guide here: https://developer.apple.com/documentation/swift/imported_c_and_objective-c_apis/importing_swift_into_objective-c – timbre timbre Jul 31 '21 at 17:07

2 Answers2

3

You declared

public func sayHello() {
    print(text)
}

That makes the method sayHello public across module, but it does not expose it to Objective-C. Instead:

@objc public func sayHello() {
    print(text)
}
matt
  • 515,959
  • 87
  • 875
  • 1,141
0

I didn't add the '@objc' qualifier to the Swift function.
I had mistakenly thought that it's not necessary due to being a member of a NSObject class per class declaration.

Also, didn't need to add the .h ObjC <--> Swift bridge file.

enter image description here

Frederick C. Lee
  • 9,019
  • 17
  • 64
  • 105
  • not wrong, depending on your project. But matt's solution is more simple. `@objc`exists not only to expose it, it is used to have fine control what is exposed and how the exposed method should be named to avoid clashes – Ol Sen Jul 31 '21 at 17:23
  • and the tricky part is that exposing objC->swift generates an IDE visible file named projectnameBridging-Header.h to control it, but the other way exposing swift->objc is an "virtual" autogenerated h.file from your @objc marks that has to be imported on the objc side or objc++ side – Ol Sen Jul 31 '21 at 17:32
  • like here https://github.com/designerfuzzi/CombineCppSwiftObjcInStaticLib/blob/a653d401a20346b01c5dbd23a8e252df1abb2ff4/CombineCppSwiftObjcInStaticLib/Hub_lib/Hub_lib.mm#L12 this file does actually not exist, it is autogenerated and is only working because of the @objc marks – Ol Sen Jul 31 '21 at 17:34