An IT professional configuring network cables in a server rack, focusing on Ethernet connections.

هل تساءلت يومًا كيف تجلب التطبيقات بيانات الطقس أو الأخبار أو الفيديوهات من الإنترنت وتعرضها لك في لحظة؟ في عالم تطوير التطبيقات باستخدام Flutter، يُعتبر التعامل مع الشبكات (Networking) خطوة أساسية لا غنى عنها. سواء كنت تطور تطبيقًا للطبخ يعرض وصفات جديدة، أو تطبيقًا للرياضة يجلب نتائج المباريات مباشرة، ستحتاج لفهم كيفية إجراء طلبات HTTP والتعامل مع الاستجابات. في هذا الدليل العملي الشامل، سنشرح كل شيء خطوة بخطوة للمبتدئين، مع أمثلة كود حقيقية وأفضل الممارسات. إذا كنت تبحث عن “الشبكات في Flutter” أو “جلب بيانات من الإنترنت في Flutter”، فأنت في المكان الصحيح. سنغطي كيفية استخدام حزمة http في Flutter، التعامل مع طلبات HTTP في Flutter، والمزيد لمساعدتك في بناء تطبيقات قوية وفعالة.

في هذا المقال ستتعلم:

  • كيف تجري طلب GET أو POST في Flutter.
  • كيفية التعامل مع الاستجابة وتحويلها إلى كائنات Dart.
  • أفضل الممارسات لهيكلة كود الشبكات.
  • مثال عملي كامل لجلب بيانات من API.
  • نصائح للتعامل مع الأخطاء وتحسين الأداء.

دعونا نبدأ رحلتنا في عالم الشبكات في Flutter!

ما هي الشبكات (Networking) في Flutter؟

للمبتدئين، دعونا نبسط المفهوم: الشبكات في Flutter تعني القدرة على تواصل تطبيقك مع خادم (Server) عبر الإنترنت باستخدام بروتوكولات مثل HTTP أو HTTPS. تخيل أن تطبيقك هو عميل (Client) يطلب معلومات من مصدر خارجي، مثل API (Application Programming Interface)، ثم يعالج هذه المعلومات ويعرضها للمستخدم.

  • طلب (Request): يرسله التطبيق، مثل “أعطني أحدث المقالات” (طلب GET) أو “أرسل هذه البيانات” (طلب POST).
  • استجابة (Response): يرسلها الخادم، عادةً بصيغة JSON أو XML، مع رمز حالة مثل 200 (نجاح) أو 404 (غير موجود) او اكواد اخرى كل كود له معنى يرشد المطور لحالة طلبه.

Flutter لا يأتي مع مكتبة HTTP مضمنة، لكن يمكنك إضافة حزمة شهيرة مثل http من خلال pub.dev. لتثبيتها، أضف إلى ملف pubspec.yaml:

dependencies:
  http: ^1.2.0

ثم قم بتشغيل flutter pub get. الآن، أنت جاهز لإجراء طلبات HTTP في Flutter!

أنواع الطلبات الشائعة في Flutter:

في Flutter، يمكنك إجراء طلبات مختلفة باستخدام حزمة http. دعونا نشرح كل نوع بتفصيل للمبتدئين:

1. طلب GET: جلب البيانات

يُستخدم لقراءة بيانات من الخادم دون تعديلها. مثال: جلب قائمة الوصفات.

مثال كود بسيط لـ GET في Flutter:

import 'package:http/http.dart' as http;

Future<String> fetchData() async {
  final url = Uri.parse('https://api.example.com/data');
  try {
    final response = await http.get(url);
    if (response.statusCode == 200) {
      return response.body; // الاستجابة كـ String، عادةً JSON
    } else {
      throw Exception('فشل في جلب البيانات: ${response.statusCode}');
    }
  } catch (e) {
    return 'حدث خطأ: $e';
  }
}

هنا، نرسل طلبًا إلى URL، نتحقق من النجاح (200)، ونعيد الجسم (body) إذا نجح.

2. طلب POST: إرسال البيانات

يُستخدم لإرسال بيانات جديدة إلى الخادم، مثل تسجيل مستخدم.

مثال كود لـ POST في Flutter:

import 'dart:convert';
import 'package:http/http.dart' as http;

Future<String> sendData(String name, String email) async {
  final url = Uri.parse('https://api.example.com/register');
  final body = jsonEncode({'name': name, 'email': email});
  try {
    final response = await http.post(
      url,
      headers: {'Content-Type': 'application/json'},
      body: body,
    );
    if (response.statusCode == 201) {
      return 'تم التسجيل بنجاح!';
    } else {
      throw Exception('فشل في الإرسال: ${response.statusCode}');
    }
  } catch (e) {
    return 'حدث خطأ: $e';
  }
}

