knl*_*knl 9 abaddressbook swift
原始问题(见下面的解决方案):
我试图在我的Swift应用程序中使用AddressBook.framework,但无法弄清楚如何实现该ABAddressBookRegisterExternalChangeCallback功能.
在Objective-C中,我只是将回调实现为C函数并传递其指针:
// somewhere in the initializer of the MyAddressBook class:
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(nil, nil);
ABAddressBookRegisterExternalChangeCallback(addressBook, externalChangeCallback, (__bridge void *)(self));
// somewhere else in the MyAddressBook class:
void externalChangeCallback(ABAddressBookRef reference, CFDictionaryRef info, void *context)
{
[(__bridge MyAddressBook *)context addressBookDidChangeExternally];
}
- (void)addressBookDidChangeExternally
{
// good old Obj-C from here on!
}
Run Code Online (Sandbox Code Playgroud)
在Swift中,我很难处理C函数.我发现Apple增加了在beta 3中传递C函数指针的能力,但是我如何声明这样的函数呢?使用Swift的闭包语法会很好,但这是否可能?
这是我创建的地方ABAddressBookRef:
var addressBookRef: ABAddressBookRef = {
let addressBookRef: ABAddressBookRef = ABAddressBookCreateWithOptions(nil, nil).takeRetainedValue()
// TODO: how do I make this work?
let externalChangeCallback: ABExternalChangeCallback = {
println("Address book changed externally!")
}
ABAddressBookRegisterExternalChangeCallback(addressBookRef, externalChangeCallback, nil)
return addressBookRef
}()
Run Code Online (Sandbox Code Playgroud)
那么如何在Swift中实现呢?
解决方案(有缺陷):
正如pNre所建议的那样,这就是我现在实现它的方式:
在Objective-C中:
AddressBookExternalChangeCallback.h:
#import <AddressBook/AddressBook.h>
void registerExternalChangeCallbackForAddressBook(ABAddressBookRef addressBookRef);
Run Code Online (Sandbox Code Playgroud)
AddressBookExternalChangeCallback.m:
#import "AddressBookExternalChangeCallback.h"
void addressBookExternalChangeCallback(ABAddressBookRef addressBookRef, CFDictionaryRef info, void *context)
{
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:@"AddressBookDidChangeExternallyNotification" object:nil];
});
}
void registerExternalChangeCallbackForAddressBook(ABAddressBookRef addressBookRef)
{
ABAddressBookRegisterExternalChangeCallback(addressBookRef, addressBookExternalChangeCallback, nil);
}
Run Code Online (Sandbox Code Playgroud)
在Swift中:
导入桥接头后:
registerExternalChangeCallbackForAddressBook(addressBookRef)
Run Code Online (Sandbox Code Playgroud)
每当地址簿发生变化时,都会发布通知.@objc但是,只有类可以注册通知,所以有没有办法调用Swift函数或方法呢?
ABExternalChangeCallback 被定义为
typealias ABExternalChangeCallback = CFunctionPointer<((ABAddressBookRef!, CFDictionary!, UnsafeMutablePointer<()>) -> Void)>
Run Code Online (Sandbox Code Playgroud)
来自 Xcode 发行说明:
但是,您不能调用 C 函数指针 (
CFunctionPointer) 或将闭包转换为 C 函数指针类型。
这意味着您不能按照您的方式分配块。但是,您可以ABAddressBookRegisterExternalChangeCallback在 objc 函数中调用并从 swift 代码中调用它来绕过此限制。
| 归档时间: |
|
| 查看次数: |
2034 次 |
| 最近记录: |