/ / Swift филтър масив с помощта на NSPredicate - ios, бърз, abaddressbook

Бързо филтриращ масив с помощта на NSPredicate - ios, бърз, abaddressbook

Имам заявка, написана в Swift, която привлича контактите на потребителите от адресната книга.

Искам да филтрирам контакта, който съдържа само име на фирмата (за да получите "вярната" връзка с истинския човек, а не с бизнеса)

Ето как се постига това във версия Objective-C на приложението ми:

NSArray *allContacts = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);

NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id person, NSDictionary *bindings) {
NSString *firstName = CFBridgingRelease(ABRecordCopyValue((__bridge ABRecordRef)person, kABPersonFirstNameProperty));
NSString *lastName  = CFBridgingRelease(ABRecordCopyValue((__bridge ABRecordRef)person, kABPersonLastNameProperty));

return (firstName || lastName);
}];

NSArray *peopleNotCompanies = [allContacts filteredArrayUsingPredicate:predicate];

Това работи перфектно, така че тук е моят опит да направите това в Swift:

var contactList: NSArray = ABAddressBookCopyArrayOfAllPeople(addressBook).takeRetainedValue()

var predicate: NSPredicate = NSPredicate { (AnyObject person, NSDictionary bindings) -> Bool in
var firstName: String = ABRecordCopyValue(person as ABRecordRef, kABPersonFirstNameProperty).takeRetainedValue() as String
var lastName: String = ABRecordCopyValue(person as ABRecordRef, kABPersonLastNameProperty).takeRetainedValue() as String

return firstName || lastName
})

Сега това има няколко проблема. Получавам тези грешки в декларацията за връщане и края на предикатното обаждане:

Съобщения за грешки

Как мога да предложа подобна функционалност, намерена в моя ObjC код в Swift? Или има ли по-добър начин да се провери дали един контакт има само име на фирма и след това да го пропусне от последния масив?

Благодаря!

Отговори:

5 за отговор № 1

Ако имате FirstName и lastName са по избор низове, можете да ги сравните с нула и да ги използвате в булев израз.

Вашата втора грешка се дължи на допълнителната парола след затварянето ви. Този код трябва да работи.

var predicate: NSPredicate = NSPredicate { (AnyObject person, NSDictionary bindings) -> Bool in
var firstName: String? = ABRecordCopyValue(person as ABRecordRef, kABPersonFirstNameProperty).takeRetainedValue() as? String
var lastName: String? = ABRecordCopyValue(person as ABRecordRef, kABPersonLastNameProperty).takeRetainedValue() as? String

return firstName != nil || lastName != nil
}

5 за отговор № 2

Ако преобразувате NSArray в Swift Array, можете да използвате метода Swift на Array.filter. Ето един пример с по-прости обекти за яснота:

let arrObjc: NSArray = ["aaa", "bab", "bbb", "baa", "cbc"]
let arr: [AnyObject] = arrObjc //create a swift array with same data

// filter takes a block that returns a boolean. True: keep the item, False: drop it.
arr.filter{
if let s = $0 as? String {  // first try to cast AnyObject to our expected type.
return contains(s, "a")   // return true if we want this item, false otherwise.
} else {
return false              // this object is of the wrong type, return false.
}
}

// returns: ["aaa", "bab", "baa"]

0 за отговор № 3

Тестът ви на последния ред в Цел-С ще бъдевръщане, ако firstName е нула или ако lastName е нула. Във вашия бърз код просто се опитвате да сравнявате две струни, сякаш са били блус. Вместо това искате да се върнете, ако firstName съществува, така че трябва вместо това да направите това както в целта си, така и в Swift кода:

return firstName != nil