Flutter: النشر عبر المنصات ومراجعة المتجر

📋 المتطلبات السابقة: يجب أن تكون قد أتقنت ما يلي أولًا

1. ما ستتعلمه


2. قصة حقيقية عن تقديم مرفوض


3. عملية النشر عبر المنصات


4. نشر أندرويد


5. نشر iOS


6. نشر الويب


7. التوافق مع الخصوصية


8. مثال كامل: قائمة فحص نشر ShopApp


9. قائمة فحص إصدار ShopApp v1.2.3

بعد استعداد بوب باستخدام القائمة، اجتاز كل من App Store وGoogle Play من التقديم الأول، ونسخة الويب أُطلقت خلال ساعة واحدة.

100%
graph TD
    REL[Release Process] --> ANDROID2[Android AAB]
    REL --> IOS2[iOS IPA]
    REL --> WEB2[Web PWA]
    ANDROID2 --> PC[Play Console]
    IOS2 --> ASC[App Store Connect]
    WEB2 --> FH[Firebase Hosting / Vercel]
    PC --> REVIEW1[Google Review]
    ASC --> REVIEW2[Apple Review]
    REVIEW1 --> LIVE1[Live on Google Play]
    REVIEW2 --> LIVE2[Live on App Store]
    FH --> LIVE3[Live on Web]

(1) التوقيع والبناء

▶ مثال: توليد Keystore

BASH
# Generate signing keystore
keytool -genkey -v -keystore shopapp-release.jks \
  -keyalg RSA -keysize 2048 -validity 10000 \
  -alias shopapp

# Verify keystore
keytool -list -v -keystore shopapp-release.jks -alias shopapp

إعدادات توقيع build.gradle

GROOVY
// android/app/build.gradle
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}

android {
    defaultConfig {
        applicationId "com.shopapp.app"
        minSdkVersion 21
        targetSdkVersion 34
        versionCode 42
        versionName "1.2.3"
    }
    signingConfigs {
        release {
            keyAlias keystoreProperties['keyAlias']
            keyPassword keystoreProperties['keyPassword']
            storeFile keystoreProperties['keyFile'] ? file(keystoreProperties['keyFile']) : null
            storePassword keystoreProperties['keyPassword']
        }
    }
    buildTypes {
        release {
            signingConfig signingConfigs.release
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

البناء والنشر

BASH
# Build release AAB (Android App Bundle)
flutter build appbundle --release
# Output: build/app/outputs/bundle/release/app-release.aab

# Build release APK (for testing)
flutter build apk --release

# Upload to Play Console manually or via CI/CD

(2) قائمة فحص إطلاق Play Console

العنصر المتطلب
مُعرِّف التطبيق اسم حزمة فريد com.shopapp.app
ملف AAB حزمة إصدار موقعة
الأيقونة PNG بحجم 512×512
لقطات الشاشة 2-8 لكل من هاتف + جهاز لوحي 7 بوصة
رابط سياسة الخصوصية يجب أن يكون قابلًا للوصول
تصنيف المحتوى أكمل استبيان IARC
الجمهور المستهدف حدد النطاق العمري

(1) إعدادات مطور Apple

الخطوة الإجراء
1. التسجيل Apple Developer Program (99$/سنة)
2. الشهادة أنشئ Distribution Certificate
3. الملف الشخصي أنشئ App Store Provisioning Profile
4. مُعرِّف التطبيق سجّل Bundle Identifier
5. سجل التطبيق أنشئ تطبيقًا في App Store Connect

إعدادات بناء Xcode

XML
<!-- ios/Runner/Info.plist -->
`<key>`CFBundleShortVersionString</key>
`<string>`1.2.3</string>
`<key>`CFBundleVersion</key>
`<string>`42</string>
`<key>`NSAppTransportSecurity</key>
`<dict>`
    `<key>`NSAllowsArbitraryLoads</key>
    `<false/>`
`</dict>`
`<key>`NSUserTrackingUsageDescription</key>
`<string>`We use tracking to personalize your shopping experience.</string>

البناء والرفع

BASH
# Build IPA
flutter build ipa --release \
  --export-options-plist=ios/ExportOptions.plist
# Output: build/ios/ipa/shopapp.ipa

# Upload via Xcode or command line
xcrun altool --upload-app \
  --type ios \
  --file build/ios/ipa/shopapp.ipa \
  --apiKey YOUR_API_KEY \
  --apiIssuer YOUR_ISSUER_ID
# Or via Transporter app

(2) قائمة فحص إطلاق App Store Connect

| Bundle ID | يجب أن يتطابق مع مشروع Xcode | | ملف IPA | بناء إصدار | | لقطات الشاشة | ثلاثة أحجام 6.7"/6.5"/5.5" | | فيديو معاينة | اختياري، ≤30 ثانية | | الوصف | ≤4000 حرف |

▶ مثال: التوافق مع قائمة خصوصية Apple

DART
import 'package:flutter/material.dart';
import 'package:app_tracking_transparency/app_tracking_transparency.dart';
import 'package:firebase_analytics/firebase_analytics.dart';

// Dependencies: app_tracking_transparency: ^0.2.0, firebase_analytics: ^10.0.0 (add to dependencies)

Future<void> requestTrackingPermission() async {
  final status = await AppTrackingTransparency.requestTrackingAuthorization();
  if (status == TrackingStatus.authorized) {
    await FirebaseAnalytics.instance.setAnalyticsCollectionEnabled(true);
  } else {
    await FirebaseAnalytics.instance.setAnalyticsCollectionEnabled(false);
  }
}

الإخراج:

TEXT
App Tracking Transparency dialog displayed
Status: authorized (or denied)
Analytics collection enabled/disabled accordingly

(1) مقارنة متطلبات التوافق

المنصة العناصر المطلوبة
Google Play سياسة الخصوصية / نموذج Data Safety / تصنيف المحتوى
App Store سياسة الخصوصية / ATT / إقران توافق التشفير
الويب (PWA) موافقة ملفات تعريف الارتباط GDPR / سياسة الخصوصية

(2) قائمة فحص التوافق مع الخصوصية

فحوصات ما قبل الإطلاق

قائمة فحص النشر عبر ثلاث منصات

(1) أندرويد

(2) iOS

(3) الويب

(4) ما بعد الإطلاق

❓ أسئلة شائعة

س ما الفرق بين AAB وAPK؟
ج AAB (Android App Bundle) هو تنسيق الرفع — Google Play يُولد تلقائيًا APKs محسنة منه. AABs أصغر لأنها تتضمن فقط الموارد التي يحتاجها الجهاز.
س كم تستغرق مراجعة App Store عادة؟
ج التقديمات الأولى تستغرق عادة 24-48 ساعة، التحديثات عادة 12-24 ساعة. إعادة التقديم بعد الرفض تتطلب انتظارًا آخر.
س كيف أدير versionCode وversionName؟
ج versionCode يجب أن يكون عددًا صحيحًا متزايدًا (+1 لكل إصدار)؛ versionName مرئي للمستخدم (مثل 1.2.3). استخدم اصطلاحات SemVer.
س هل نسخة الويب تحتاج تسجيل ICP؟
ج الخوادم في الصين القارية تحتاج تسجيل ICP. الخوادم الخارجية (Firebase/Vercel) لا تحتاج.
س ماذا يتطلب التوافق مع GDPR؟
ج 1) إظهار موافقة الخصوصية عند أول تشغيل؛ 2) توفير خيار حذف البيانات؛ 3) رابط سياسة الخصوصية؛ 4) تقليل جمع البيانات؛ 5) يمكن للمستخدمين إلغاء الموافقة.
س ماذا أفعل إذا رفض App Store تقديمي؟
ج اقرأ سبب الرفض بعناية، أصلح المشاكل، وأعد التقديم. أسباب شائعة: سياسة خصوصية مفقودة، نافذة ATT لم تُعرض، أعطال، انتهاكات سياسة المحتوى.

