DEV Community

Nuh Mehmet Demirkol
Nuh Mehmet Demirkol

Posted on Originally published at nmdemirkol.com

App Store Retlerinden Kaçınma: Guideline 2.1 (Performance) ve 4.8 (Sign in with Apple) Engellerini Aşmak İçin Mimari Çözümler

App Store Retlerinden Kaçınma: Guideline 2.1 ve 4.8 Engellerini Aşmak İçin Mimari Çözümler

Mobil uygulama geliştirme süreçlerinde en büyük darboğazlardan biri, haftalarca süren emeğin ardından karşılaşılan App Store retleridir (App Store Rejections). Apple'ın katı denetim mekanizması, özellikle Guideline 2.1 (Performance - App Completeness) ve Guideline 4.8 (Sign in with Apple) maddelerinde geliştiricileri ciddi şekilde zorlamaktadır.

Bu teknik makalede, bir Mobil Yazılım Mimarı gözünden, bu iki kritik ret sebebini derinlemesine inceleyecek, mimari seviyede nasıl önlemler alabileceğinizi ve Apple denetçilerinin (Reviewers) onayından tek seferde geçecek sistemleri nasıl kuracağınızı kod örnekleriyle ele alacağız.


1. Guideline 2.1 - App Completeness (Uygulama Bütünlüğü)

Guideline 2.1, uygulamanızın kararlı, test edilmiş ve tüm fonksiyonlarıyla çalışır durumda olmasını şart koşar. "Under construction" ibareleri, boş ekranlar, mock veriler, ağ bağlantısı koptuğunda çöken veya tepkisiz kalan arayüzler doğrudan bu maddeden ret alır.

Mimari Çözüm: State-Driven UI ve Güçlü Hata Yönetimi

2.1 retlerini önlemenin en kesin yolu, uygulamanın her ekranını bir durum makinesi (State Machine) olarak tasarlamaktır. UI katmanı hiçbir zaman doğrudan ham veriye erişmemeli; her zaman Idle, Loading, Success(Data) ve Failure(Error) durumlarından birini render etmelidir.

Aşağıdaki Swift/Combine örneğinde, ağ hatası durumunda uygulamayı kilitlemek yerine kullanıcıya anlamlı bir kurtarma senaryosu sunan ve denetçinin uygulamadan çıkmadan süreci tekrar denemesini sağlayan (Retry Mechanism) mimariyi görebilirsiniz:

swift
import Combine
import Foundation

// 1. Ekran Durum Tanımları
enum ViewState {
case idle
case loading
case success(T)
case failure(Error)
}

// 2. Ağ Bağlantısı Takip Servisi
class NetworkMonitor: ObservableObject {
static let shared = NetworkMonitor()
@Published var isConnected: Bool = true
// Gerçek senaryoda NWPathMonitor entegre edilmelidir.
}

// 3. ViewModel Mimarisi
class ProductViewModel: ObservableObject {
@Published var state: ViewState<[String]> = .idle
private var cancellables = Set()
private let networkMonitor = NetworkMonitor.shared

func fetchProducts() {
    // Ağ kontrolü - Denetçinin çevrimdışı senaryoda kilitlenmesini önler
    guard networkMonitor.isConnected else {
        self.state = .failure(NSError(domain: "Network", code: -1009, userInfo: [NSLocalizedDescriptionKey: "İnternet bağlantısı bulunamadı. Lütfen kontrol edip tekrar deneyiniz."]))
        return
    }

    self.state = .loading

    // Mock API Call simulating network
    Just(["Premium Üyelik", "Sınırsız Depolama", "Yapay Zeka Asistanı"])
        .delay(for: .seconds(1), scheduler: RunLoop.main)
        .map { ViewState.success($0) }
        .catch { Just(ViewState.failure($0)) }
        .assign(to: \.state, on: self)
        .store(in: &cancellables)
}
Enter fullscreen mode Exit fullscreen mode

}

Apple Denetçilerine Özel İpuçları (Guideline 2.1 İçin):

  • Demo Hesapları: Uygulamanız iki adımlı doğrulama (2FA) veya SMS doğrulaması kullanıyorsa, Apple denetçileri için çalışan static bir test telefon numarası ve OTP kodu (örn: +90 555 555 55 55 / Code: 123456) tanımlayın.
  • Mock Veri Kontrolü: "Lorem Ipsum" içeren metinleri ve geçici görsel asset'lerini prodüksiyon build'inden kesinlikle temizleyin.

2. Guideline 4.8 - Sign in with Apple (Apple ile Giriş)

Eğer uygulamanızda Google, Facebook veya X (Twitter) gibi üçüncü taraf sosyal giriş (Social Sign-In) yöntemleri sunuyorsanız, Sign in with Apple seçeneğini de eşdeğer bir görsel öncelikle sunmak zorundasınız.

İstisnalar Nelerdir?

Eğer uygulamanız;

  • Sadece şirkete özel kurumsal hesap altyapısı kullanıyorsa,
  • E-posta/Şifre ile kendi veritabanınız üzerinden üyelik sunuyorsa (sosyal giriş olmadan),
  • Doğrudan bir devlet/kamu kimlik doğrulama sistemi kullanıyorsa Apple ile Giriş zorunlu değildir.

Mimari Çözüm: Dynamic Identity Provider Factory

Platforma göre dinamik giriş butonları üreten ve Apple'ın tasarım kılavuzlarına (Human Interface Guidelines) tam uyumlu bir buton hiyerarşisi oluşturan Swift/SwiftUI mimarisi:

swift
import SwiftUI
import AuthenticationServices

struct LoginView: View {
@StateObject private var viewModel = LoginViewModel()

var body: some View {
    VStack(spacing: 16) {
        // Standart Giriş Alanları
        TextField("E-posta", text: $viewModel.email)
            .textFieldStyle(RoundedBorderTextFieldStyle())
            .padding()

        Button("E-posta ile Giriş Yap") {
            viewModel.loginWithEmail()
        }
        .buttonStyle(.borderedProminent)

        Divider().padding(.vertical)

        // Sosyal Giriş Bölümü
        VStack(spacing: 12) {
            // 1. Google Giriş Butonu
            Button(action: { viewModel.loginWithGoogle() }) {
                HStack {
                    Image("google_icon") // Custom asset
                    Text("Google ile Devam Et")
                }
                .frame(maxWidth: .infinity)
                .padding()
                .background(Color.white)
                .cornerRadius(8)
                .overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.gray, lineWidth: 1))
            }

            // 2. Apple ile Giriş - Guideline 4.8 Gereksinimi
            SignInWithAppleButton(
                onRequest: { request in
                    request.requestedScopes = [.fullName, .email]
                },
                onCompletion: { result in
                    switch result {
                    case .success(let authorization):
                        viewModel.handleAppleSignIn(authorization: authorization)
                    case .failure(let error):
                        print("Apple Sign-In Hatası: \(error.localizedDescription)")
                    }
                }
            )
            .signInWithAppleButtonStyle(.black)
            .frame(height: 50)
            .cornerRadius(8)
        }
        .padding(.horizontal)
    }
}
Enter fullscreen mode Exit fullscreen mode

}

Sunucu Tarafı (Backend) Doğrulaması

Apple Sign-In entegrasyonunda yapılan en büyük hata, client tarafında alınan identityToken değerini backend tarafında doğrulamadan doğrudan kullanıcıyı içeri almaktır. JWT (JSON Web Token) formatındaki bu token, Apple'ın public anahtarları (https://appleid.apple.com/auth/keys) kullanılarak arka planda doğrulanmalıdır.


3. App Store Gönderim Öncesi Kontrol Listesi (Checklist)

Yayına çıkmadan önce bu kontrol listesini tamamladığınızdan emin olun:

Madde Açıklama İlgili Kılavuz
Giriş Bilgileri Reviewer için çalışan, kilitlenmeyen test hesabı hazır mı? Guideline 2.1
IPv6 Desteği Uygulama sadece IPv6 kullanan ağlarda düzgün çalışıyor mu? Guideline 2.1
Giriş Koşulu Sosyal girişlerin yanında Apple Sign-In butonu aynı boyutta var mı? Guideline 4.8
Hesap Silme Kullanıcı hesap silme (Delete Account) butonu uygulama içinde kolayca erişilebilir mi? Guideline 5.1.1

Sonuç

App Store onay süreçleri, teknik kalitenin yanında Apple'ın tasarım ve iş etiği kurallarına sıkı sıkıya bağlı kalmayı gerektirir. Uygulama mimarinizi en baştan esnek, hata toleranslı ve platform standartlarına uyumlu kurgulamak, projelerinizin zamanında canlıya çıkmasını garanti eder.


Profesyonel Mobil Mimari ve Süreç Yönetimi Desteği

Uygulamanızın App Store onay süreçlerinde takıldınız mı, yoksa sıfırdan ölçeklenebilir ve Apple standartlarına tam uyumlu bir mobil mimari mi inşa etmek istiyorsunuz? Ankara merkezli mühendislik ofisimizde, küresel standartlarda mobil yazılım mimarisi, kod kalitesi denetimi (Code Review) ve App Store/Google Play Store yayın süreçleri yönetimi danışmanlığı sunuyoruz.

  • Yazan: Nuh Mehmet Demirkol (Lisanslı Bilgisayar Mühendisi)
  • Web Sitesi: nmdemirkol.com
  • Ofis Lokasyonu: Ankara, Türkiye
  • Doğrudan İletişim (WhatsApp): +90 507 823 68 11 Teknik mimari, danışmanlık ve kurumsal çözümler için dilediğiniz an iletişime geçebilirsiniz.

Top comments (0)