Telefonsuz App Store Ekran Görüntüleri: Robolectric, Sahte Görsel Yükleyici ve Başsız Tarayıcı
Nesim Razon, bağımsız Android geliştiricisi · 2026-11-16
iPhone uygulamalarım ekranlarını Android sürümleriyle paylaşıyor; bir kez Compose ile yazılmış durumdalar. App Store Connect 1206x2622 piksellik ekran görüntüleri istiyor; ben ise Windows dizüstüyle çalışıyorum, bu iş için ayıracak bir iPhone'um yok ve gerçek derlemelere harcamayı tercih ettiğim sınırlı bir bulut derleme dakikam var. Bu yüzden ekranları birim testlerine çizdiriyorum. İşte nasıl çalıştığı, nelerin bozulduğu ve bu görüntülerin dürüstçe ne olduğu.
Fikir: ekranı bir birim testi çizsin
Robolectric, Android kodunu masaüstü JVM'de çalıştırır; yerel grafik moduyla Compose'u gerçek bir bit eşlemeye çizebilir. Roborazzi bu bit eşlemi PNG olarak kaydeder. Yani ekran görüntüsü bir teste dönüşür: ekranı kur, istediğim duruma tıkla, kök düğümü yakala, bitti. Emülatör yok, telefon yok, derleme servisi yok.
Boyutu tek bir nitelik belirliyor: w402dp-h874dp-xxhdpi. Bu, dp başına üç piksellik 402 x 874 dp bir ekran; sonuç tam 1206x2622 piksel, yani App Store Connect'in istediği boyut. Hesaba güvenmek yerine çıktı dosyalarına baktım.
Güvenli alanları elle vermek
Android test penceresinde çentik yok; bu yüzden her ekranın üstü Dynamic Island'ın geleceği yerin altında kalırdı. Testte uygulamayı üstten 47 dp boşluklu bir kutuya sarıyorum; bu iPhone güvenli alanını temsil ediyor. Bir uygulamada ayrıca alta, ana ekran göstergesi için 34 dp ekledim, çünkü o uygulamada altta bir gezinme çubuğu var.
Bu kaba bir vekil, ölçüm değil. Tek işi, yerleşimin telefonda görüneceği gibi görünmesini, hiçbir şeyin adanın altında kalmamasını sağlamak.
Hiç yüklenmeyen ağ görselleri
Bu testlerde Robolectric'in işe yarar bir ağı yok; makale kapakları ve uydu görüntüleri boş kutu olarak çıkardı. Coil'in bunun için bir FakeImageLoaderEngine'i var: test kaynağı olarak kaydettiğim gerçek görselleri, uygulamanın isteyeceği adreslere ya da adres kalıplarına bağlıyorum. Böylece ekran görüntüsünde yer tutucu değil gerçek resimler görünüyor.
Veri de aynı muameleyi görüyor. Haber okuyucuda testteki besleme, canlı siteden alınmış gerçek beslemenin kopyası. Uzay uygulamasında günlük veri, gerçek günlük dosyanın kopyası. Mağaza sayfası için içerik uydurmuyorum; gerçek içeriği donduruyorum.
Canlı içerik ve bitmeyen döngüler
Bazı ekranlar uzay istasyonunun anlık konumu gibi değişen şeyleri gösterir. Bunlar için test sabit bir örnek nesne veriyor ve ekran onu yeni gelmiş gibi çiziyor.
Bunun için uygulama kodunda bir değişiklik gerekti. Canlı ekran bir döngüyle yoklama yapıyordu; içinde gecikme olan bir while(true) döngüsü, test çerçevesinin waitForIdle'ının hiç dönmemesine yol açabilir, çünkü uygulama hiç boşta kalmıyor. Takılıp takılmayacağını denemeden, baştan bir önizleme parametresi ekledim: örnek verilirse ekran onu gösteriyor ve döngüyü başlatmıyor. Küçük bir test dikişi, ekranı önizlemeyi de kolaylaştırıyor.
WebView içeren ekranlar
Robolectric WebView çizmez. Haber uygulamalarımdaki yazı ekranı ve statik sayfalar WebView; bu yüzden ekran görüntüsü, sayfanın olması gereken yerde bir delikle çıktı.
Çözümün iki yarısı var. Test, uygulamanın kullandığı aynı ortak işlevle üretilen sayfa HTML'ini ve sayfasız ekranın görüntüsünü, yani yalnızca 111 dp ya da 333 piksel yüksekliğindeki üst çubuğu yazıyor. Sonra bir Python betiği o HTML'i başsız Edge'de, 402 piksel genişliğinde bir iframe içinde 3 kat ölçekle çiziyor ve sonucu üst çubuğun altına yapıştırıyor. Sayfayı gerçek bir tarayıcı motoru, çubuğu Compose çiziyor ve ikisi sabit bir çizgide buluşuyor.
Tuzaklar
Bunların her biri bir akşamımı ya da bir kısmını aldı.
- Başsız Edge yaklaşık 500 pikselden daha dar olmuyor; sayfa sağdan kesiliyordu. Çözüm, 402 piksellik bir iframe'li sarmalayıcı sayfa ve ardından ekran görüntüsünü kırpmaktı.
- Edge süreçten ayrılabiliyor; ekran görüntüsü dosyası komut döndükten sonra beliriyor. Betik dosyayı yoklayarak bekliyor ve açık tarayıcımla çakışmaması için kendi kullanıcı veri klasörünü kullanıyor.
- Roborazzi RGBA PNG yazıyor, App Store Connect ise saydamsız RGB istiyor. Küçük bir betik yüklemeden önce bunları düzleştiriyor.
- Bir uygulama deposunda screenshots_ios adlı bir klasörü, web sitesi üreticim daha yeni ekran görüntüleri klasörü sandı. Arama, rakamlı sürüm biçimindeki klasör adlarıyla sınırlanana kadar üç web sayfası sessizce ekran görüntülerini kaybetti.
Bu görüntüler ne, ne değil
Bunlar iPhone boyutuna getirilmiş Android çizimleri. Yazı tipleri, kaydırma hissi, sistem çubukları ve bazı küçük denetimler iOS'un çizdiği gibi değil. Ortak arayüz aynı kod olduğu için bunu mağaza sayfası adına kabul ediyorum, ama onlara iOS yakalaması demiyorum.
Bu uygulamaların gerçek iPhone davranışını ayrıca, TestFlight ile kurulu bir iPhone 7'de denedim. Ekran görüntüleri ekranları gösteriyor; ekranların çalışıp çalışmadığını gerçek cihaz söyledi.
Sık sorulan sorular
Bu yöntem gerçek iOS ekran görüntüsü üretir mi?
Hayır. Ortak Compose arayüzünün 1206x2622 boyutuna getirilmiş Android çizimleri. Gerçek iPhone davranışı ayrıca bir cihazda TestFlight ile denendi.
Boyut neden tam 1206x2622?
Test, xxhdpi'da 402 x 874 dp bir pencere kullanıyor; bu dp başına üç piksel demek, çıktı da 1206 x 2622 piksel oluyor.
Neden gerçek iPhone'da ya da simülatörde ekran görüntüsü almıyorsun?
Bunun için boş bir cihazım ve Mac'im yok, bulut derleme dakikalarımı da gerçek derlemelere saklamak istiyorum. Birim testleri kendi dizüstümde ücretsiz çalışıyor ve istediğim zaman tekrarlanabiliyor.
WebView ekranları neden ayrı ele alınıyor?
Robolectric WebView çizmez; bu yüzden sayfa HTML'i başsız Edge'de çizilip Compose'un çizdiği üst çubuğun altına yapıştırılıyor.
Diğer yazılar
- App Store Bağlantım Neden 404 Verdi ve Sayfa 2018 Ekran Görüntülerini Gösterdi
- App Store İnceleme Kuralı 2.1 "Bilgi Gerekli": Ne Gönderdim
- İki Mağaza İçin Tek QR Kodu: Küçük Bir Yönlendirme Sayfası
- Davranışı Değiştirmeden Kotlin Multiplatform'a Geçiş: Eski Kodu Test Kâhini Olarak Tutmak
- "Diğer Oyunlarım" İçin Sunucusuz Uzak Liste: GitHub Pages'te Tek JSON Dosyası
- iPhone'u Windows'tan USB ile Ayıklamak: Python ile Ekran Görüntüsü ve Günlük