تجزیه فایل لوکال Json در فلاتر به صورت asynchronous



برای ساختن و توسعه دادن اپ های بزرگ موبایل ما احتیاج داریم که با استفاده از API داده های رو به صورت JSON از سرور دریافت کنیم.

کلمه JSON سرنام واژگان JavaScript Object Notation یک استاندارد سبک، باز ، متنی و خوانا برای انسان جهت انتقال داده و جایگزینی برای xml است. خوب خیلی کتابی شد ? چون کپی بود ادامشم اینجاست.

در نهایت ما این داده ها رو میتونیم به صورت لیستی از اشیاء(objects) نشون بدیم.

اما گاهی وقت ها ممکنه ما این داده ها رو به صورت یک فایل json در اپلیکیشن ذخیره کرده باشیم به جای اینکه از سرور بگیریم .

این فایل رو ما میتونیم در هرجایی از دایرکتوری اپلیکیشن ذخیره کنیم طبق دستور العمل فلاتر ما این رو در پوشه assets ذخیره میکنیم و در زمان اجرا (runtime) بهش دسترسی پیدا میکنیم و از اون استفاده میکنیم.



در این پست من یک اپلیکیشن فلاتر ایجاد میکنم و یک فایل json رو به صورت لوکال در اپ قرار میدم و از اون استفاده میکنم.

ساخت پروژه جدید

  1. یک پروژه جدید فلاتر رو توسط IDE محبوبتون ایجاد کنید.
  2. یه پوشه به نام assets در روت پروژتون ایجاد کنید و این فایل country.json داخل پوشه کپی کنید.

برای اینکه داخل پروژه بتونید به فایل دسترسی پیدا کنید باید اون رو pubspecs.yaml در تعریف کنیم به این شکل:

3. یه فایل به نام list.dart ایجاد میکنیم . در این فایل ما لیستی از کشور ها رو به صورت array دریافت میکنیم و با استفاده از listview اونها رو نمایش میدیم.

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_load_local_json/country.dart';

class CountyList extends StatelessWidget {
  final List<Country> country;
  CountyList({Key key, this.country}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return new ListView.builder(
        itemCount: country == null ? 0 : country.length,
        itemBuilder: (BuildContext context, int index) {
          return
                new Card(
                  child: new Container(
                    child: new Center(
                        child: new Column(
                      // Stretch the cards in horizontal axis
                      crossAxisAlignment: CrossAxisAlignment.stretch,
                      children: <Widget>[

                        new Text(
                          // Read the name field value and set it in the Text widget
                          country[index].name,
                          // set some style to text
                          style: new TextStyle(
                              fontSize: 20.0, color: Colors.lightBlueAccent),
                        ),
                        new Text(
                          // Read the name field value and set it in the Text widget
                          &quotCapital:- &quot + country[index].capital,
                          // set some style to text
                          style: new TextStyle(
                              fontSize: 20.0, color: Colors.amber),
                        ),
                      ],
                    )),
                    padding: const EdgeInsets.all(15.0),
                  ),
             );
        });
    }
}

4.حالا فایل country.dart رو ایجاد میکنیم که حاوی مدل PODO فایل json ما هست و به وسیله این کلاس ما میتونم فایل json خودمون رو تجزیه (parse) کنیم.

class Country {
  final String name;
  final String flag;
  final String capital;

  Country({this.name, this.flag, this.capital});

  factory Country.fromJson(Map<String, dynamic> json) {
    return new Country(
      name: json['name'] as String,
      flag: json['flag'] as String,
      capital: json['capital'] as String,
    );
  }
}

5. در پایان ما وارد فایل main.dart میشیم و و نحوه دریافت فایل و تجزیش رو مینویسم.

برای انجام این کار ما از ویجت FutureBuilder استفاده میکنیم.

همینجور که پایین میبینید من برای دریافت فایل json از پوشه assets از ویجت DefaultAssetBundle استفاده کردم و این فایل رو به پارامتر future ویجت FutureBuilder پاس دادم.

future: DefaultAssetBundle.of(context)
                    .loadString('assets/country.json'),

زمانی که فایل به صورت کامل دریافت بشه ما محتویات فایل رو از پارامتر builder به صورت snapshot.data.toString() دریافت میکنیم و ما اون رو به متد parseJson() پاس میدیم تا تجزیش کنیم.

List<Country> countries =
                      parseJson(snapshot.data.toString());

متد parseJson() برای ما لیستی از کشورها رو می سازه.

List<Country> parseJosn(String response) {
    if(response==null){
      return [];
    }
    final parsed =
        json.decode(response.toString()).cast<Map<String, dynamic>>();
    return parsed.map<Country>((json) => new Country.fromJson(json)).toList();
  }

در اینجا شما فایل main.dart به صورت کامل میبینید. حالا پروژه رو run کنید.

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_load_local_json/country.dart';
import 'package:flutter_load_local_json/list.dart';

void main() {
  runApp(new MaterialApp(
    debugShowCheckedModeBanner: false,
    theme: new ThemeData(
      primaryColor: const Color(0xFF02BB9F),
      primaryColorDark: const Color(0xFF167F67),
      accentColor: const Color(0xFF167F67),
    ),
    home: new MyApp(),
  ));
}

class MyApp extends StatefulWidget {
  @override
  MyAppState createState() => new MyAppState();
}

class MyAppState extends State<MyApp> {
  List data;

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text(&quotLoad local JSON file&quot,
            style: new TextStyle(color: Colors.white),),
        ),
        body: new Container(
          child: new Center(
            // Use future builder and DefaultAssetBundle to load the local JSON file
            child: new FutureBuilder(
                future: DefaultAssetBundle.of(context)
                    .loadString('assets/country.json'),
                builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
                  switch (snapshot.connectionState) {
                    case ConnectionState.none:
                      return Text('Press button to start.');
                    case ConnectionState.active:
                    case ConnectionState.waiting:
                      return new Center(child: new CircularProgressIndicator());
                    case ConnectionState.done:
                      if (snapshot.hasError){
                        return Text('Error: ${snapshot.error}');
                      }else{
                        List<Country> countries =
                        parseJosn(snapshot.data.toString());
                        return !countries.isEmpty
                            ? new CountyList(country: countries)
                            : new Text(&quotfile is empty&quot);
                      }

                  }
                  return null; // unreachable
                },
          ),
        )));
  }

  List<Country> parseJosn(String response) {
    if(response==null){
      return [];
    }
    final parsed =
    json.decode(response.toString()).cast<Map<String, dynamic>>();
    return parsed.map<Country>((json) => new Country.fromJson(json)).toList();
  }
}

اگر شما تمام کارهای بالا رو انجام داده باشید میبیند که اپلیکیشن کاملا روان بدون هیچ لاگی فایل رو دریافت میکنه و لیستی از کشور ها رو نمایش میده. اگر سوالی داشتید بپرسید. موفق باشید

ادرس گیت هاب پروژه

من چیزهای زیاد از فلاتر توی کانالم میزارم میتونید من رو از اونجا دنبال کنید.

کانال من