2

I am trying to listen to CoreTelephony notifications using the (now private) CTTelephonyCenterAddObserver C function and CFNotificationCallback callback blocks.

My bridging header (to extern the private C functions):

#include <CoreFoundation/CoreFoundation.h>

#if __cplusplus
extern "C" {
#endif

#pragma mark - API

    /* This API is a mimic of CFNotificationCenter. */

    CFNotificationCenterRef CTTelephonyCenterGetDefault();
    void CTTelephonyCenterAddObserver(CFNotificationCenterRef center, const void *observer, CFNotificationCallback callBack, CFStringRef name, const void *object, CFNotificationSuspensionBehavior suspensionBehavior);
    void CTTelephonyCenterRemoveObserver(CFNotificationCenterRef center, const void *observer, CFStringRef name, const void *object);
    void CTTelephonyCenterRemoveEveryObserver(CFNotificationCenterRef center, const void *observer);

    void CTIndicatorsGetSignalStrength(long int *raw, long int *graded, long int *bars);

#pragma mark - Definitions

    /* For use with the CoreTelephony notification system. */
    extern CFStringRef kCTIndicatorsSignalStrengthNotification;

#if __cplusplus
}
#endif

My Swift code:

let callback: CFNotificationCallback = { (center: CFNotificationCenter?, observer: UnsafeRawPointer?, name: CFString?, object: UnsafeRawPointer?, info: CFDictionary?) -> Void in
    // ...
}

CTTelephonyCenterAddObserver(CTTelephonyCenterGetDefault().takeUnretainedValue(), nil, callback, kCTIndicatorsSignalStrengthNotification.takeUnretainedValue(), nil, .coalesce)

However, I can't get the signature of my completion variable to match the requirements of the CFNotificationCallback typealias.

Cannot convert value of type
'(CFNotificationCenter?, UnsafeRawPointer?, CFString?, UnsafeRawPointer?, CFDictionary?) -> Void'
to specified type
'CFNotificationCallback' (aka '@convention(c) (Optional<CFNotificationCenter>, Optional<UnsafeMutableRawPointer>, Optional<CFNotificationName>, Optional<UnsafeRawPointer>, Optional<CFDictionary>) -> ()')

How can I get @convention(c) closures to play nicely in Swift?

1
  • 1
    It does not compile because observer is a UnsafeMutableRawPointer, not a UnsafeRawPointer. Commented Jan 30, 2017 at 12:55

2 Answers 2

3

Letting the compiler infer the closure's signature works fine:

let callback: CFNotificationCallback = { center, observer, name, object, info in
    //works fine
}

Trying to specify @convention(c) in the closure's declaration gives an error:

let callback: CFNotificationCallback = { @convention(c) (center: CFNotificationCenter?, observer: UnsafeRawPointer?, name: CFString?, object: UnsafeRawPointer?, info: CFDictionary?) -> Void in
    //Attribute can only be applied to types, not declarations.
}

It seems like what's going on is that when you manually declare the closure's type, it forces the compiler to use that exact type. But that's technically a closure declaration and not a type declaration, so the @convention attribute isn't allowed. When the compiler is allowed to infer the closure's type (from the type of the variable it is being stored in), it can infer the attribute too.

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

1 Comment

Ah so it does, I was overcomplicating things. Thanks!
0
class SomeClass {
   func someFunc() {
       CFNotificationCenterAddObserver(nc, nil, queryProgress_cust, kMDQueryProgressNotification, nil, .deliverImmediately)
   }
}

// IMPORTANT: Following code must be NOT related to some class or struct(!!!!)
// "_cust" added for being sure that function will have no duplicates... because of absolutely contrintuitive errors will tell you nothing
fileprivate func queryProgress_cust(_ notifCenter: CFNotificationCenter?, _ observer: UnsafeMutableRawPointer?, _ name: CFNotificationName?, _ obj: UnsafeRawPointer?, _ cfDict: CFDictionary?) {
    //code
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.