How to access swift class in objective-c file - ios

I have a swift project and i import a singleton, objective-c coded class in the project.
I tried to import the productname_swift.h file but no luck.
How can i access swift class in that singleton class?

Project made in Swift : To use Swift class in Objective C
To use Swift class in Objective C , follow given steps :
Create one Objective C class named User.
A popup display with "Would You like to configure an Objective-C bridging Header". Choose Create Bridging Header.
User.h
#import <Foundation/Foundation.h>
#interface User : NSObject
+(id) sharedUser ;
#end
User.m
#import "User.h"
#import "SwiftInObjectiveC-swift.h"
#implementation User
//Singleton of User
+(id)sharedUser{
static User *sharedUser = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedUser = [[self alloc] init];
//Class Method of ViewController.swift
[ViewController mySwiftClassFunction];
//Instance Method of ViewController.swift
ViewController *vc = [[ViewController alloc] init];
[vc mySwiftFunction];
});
return sharedUser;
}
-(void) myObjcectivecMethod {
ViewController *vc = [[ViewController alloc] init];
[vc mySwiftFunction];
}
Add #objc in your .swift class in front of Class name.
import UIKit
#objc class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func mySwiftFunction() {
print("Swift Function")
}
class func mySwiftClassFunction (){
print("Swift Class Function")
}
}
Go to Build Settings.
Set Product Module Name : ProjectName
Set Defines Module : YES
Set Embedded Content Contains Swift : YES
Set Install Objective-C Compatibility Header : YES
Set Objective-C Bridging Header : SwiftInObjectiveC/SwiftInObjectiveC-Bridging-Header.h
Import Auto generated header "ProjectName-swift.h" in your *.m file.
Clean and Run your Project.
It will work!!!
Follow Apple link for Mix and Match for detailed information.

It is very simple use Swift classes in Objective-C. Just follow steps given below
Open your Objective-C project.
Add a new swift file to the project.
One default dialogue will open to create a bridging header (If it
does not open by default, add a bridging header file).
Go to build settings type Swift Compiler and you will see Your
ProjectName-Swift.h in Swift Compiler- General like below
Import you desired swift classes build and run.

Adding multiple Swift files to an Objective-C project.
Let’s say you want to add Class1.swift, Class2.swift, and Class3.swift file to the SwiftToObjC project
Add Class1.swift file to the project.
XCode will ask "Would You like to configure an Objective-C bridging Header"? You choose "Create Bridging Header". So the SwiftToObjC-Bridging-Header.h file as well as the SwiftToObjC-Swift.h file are generated.
In the SwiftToObjC-Bridging-Header.h file you add this line
#class Class1;
When you add Class2.swift and Class3.swift to the project, you also add these two classes to the SwiftToObjC-Bridging-Header.h file as follows.
#class Class1;
#class Class2;
#class Class3;


5. In the target SwiftToObjC, under Build Settings, Swift-Compiler General you should see these two settings:
Objective-C Bridging Header -> SwiftToObjC-Bridging-Header.h
Objective-C Generated Interface Header Name -> SwiftToObjC-Swift.h


6. In the target SwiftToObjC, under Build Settings, Define Module is set to YES.
If you want to access Class1 in say MyViewController, then in MyViewController.m, you should import.
#import "SwiftToObjC-Bridging-Header.h"
In your Class1.swift file, declare your class as “#objc public” as follows. The same #objc public is used for Class2 and Class3.

#objc public class Class1: UITableViewController
Note that: UITableViewController is only an example for demonstration purpose.
That’s all.

Related

How to call Swift from an Objective C project App Delegate?

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 generated project-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 from Constants.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
Edit: error when adding #objc to the enum declaration in Constants.swift
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:
#objcMembers
class Constants: NSObject {
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
private override init() {}
}
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.

Import Swift into Objective-C - "use of undeclared identifier"

I'm not able to import Swift class into Objective-C.
Xcode version: 10.1
Swift: 4.2
My steps:
Create empty Single-View Objective-C project called "test".
Create Swift class (mytestclass.swift)
Create bridging empty header "test-Swift.h"
Try to use in ViewController.m like this: #import "test-Swift.h"
[[MyTestClass init] calculate];
mytestclass.swift
import Foundation
#objc public class MyTestClass: NSObject {
#objc public func calculate() {
print("TEST")
}
}
After compilation I get:
/Users/xxx/Desktop/test/ViewController.m:19:7: Use of undeclared
identifier 'MyTestClass'
What am I missing?
Your problem is in step
3- Create bridging empty header "test-Swift.h"
You shouldn't create that file manually , as it's created when you add the swift file to your Objective-C , also you need to replace this line
[[MyTestClass init] calculate];
with
[[[MyTestClass alloc] init] calculate];
or
[[MyTestClass new] calculate];
Here is a working demo

Implementing an Obj-C class in my Swift project