نحول البيانات إلى JSON باستخدام jsonEncode، ونرسلها مع headers مناسبة.

3. أنواع أخرى: PUT، DELETE، وHEADERS

  • PUT: لتحديث بيانات موجودة.
  • DELETE: لحذف بيانات.
  • Headers: أضف رؤوس مثل Authorization للتحقق من الهوية.

للمبتدئين، ابدأ بـ GET، ثم جرب POST. تذكر: استخدم async/await للتعامل مع العمليات غير المتزامنة دون تجميد الواجهة.

مثال عملي كامل: جلب بيانات الوصفات من API في Flutter

دعونا نطبق ما تعلمناه في مثال حقيقي: تطبيق يجلب وصفات من API مثل Spoonacular (استخدم API مجانيًا). سننشئ نموذج (Model) للوصفة، ثم نجلب البيانات ونعرضها في ListView.

الخطوة 1: إنشاء نموذج الوصفة (Recipe Model)

class Recipe {
  final int id;
  final String title;
  final String description;

  Recipe({required this.id, required this.title, required this.description});

  factory Recipe.fromJson(Map<String, dynamic> json) {
    return Recipe(
      id: json['id'],
      title: json['title'],
      description: json['description'],
    );
  }
}

الخطوة 2: دالة جلب البيانات (Fetch Recipes)

import 'dart:convert';
import 'package:http/http.dart' as http;

Future<List<Recipe>> fetchRecipes() async {
  final url = Uri.parse('https://api.example.com/recipes'); // استبدل بـ API حقيقي
  final response = await http.get(url);

  if (response.statusCode == 200) {
    final List data = jsonDecode(response.body);
    return data.map((e) => Recipe.fromJson(e)).toList();
  } else {
    throw Exception('فشل تحميل البيانات: ${response.statusCode}');
  }
}

الخطوة 3: عرض البيانات في الواجهة باستخدام FutureBuilder

import 'package:flutter/material.dart';

class RecipesScreen extends StatelessWidget {
  const RecipesScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('وصفات الطعام')),
      body: FutureBuilder<List<Recipe>>(
        future: fetchRecipes(),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(child: CircularProgressIndicator());
          } else if (snapshot.hasError) {
            return Center(child: Text('خطأ: ${snapshot.error}'));
          } else if (snapshot.hasData) {
            return ListView.builder(
              itemCount: snapshot.data!.length,
              itemBuilder: (context, index) {
                final recipe = snapshot.data![index];
                return ListTile(
                  title: Text(recipe.title),
                  subtitle: Text(recipe.description),
                );
              },
            );
          } else {
            return const Center(child: Text('لا توجد بيانات'));
          }
        },
      ),
    );
  }
}

أفضل الممارسات لكود الشبكات في Flutter

للمبتدئين، إليك نصائح عملية لجعل كودك نظيفًا وفعالًا:

  • افصل منطق الشبكة عن الواجهة: أنشئ مجلد services أو api، وضع فيه دالة fetchRecipes. هذا يسهل الاختبار والصيانة.
  • التعامل مع الأخطاء (Error Handling): استخدم try-catch، وأظهر رسائل ودية للمستخدم مثل “لا يوجد اتصال بالإنترنت”. أضف timeout لتجنب الانتظار الطويل.
  • التحقق من الاتصال بالإنترنت: استخدم حزمة connectivity_plus للتحقق قبل الطلب.
  • استخدام مكتبات متقدمة: جرّب dio لميزات مثل retry، interceptors (لإضافة headers تلقائيًا)، ودعم ملفات التحميل.
  • Caching (التخزين المؤقت): استخدم hive أو shared_preferences لحفظ البيانات محليًا، مما يقلل من الطلبات ويعمل offline.
  • الأمان: استخدم HTTPS دائمًا، وأضف authentication إذا لزم الأمر.

تجنب وضع كود الشبكات داخل build، فهو يُعاد تنفيذه كثيرًا!

🎯 الخاتمة: ابدأ رحلتك في جلب البيانات من الإنترنت في Flutter

تعلمت اليوم كيف تجري طلبات HTTP في Flutter، تحول JSON إلى كائنات Dart، وتطبق أفضل الممارسات لفصل المنطق عن الواجهة. الشبكات هي الخطوة الأولى فقط! في المقال القادم من سلسلة “البيانات والباك-إند في Flutter” سنتناول موضوع التسلسل (Serialization): كيف تحول بيانات JSON إلى كائنات Dart بسهولة وأمان. جرب الأمثلة في مشروعك، وشارك تجربتك في التعليقات. للمزيد عن “طلبات HTTP في Flutter” أو “حزمة http في Flutter”، تابع مدونتنا!

By احمد علي

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

One thought on “الفصل العاشر – Data & backend : الشبكات في Flutter: الدليل العملي لجلب البيانات من الإنترنت”

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *