Siirry sisältöön
Kaikki oppaat
Käytännön opas45 min lukuaika

Kuinka automatisoida App Store -kuvakaappaukset CI/CD:ssä

Käytännönläheinen päästä päähän -putki App Storen ja Google Playn kuvakaappausten generointiin CI-järjestelmästäsi käyttäen Fastlanea, GitHub Actionsia ja Bitriseä — konkreettisilla konfiguraatioilla, jotka voit liittää suoraan repoosi.

Eric Isensee
Eric IsenseeFounder · Last updated 5. toukokuuta 2026

TL;DR

Kaappaa raa'at sovelluksen kuvakaappaukset testiajossasi, lähetä ne Screenshots.live-rajapintaan template-ID:n ja kielilistan kanssa, ja Fastlane kirjoittaa renderöidyn, kehystetyn ja lokalisoidun lopputuloksen takaisin repoosi. Fastlanen deliver / supply työntää ne kauppoihin. Koko putki ajetaan tagi-pushilla tai yöllisellä cronilla alle viidessä minuutissa.

Miksi ylipäänsä automatisoida kuvakaappauksia?

Useimmat tiimit käsittelevät App Storen ja Google Playn kuvakaappauksia kertaluonteisina, käsin tehtyinä assetteina: suunnittelija mallintaa ne Figmassa, markkinoija pudottaa ne App Store Connectiin, eikä kukaan koske niihin ennen seuraavaa suurta uudelleenmuotoilua. Se malli kaatuu heti, kun julkaiset useammalle kuin yhdelle kielelle. 13 tuetulla kielellä, kolmella vaaditulla iPhonen koolla, kahdella iPadin koolla, sekä puhelimella ja tabletilla Google Playssa, puhutaan yli 100 PNG-tiedostosta yhtä julkaisua kohden. Kerro tämä jokaisella tekstimuutoksella, jokaisella kampanjalla ja jokaisella A/B-testivariantilla, eikä matematiikka enää toimi.

CI/CD:ssä automatisointi tekee kuvakaappauksista build-artefakteja, kuten mistä tahansa muusta binäärituotteesta. Ne ovat versioituja, toistettavia ja sidottuja committiin. Kun markkinointi muuttaa kuvatekstiä, putki rakentaa uudelleen jokaisen kielen ja lataa ne — ei manuaalisia Photoshop-sessioita, ei kielten välistä assettien ajautumista, eikä hylkäystä lähetyksessä, koska joku unohti 6,7 tuuman iPhone-variantin.

Miltä putki oikeastaan näyttää?

Siistin CI-kuvakaappausputken muoto on kolme vaihetta: kaappaus, renderöinti ja toimitus. Kaappaus on olemassa oleva UI-testisarjasi — XCUITest iOS:llä, Espresso Androidilla, Detox tai Maestro React Nativelle. Renderöinti on yksi Screenshots.live-rajapintakutsu kieltä kohden, joka koostaa raa'at framet kerran suunnittelemasi templaten päälle. Toimitus on olemassa olevat Fastlanen deliver- ja supply-toiminnot, joita käytät jo binääristen tiedostojen pushaukseen.

Screenshots.liven REST-renderöintirajapinta on koko järjestelmän kulmakivi. Lähetät raa'at kuvakaappaukset kerran ja saat takaisin jokaisen laitekoon, jokaisen kielen ja jokaisen variantin — täysin kehystettyinä, kuvatekstitettyinä ja lokalisoituina. Ei headless-selainta, ei Puppeteeria, ei manuaalista koon muuttamista.

Miten kytket sen Fastlaneen?

Fastlane on iOS:n / Androidin kanoninen julkaisuautomaatiotyökalu. Toimitamme virallisen Fastlane-pluginin, joka kapseloi renderöintirajapinnan yhteen toimintoon. Asenna se projektisi juuresta:

terminal
bash
fastlane add_plugin screenshotslive

Lisää sitten Fastfile-tiedostoosi lane, joka kaappaa, renderöi ja kirjoittaa renderöidyn ulosannin:

fastlane/Fastfile
ruby
lane :render_screenshots do
  # 1. Capture raw frames with XCUITest
  capture_screenshots(
    workspace: "MyApp.xcworkspace",
    scheme: "MyAppUITests",
    devices: ["iPhone 16 Pro Max", "iPad Pro 12.9-inch"],
    languages: ["en-US", "de-DE", "es-ES", "fr-FR", "pt-BR"]
  )

  # 2. Send raw frames to Screenshots.live, get framed PNGs back
  screenshotslive_render(
    api_token: ENV["SCREENSHOTSLIVE_API_TOKEN"],
    template_id: "tpl_app_release_v3",
    input_dir: "./fastlane/screenshots",
    output_dir: "./fastlane/rendered",
    locales: ["en", "de", "es", "fr", "pt"],
    devices: ["iphone-6.7", "iphone-6.1", "ipad-12.9"]
  )

  # 3. Push to App Store Connect
  deliver(
    screenshots_path: "./fastlane/rendered",
    skip_binary_upload: true,
    skip_metadata: false
  )
end

Plugin hoitaa lataukset, valmistumisen pollauksen ja latauksen rinnakkain. Tyypillinen 5 kielen ja 3 laitteen renderöinti valmistuu 60–90 sekunnissa.

Miten ajat tämän GitHub Actionsissa?

Pudota lane workflow-tiedostoon. Alla oleva workflow ajetaan jokaisella tagi-pushilla, joka vastaa v*-kuviota, sekä yöllisellä aikataululla, joten manuaalinen git tag v1.2.0 && git push --tags riittää tuoreen renderöinnin käynnistämiseen.

.github/workflows/screenshots.yml
yaml
name: Render Store Screenshots

on:
  push:
    tags: ["v*"]
  schedule:
    - cron: "0 4 * * *"  # nightly at 04:00 UTC
  workflow_dispatch:

jobs:
  render:
    runs-on: macos-14
    steps:
      - uses: actions/checkout@v4

      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: "3.2"
          bundler-cache: true

      - name: Render screenshots
        env:
          SCREENSHOTSLIVE_API_TOKEN: ${{ secrets.SCREENSHOTSLIVE_API_TOKEN }}
          FASTLANE_USER: ${{ secrets.FASTLANE_USER }}
          FASTLANE_PASSWORD: ${{ secrets.FASTLANE_PASSWORD }}
        run: bundle exec fastlane render_screenshots

      - name: Upload rendered artifacts
        uses: actions/upload-artifact@v4
        with:
          name: store-screenshots
          path: fastlane/rendered/

Tiimeille, jotka haluavat GitHub Actionin ilman Fastlanea, julkaisemme myös itsenäisen GitHub Actionin, joka keskustelee suoraan rajapinnan kanssa:

.github/workflows/screenshots-direct.yml
yaml
- uses: Screenshots-Live/render-screenshots-action@v1
  with:
    api-token: ${{ secrets.SCREENSHOTSLIVE_API_TOKEN }}
    template-id: tpl_app_release_v3
    locales: en,de,es,fr,pt,it,nl
    devices: iphone-6.7,iphone-6.1,ipad-12.9
    output-dir: ./screenshots

Entä Bitrise?

Bitrise-käyttäjät saavat saman lanen olemassa olevan Fastlane-stepin kautta. Lisää salaisuus nimeltä SCREENSHOTSLIVE_API_TOKEN Bitrise-työtilaasi, ja pudota tämä bitrise.yml-tiedostoosi:

bitrise.yml
yaml
workflows:
  render-screenshots:
    steps:
    - activate-ssh-key@4: {}
    - git-clone@8: {}
    - script@1:
        title: Install Fastlane plugins
        inputs:
        - content: |-
            #!/usr/bin/env bash
            bundle install
            bundle exec fastlane add_plugin screenshotslive
    - fastlane@3:
        inputs:
        - lane: render_screenshots
        - work_dir: "$BITRISE_SOURCE_DIR"
    - deploy-to-bitrise-io@2:
        inputs:
        - deploy_path: ./fastlane/rendered

Miten pidät build-ajat alhaisina?

