3

I am trying to use a popular swift library, Siren, in an iOS Objective-C application. I have included the library as a framework using cocoapods, I ran pod init and then pod install with a podfile like this:

# Uncomment the next line to define a global platform for your project
platform :ios, '9.0'

target 'MyObjectiveCApp' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for MyObjectiveCApp
  pod 'Siren'

end

and I've imported the swift code into the AppDelegate.m file like so:

#import <Siren/Siren-Swift.h>

I can now access the Siren class, but I can't seem to reference the shared static property on the Siren class. I have tried [Siren shared] and Siren.shared but neither is working. Here is the first few lines of the Siren class:

import UIKit

/// The Siren Class.
public final class Siren: NSObject {
    /// Return results or errors obtained from performing a version check with Siren.
    public typealias ResultsHandler = (Result<UpdateResults, KnownError>) -> Void

    /// The Siren singleton. The main point of entry to the Siren library.
    public static let shared = Siren()

Is there any documentation or examples of using Siren in an Objective-C iOS application? Is this possible? I know I could use Harpy, but since it is no longer supported, I was trying to avoid it if possible. I have researched using Swift in Objective-C code, but I couldn't find anything specifically related to accessing a static let property on a class. I found this helpful answer, but it mentions global variables, not static class properties.

mogelbuster
  • 1,066
  • 9
  • 19
  • @AndreiKonstantinov I tried `@import Siren;`, but I am getting the same errors. I also tried `#import "Siren-Swift.h"` with the same errors. If I don't include any of those 3 import statements, the `Siren` class isn't recognized at all, which is expected, but it proves those statements are doing something. – mogelbuster Jun 03 '19 at 21:15
  • @AndreiKonstantinov Yes I believe so. I added `@import Siren`, commented out the other import statement, commented out all references to Siren in objective-c, Cleaned the App, Built the App (successfully), added `[Siren shared];` back in, Built the App, and got the error `No known class method for selector 'shared'` – mogelbuster Jun 03 '19 at 21:23

1 Answers1

2

The reason why you can't access shared property, is because it doesn't get exported to Siren-Swift.h header (you can check generated header file).

That's because Siren class is not explicitly marked as @objc. The class itself is exported, because it's subclass of NSObject, but the properties are not exported by default. I think we can't solve it on our own.

What we can do is a workaround:

  • Let the author know via GitHub issue;
  • In meantime you can make your own Swift class-wrapper that direct every call to Siren under the hood, create internal pointer to Siren.shared, copy-paste all getters-setters from Siren, proxy calls to real Siren.shared;
  • Mark your class as @objc;
  • When (and if) author will solve the issue , you can update Siren, delete your class-wrapper and call Siren directly.
Andrei Konstantinov
  • 6,971
  • 4
  • 41
  • 57
  • Thank you so much for your answer! I can confirm this works! I opened a [github issue about this](https://github.com/ArtSabintsev/Siren/issues/290). Hopefully it will turn into a feature of the library. This is also great advice for any Swift library that is incompatible with Objective-C. – mogelbuster Jun 04 '19 at 17:13
  • Maybe the author do not want change it. He says: "Unfortunately, your use case is one that doesn't follow the 80-20 rule. While I understand that many projects exist that are 100% Objective-C, or that have mixed codebases, I don't believe that language is the future of the iOS platform." – Ignacio Hernández Aug 06 '20 at 19:06