After importing the objective C robbiehanson/XMPPFramework into a swift project (setting up build setting, bridging header, etc). I am able to call normal methods in the imported classes and set properties directly.
However, certain instance methods that set properties cause immediate errors as if they don t exist in the instances I m calling them on. For example:
- (void)setMyJID:(XMPPJID *)newMyJID
{
[self setMyJID_setByClient:newMyJID];
}
Or even the setMyJID_setByClient:newMyJID method which actually does the setting.
In two separate objective c example projects I have looked at, the setMyJID method is being called from other classes. However, while I am able to call other instance methods on the class, I can t call this one. Since I am not very familiar with objective c, I though this might be because it wasn t declared in the header file, causing some swift specific problem, but attempts to add a declaration for it did not help.
I am able to set the relevant property directly, but this is not only undesirable, I also would like to understand why I am not able to call certain methods.
I am attempting to make the call on an instance of the XMPPStream class like this
//This shows immediate error: XMPPStream does not have a member named setMyJID
stream.setMyJID(XMPPJID.jidWithString(someXMPPAddress)
// This works perfectly
stream.myJID = (XMPPJID.jidWithString(someXMPPAddress))
Any help would be appreciated.
https://github.com/robbiehanson/XMPPFramework/blob/master/Core/XMPPStream.h
https://github.com/robbiehanson/XMPPFramework/blob/master/Core/XMPPStream.h
@property (readwrite, copy) XMPPJID *myJID;
In Objective-C, this means that there are actually two methods on the XMPPStream class that conform to the following signatures:
- (XMPPJID *)myJID;
- (void)setMyJID:(XMPPJID *)myJID;
So, from Objective-C code, you can call them like any other method. However, as you know, you also have the option of using the syntactic sugar in the language known as "dot notation":
// getter with dot notation
XMPPJID *jid = stream.myJID;
// setter with dot notation
stream.myJID = jid;
However, in Objective-C, these dot notation expressions are directly translated into calls to the getter and setter. They re just there to look nice.
Things are different in Swift. When you have a property, like this one:
var myJID: XMPPJID
this does not mean that there exist separate getter and setter methods, like you might be imagining:
func myJID() -> XMPPJID {}
func setMyJID(jid: XMPPJID) {}
In Swift, you must access properties using dot syntax.
Knowing this, your problem becomes obvious. When you tried:
stream.setMyJID(XMPPJID.jidWithString(someXMPPAddress)
Swift tried to run the instance method setMyJID of stream, and found, rightly, that it did not exist! This, of course:
stream.myJID = (XMPPJID.jidWithString(someXMPPAddress))
works perfectly, because you re setting a property as Swift requires.
As an educational aside, you may sometimes see cases where, when accessing Objective-C properties from Swift, you not only can, but must use the getter and setter methods - dot notation won t even work! This seems totally counterintuitive, but there s a good reason for why this happens. One example of this that I can think of off the top of my head is the verbosely-named UIView property translatesAutoresizingMaskIntoConstraints, used for view layout. If you try to use it in Swift, like so:
// Set translatesAutoresizingMaskIntoConstraints to false on self
translatesAutoresizingMaskIntoConstraints = false
you would get a compilation error! Specifically,
Cannot assign to translatesAutoresizingMaskIntoConstraints in self
Why? The answer lies in the UIView headers:
- (BOOL)translatesAutoresizingMaskIntoConstraints NS_AVAILABLE_IOS(6_0); // Default YES
- (void)setTranslatesAutoresizingMaskIntoConstraints:(BOOL)flag NS_AVAILABLE_IOS(6_0);
It turns out that this "property," like many others in the Cocoa frameworks, is actually just a pair of methods that look like property accessors. Because of how Objective-C translates dot notation into method calls, you d never notice before. Now, though, Swift is stricter – to get and set this "property," you must call the appropriate methods.
http://stackoverflow.com/questions/29049517/does-not-have-member-when-calling-objective-c-setter-method-from-swift