---
title: "Flutter SDK'da ilk açılışta AA hedefli paywall gösterme"
description: "Flutter'da ilk açılışta paywall göstermeden önce Apple Ads attribution verisini kısa süre bekleyin; zaman aşımında varsayılan kitleye geri dönün. AdaptyProfile.appliedAttributionSources kullanır."
---

Apple Ads (AA) attribution, `Adapty().activate()` çağrısından sonra asenkron olarak gelir. İlk açılışta genellikle henüz gelmemiş olduğundan, hemen `getPaywall` çağırırsanız Adapty isteği varsayılan kitleye göre çözümler ve Apple Ads kullanıcıları AA segmentine özel paywallunuzu göremez. Bir paywallı gösterip sonra değiştirmek yerine, herhangi bir şey göstermeden önce AA attribution'ının gelmesini kısaca bekleyin: attribution kısa bir zaman aşımı içinde gelirse hedeflenmiş paywallı, gelmezse varsayılan kitle paywallını gösterin. `AdaptyProfile.appliedAttributionSources`, AA attribution'ının uygulanıp uygulanmadığını size bildirir.
## Başlamadan önce \{#before-you-start\}

İhtiyacınız olanlar:
- Adapty Flutter SDK **3.17.0** veya üzeri.
- Adapty'de uygulama için yapılandırılmış Apple Ads. Bkz. [Apple Ads](apple-search-ads).
## Nasıl çalışır \{#how-it-works\}

`Adapty().activate()` çağrısının ardından SDK, arka planda Apple'dan Apple Ads attribution verilerini ister ve sonucu Adapty'nin backend'ine iletir. AA, profil için aktif attribution kaynağı haline geldiğinde SDK, `didUpdateProfileStream` dinleyicinize güncellenmiş bir `AdaptyProfile` iletir; bu profil, `appliedAttributionSources` listesinde `AdaptyAttributionSource.appleAds` değerini içerir.

İlk başlatmada ele almanız gereken iki olası sonuç vardır:
1. **Attribution zaman aşımı süreniz içinde gelir.** `getPaywall` çağrısı yapın — Adapty isteği Apple Ads kitlesine göre çözümler ve hedeflenmiş paywall'ı döndürür.
2. **Önce zaman aşımı süresi dolar.** Bunun yerine varsayılan kitle paywall'ını gösterin; böylece Apple Ads attribution'ı olmayan kullanıcılar beklemek zorunda kalmaz. `getPaywallForDefaultAudience`, segmentasyon için beklemeden bunu döndürür.

`appliedAttributionSources` boş olabilir. Bu şu anlama gelir:

- Bu profil için Apple Ads attribution'ı henüz işlenmemiştir veya
- hiç attribution gelmemiştir.
Her iki durumda da `getPaywallForDefaultAudience` güvenle çağrılabilir — profil durumundan bağımsız olarak varsayılan kitleye ait paywall'ı döndürür.

:::important
Bekleme yalnızca ilk başlatma için geçerlidir. Apple Ads attribution'ı bir kez kaydedildikten sonra, profilde kalıcı olarak saklanır. Sonraki her başlatmada, önbelleğe alınmış profil zaten `appliedAttributionSources` içinde `AdaptyAttributionSource.appleAds` bilgisini taşır; bu sayede attribution yolu hemen çözümlenir ve `getPaywall` herhangi bir gecikme olmadan Apple Ads segmentine göre paywall'ı döndürür.
:::
## Uygulama \{#implementation\}

