Przejdź do treści
AppFoyer
Zacznij

Poradniki Po premierze

Jak utrzymać politykę prywatności w zgodzie z buildem

Politykę prywatności pisze się raz, a dezaktualizuje się w dniu, w którym pull request dodaje SDK. Jak zauważyć to w samym pull requeście dzięki bezpłatnej kontroli, która czyta tylko pliki builda.

Zapisz, na podstawie jakich SDK, typów danych i uprawnień powstały Twoje strony, a potem porównuj z tym zapisem pliki builda w każdym pull requeście. Gdy pojawi się zależność lub uprawnienie, którego zapis nie zawiera, pull request pokaże to przed wydaniem, gdy politykę prywatności i formularze w sklepach nadal łatwo zaktualizować.

Zrób to zamiast tego w kilka minut

AppFoyer hostuje strony, o których jest ten poradnik — politykę prywatności, regulamin, wsparcie, usuwanie konta i app-ads.txt — na ich własnej subdomenie, bez Twojej własnej domeny i serwera. Jedna aplikacja jest za darmo, a nic, czego wymaga sklep, nigdy nie jest płatne.

Sprawdzono 30 września 2026. Zasady sklepów się zmieniają, czasem bez zapowiedzi. Wszystko poniżej linkuje do oficjalnej dokumentacji i to ona — nie ta strona — jest rozstrzygająca. Jeśli się różnią, rację ma sklep. Ten poradnik jest przetłumaczony z angielskiego; cytaty z dokumentacji sklepów pozostawiono w oryginalnym brzmieniu angielskim.

Napisanie polityki prywatności to jednorazowa praca. Utrzymanie jej prawdziwości już nie: polityka opisuje build, który miałeś w chwili jej pisania, a build ciągle się zmienia. Pull request dodaje raportowanie awarii, bibliotekę subskrypcji albo uprawnienie do lokalizacji, aplikacja trafia do wydania, a polityka, formularz Data safety i szczegóły App Privacy nadal opisują starą aplikację.

Oba sklepy traktują to jako Twój problem, nie swój. Google Play mówi, że Twoje odpowiedzi w Data safety muszą być zawsze dokładne i kompletne, a dane zbierane przez biblioteki i SDK firm trzecich w Twojej aplikacji musisz zadeklarować sam. Apple mówi to samo o szczegółach App Privacy i dodaje, że odpowiedzi w App Store Connect możesz zmienić w dowolnym momencie bez przesyłania aktualizacji.

Skąd naprawdę bierze się rozbieżność

Prawie nigdy z decyzji, by „zbierać więcej danych”. Bierze się ze zwykłej pracy inżynierskiej:

  • Nowa zależność. Raportowanie awarii, analityka, SDK paywalla, biblioteka map.
  • Nowe uprawnienie. Lokalizacja dla jednej funkcji, aparat dla skanera, śledzenie na potrzeby reklam.
  • Flavor lub target. Darmowy build dostaje SDK reklamowy, którego nie ma build płatny.
  • Usunięcie. To też rozbieżność: polityka deklaruje teraz za dużo, co jest bezpieczniejszym błędem, ale nadal błędem.

Każda z tych zmian trafia do pliku builda: build.gradle, AndroidManifest.xml, Podfile, Package.swift, Info.plist, pubspec.yaml, package.json. Dzięki temu da się to sprawdzić.

Podejście: zapis i kontrola w każdym pull requeście

  1. Gdy Twoje strony są pisane, zapisz, na podstawie czego powstały: SDK, typy danych i uprawnienia obecne w tym momencie w buildzie.
  2. W każdym pull requeście ponownie przeczytaj pliki builda i porównaj.
  3. Gdy coś się różni, powiedz co, gdzie (plik i linia) i na którą stronę lub formularz może to wpłynąć.

Liczą się dwie właściwości. Kontrola musi czytać wyłącznie pliki builda, nigdy kod źródłowy, nigdy sekrety, więc można ją bezpiecznie uruchomić w każdym repozytorium. I musi mówić „może być nieaktualne”, a nie „naruszenie”: biblioteka w pliku builda nie dowodzi, że aplikacja jej używa, a tylko Ty wiesz, czy zmienia ona to, co zbiera Twoja aplikacja.

Konfiguracja z AppFoyer

Kontrola jest bezpłatna w każdym planie. Czyta tylko pliki builda, nie potrzebuje klucza ani sekretu, niczego nigdzie nie wysyła i nigdy nie zmienia żadnej strony.

