Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/94.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Swift for iOS中正确使用CFNotificationCenterAddObserver_Ios_Swift_Notifications_Darwin - Fatal编程技术网

如何在Swift for iOS中正确使用CFNotificationCenterAddObserver

如何在Swift for iOS中正确使用CFNotificationCenterAddObserver,ios,swift,notifications,darwin,Ios,Swift,Notifications,Darwin,把我的头发拔出来让cf通知中心添加观察者在Swift中工作 CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), UnsafePointer<Void>(self), iosLocked, "com.apple.springboard.lockcomputer" as CFString, nil,

把我的头发拔出来让
cf通知中心添加观察者
在Swift中工作

        CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),
        UnsafePointer<Void>(self),
        iosLocked,
        "com.apple.springboard.lockcomputer" as CFString,
        nil,
        CFNotificationSuspensionBehavior.DeliverImmediately)
我也试着按照建议连接到objc,但没有成功

这是我的桥:

LockNotifierCallback.h:

#import <Foundation/Foundation.h>

@interface LockNotifierCallback : NSObject

+ (void(*)(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo))notifierProc;

@end
使用更新的CFNotificationCenterAddObserver调用,如下所示:

CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),
        LockNotifierCallback.notifierProc,
        iosLocked,
        "com.apple.springboard.lockcomputer" as CFString,
        nil,
        CFNotificationSuspensionBehavior.DeliverImmediately)
当然,LockNotifierCallback.h在我的桥接头中。错误继续:

Cannot convert the expression's type '(CFNotificationCenter!, () -> CFunctionPointer<((CFNotificationCenter!, UnsafeMutablePointer<Void>, CFString!, UnsafePointer<Void>, CFDictionary!) -> Void)>, () -> (), CFString, NilLiteralConvertible, CFNotificationSuspensionBehavior)' to type 'StringLiteralConvertible'
无法将表达式的类型“(CFNotificationCenter!,()->cfFunctionPointer Void)>,()->(),CFString,NilLiteralConverable,CFNotificationSuspensionBehavior)转换为类型“StringLiteralConverable”

我在DarwinNotifications方面遇到一些问题,您可以尝试使用此包装器类 只需在桥接文件中包含头文件。你可以在swift中使用它

DarwinNotificationsManager.h:

#import <Foundation/Foundation.h>

#ifndef DarwinNotifications_h
#define DarwinNotifications_h

@interface DarwinNotificationsManager : NSObject

@property (strong, nonatomic) id someProperty;

+ (instancetype)sharedInstance;

- (void)registerForNotificationName:(NSString *)name callback:(void (^)(void))callback;
- (void)postNotificationWithName:(NSString *)name;

@end

#endif

我写这篇文章是为了将一个通知从共享扩展传递到它的父应用程序,当在iPadOS中时,两者都可以同时激活

它们被放置在应用程序和扩展共享的库中。应用程序使用ExtensionListener,扩展程序使用ExtensionEvent

final public class ExtensionListener: NSObject {

    // the inter-process NotificationCenter
    private let center = CFNotificationCenterGetDarwinNotifyCenter()
    private var listenersStarted = false
    fileprivate static let notificationName = "com.example.CrossProcessExtensionAction" as CFString

    public override init() {
        super.init()
        // listen for an action in the Share Extension
        startListeners()
    }

    deinit {
        // don't listen anymore
        stopListeners()
    }

    //    MARK: listening
    fileprivate func startListeners() {
        if !listenersStarted {
            self.listenersStarted = true
            CFNotificationCenterAddObserver(center, Unmanaged.passRetained(self).toOpaque(), { (center, observer, name, object, userInfo) in
                // send the equivalent internal notification
                NotificationCenter.default.post(name: NSNotification.Name.SomeInternalExtensionAction, object: nil)
            }, Self.notificationName, nil, .deliverImmediately)
        }
    }

    fileprivate func stopListeners() {
        if listenersStarted {
            CFNotificationCenterRemoveEveryObserver(center, Unmanaged.passRetained(self).toOpaque())
            listenersStarted = false
        }
    }
}

final public class ExtensionEvent: NSObject {
    public static func post() {
        CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), CFNotificationName(rawValue: ExtensionListener.notificationName), nil, nil, true)
    }
}