İlk başlatmada `AdaptyAttributionSource.appleAds` için bekleyin ve katı bir zaman aşımı uygulayın — Apple Ads attribution hiç gelmese de, bu kullanıcıların yine de bir paywall görmesi gerekir.
1. **SDK'yı etkinleştirin.** Bkz. [Flutter SDK'yı yükle ve yapılandır](sdk-installation-flutter).
2. **`Adapty().didUpdateProfileStream.listen(…)` ile profil güncellemelerini dinleyin.** Henüz dinleyiciyi kurmadıysanız bkz. [Abonelik güncellemelerini dinle](flutter-check-subscription-status#listen-to-subscription-updates).
3. **`appliedAttributionSources` içinde `AdaptyAttributionSource.appleAds` değerini bekleyin.** Bu değer göründüğünde `getPaywall` ile paywallı yükleyin — Adapty, AA segmentine uygun varyantı döndürür:
```dart
final subscription = Adapty().didUpdateProfileStream.listen((profile) async {
  if (!profile.appliedAttributionSources.contains(AdaptyAttributionSource.appleAds)) return;
  final paywall = await Adapty().getPaywall(placementId: placementId);
  // segmentlenmiş paywall'u göster, ardından aboneliği ve zamanlayıcıyı iptal et
});
```

   `didUpdateProfileStream` bir broadcast stream'dir ve yeniden oynatma yapmaz; bu nedenle `getProfile()` ile mevcut profili bir kez de doğrudan kontrol edin. Uygulama yeniden başlatıldığında, kaydedilmiş attribution zaten uygulanmış olur ve yeniden emit edilmez.
4. **Abonelikle paralel olarak 3–5 saniyelik bir zamanlayıcı başlatın.** Zamanlayıcı, `AdaptyAttributionSource.appleAds` gelmeden önce tetiklenirse, bunun yerine `getPaywallForDefaultAudience` ile varsayılan kitle paywallını yükleyin. Önce çözümlenen paywallı gösterin ve diğer yolu iptal edin; böylece paywall iki kez çekilmez. Ağ isteği başarısız olursa kullanıcının askıda kalmaması için placement'a bir [yedek paywall](flutter-use-fallback-paywalls) yapılandırın.
## Tam örnek \{#complete-example\}

Aşağıdaki uygulama, attribution'ı bir zaman aşımıyla yarıştırır, varsayılan kitle paywall'ını paralelde önceden yükler ve uygun olan paywall'ı döndürür. Çağıran taraf yalnızca tek bir fonksiyonu bekler — çağrı noktasında yönetilecek dinleyici veya durum bayrağı yoktur:

- Attribution `timeout` süresi içinde gelirse, `getPaywall` aracılığıyla segmentlere ayrılmış paywall'ı döndürür.
- Önce `timeout` süresi dolarsa, `getPaywallForDefaultAudience` aracılığıyla önceden yüklenmiş varsayılan kitle paywall'ını döndürür.
```dart title="apple_ads_paywall.dart"

/// Returns the Apple Ads-segmented paywall if attribution is applied within
/// [timeout], otherwise the default-audience paywall. Call after Adapty().activate().
Future<AdaptyPaywall> getPaywallOrDefault({
  required String placementId,
  required Duration timeout,
}) {
  // Prefetch the default-audience paywall right away so the timeout path resolves
  // without an extra network round-trip. `getPaywallForDefaultAudience` skips the
  // wait for segmentation data. `..ignore()` keeps an unused prefetch from surfacing
  // as an unhandled error; the error still reaches the caller if this paywall wins.
  final defaultPaywall =
      Adapty().getPaywallForDefaultAudience(placementId: placementId)..ignore();

  final completer = Completer<AdaptyPaywall>();
  late final StreamSubscription<AdaptyProfile> subscription;
  late final Timer timer;

  void resolve(Future<AdaptyPaywall> paywall) {
    if (completer.isCompleted) return;
    timer.cancel();
    subscription.cancel();
    completer.complete(paywall);
  }

  void onProfile(AdaptyProfile profile) {
    if (profile.appliedAttributionSources.contains(AdaptyAttributionSource.appleAds)) {
      resolve(Adapty().getPaywall(placementId: placementId));
    }
  }

  // Attribution path: react to profile updates as attribution is applied.
  subscription = Adapty().didUpdateProfileStream.listen(onProfile);

  // The stream is a broadcast stream and doesn't replay, so check the current
  // profile too — on relaunches attribution is already stored and won't re-emit.
  Adapty().getProfile().then(onProfile).ignore();

  // Timeout path: fall back to the prefetched default-audience paywall.
  timer = Timer(timeout, () => resolve(defaultPaywall));

  return completer.future;
}
```

Splash ekranınızdan çağırın, ardından tamamlandığında paywallı gösterin:

```dart
try {
  final paywall = await getPaywallOrDefault(
    placementId: 'YOUR_PLACEMENT_ID',
    timeout: const Duration(seconds: 5),
  );
  // present the paywall
} on AdaptyError catch (adaptyError) {
  // handle the error or show a fallback paywall
} catch (e) {
  // handle the error
}
```
`timeout` değerini, kullanıcılarınızı herhangi bir paywall görünmeden önce ne kadar bekletmek istediğinize göre ayarlayın. Kullanıcıların büyük çoğunluğunun Apple Ads attribution verisi olmadığını düşünürsek, hepsi tam timeout süresini bekler; bu yüzden 3 ila 5 saniye makul bir denge noktasıdır. Gelmesi beklenen attribution verisi genellikle uygulama açılışından birkaç saniye içinde ulaşır.
Uygulamanız başka amaçlarla (örneğin, [abonelik durumunu kontrol etmek](flutter-check-subscription-status#listen-to-subscription-updates) için) zaten `didUpdateProfileStream`'i dinliyorsa, herhangi bir değişiklik yapmanıza gerek yok. `didUpdateProfileStream` bir broadcast stream olduğundan, birbirinden bağımsız birden fazla dinleyiciyi destekler ve bunları birbirini etkilemeden kullanabilirsiniz.