Swift 中的 ABMultiValue 通讯簿多值属性编译错误
ABMultiValue address book multi-value properties compile error in Swift
代码在 Objective-C 中有效,正在尝试转换为 Swift。我提供了有效的 Objective-C 代码和 Swift 代码,它们在第 10 行给出了编译错误(for subValue in aPropertyValue ...
快速枚举器。Swift 错误 "Type 'ABMultiValue' does not conform to protocol 'SequenceType'"。
某些 ABPerson
属性可能包含多个值(例如多个 phone 数字)并且是 ABMultiValue
class 的对象(尽管 Xcode 调试器将它们报告为 ABMultiValueCoreDataWrapper
class)。附加的 Objective-C 代码循环遍历多个值。我试图在 Swift 中做同样的事情,但无法通过编译错误。两者都是 Xcode 命令行项目。
Objective-C代码:
#import <Foundation/Foundation.h>
#import <AddressBook/AddressBook.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
ABAddressBook *addressBook = [ABAddressBook sharedAddressBook];
NSArray *people = [addressBook people];
for (ABPerson *person in people) {
for (NSString *aProperty in [ABPerson properties]) {
id aPropertyValue = [person valueForProperty: aProperty];
if ([aPropertyValue isKindOfClass: [ABMultiValue class]]) {
for (id subValue in aPropertyValue) {
NSLog(@"%@",subValue);
}
}
}
}
}
return 0;
}
swift代码:
import Foundation
import AddressBook
let addressBook = ABAddressBook.sharedAddressBook()
let people = addressBook.people()
for person in people {
for property in ABPerson.properties() {
if let aPropertyValue : AnyObject = person.valueForProperty(property as NSString) {
if aPropertyValue is ABMultiValue {
// for subValue in aPropertyValue {
for subValue in aPropertyValue as ABMultiValue {
println("\(subValue)")
}
}
}
}
}
您显然可以使用索引:
let addressBook = ABAddressBook.sharedAddressBook()
let people = addressBook.people()
for person in people {
for property in ABPerson.properties() {
if let multiValue = person.valueForProperty(property as NSString) as? ABMultiValue {
for i in 0 ..< multiValue.count() {
println(multiValue.valueAtIndex(i))
}
}
}
}
或者,如 this answer 中所建议,您可以定义一个符合 SequenceType
:
的扩展
extension ABMultiValue: SequenceType {
public func generate() -> NSFastGenerator {
return NSFastGenerator(self)
}
}
那么您可以:
let addressBook = ABAddressBook.sharedAddressBook()
let people = addressBook.people()
for person in people {
for property in ABPerson.properties() {
if let multiValue = person.valueForProperty(property as NSString) as? ABMultiValue {
for identifier in multiValue {
let value: AnyObject = multiValue.valueForIdentifier(identifier as String)
println("\(identifier) : \(value)")
}
}
}
}
代码在 Objective-C 中有效,正在尝试转换为 Swift。我提供了有效的 Objective-C 代码和 Swift 代码,它们在第 10 行给出了编译错误(for subValue in aPropertyValue ...
快速枚举器。Swift 错误 "Type 'ABMultiValue' does not conform to protocol 'SequenceType'"。
某些 ABPerson
属性可能包含多个值(例如多个 phone 数字)并且是 ABMultiValue
class 的对象(尽管 Xcode 调试器将它们报告为 ABMultiValueCoreDataWrapper
class)。附加的 Objective-C 代码循环遍历多个值。我试图在 Swift 中做同样的事情,但无法通过编译错误。两者都是 Xcode 命令行项目。
Objective-C代码:
#import <Foundation/Foundation.h>
#import <AddressBook/AddressBook.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
ABAddressBook *addressBook = [ABAddressBook sharedAddressBook];
NSArray *people = [addressBook people];
for (ABPerson *person in people) {
for (NSString *aProperty in [ABPerson properties]) {
id aPropertyValue = [person valueForProperty: aProperty];
if ([aPropertyValue isKindOfClass: [ABMultiValue class]]) {
for (id subValue in aPropertyValue) {
NSLog(@"%@",subValue);
}
}
}
}
}
return 0;
}
swift代码:
import Foundation
import AddressBook
let addressBook = ABAddressBook.sharedAddressBook()
let people = addressBook.people()
for person in people {
for property in ABPerson.properties() {
if let aPropertyValue : AnyObject = person.valueForProperty(property as NSString) {
if aPropertyValue is ABMultiValue {
// for subValue in aPropertyValue {
for subValue in aPropertyValue as ABMultiValue {
println("\(subValue)")
}
}
}
}
}
您显然可以使用索引:
let addressBook = ABAddressBook.sharedAddressBook()
let people = addressBook.people()
for person in people {
for property in ABPerson.properties() {
if let multiValue = person.valueForProperty(property as NSString) as? ABMultiValue {
for i in 0 ..< multiValue.count() {
println(multiValue.valueAtIndex(i))
}
}
}
}
或者,如 this answer 中所建议,您可以定义一个符合 SequenceType
:
extension ABMultiValue: SequenceType {
public func generate() -> NSFastGenerator {
return NSFastGenerator(self)
}
}
那么您可以:
let addressBook = ABAddressBook.sharedAddressBook()
let people = addressBook.people()
for person in people {
for property in ABPerson.properties() {
if let multiValue = person.valueForProperty(property as NSString) as? ABMultiValue {
for identifier in multiValue {
let value: AnyObject = multiValue.valueForIdentifier(identifier as String)
println("\(identifier) : \(value)")
}
}
}
}