This code is from a Swift project App delegate. It is used to help configure Stripe with a publishable key.
//Appdelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:
[UIApplicationLaunchOptionsKey: Any]?) -> Bool
{
//The code helps configure Stripe with a publishable key.
STPPaymentConfiguration.shared().publishableKey = Constants.publishableKey
...
}
Two errors are displayed when building the app after adding the Swift line to the Objective C App Delegate
//AppDelegate.h
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
STPPaymentConfiguration.shared().publishableKey = Constants.publishableKey
Property 'shared' not found on object of type 'STPPaymentConfiguration'
Use of undeclared identifier 'Constants'
This was a similar error in compiling before @objc
was added to the demo Swift function, MockApiClient. Should it be added elsewhere? I’ve tried adding @objc
to the enum as mentioned in the answer here to no avail yet.
//Constants.swift
//This is the file the original Swift app delegate accesses
import Foundation
enum Constants {
static let publishableKey = "pk_live_..."
static let baseURLString = "http://54.33.123.227:1234"
static let defaultCurrency = "usd"
static let defaultDescription = "Receipt" //change to describe actual app & charge
}
Steps taken:
-
Opened the Objective C project and created a bridging header
-
Created a demo class in Swift while still in the Obj C project to make sure it can be used, in this case to print from an Objective C file when the view is loaded. Specifically derived from an NSObject. Adding the override to the initializer and using the
@objc
prefix.// MockApiClient.swift import Foundation class MockApiClient: NSObject { override init() { print("Initializer called in Mock API client") } @objc func executeRequest() { print("The execute request has been called in the Mock API Client") } } //ViewController.h //Prints the Swift request written in the MockApiClient the the view loads @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. MockApiClient *client = [MockApiClient new]; [client executeRequest]; }
-
Copied the
#import "ViewController.h"
import to the automatically generatedproject-Bridging-Header.h
file to expose the Objective C in it to swift -
Added the necessary Swift files to the Objective C project so that the
Constants.publishablekey
data fromConstants.swift
can be found
How can this Swift App delegate code be added to the App delegate of an Objective C project?
Edit: error when adding @objc
to the enum
declaration in Constants.swift
2
Answers
The ability of Objective-C to see things defined in Swift depends on the automatically generated header file. This is not the bridging header. It is a header file buried in your derived data called YourProject-Swift.h. Your Objective-C .m file needs to
#import "YourProject-Swift.h"
(using the correct name).Then, your Swift things need to get into that file. For that to happen, they need to be of a type that Objective-C can see at all (i.e. classes) and they need to be explicitly exposed to Objective-C with appropriate
@objc
attributes.Swift enums used as namespace cannot be exposed to Objective-C.
You may need to use
class
to make it work both for Swift and Objective-C: