Компонент Advanced Place Details
Расширенная версия компонента Place Details предлагает те же функции, что и Places Details Essentials. Вы также можете выбрать, будет ли показываться название места, настроить командные кнопки компонента и применить параметры поиска и фильтрации к показываемым отзывам и медиафайлам.
Расширенная конфигурация Place Details
Чтобы получить доступ к продвинутым функциям, используйте AdvancedPlaceDetailsView или AdvancedPlaceDetailsCompactView.
Параметры показа контента
Вы можете указать, какой контент показывать, используя перечисления в AdvancedPlaceDetailsContent. Вы можете настроить весь контент, доступный в Places Details Essentials, а также выбрать, будет ли показываться название места.
Как настроить командные кнопки
Чтобы удалить или настроить командные кнопки, используйте методы .cornerActions и .mainActions класса AdvancedPlaceDetailsView или AdvancedPlaceDetailsCompactView.
Требования к визуальному указанию авторства
Важно! Вы должны четко сообщить конечным пользователям, что при нажатии кнопки настраиваемого действия их данные будут переданы третьей стороне, не связанной с Google. Подробнее о требованиях по указанию авторства…
На примере справа показано специальное изображение, из которого понятно, что информация о пользователе будет отправлена в Altostrat.
Как использовать поиск и фильтры
Используйте методы .searchMediaOptions и .searchReviewOptions из AdvancedPlaceDetailsView или AdvancedPlaceDetailsCompactView, чтобы включить поиск и фильтрацию медиаконтента или отзывов.
Как создавать собственные рекламные места
С помощью специальных рекламных мест вы можете добавлять собственный контент (например, сводки, созданные ИИ, временные метки маршрута или специальные значки) непосредственно в предопределенные зоны макета.
Чтобы добавить пользовательские стили контента, используйте метод .placeDetailsCompactContentSlot класса AdvancedPlaceDetailsCompactView. Доступны позиции .basicSectionTop и .basicSectionBottom.
Требования по указанию авторства и рекомендации по контенту для слотов контента
Когда встраивается рекламное место для собственного контента, раскрытие информации автоматически обновляется, чтобы уточнить, какой контент предоставляется Google, а какой – третьими лицами.
Значки должны:
Поддерживайте четкую визуальную иерархию между информацией о местах Google и собственным контентом, чтобы у пользователей не возникало сомнений в источнике информации.
Значки должны:
Предоставляйте пользователям локализованную и ценную информацию, которая поможет им достичь своих целей. Например, данные о доступности номеров в реальном времени или о сроках бронирования помогут пользователям быстрее принимать взвешенные решения.
Чего не следует делать
Не дублируйте существующую информацию о местах в Google, такую как оценки, отзывы или часы работы, даже если вы скрыли контент, предоставленный Google. В противном случае пользователи могут не понять, откуда поступает контент – от Google или от стороннего поставщика.
Чего не следует делать
Не используйте заявления и значки без указания авторства (например, "Лучшая рекомендация!"), которые могут быть ошибочно приняты за официальные рекомендации Google. В пользовательском контенте должен быть явно указан источник.
Чего не следует делать
Не добавляйте в контейнеры пользовательских мест рекламу, маркетинговые тексты, скидки и предложения оформить подписку.
Примеры расширенных сведений о месте
Не указывайте название места.
Чтобы не указывать название места, не добавляйте.name в параметр content в AdvancedPlaceDetailsConfiguration.
Swift
struct DemoView: View { static let peetsCoffeePlaceID = "ChIJT7FdmYiAhYAROFOvrIxRJDU" // Query for loading the place details component. @State var query: PlaceDetailsQuery = PlaceDetailsQuery( identifier: .placeID(peetsCoffeePlaceID) ) @State private var favoritePlaces: Set<String> = [] var body: some View { AdvancedPlaceDetailsView( query: $query, configuration: AdvancedPlaceDetailsConfiguration( content:[.address()], theme: PlacesMaterialTheme() ), placeDetailsCallback: { result in if let place = result.place { print("Place: \(place.description)") } else { print("Error: \(String(describing: result.error))") } } ) } }
Как удалить командные кнопки
Swift
struct DemoView: View { static let peetsCoffeePlaceID = "ChIJT7FdmYiAhYAROFOvrIxRJDU" @State var query: PlaceDetailsQuery = PlaceDetailsQuery( identifier: .placeID(peetsCoffeePlaceID) ) var body: some View { AdvancedPlaceDetailsView( query: $query, configuration: AdvancedPlaceDetailsConfiguration( content: AdvancedPlaceDetailsView.allContent, theme: PlacesMaterialTheme() ), placeDetailsCallback: { result in if let place = result.place { print("Place: \(place.description)") } else { print("Error: \(String(describing: result.error))") } } ) .mainActions{ _ in return [] } } }
Добавление специальных и стандартных действий
В этом примере пользователю предлагается добавить место в избранное или удалить его оттуда, а также выполнить стандартное действие Открыть в Картах.
Swift
struct DemoView: View { static let peetsCoffeePlaceID = "ChIJT7FdmYiAhYAROFOvrIxRJDU" @State var query: PlaceDetailsQuery = PlaceDetailsQuery( identifier: .placeID(peetsCoffeePlaceID) ) @State var favoritePlaces: Set<String> = [] var body: some View { AdvancedPlaceDetailsView( query: $query, configuration: AdvancedPlaceDetailsConfiguration( content: AdvancedPlaceDetailsView.allContent, theme: PlacesMaterialTheme() ), placeDetailsCallback: { result in if let place = result.place { print("Place: \(place.description)") } else { print("Error: \(String(describing: result.error))") } } ) .mainActions{ place in var actions: [MainPlaceActionElement] = [] let placeID = place.placeID! if self.favoritePlaces.contains(placeID) { actions.append( .action( MainPlaceAction( image: Image(systemName: "heart.fill"), label: "Unfavorite" ) { _ in self.toggleFavorite(placeID) } ) ) } else { actions.append( .action( MainPlaceAction( image: Image(systemName: "heart"), label: "Favorite" ) { _ in self.toggleFavorite(placeID) } ) ) } actions.append(.actionId(.openMap(style: .primary))) return actions } .cornerActions { place in var actions: [CornerPlaceActionElement] = [] let placeID = place.placeID! if self.favoritePlaces.contains(placeID) { actions.append( .action( CornerPlaceAction( image: Image(systemName: "heart.fill"), accessibilityLabel: "Unfavorite", ) { _ in self.toggleFavorite(placeID) } ) ) } else { actions.append( .action( CornerPlaceAction( image: Image(systemName: "heart"), accessibilityLabel: "Favorite", ) { _ in self.toggleFavorite(placeID) } ) ) } actions.append(.actionId(.openMap(style: .primary))) return actions } } func toggleFavorite(_ placeID: String) { if favoritePlaces.contains(placeID) { favoritePlaces.remove(placeID) } else { favoritePlaces.insert(placeID) } } }
Фильтровать отзывы и медиаконтент
В этом примере кода показаны только медиафайлы и отзывы, в которых упоминается кофе.
Swift
struct DemoView: View { static let peetsCoffeePlaceID = "ChIJT7FdmYiAhYAROFOvrIxRJDU" @State var query: PlaceDetailsQuery = PlaceDetailsQuery( identifier: .placeID(peetsCoffeePlaceID) ) let searchMediaOptions = SearchMediaOptions(query: "coffee") let searchReviewsOptions = SearchReviewsOptions(query: "coffee") var body: some View { AdvancedPlaceDetailsView( query: $query, configuration: AdvancedPlaceDetailsConfiguration( content: [.media(), .reviews()], theme: PlacesMaterialTheme() ), placeDetailsCallback: { _ in } ) .searchMediaOptions(searchMediaOptions) { results in guard let result = results.first else { return } switch result { case .success(let summary): print("Summary: \(summary)") case .failure(let error): print("Error: \(error)") } } .searchReviewsOptions(searchReviewsOptions) { results in guard let result = results.first else { return } switch result { case .success(let summary): print("Summary: \(summary)") case .failure(let error): print("Error: \(error)") } } } }
Как создать рекламные места
В этом примере контент добавляется в рекламные места basicSectionTop и basicSectionBottom.
Swift
import SwiftUI import PlacesSwift struct ItineraryCard: View { static let peetsCoffeePlaceID = "ChIJT7FdmYiAhYAROFOvrIxRJDU" @State var query: PlaceDetailsQuery = PlaceDetailsQuery( identifier: .placeID(peetsCoffeePlaceID) ) var body: some View { AdvancedPlaceDetailsCompactView( orientation: .vertical, query: $query, configuration: AdvancedPlaceDetailsCompactConfiguration( content: AdvancedPlaceDetailsCompactView.allContent, theme: PlacesMaterialTheme() ), placeDetailsCallback: { _ in } ) .placeDetailsCompactContentSlot(position: .basicSectionTop) { place in Text("Day 2 • 2:30 PM") .font(.caption) .fontWeight(.bold) .foregroundColor(.accentColor) } .placeDetailsCompactContentSlot(position: .basicSectionBottom) { place in VStack(alignment: .leading, spacing: 4) { Text("AI Notes") .font(.caption) .bold() Text("Great quiet atmosphere for morning meetings. Famous for house-roasted pour-overs.") .font(.footnote) .foregroundColor(.secondary) } .padding(8) .background(Color(.systemGray6)) .cornerRadius(8) } } }