How to Call Objective-C Instancetype Method in Swift

How to call Objective-C instancetype method in Swift?

You are not supposed to write initializer like that in Objective C. Either you should have it just init or then if you are passing argument in constructor then only you can name it otherwise.

Here is how you can do it,

@interface CustomObjectHavingData : NSObject

@property (nonatomic, strong) NSData *objWithData;

- (instancetype)initWithObjHavingData:(NSData *)data;

@end

@implementation CustomObjectHavingData

- (instancetype)initWithObjHavingData:(NSData *)data
{
if (self = [super init]) {
_objWithData = data;
}

return self;
}

@end

In Swift, you can simply call it like this,

  let myCustomObject = CustomObjectHavingData(objHavingData: someData)

The name is quite inappropriate though.

How can I initiate an instancetype from Objective-C with Swift

var mobileApi = MobileAPI.newDemoInstance()

or

let mobileApi = MobileAPI.newDemoInstance()

if you don't intend to modify it.

How to access Customalertview objective C instancetype method in swift

It should look something like this:

UIAlertView(title: "Title", message: "Message", delegate: self, cancelButtonTitle: "Cancel", otherButtonTitles: "OtherButton1", "OtherButton2")

I'm not sure what CustomAlertView is. If that's your class, replace UIAlertView with CustomAlertView in the initializer.

otherButtonTitles is a comma separated list of Strings:

public convenience init(title: String, message: String, delegate: UIAlertViewDelegate?, cancelButtonTitle: String?, otherButtonTitles firstButtonTitle: String, _ moreButtonTitles: String...)

You don't need to use a singleton like in Rahul's answer.

Assuming your CustomAlertView.h file looks like this:

#import <UIKit/UIKit.h>

@interface CustomAlertView : UIAlertView

-(instancetype)initWithTitle:(NSString *)title message:(NSString *)message delegate:(id)delegate cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ...;

@end

You can import CustomAlertView.h into your bridging header and initialize the class like this in Swift 3:

CustomAlertView(title: "Title", message: "Message", delegate: self, cancelButtonTitle: "Cancel", otherButtonTitles: "Other1", "Other2")

How can I return instancetype in Swift from instance method

The very short answer is no there is no direct equivalent.

The more detailed answer is that the languages are conceptually different.

  • In Objective-C anything returned is an object aka id. Using instancetype is a hint to the compiler and IDE for a specific type to allow further checks and auto-completion. This works for sub-classing and extensions.
  • Swift is strongly typed, there is no base object and we also have classes and structs. A function can only return a specific type, Self, a generic type or an associatedtype. The best approximation would be to move this functionality into an extension or protocol and use Self. This would work the same way. There is no equivalent for this in a sub classing context.

Long detailed answer Return instancetype in Swift

How can I return instancetype in Swift

You can do it. Playground code below. It's self() that niceObject() has to return. Additionally, you must have a required init on the base class.

class A {
required init() {
}

func whatClassAmI() -> String {
return "Class A"
}
}

class B: A {
required init() {
super.init()
}
override func whatClassAmI() -> String {
return "Class B"
}
}

let a = A()
let sa = a.whatClassAmI() // "Class A", of course

let b = B()
let sb = b.whatClassAmI() // "Class B", of course

extension A {
class func niceObject() -> Self {
return self.init()
}
}

let aa = A.niceObject()
let saa = aa.whatClassAmI() // "Class A"

let bb = B.niceObject()
let sbb = bb.whatClassAmI() // "Class B", as required

How to call a swift method which parameter is a protocol from Objective-C

I don't think sendMessage will ever appear in compiled TargetName-Swift.h because Generics and Encodable protocol is not available in Objective-C.

Clearly when you use

sendMessage<Serializable: Encodable>(message:Serializable)

You employ Generics as well as Encodable protocol which is only available in Swift not in Objective-C

When you try to access the Swift functions in your Objective-C files, compiler creates a Objective-C equivalent/ counterpart of your Swift functions hence you see the signature for those methods in your TargetName-Swift.h files.

But Generics and Encodable protocol are not available in Objective-C so it can't translate your Swift function using Generics and Encodable protocol to Objective-C equivalent. Hence You can never call such Swift methods from Objective-C files

How do I invoke an Objective-C `initFoo` method with no arguments from Swift?

var x = MyClass(defaultsFoo: ())

should work. The reason why it seemingly didn't was because when XCode autocompleted the call, it filled in a placeholder that looks like () but isn't actually ().

Sample Image

(Note the blue highlighting. Inspecting the file on disk also shows that the placeholder is written out as <#T##()#>.)

Alternatively:

var x = MyClass(defaultsFoo: Void())

also seems to work but is probably uglier.

Obj-C Instance method returning a instanceType called from Swift - Function produces expected type 'UIImage!' error

If you look at the method you have defined in Objective C image category, it is instance method and you are trying to call it using UIImage class in swift.

You can basically use either one of the following two approaches,

Either,

self.backgroundImageView.image = self.someImage.applyDarkEffect() // notice the method does not take argument

Or if you want to use class level method, then first create a closure and call it as,

let applyEffectToImageClosure = UIImage.applyDarkEffect(self.someImage)
self.backgroundImageView.image = applyEffectToImageClosure()

Invoking an Obj-C class method named `init` from Swift

The ambiguity arises (in Swift <= 4.1) because both the class method

+ (void)init;

and NSObjects init method

- (instancetype)init

are called from Swift as My3rdPartyClass.init(). Possible solutions
are:

  • Rename the Objective-C class method.
  • Annotate the function declaration with a different Swift name:

    +(void)init NS_SWIFT_NAME(classInit());

    That leaves the Objective-C interface unchanged, but the function can
    be called from Swift as

    OClass.classInit()
  • If no modification of the Objective-C header file is possible then
    you can still call the function from Swift as

    My3rdPartyClass.init() as Void

    The Void return type resolves the ambiguity.

Starting with Swift 4.2 (Xcode 10) you can call the class method as

OClass.`init`()

without any changes in the Objective-C API (attribution goes to
@Hamish). The backticks tell the compiler that you mean the
member function, not the initializer.



Related Topics



Leave a reply



Submit