Hidas osa missä tahansa CI-kuvakaappausputkessa on renderöinti, ei lähetys. Niksinä on välimuistittaa renderöinnit sisältöhashilla, jotta muuttumattomat kielet käyttävät uudelleen aiempaa lopputulosta. Screenshots.live palauttaa stabiilin renderHash-arvon vastauksessa — käytä sitä välimuistiavaimena:

  • Templaten versio + kieli + variantin hash → välimuistiavain
  • Renderöidyt PNG-tavut → välimuistiarvo
  • Välimuistin TTL: 30 päivää, tai kunnes template julkaistaan uudelleen

GitHub Actionsissa käytä actions/cache@v4:ää avaimella, joka johdetaan template-ID:stäsi ja kielilistasta. Useimmat julkaisubuildit ohittavat renderöinnin kokonaan ja rakentavat uudelleen vain sen kielen, joka todella muuttui.

Miten validoit lopputuloksen ennen lähettämistä?

Sekä Apple että Google hylkäävät kuvakaappaukset hiljaisesti, kun ne eivät läpäise muototarkistuksia: PNG alfa-kanavalla, JPEG koodattuna CMYK:nä, tai 6,7 tuuman iPhonen kuvakaappaus yhden pikselin liian lyhyt. Rakenna 20 rivin lint-vaihe, joka nappaa nämä ennen lähettämistä:

fastlane/lint_screenshots.rb
ruby
require "chunky_png"

Dir.glob("./fastlane/rendered/**/*.png").each do |path|
  png = ChunkyPNG::Image.from_file(path)
  raise "alpha channel: #{path}" if png.metadata["ColorType"] == 6
  raise "too large: #{path}"     if File.size(path) > 30 * 1024 * 1024
  raise "wrong size: #{path}"    if png.width < 1242
end

Pitäisikö se ajaa aikataulutetusti?

Kyllä. Yöllinen cron tarkoittaa, että kuvakaappaukset regeneroituvat aina, kun templatesi muuttuu — tuli muutos sitten suunnittelijalta editorissa, tekstipäivityksenä markkinoinnilta tai uuden kielen lisäyksenä. Ilman aikataulua kauppojen listaukset ajautuvat pois synkasta todellisesta tuotteestasi, ja jonkun on muistettava pushata tuore build ennen jokaista lähetystä.

Yhdistä aikataulu Slack- tai sähköpostihälytykseen virheistä. Rikkinäinen renderöinti klo 04.00 UTC on ilmoitus klo 07.00 paikallista aikaa — ei julkaisua estävä ongelma, joka löydetään klo 17.00 sinä päivänä, kun halusit toimittaa.

Entä Android, React Native ja Flutter?

Putki on alustariippumaton renderöintipuolella — vain kaappausvaihe muuttuu. Androidille vaihda capture_screenshots Fastlanen screengrab:iin ja Espresso-sarjaasi. React Nativelle käytä Detoxin snapshotteja. Flutterille käytä integration_test-kuvakaappauksia. Kaikki tuottavat raakoja PNG-tiedostoja, joita Screenshots.live käsittelee identtisesti.

Lue lisää monialustatuen oppaastamme kunkin pinon kaappauskonfiguraatiosta.

Mihin jatkat tästä?

Kun CI-putkesi toimittaa kuvakaappauksia luotettavasti, seuraava kysymys on, mitkä kuvakaappaukset voittavat. Yhdistä tämä putki A/B-testausoppaaseen toimittaaksesi variantteja aikataulutetusti ja mitataksesi konversiota. Yhdistä se lokalisointioppaaseen lisätäksesi yli 30 kieltä ilman yli 30 putkea.

Auktoritatiivisia viitteitä lisälukemiseen: Fastlanen iOS-kuvakaappausten dokumentaatio, Fastlanen deliver-toiminto, ja App Store Connectin viralliset kuvakaappausspesifikaatiot.

Kokeile sitä oikeassa repossa

Luo kaikki nämä koot automaattisesti

Lopeta kuvakaappausten manuaalinen koon muuttaminen. Suunnittele yksi malli ja renderöi jokainen koko, laite ja kieliversio yhdellä API-kutsulla.

Aloita ilmaiseksi — Kokeile Screenshots.liveä