2015-04-09 2 views
0

У меня есть панель поиска. И данные отображаются в ярлыках с scrollview.Панель поиска с основными проблемами с данными

Для Ex:

основные поля данных:

1.id
2.company
3.Employe Имя

4.Address

Если я идентификатор типа, компания или Employee Name в строке поиска я хочу рассказать о связанных результатах.

мой код:

Для поиска данных:

func searchBar(searchBar: UISearchBar, textDidChange searchText: String) { 

     var request = NSFetchRequest(entityName: "Agency") 
    request.returnsObjectsAsFaults = false 
     var countResult : NSArray = context.executeFetchRequest(request, error: nil)! 



    let result = NSPredicate(format: "SELF CONTAINS[c] %@",searchText) 


    self.filtered = self.countResult.filteredArrayUsingPredicate(result!) 



    if (filtered.count == 0) { 
     searchActive = false; 
    }else { 
     searchActive = true; 
    } 

    println(filtered) 

} 

Это показывает ошибка "«Невозможно использовать в/содержит оператор с коллекцией".

Эти коды не могут удовлетворить то, что я хочу. А также у меня нет идеи, как получить связанные строки в соответствии с введенным значением в строке поиска.

Спасибо заранее.

+0

Является ли это ошибкой во время выполнения? Если это, у меня есть довольно хорошая идея, какова ваша проблема. – ABakerSmith

ответ

3

Первая проблема заключается в ваш предикат - вы пытаетесь использовать CONTAINS на NSManagedObject подкласса, но CONTAINS работает только с String. Чтобы проверить, содержится ли ваш текст поиска в любом из ваших управляемых объектов, вам необходимо оценить, содержится ли он в каждом атрибуте (в вашем случае id, company и empolyeeName, я предполагаю, что они все String s).

Чтобы сделать это, вы должны изменить свой предикат:

let searchPredicate = NSPredicate(format: "id BEGINSWITH %@ OR 
              company BEGINSWITH %@ OR 
              employeeName BEGINSWITH %@", 
              searchText, searchText, searchText) 

Я бы рекомендовал использовать BEGINSWITH вместо CONTAINS[c], так как при поиске вашего пользователя, скорее всего, входя в первую часть фразы. Кроме того, как сказал Apple, в их 2013 WWDC ток ядра Оптимизация производительности данных и отладки -

... у нас начинается с и заканчивается, и это, безусловно, самый дешевый запрос, который вы можете выполнить.

...

Содержит более дорогим, потому что мы должны работать вместе и посмотреть содержит ли ...

И в случае поиска, вы хотите, чтобы это было быстро !

Во-вторых, вам не нужно фильтровать ваши результаты после, возвращая их из CoreData. Вы можете установить свойство predicate на свой NSFetchRequest, и ваши возвращенные результаты будут отфильтрованы.Например:

let request = NSFetchRequest(entityName: "Agency") 
request.predicate = // Your predicate... 

let results = context.executeFetchRequest(request, error) 
// Now do what you need with the results. 

Заключительное примечание, то лучше не заставлять разворачивать свои результаты от executeRequest в случае, если есть какая-то проблема и nil возвращается - в этом случае приложение будет катастрофа. Можно использовать вместо:

if let unwrappedResults = results { 
    // Now do what you want with the unwrapped results. 
} 
+0

ok Спасибо большое. Я попробую с вашим предложением. – Lydia

+0

Я использую метки для заполнения данных результата вместо tableview. Можете ли вы привести пример кода для этого. – Lydia

+0

Приведенный выше код должен хорошо работать с этим. Для заполнения ярлыков вы должны использовать unwrappedResults. Есть ли конкретная причина, по которой вы не используете UITableView? – ABakerSmith

1

Я подозреваю, что это что-то делать с использованием SELF в формате предиката, и «сбор», упомянутый в сообщении об ошибке является контроллер суб/класс, в течение которого ваш код проживает.

Попробуйте что-нибудь подобное (простите меня, я Obj-C не Swift, поэтому может быть неправильный синтаксис).

let searchAttribute = <<entity.attribute key path>> 
let result = NSPredicate(format:"%K CONTAINS[cd] %@",searchAttribute, searchText) 

Где% K ссылается на путь ключа, который в случае с основными данными является вашим атрибутом объекта. Например: Agency.name, если этот атрибут существует для объекта вашего агентства.

Подробнее о Predicate Format String Syntax.


UPDATE после третьего комментария ...

В моих приложениях мое решение включает в себя создание пользовательского метода в продлении основных данных генерируется NSManagedObject подкласса. Если это звучит так, как будто вы знаете, что я имею в виду, дайте мне знать, и я напишу подробности.

В то же время, создать специальный метод, в какой бы класс ваш UISearchBar управляется ... (Извинения Obj-C не Swift)

- (NSString *)searchKey { 
    NSString *tempSearchKey = nil; 

    NSString *searchAtrribute1 = Agency.attribute1; 
    NSString *searchAtrribute2 = Agency.attribute2; 
    NSString *searchAtrribute3 = Agency.attribute3; 
    NSString *searchAtrribute4 = Agency.attribute4; 

    tempSearchKey = [NSString stringWithFormat:@"%@ %@ %@ %@", searchAtrribute1, searchAtrribute2, searchAtrribute3, searchAtrribute4]; 

    return tempSearchKey; 
} 

Вам, очевидно, нужен сильный ссылка для вашего объекта Agency объекта для сохранения внутри класса, в противном случае вам понадобится встроить этот бит кода в функцию searchBar.

Работать нормально?

+0

Ницца, но у меня более 11 полей. – Lydia

+0

Более 11 атрибутов для одного объекта? – andrewbuilder

+0

Да, но я хочу предикатировать только 3, так как изменение кода, – Lydia

Смежные вопросы