CFNotificationCenterAddObserver
获取一个
cffunctionpointer
,您无法真正从Swift创建它(请参阅)。你可以通过做一些类似于这样的Objective-C桥接来解决这个问题:谢谢Mark,但是为什么它会在ios文档中以swift声明的形式出现呢?您仍然可以从Swift使用它,您只需将C或Objective-C中定义的函数传递给它,而不是Swift闭包函数。再次感谢Mark。我仍然被卡住了,请参见上面编辑的Q。我不确定什么是
iosLocked
,但看起来您只是把参数放错了位置。这为我编译:
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),nil,LockNotifierCallback.notifierProc(),“com.apple.springboard.lockcomputer”,nil,CFNotificationSuspensionBehavior.Delivery立即)
如果启用后台应用程序刷新,收到darwin通知后,应用程序是否会从后台醒来,执行一些与远程通知类似的代码?保持电源按钮的“YourNotificationName”是什么。如何通过
CFNotificationCenterPostNotification
中的
String
消息?我的问题已结束,请参阅
#import <Foundation/Foundation.h>

#ifndef DarwinNotifications_h
#define DarwinNotifications_h

@interface DarwinNotificationsManager : NSObject

@property (strong, nonatomic) id someProperty;

+ (instancetype)sharedInstance;

- (void)registerForNotificationName:(NSString *)name callback:(void (^)(void))callback;
- (void)postNotificationWithName:(NSString *)name;

@end

#endif
#import <Foundation/Foundation.h>
#import "DarwinNotificationsManager.h"


@implementation DarwinNotificationsManager {
    NSMutableDictionary * handlers;
}

+ (instancetype)sharedInstance {
    static id instance = NULL;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
    });
    return instance;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        handlers = [NSMutableDictionary dictionary];
    }
    return self;
}

- (void)registerForNotificationName:(NSString *)name callback:(void (^)(void))callback {
    handlers[name] = callback;
    CFNotificationCenterRef center = CFNotificationCenterGetDarwinNotifyCenter();
    CFNotificationCenterAddObserver(center, (__bridge const void *)(self), defaultNotificationCallback, (__bridge CFStringRef)name, NULL, CFNotificationSuspensionBehaviorDeliverImmediately);
}

- (void)postNotificationWithName:(NSString *)name {
    CFNotificationCenterRef center = CFNotificationCenterGetDarwinNotifyCenter();
    CFNotificationCenterPostNotification(center, (__bridge CFStringRef)name, NULL, NULL, YES);
}

- (void)notificationCallbackReceivedWithName:(NSString *)name {
    void (^callback)(void) = handlers[name];
    callback();
}

void defaultNotificationCallback (CFNotificationCenterRef center,
                 void *observer,
                 CFStringRef name,
                 const void *object,
                 CFDictionaryRef userInfo)
{
    NSLog(@"name: %@", name);
    NSLog(@"userinfo: %@", userInfo);

    NSString *identifier = (__bridge NSString *)name;
    [[DarwinNotificationsManager sharedInstance] notificationCallbackReceivedWithName:identifier];
}


- (void)dealloc {
    CFNotificationCenterRef center = CFNotificationCenterGetDarwinNotifyCenter();
    CFNotificationCenterRemoveEveryObserver(center, (__bridge const void *)(self));
}


@end
let darwinNotificationCenter = DarwinNotificationsManager.sharedInstance()
darwinNotificationCenter.registerForNotificationName("YourNotificationName"){
            //code to execute on notification
}
final public class ExtensionListener: NSObject {

    // the inter-process NotificationCenter
    private let center = CFNotificationCenterGetDarwinNotifyCenter()
    private var listenersStarted = false
    fileprivate static let notificationName = "com.example.CrossProcessExtensionAction" as CFString

    public override init() {
        super.init()
        // listen for an action in the Share Extension
        startListeners()
    }

    deinit {
        // don't listen anymore
        stopListeners()
    }

    //    MARK: listening
    fileprivate func startListeners() {
        if !listenersStarted {
            self.listenersStarted = true
            CFNotificationCenterAddObserver(center, Unmanaged.passRetained(self).toOpaque(), { (center, observer, name, object, userInfo) in
                // send the equivalent internal notification
                NotificationCenter.default.post(name: NSNotification.Name.SomeInternalExtensionAction, object: nil)
            }, Self.notificationName, nil, .deliverImmediately)
        }
    }

    fileprivate func stopListeners() {
        if listenersStarted {
            CFNotificationCenterRemoveEveryObserver(center, Unmanaged.passRetained(self).toOpaque())
            listenersStarted = false
        }
    }
}

final public class ExtensionEvent: NSObject {
    public static func post() {
        CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), CFNotificationName(rawValue: ExtensionListener.notificationName), nil, nil, true)
    }
}