iOS 9 Search
14 %
86 %
Приложения
Веб
Время проводимое в приложениях и веб
Разработчики сами выбирают какой контент
индексировать
Результаты поиска появляются в Spotlight и Safari
Результаты поиска видны даже когда приложение не
установлено
Поиск в приложении
Три доступных API
NSUserActivity CoreSpotlight Web Markup
Просмотренный
контент приложения
Любой контент
приложения
Контент приложения
в вебе
NSUserActivity CoreSpotlight Web Markup
Просмотренный
контент приложения
Любой контент
приложения
Контент приложения
в вебе
NSUserActivity + Search
NSUserActivity + Search
NSDictionary *userInfoDictionary = @{@"id":[NSString stringWithFormat:@"service-%@",service.serviceId]};
NSUserActivity *serviceActivity = [[NSUserActivity alloc] initWithActivityType:serviceDomainIdentifier];
serviceActivity.title = service.title;
serviceActivity.userInfo = userInfoDictionary;
serviceActivity.keywords =[NSSet setWithArray:service.keywords];
serviceActivity.webpageURL = [NSURL URLWithString:service.webpageURL];
serviceActivity.requiredUserInfoKeys =[NSSet setWithObject:userInfoDictionary];
serviceActivity.contentAttributeSet = attributeSet;
CSSearchableItemAttributeSet *attributeSet = [[CSSearchableItemAttributeSet alloc] initWithItemContentType:
(NSString *)kUTTypeCompositeContent];
attributeSet.title = service.title;
attributeSet.contentDescription = service.contentDescription;
attributeSet.relatedUniqueIdentifier = [NSString stringWithFormat:@"service-%@",service.serviceId];
serviceActivity.title
attributeSet.

contentDescription
attributeSet.

thumbnailData
CSSearchableItemAttributeSet *attributeSet = [[CSSearchableItemAttributeSet alloc] initWithItemContentType:
(NSString *)kUTTypeCompositeContent];
attributeSet.title = service.title;
attributeSet.contentDescription = service.contentDescription;
attributeSet.relatedUniqueIdentifier = [NSString stringWithFormat:@“service-%@",service.serviceId];
NSDictionary *userInfoDictionary = @{@"id":[NSString stringWithFormat:@"service-%@",service.serviceId]};
NSUserActivity *serviceActivity = [[NSUserActivity alloc] initWithActivityType:serviceDomainIdentifier];
serviceActivity.title = service.title;
serviceActivity.userInfo = userInfoDictionary;
serviceActivity.keywords =[NSSet setWithArray:service.keywords];
serviceActivity.webpageURL = [NSURL URLWithString:service.webpageURL];
serviceActivity.requiredUserInfoKeys =[NSSet setWithObject:userInfoDictionary];
serviceActivity.contentAttributeSet = attributeSet;
serviceActivity.eligibleForSearch = YES;
serviceActivity.eligibleForPublicIndexing = YES;
NSUserActivity + Search
NSUserActivity + Public Indexing
serviceActivity.webpageURL = [NSURL URLWithString:service.webpageURL];
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler {
if ([userActivity.activityType isEqualToString:serviceDomainIdentifier]) {
NSString *identifierPath = [NSString stringWithFormat:@"%@",[userActivity.userInfo objectForKey:@"id"]];
[self continueActivityForItemWith:identifierPath];
return YES;
}
return NO;
}
NSUserActivity delegate
NSUserActivity *serviceActivity = [[NSUserActivity alloc] initWithActivityType:serviceDomainIdentifier];serviceDomainIdentifier
Core Spotlight
NSUserActivity CoreSpotlight Web Markup
Просмотренный
контент приложения
Любой контент
приложения
Контент приложения
в вебе
Core Spotlight
CSSearchableItem CSSearchableItemAttributeSet
CSSearchableIndex
Item 1 Item 2 Item 3 Item 4 Item 5
Core Spotlight
CSSearchableItemAttributeSet *attributeSetPizza = [[CSSearchableItemAttributeSet alloc]
initWithItemContentType:(NSString *)kUTTypeCompositeContent];
attributeSet.title = @"Пицца";
attributeSet.contentDescription = @“Заказать пиццу”;
attributeSet.keywords = [NSArray arrayWithObjects:@"пицца", @"pizza", @"🍕 ", nil];
CSSearchableItem *item1 = [[CSSearchableItem alloc] initWithUniqueIdentifier:uniqueIdentifierPizza
domainIdentifier:restaurantTypeDomainIdentifier attributeSet:attributeSetPizza];
[[CSSearchableIndex defaultSearchableIndex] indexSearchableItems:[NSArray arrayWithObjects:item1, item2]
completionHandler:^(NSError * _Nullable error) {
NSLog(@"Search item indexed");
}];
CSSearchableItemAttributeSet *attributeSetSushi = [[CSSearchableItemAttributeSet alloc]
initWithItemContentType:(NSString *)kUTTypeCompositeContent];
attributeSet.title = @"Суши";
attributeSet.contentDescription = @“Заказать суши”;
attributeSet.keywords = [NSArray arrayWithObjects:@"суши", @"susi", @" 🍣 ", nil];
CSSearchableItem *item2 = [[CSSearchableItem alloc] initWithUniqueIdentifier:uniqueIdentifierSushi
domainIdentifier:restaurantTypeDomainIdentifier attributeSet:attributeSetSushi];
Core Spotlight Restore
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler {
if ([userActivity.activityType isEqualToString:CSSearchableItemActionType]) {
NSString * identifierPath = [NSString stringWithFormat:@"%@",[userActivity.userInfo
objectForKey:CSSearchableItemActivityIdentifier]];
[self continueActivityForItemWith:identifierPath];
return YES;
}
return NO;
}
CSSearchableItem *item1 = [[CSSearchableItem alloc] initWithUniqueIdentifier:uniqueIdentifierPizza
domainIdentifier:restaurantTypeDomainIdentifier attributeSet:attributeSetPizza];
uniqueIdentifierPizza
Сами добавляем и удаляем CSSearchableItem
Core Spotlight vs NSUserActivity index
CSSearchableItem не имеет срока жизни
Индексация большого объема данных
Методы делегата и дополнения
Core Spotlight vs NSUserActivity index
NSUserActivity
Core Spotlight
NSUserActivity CoreSpotlight Web Markup
Просмотренный
контент приложения
Любой контент
приложения
Контент приложения
в вебе
Web markup
Позволить Apple находить ваш сайт
Сайт имеет необходимую разметку для deep link
Приложение поддерживает обработку deep link
Контент структурирован по специальной форме
Web markup
Позволить Apple находить ваш сайт
Web markup
Сайт имеет необходимую разметку для deep link
<meta name="myApp" content="app-id=123,

app-argument=http://example.com/about”>

Delivery Club
View
GET — On the App Store
https://www.delivery-club.ru/pizza
Web markup
Приложение поддерживает обработку deep link
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options {
NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:YES];
NSString *path = components.path;
NSString *query = components.query;
if ([path isEqualToString:@"/pizza"]) {
//go to pizza controller passing query
}
}
Web markup
Контент структурирован по специальной форме
<meta property="og:image" content="http://example.com/hello.jpg">
<meta property="og:audio" content="http://example.com/music.m4a">
<meta property="og:video" content="http://example.com/cats.mp4">
Open Graph
<div itemprop="aggregateRating" itemscope itemtype="http://schema.org/
AggregateRating">
<span itemprop="ratingValue">4</span> stars -
<span itemprop="reviewCount">250</span> reviews
</div>
schema.org
Web markup
Контент структурирован по специальной форме
Итоги
NSUserActivity CoreSpotlight Web Markup
Спасибо!
Давид Лашхи
lashkhi@me.com