Z pluginem Claude Code

  1. Powiedz “make this app store-ready” (przygotuj tę aplikację do sklepów). Oprócz przygotowania projektów stron plugin zapisuje appfoyer.json w katalogu głównym repozytorium: zapis tego, na podstawie czego powstały strony.
  2. Powiedz “add the AppFoyer drift check” (dodaj kontrolę rozbieżności AppFoyer). Plugin pokaże Ci workflow GitHub i zapisze .github/workflows/appfoyer.yml, gdy się zgodzisz.
  3. Zatwierdź (commit) oba pliki. Plugin nigdy nie robi za Ciebie commitów ani pushy.

Bez pluginu

Dodaj workflow samodzielnie:

name: AppFoyer drift check
on: pull_request
permissions:
  contents: read
jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - uses: appfoyer/check-action@v1

Otwórz pull request. Gdy w repozytorium nie ma jeszcze appfoyer.json, podsumowanie zadania (job summary) pokazuje plik, który zostałby zapisany na podstawie Twojego builda. Porównaj go z opublikowanymi stronami i zatwierdź.

Albo utwórz go lokalnie, tym samym skanerem opublikowanym w npm:

npx @appfoyer/check init

W innym systemie CI

Pakiet npm działa wszędzie tam, gdzie działa Node 20 lub nowszy. Na przykład w GitLab:

appfoyer-drift-check:
  image: node:22
  script:
    - npx -y @appfoyer/check --fail-on-drift

--format markdown daje ten sam raport, który pokazuje podsumowanie zadania w GitHub; --format json jest przeznaczony dla skryptów.

Jak wygląda wynik

Pull request, który dodaje RevenueCat do aplikacji, której strony napisano bez niego:

"Trail Notes": 2 changes
  + In-app purchases / subscriptions (data collected)  app/build.gradle.kts:28
      → Privacy policy may not declare "In-app purchases / subscriptions"
      → Google Play Data safety and Apple App Privacy answers may be outdated
      → Terms may not cover purchases and subscriptions
  + RevenueCat (SDK)  app/build.gradle.kts:28
      → Store forms: RevenueCat is not in the app's SDK list
      → Privacy policy may not name this SDK

Domyślnie zadanie raportuje i przechodzi. Dodaj fail-on-drift: "true" pod with:, aby kończyło się niepowodzeniem, dopóki zapis nie zostanie zaktualizowany.

Gdy kontrola zgłosi zmianę

  1. Zaktualizuj to, na co zmiana wpływa. Powiedz ponownie “make this app store-ready” na tej samej gałęzi: plugin ponownie przeczyta build, zaktualizuje fakty o aplikacji, przygotuje nowe projekty stron, których dotyczy zmiana, i przepisze appfoyer.json. Albo samodzielnie edytuj strony i kartę Store forms w panelu.
  2. Odśwież zapis. Plugin już to zrobił. Po edycji w panelu uruchom npx @appfoyer/check update albo skopiuj odświeżony plik z podsumowania zadania, gdzie znajduje się pod wynikami.
  3. Zatwierdź go w tym samym pull requeście. Następne uruchomienie nie pokaże zmian, a historia pokaże, że zależność i zmiana w ujawnieniach pojawiły się razem.
  4. Zaktualizuj formularze w konsolach sklepów. Ani kontrola, ani AppFoyer nie mają dostępu do Play Console ani App Store Connect. Projekty odpowiedzi są na karcie Store forms w panelu.
  5. Opublikuj zaktualizowane projekty z ekranu przeglądu.

Kilka aplikacji w jednym repozytorium

appfoyer.json zawiera jeden wpis na każdą stronę aplikacji w sklepie. Product flavor z własnym application id dostaje własny wpis, więc SDK reklamowy używany tylko przez darmowy flavor jest porównywany ze stronami darmowego flavora, a nie płatnego. Plugin zapisuje jeden wpis na każdy flavor, który przygotował do sklepów. Ręcznie wpis przyjmuje listę sourceSets (["free"] albo, w buildzie z wieloma wymiarami, każdy flavor z kombinacji plus samą kombinację) oraz folder root, gdy aplikacja znajduje się w monorepo.

Czego kontrola nie widzi

  • Zależności zależności, z wyjątkiem iOS, gdzie wymienia je Podfile.lock. SDK dołączony przez inną bibliotekę nie pojawia się w Twoim pliku builda, więc nie pojawia się też tutaj.
  • Konfiguracji zapisanej tylko w kodzie. app.config.js / app.config.ts w Expo to JavaScript i nie jest czytany; app.json i package.json są.
  • Czy używasz tego, co deklarujesz. Zależność, która jest obecna, ale nieużywana, i tak zostanie zgłoszona.
  • Twojego backendu. Nic w pliku builda nie mówi, co i jak długo przechowuje Twój serwer.

To przypomnienie w chwili, gdy ujawnienie zmiany jest najtańsze, a nie werdykt zgodności i nie porada prawna.

Źródła oficjalne