How to access iOS private APIs in Swift?

How can I name non-public functions of iOS and access non-public functions from Swift? In particular, I would like to use one non-public class in the QuartzCore framework.

One solution that came to my mind was to create an Objective-C bridge project that would wrap these non-public APIs publicly and then call these Objective-C functions from Swift. However, now my solution is pure Swift, and I would prefer to keep it that way. Is there an even easier way? (e.g. adding something to the Objective-C bridge header file )

Note. I know that you think private APIs are private because they should not be used. I know the risks, I know all the donsids, restrictions on the app store, etc. After all that has been carefully considered and a lot of research, this, unfortunately, still seems to be the best way in this particular case.

+13
source share
2 answers

You can do the very trick you would do if your project were Objective-C.

Create a header file and place the category declaration in the class along with the declaration of the private methods you want to open. Then tell the Swift compiler to import this bridge header.

For demonstration purposes, I will be speaking inside the NSBigMutableString , a private subclass of NSMutableString , and I will call it the _isMarkedAsImmutable method.

Please note that here the whole class itself is private, so I must first declare it as a subclass of my real superclass. Because of this, I could also declare a method directly in the declaration of the class itself; which, however, would not demonstrate the use of the (Private) category of tricks.

If your class is publicly available, then obviously you only need a category and you do not need to (re) declare the class itself.

Bridge.h:

 #import <Foundation/Foundation.h> @interface NSMutableString (Private) - (BOOL)_isMarkedAsImmutable; // this is a lie @end @interface NSBigMutableString : NSMutableString @end 

s.swift:

 let s = NSBigMutableString() println(s._isMarkedAsImmutable()) 

Compile and run:

 $ xcrun -sdk macosx swiftc -o foo -import-objc-header Bridge.h s.swift $ ./foo false $ 
+15
source

You can get private classes using NSClassFromString: and interact with them using performSelector .

+7
source

Source: https://habr.com/ru/post/1012071/


All Articles