iOS 9 Search

  • 1.
  • 2.
  • 3.
    Разработчики сами выбираюткакой контент индексировать Результаты поиска появляются в Spotlight и Safari Результаты поиска видны даже когда приложение не установлено
  • 4.
    Поиск в приложении Тридоступных API NSUserActivity CoreSpotlight Web Markup Просмотренный контент приложения Любой контент приложения Контент приложения в вебе
  • 5.
    NSUserActivity CoreSpotlight WebMarkup Просмотренный контент приложения Любой контент приложения Контент приложения в вебе NSUserActivity + Search
  • 6.
    NSUserActivity + Search NSDictionary*userInfoDictionary = @{@"id":[NSString stringWithFormat:@"service-%@",service.serviceId]}; NSUserActivity *serviceActivity = [[NSUserActivity alloc] initWithActivityType:serviceDomainIdentifier]; serviceActivity.title = service.title; serviceActivity.userInfo = userInfoDictionary; serviceActivity.keywords =[NSSet setWithArray:service.keywords]; serviceActivity.webpageURL = [NSURL URLWithString:service.webpageURL]; serviceActivity.requiredUserInfoKeys =[NSSet setWithObject:userInfoDictionary]; serviceActivity.contentAttributeSet = attributeSet; CSSearchableItemAttributeSet *attributeSet = [[CSSearchableItemAttributeSet alloc] initWithItemContentType: (NSString *)kUTTypeCompositeContent]; attributeSet.title = service.title; attributeSet.contentDescription = service.contentDescription; attributeSet.relatedUniqueIdentifier = [NSString stringWithFormat:@"service-%@",service.serviceId];
  • 7.
  • 8.
    CSSearchableItemAttributeSet *attributeSet =[[CSSearchableItemAttributeSet alloc] initWithItemContentType: (NSString *)kUTTypeCompositeContent]; attributeSet.title = service.title; attributeSet.contentDescription = service.contentDescription; attributeSet.relatedUniqueIdentifier = [NSString stringWithFormat:@“service-%@",service.serviceId]; NSDictionary *userInfoDictionary = @{@"id":[NSString stringWithFormat:@"service-%@",service.serviceId]}; NSUserActivity *serviceActivity = [[NSUserActivity alloc] initWithActivityType:serviceDomainIdentifier]; serviceActivity.title = service.title; serviceActivity.userInfo = userInfoDictionary; serviceActivity.keywords =[NSSet setWithArray:service.keywords]; serviceActivity.webpageURL = [NSURL URLWithString:service.webpageURL]; serviceActivity.requiredUserInfoKeys =[NSSet setWithObject:userInfoDictionary]; serviceActivity.contentAttributeSet = attributeSet; serviceActivity.eligibleForSearch = YES; serviceActivity.eligibleForPublicIndexing = YES; NSUserActivity + Search
  • 9.
    NSUserActivity + PublicIndexing serviceActivity.webpageURL = [NSURL URLWithString:service.webpageURL];
  • 10.
    - (BOOL)application:(UIApplication *)applicationcontinueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler { if ([userActivity.activityType isEqualToString:serviceDomainIdentifier]) { NSString *identifierPath = [NSString stringWithFormat:@"%@",[userActivity.userInfo objectForKey:@"id"]]; [self continueActivityForItemWith:identifierPath]; return YES; } return NO; } NSUserActivity delegate NSUserActivity *serviceActivity = [[NSUserActivity alloc] initWithActivityType:serviceDomainIdentifier];serviceDomainIdentifier
  • 11.
    Core Spotlight NSUserActivity CoreSpotlightWeb Markup Просмотренный контент приложения Любой контент приложения Контент приложения в вебе
  • 12.
  • 13.
    Core Spotlight CSSearchableItemAttributeSet *attributeSetPizza= [[CSSearchableItemAttributeSet alloc] initWithItemContentType:(NSString *)kUTTypeCompositeContent]; attributeSet.title = @"Пицца"; attributeSet.contentDescription = @“Заказать пиццу”; attributeSet.keywords = [NSArray arrayWithObjects:@"пицца", @"pizza", @"🍕 ", nil]; CSSearchableItem *item1 = [[CSSearchableItem alloc] initWithUniqueIdentifier:uniqueIdentifierPizza domainIdentifier:restaurantTypeDomainIdentifier attributeSet:attributeSetPizza]; [[CSSearchableIndex defaultSearchableIndex] indexSearchableItems:[NSArray arrayWithObjects:item1, item2] completionHandler:^(NSError * _Nullable error) { NSLog(@"Search item indexed"); }]; CSSearchableItemAttributeSet *attributeSetSushi = [[CSSearchableItemAttributeSet alloc] initWithItemContentType:(NSString *)kUTTypeCompositeContent]; attributeSet.title = @"Суши"; attributeSet.contentDescription = @“Заказать суши”; attributeSet.keywords = [NSArray arrayWithObjects:@"суши", @"susi", @" 🍣 ", nil]; CSSearchableItem *item2 = [[CSSearchableItem alloc] initWithUniqueIdentifier:uniqueIdentifierSushi domainIdentifier:restaurantTypeDomainIdentifier attributeSet:attributeSetSushi];
  • 14.
    Core Spotlight Restore -(BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler { if ([userActivity.activityType isEqualToString:CSSearchableItemActionType]) { NSString * identifierPath = [NSString stringWithFormat:@"%@",[userActivity.userInfo objectForKey:CSSearchableItemActivityIdentifier]]; [self continueActivityForItemWith:identifierPath]; return YES; } return NO; } CSSearchableItem *item1 = [[CSSearchableItem alloc] initWithUniqueIdentifier:uniqueIdentifierPizza domainIdentifier:restaurantTypeDomainIdentifier attributeSet:attributeSetPizza]; uniqueIdentifierPizza
  • 15.
    Сами добавляем иудаляем CSSearchableItem Core Spotlight vs NSUserActivity index CSSearchableItem не имеет срока жизни Индексация большого объема данных Методы делегата и дополнения
  • 16.
    Core Spotlight vsNSUserActivity index NSUserActivity Core Spotlight
  • 17.
    NSUserActivity CoreSpotlight WebMarkup Просмотренный контент приложения Любой контент приложения Контент приложения в вебе
  • 18.
    Web markup Позволить Appleнаходить ваш сайт Сайт имеет необходимую разметку для deep link Приложение поддерживает обработку deep link Контент структурирован по специальной форме
  • 19.
    Web markup Позволить Appleнаходить ваш сайт
  • 20.
    Web markup Сайт имеетнеобходимую разметку для deep link <meta name="myApp" content="app-id=123, app-argument=http://example.com/about”> Delivery Club View GET — On the App Store https://www.delivery-club.ru/pizza
  • 21.
    Web markup Приложение поддерживаетобработку deep link - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options { NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:YES]; NSString *path = components.path; NSString *query = components.query; if ([path isEqualToString:@"/pizza"]) { //go to pizza controller passing query } }
  • 22.
    Web markup Контент структурированпо специальной форме <meta property="og:image" content="http://example.com/hello.jpg"> <meta property="og:audio" content="http://example.com/music.m4a"> <meta property="og:video" content="http://example.com/cats.mp4"> Open Graph <div itemprop="aggregateRating" itemscope itemtype="http://schema.org/ AggregateRating"> <span itemprop="ratingValue">4</span> stars - <span itemprop="reviewCount">250</span> reviews </div> schema.org
  • 23.
    Web markup Контент структурированпо специальной форме
  • 24.
  • 25.