Komponent Zaawansowane informacje o miejscu

Wersja zaawansowana komponentu Informacje o miejscu oferuje te same funkcje co Informacje o miejscu w wersji podstawowej. Umożliwia też określenie, czy ma być wyświetlana nazwa miejsca, skonfigurowanie przycisków działania komponentu oraz zastosowanie opcji wyszukiwania i filtrowania wyświetlanych opinii i multimediów.

Zaawansowana konfiguracja komponentu Informacje o miejscu

Użyj AdvancedPlaceDetailsView lub AdvancedPlaceDetailsCompactView, aby uzyskać dostęp do funkcji zaawansowanych.

Opcje wyświetlania treści

Możesz określić, które treści mają być wyświetlane, za pomocą wyliczeń w AdvancedPlaceDetailsContent. Możesz skonfigurować wszystkie te same treści co w przypadku Podstawowych informacji o miejscu, a także wybrać, czy ma być wyświetlana nazwa miejsca.

Konfigurowanie przycisków działań

Użyj metod .cornerActions i .mainActions w przypadku AdvancedPlaceDetailsView lub AdvancedPlaceDetailsCompactView, aby usunąć lub dostosować przyciski działania.

Wymagania dotyczące podania źródła w przypadku treści wizualnych

Kompaktowy widok informacji o miejscu z dostosowanymi przyciskami
Widok kompaktowy zaawansowanych informacji o miejscu z dostosowanym przyciskiem

Ważne: musisz informować użytkowników, kiedy przycisk polecenia niestandardowego będzie udostępniać informacje o użytkowniku podmiotowi zewnętrznemu innemu niż Google. Zobacz wymagania dotyczące atrybucji wizualnej.

Przykład po prawej stronie przedstawia obraz niestandardowy, który wyraźnie informuje, że dane użytkownika zostaną wysłane do firmy „Altostrat”.

Stosowanie opcji wyszukiwania i filtrowania

Użyj metod .searchMediaOptions i .searchReviewOptions w przypadku AdvancedPlaceDetailsView lub AdvancedPlaceDetailsCompactView, aby włączyć wyszukiwanie i filtrowanie multimediów lub recenzji.

Tworzenie niestandardowych miejsc na treści

Opcje miejsc docelowych niestandardowych miejsc na treści

Niestandardowe miejsca na treści umożliwiają dodawanie własnych treści (takich jak podsumowania wygenerowane przez AI, sygnatury czasowe planu podróży lub niestandardowe odznaki) bezpośrednio do wstępnie zdefiniowanych stref układu.

Aby dodać niestandardowe treści, użyj metody .placeDetailsCompactContentSlot w przypadku AdvancedPlaceDetailsCompactView. Dostępne pozycje to .basicSectionTop i .basicSectionBottom.

Wymagania dotyczące atrybucji i sugestie treści w przypadku miejsc na treści

Gdy niestandardowe miejsce na treści zostanie zamontowane, informacja automatycznie się zaktualizuje, aby wyjaśnić, które treści są dostarczane przez Google, a które przez osoby trzecie.

Należy

Zachowaj wyraźną hierarchię wizualną między szczegółami miejsca w Google a treściami niestandardowymi, aby uniknąć niejasności co do źródła informacji.

Zapobieganie niejasnościom dotyczącym źródła informacji

Należy

Zastanów się nad lokalnymi, wartościowymi informacjami dostosowanymi do bieżących celów użytkowników. Spersonalizowane treści, takie jak okna rezerwacji w czasie rzeczywistym czy aktualna dostępność, pomagają użytkownikom podejmować szybsze i bardziej świadome decyzje.

Dostarczanie cennych informacji

Nie

Nie powielaj istniejących szczegółów miejsca w Google, takich jak oceny, opinie czy godziny otwarcia, nawet jeśli ukryjesz treści dostarczone przez Google. Może to wprowadzać użytkowników w błąd co do źródła treści i tego, czy pochodzą one od Google, czy od osoby trzeciej.

Nie duplikuj istniejących informacji o miejscu w Google

Nie

Nie wyświetlaj nieprzypisanych twierdzeń ani plakietek (np. „Najlepsza rekomendacja!”), które można pomylić z oficjalnymi rekomendacjami Google. Treści niestandardowe muszą wyraźnie wskazywać źródło.

Nie wyświetlaj nieprzypisanych twierdzeń ani odznak

Nie

Nie umieszczaj w kontenerach niestandardowych miejsc reklam, tekstów marketingowych, rabatów promocyjnych ani zachęt do subskrypcji.

Nie umieszczaj reklam, tekstów marketingowych, rabatów promocyjnych ani zachęt do subskrypcji.

Przykłady zaawansowanych informacji o miejscu

Pomiń nazwę miejsca

Aby pominąć nazwę miejsca, nie umieszczaj .name w parametrze content funkcji 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))")
        }
      }
    )
  }
}

Usuwanie przycisków poleceń

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 []
    }
  }
}

Dodawanie działań niestandardowych i wstępnie zdefiniowanych

Ten przykład dodaje opcję oznaczania miejsca jako ulubionego lub usuwania go z ulubionych, a także predefiniowane działanie Otwórz w Mapach.

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)
    }
  }
}

Filtrowanie opinii i multimediów

Ten przykładowy kod pokazuje tylko media i opinie, w których pojawia się słowo „kawa”.

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)")
      }
    }
  }
}

Tworzenie miejsc na treści

Ten przykład dodaje treści do slotów basicSectionTop i 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)
      }
    }
}