📖 ملخص


(1) مثال: وتيرة إصدار أرقام النسخ

TEXT
1.0.0  →  MVP launch (first release)
1.0.1  →  Urgent bug fix (patch)
1.1.0  →  New feature (minor)
1.2.3  →  ShopApp release (minor + patch)
2.0.0  →  Major refactoring (major)

الإخراج:

TEXT
SemVer: MAJOR.MINOR.PATCH
- MAJOR breaking changes
- MINOR compatible additions
- PATCH compatible fixes

(2) مثال: تكامل Firebase Crashlytics

DART
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'dart:ui' show PlatformDispatcher;

// Dependencies: firebase_core: ^2.0.0, firebase_crashlytics: ^3.0.0 (add to dependencies)
// ShopApp comes from project lib/app.dart

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();

  FlutterError.onError = (details) {
    FirebaseCrashlytics.instance.recordFlutterFatalError(details);
  };

  PlatformDispatcher.instance.onError = (error, stack) {
    FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
    return true;
  };

  runApp(const ShopApp());
}

الإخراج:

TEXT
Crashlytics initialized
Fatal errors auto-reported
Non-fatal errors auto-reported

(3) مثال: لوحة مراقبة الإصدار

BASH
# Firebase Crashlytics
firebase functions:log --only publishMonitor
# Expected output:
# {"status":"ok","version":"1.2.3","crashRate":"0.05%"}

الإخراج:

TEXT
Crash rate after rollout:
- 1h: 0.05% (baseline 0.10%)
- 24h: 0.04% (healthy)
- ANR rate: 0.01% (acceptable)

📝 تمارين

  1. أساسي (الصعوبة ⭐): أنشئ Keystore أندرويد لـ ShopApp، أعد توقيع build.gradle، وابنِ AAB إصدار بنجاح.
  2. متوسط (الصعوبة ⭐⭐): أكمل تحضير نشر ShopApp ثنائي المنصة — توقيع AAB أندرويد + إعدادات شهادة iOS، واكتب قائمة فحص نشر متعددة المنصات.
  3. متقدم (الصعوبة ⭐⭐⭐): نفذ عملية نشر ShopApp الكاملة عبر المنصات (أندرويد + iOS + الويب)، بما في ذلك إقرانات التوافق مع الخصوصية، توليد لقطات شاشة متعددة القنوات، وكتابة وصف App Store.

Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%