مكوّن "تفاصيل المكان المتقدّمة"

يوفّر الإصدار المتقدّم من مكوّن "تفاصيل المكان" الميزات نفسها التي يوفّرها Places Details Essentials. ويتيح لك أيضًا اختيار ما إذا كان سيتم عرض اسم المكان، وضبط أزرار الإجراءات الخاصة بالمكوّن، وتطبيق خيارات البحث والفلترة على المراجعات والوسائط المعروضة.

الإعدادات المتقدّمة لخدمة "تفاصيل المكان"

استخدِم AdvancedPlaceDetailsView أو AdvancedPlaceDetailsCompactView للوصول إلى الميزات المتقدّمة.

خيارات عرض المحتوى

يمكنك تحديد المحتوى الذي تريد عرضه باستخدام التعدادات في AdvancedPlaceDetailsContent. يمكنك ضبط كل المحتوى نفسه مثل أساسيات تفاصيل الأماكن، بالإضافة إلى اختيار ما إذا كان سيتم عرض اسم المكان.

ضبط أزرار الإجراءات

استخدِم الطريقتَين .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 []
    }
  }
}

إضافة إجراءات مخصّصة ومحدّدة مسبقًا

يضيف هذا النموذج خيارًا للمستخدم لإضافة مكان إلى المفضّلة أو إزالته منها، إلى جانب الإجراء المحدّد مسبقًا الفتح في "خرائط Google".

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