3

I have an Objective-C class that I am trying to use in a Swift project.

Some of the methods in this class are not suitable for Swift and the simplest solution in my opinion is to have slightly different alternatives that will work in Swift.

eg. Current Method:

+(void)doSomethingWithFormat:(NSString*)format,...; 

eg. New Method:

+(void)doSomethingWithString:(NSString*)string; 

That works fine but my problem is the new method will then be available in Objective-C projects where it isn't really needed and just clutters up the code complete menu.

My question: Is there a way to mark all of the new methods as only being available in Swift and not in Objective-C?

EDIT: What I'm hoping for is something along the lines of

@available(swift,*) +(void)doSomethingWithString:(NSString*)string; 

or

#if SWIFT +(void)doSomethingWithString:(NSString*)string; #endif 

2 Answers 2

5

What you are looking for is the opposite of NS_SWIFT_UNAVAILABLE which Apple provide to make an Objective-C API unavailable to Swift. There is an NS_UNAVAILABLE which makes the API unavailable in both, bot not an NS_OBJC_UNAVAILABLE.

End of Answer. I will deny posting the following ;-)

In the following Objective-C sees bar, Swift sees bar() and foo()...

@interface Foo : NSObject - (void) bar; - (void) /*__*/‍/*__ between these comments there is a zero-wdith non-joiner character U+200D */ NS_SWIFT_NAME(foo()); @end 

Yes, it seems you can name a method in Objective-C using the zero-width non-joiner character. You won't see this in auto complete, you'll see a blank!

I will now face the corner and repeat "I will not give methods invisible weird names" 1000 times ;-)

Sign up to request clarification or add additional context in comments.

4 Comments

Yes I'm looking for something like 'NS_OBJC_UNAVAILABLE', I figured it was a long shot - it would be strange if there was a way to hide Obj-C code from all other Obj-C code. As much as I love the evil genius-ness of the rest of the answer, I do have about 15 methods I need to deal with in the same way so that is definitely not an option. An NSObject category with that -(void); method could make for a good prank though.
That would only require 15 U+200D in the last name, and I suspect other characters work so you probably only need at most 4 in every name (2^4 combos) ;-) But yes, I wouldn't recommend i. But go ahead and use it for a prank, opening an app source to find every variable name was invisible would certainly throw someone! :-)
BTW Though it won't address the "clutter up" issue your other option is to name the methods to indicate they shouldn't be used and use NS_SWIFT_NAME to give sensible names for Swift e.g. __DO_NOT_USE_foo, __SWIFT_ONLY_foo or even ______________________________foo – they will appear in auto-complete but shouldn't cause confusion over whether they are valid choices.
This is hilarious. I think the suggestion from @CRD is probably more future maintainer friendly :D
1

I suggest using an extension of ObjC class in Swift-file.

I mean, in ObjC create your class MyClass: NSObject ...

in Swift file use:

extension MyClass { /* your methods */}

5 Comments

But the methods in the extension can still be used by any other Objective-C code blocks.
Nope. Have you tried? If you try this, you will see 'no visible interface forcdeclaresvthe selector'
I was hoping to avoid using swift code here because the class in question is part of an library which is purely objective-c and I'd prefer it to stay that way if possible.
@KristianFox why?
@Vyacheslav, I'd rather not mix Swift code into a Objective-C library unless it is actually useful to an Objective-C project.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.