I'm trying to add a webshop to my app. The problem is that the webshop has provided me with an Obj-C framework and I'm only familiar with making iOS apps in Swift.
I've managed to setup an Obj-C bridging header and instantiate the webshop object.
My project looks like this:
When the shop button on my CodeDetailViewController gets tapped this function gets triggered:
#IBAction func shopButtonPressed(sender: UIButton){
let instanceOfShop : Shop = Shop()
instanceOfShop.showShop()
}
My Shop.m looks like this:
#import <Foundation/Foundation.h>
#import <FMShop/FMShop.h>
#import "Shop.h"
#implementation Shop
- (void) showShop {
//SANDBOX
FMShop* shop = [[FMShop alloc] initWithKey:#"4M7HDPAQMY68S"
storeKey:#"C8RSHBH710GK8"
buyerID:nil
sandbox:YES
controller:nil
delegate:nil];
[shop showStore:kShopViewHome ID:nil];
}
#end
The showShop function in this class gets triggered. Nothing however shows up.
The manual on how to implement this webshop is aimed at Obj-C apps. Concerning the delegate it states:
delegate: Please define a class or an interface that implements the delegates. Without such, the Store will not show. Please go to FMShopDelegate to see the supported list of methods and callbacks.
This is what I could find in the framework:
#protocol FMShopDelegate <NSObject>
#optional
-(void)shopWillAppear:(FMShop*)shop;
-(void)shopDidAppear:(FMShop*)shop;
-(void)shopWillDisappear:(FMShop*)shop;
-(void)shopDidDisappear:(FMShop*)shop;
-(void)shopProductInfo:(FMShop*)shop products:(NSArray*)productArray;
-(void)shopHistoryOrderInfo:(FMShop*)shop orders:(NSArray*)orderArray;
-(void)shopPlaceOrderSuccess:(FMShop*)shop orderID:(NSString*)orderID;
-(void)shopOrderUserCancelled:(FMShop*)shop orderID:(NSString*)orderID;
-(void)shopFailed:(FMShop*)shop error:(FMShopErrorType)error;
#end
Can anyone tell me how to connect this final method to the right delegate?
Sounds like if you don't provide a delegate when you instantiate your instance of FMShop, then the show method will not work. In your Shop.m file, you're instantiating the FMShop object with nil as the delegate parameter.
Try having an object conform to the FMShopDelegate protocol, and passing this object as the delegate parameter. You could even have your Shop object conform to the protocol itself, and pass self as the delegate if that would serve your purposes.
You could do this in Swift in a new Shop.swift file, or in the Shop.m file in Objective-C:
Swift:
class Shop: NSObject {
func showShop() {
// I'm guessing on the syntax here, Xcode will help autocomplete the correct functions
let shop = FMShop(key: KEY, storeKey: STOREKEY...)
shop.show(store: kShopViewHome, id: nil)
}
}
extension Shop: FMShopDelegate {
// Implement any of the protocol functions you want here
}
Objective-C:
#interface Shop() <FMShopDelegate> // Conform to the delegate here
#end
#implementation Shop
- (void) showShop {
//SANDBOX
FMShop* shop = [[FMShop alloc] initWithKey:#"4M7HDPAQMY68S"
storeKey:#"C8RSHBH710GK8"
buyerID:nil
sandbox:YES
controller:nil
delegate:self];
[shop showStore:kShopViewHome ID:nil];
}
// Implement any of the protocol methods here
#end
You have to use bridging header for accessing obj-c file in swift
Below is the apple doc to describe how to create & use bridging header
Apple Doc
Use bridging header in your project.
https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html

Method in swift extension of an Objective-C class can not be access from .m file

Method in Swift extension of an Objective-C class can not be access from .m file
I have a bridge header:
extension foViewController {
public func gome()
{
print("Hi");
}
}
I can't call method like [self gome]; in viewdidload of .m file
To access Swift files in Objective-C classes, we have to add an import.
For example, if the project name is "De", add:
#import "De-Swift.h"
Only then we can access Swift files in Objective-C.

using swift and obj c both

I've read this question: How to call Objective-C code from Swift1. But I can found what I need.
I'm using swift like first language in my project and later I've add Objective C. But my problem is in Objective c file how I can call a function in swift, now I can do only the contrary (working in swift and using objective c class).
When I following code :
#import "ViewController-Swift.h"
xcode issues is that: file not found.
That's my problem now:
#objc class ShareViewController: UIViewController {
var name: String
init(name: String) {
self.name = name
}
// Needed to add a class level initializer
class func newInstanceNamed(name: String) -> ShareViewController {
return ShareViewController(name: name)
}
func abilitaTimer(){
println("ciao")
}
}
}
xcode issues is that: required initializer init coder...
Unless the project you are building is called ViewController, then you have the wrong file name. Look at the bridging header file that was created for you. If it is called xyzzy-Bridging-Header.h, then the file you want to import in Objective-C is xyzzy-Swift.h.
Swift migrate in Objc-based project:
Create new *.swift file (in Xcode) or add it by using Finder
Add swift bridging empty header if Xcode have not done this before (see 4 below)
Implement your Swift class by using #objc attribute:
import UIKit
#objc class Hello {
func sayHello () {
println("Hi there!")
}
}
Open Build Settings and check following parameters:
Product Module Name : myproject
Defines Module : YES
Embedded Content Contains Swift : YES
Install Objective-C Compatibility Header : YES
Objective-C Bridging Header : $(SRCROOT)/Sources/SwiftBridging.h
Import header (which is auto generated by Xcode) in your *.m file. Ex Suppose your project name is myproject then that file will be myproject-Swift.h.
#import "myproject-Swift.h"
Clean and rebuild your Xcode project

Resources