Is it possible to detect if some global function (not class method) is defined (in iOS)? Something like respondsToSelector
in a class...
Asked
Active
Viewed 584 times
8

JMI
- 2,530
- 15
- 26
-
Are you specifically looking for a Swift function—or a C function imported from Apple's frameworks? – Nikolai Ruhe Jul 13 '16 at 14:00
-
1@NikolaiRuhe I wonder, can you detect either of them? – Sulthan Jul 13 '16 at 14:02
-
@NikolaiRuhe Everything is helpful. – JMI Jul 13 '16 at 14:05
-
2if its global function, so why do you care about checking its existence. Just curious – Hossam Ghareeb Jul 13 '16 at 14:12
-
@Sulthan See my answer. – Nikolai Ruhe Jul 13 '16 at 14:28
-
@HossamGhareeb That's commonly needed to check availability of functions from Apple's frameworks. Some functions are supported only on later OS versions. – Nikolai Ruhe Jul 13 '16 at 14:30
-
1@NikolaiRuhe In Swift we are supposed to use `#available` for that. – Sulthan Jul 13 '16 at 14:42
-
@Sulthan There's a slight difference: `#available` can only check for OS versions. The question is explicitly about checking the existence of a global function. Anyway, for the common use case (Apple frameworks) the result is the same. – Nikolai Ruhe Jul 13 '16 at 15:27
2 Answers
6
Swift currently does not support looking up global functions.
For C functions (most global functions from Apple's frameworks are C functions) there are at least two ways:
- using a weakly linked symbol
- the dynamic linker API:
dlopen
Both check dynamically (at runtime) if a symbol can be found.
Here's an example that checks if UIGraphicsBeginImageContextWithOptions
(introduced with iOS 4) is available:
void UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale) __attribute__((weak));
static inline BOOL hasUIGraphicsBeginImageContextWithOptions() {
return UIGraphicsBeginImageContextWithOptions != NULL;
}
Here's the same check, using dlsym
:
#import <dlfcn.h>
static inline BOOL hasUIGraphicsBeginImageContextWithOptions() {
return dlsym(RTLD_SELF, "UIGraphicsBeginImageContextWithOptions") != NULL;
}
The advantage of using dlsym
is that you don't need a declaration and that it's easily portable to Swift.

Nikolai Ruhe
- 81,520
- 17
- 180
- 200
-
Now I remember I actually have used the weak linking myself before. I am not really sure if that would work for Swift globals though. – Sulthan Jul 13 '16 at 14:42
-
@Sulthan It wouldn't, because Objective-C cannot see Swift globals. But perhaps that is not what the OP is asking. – matt Jul 13 '16 at 14:46
-
@Sulthan Swift's name mangling is preventing simple symbol lookup. – Nikolai Ruhe Jul 13 '16 at 15:23
0
No, it's not possible in Swift.
Even respondsToSelector
uses the Obj-C runtime and can be used only for functions available in Obj-C.

Sulthan
- 128,090
- 22
- 218
- 270
-
-
-
@Feldur You can always declare a function (as `extern`, but that's the default) and then leave it up to the dynamic linker to resolve the symbol. That's what happens all of the time when linking to system frameworks. – Nikolai Ruhe Jul 13 '16 at 15:59
-
1Wa's the question not relative to doing this in Swift? Extern does not seem to be a swift keyword – Feldur Jul 13 '16 at 16:29