কীভাবে প্লাটার / ডার্টে প্ল্যাটফর্মের নির্দিষ্ট নির্ভরতা আমদানি করবেন? (অ্যান্ড্রয়েড / আইওএসের সাথে ওয়েব সংমিশ্রণ)


9

আমি shared_preferencesআইওএস এবং অ্যান্ড্রয়েডের জন্য আমার ফ্লটার অ্যাপ্লিকেশনটিতে ব্যবহার করছি । ওয়েবে আমি http:dartনির্ভরতা window.localStorageনিজেই ব্যবহার করছি । যেহেতু ওয়েবের জন্য ফ্লাটারটি ফ্লটার রেপোতে একীভূত হয়েছিল, তাই আমি ক্রস প্ল্যাটফর্ম সমাধান তৈরি করতে চাই।

এর অর্থ আমার দুটি পৃথক এপিআই আমদানি করতে হবে। এটি ডার্টে এখনও খুব ভাল সমর্থিত বলে মনে হচ্ছে না, তবে আমি এটি করেছি:

import 'package:some_project/stub/preference_utils_stub.dart'
    if (dart.library.html) 'dart:html'
    if (dart.library.io) 'package:shared_preferences/shared_preferences.dart';

আমার preference_utils_stub.dartফাইলে, আমি সমস্ত ক্লাস / ভেরিয়েবল প্রয়োগ করেছি যা সংকলনের সময় দৃশ্যমান হওয়া দরকার:

Window window;

class SharedPreferences {
  static Future<SharedPreferences> get getInstance async {}
  setString(String key, String value) {}
  getString(String key) {}
}

class Window {
  Map<String, String> localStorage;
}

এটি সংকলনের আগে সমস্ত ত্রুটি থেকে মুক্তি পেয়ে যায়। এখন আমি কিছু পদ্ধতি প্রয়োগ করেছি যা অ্যাপ্লিকেশনটি ওয়েবটি ব্যবহার করছে কিনা তা পরীক্ষা করে:

static Future<String> getString(String key) async {
    if (kIsWeb) {
       return window.localStorage[key];
    }
    SharedPreferences preferences = await SharedPreferences.getInstance;
    return preferences.getString(key);
}

যাইহোক, এটি ত্রুটিগুলির প্রচুর পরিমাণ দেয়:

lib/utils/preference_utils.dart:13:7: Error: Getter not found:
'window'.
      window.localStorage[key] = value;
      ^^^^^^ lib/utils/preference_utils.dart:15:39: Error: A value of type 'Future<SharedPreferences> Function()' can't be assigned to a
variable of type 'SharedPreferences'.
 - 'Future' is from 'dart:async'.
 - 'SharedPreferences' is from 'package:shared_preferences/shared_preferences.dart'
('../../flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.4+3/lib/shared_preferences.dart').
      SharedPreferences preferences = await SharedPreferences.getInstance;
                                      ^ lib/utils/preference_utils.dart:22:14: Error: Getter not found:
'window'.
      return window.localStorage[key];

ইত্যাদি। এই ত্রুটিগুলি ছাড়াই প্ল্যাটফর্মের উপর নির্ভর করে কেউ কীভাবে বিভিন্ন পদ্ধতি / ক্লাস ব্যবহার করতে পারে? মনে রাখবেন যে আমি কেবল পছন্দগুলি নয়, এইভাবে আরও নির্ভরতা ব্যবহার করছি। ধন্যবাদ!


আমার সীমিত জ্ঞানে আপনার একই পদ্ধতি বা শ্রেণীর উভয়ই নির্ভরতা localstorageএবং shared preferencesনির্ভরতা থাকা উচিত নয় । এর অর্থ হ'ল সংকলক এই নির্ভরতাগুলির মধ্যে কোনওটিই নাড়াচাড়া করতে পারে না। আদর্শভাবে আমদানিতে এই প্রয়োগগুলি লুকাতে হবে। আমি একটি পরিষ্কার বাস্তবায়নের উদাহরণ নিয়ে আসার চেষ্টা করব।
অভিলাষ চন্দ্রন

আপনি বিশ্বব্যাপী বুলেটিয়ান কিআইএসওয়েব ব্যবহার করতে পারেন যা ওয়েবে চালানোর জন্য অ্যাপটি সংকলিত হয়েছিল কিনা তা আপনাকে বলতে পারে। ডকুমেন্টেশন: api.flutter.dev/flutter/foundation/kIsWeb-constant.html if (kIsWeb) {// ওয়েবে চলছে! ওয়েব ডিবি আরম্ভ করুন} অন্য {// ভাগ করে নেওয়া পছন্দগুলি ব্যবহার করুন}
শামিক চোদনঙ্কার

উত্তর:


20

আপনার ইস্যুতে আমার এই পদ্ধতিটি এখানে। এটি এখানেhttp হিসাবে প্যাকেজ থেকে বাস্তবায়ন উপর ভিত্তি করে ।

মূল ধারণাটি নিম্নরূপ।

  1. আপনার যে পদ্ধতিগুলি ব্যবহার করতে হবে তা নির্ধারণ করতে একটি বিমূর্ত শ্রেণি তৈরি করুন Create
  2. নির্দিষ্টকরণ webএবং androidনির্ভরতাগুলি তৈরি করুন যা এই বিমূর্ত শ্রেণিকে প্রসারিত করে।
  3. এই স্ট্যাব তৈরি করুন যা এই বিমূর্ত বাস্তবায়নের উদাহরণটি ফেরত দেওয়ার জন্য কোনও পদ্ধতি প্রকাশ করে। এটি কেবল ডার্ট বিশ্লেষণের সরঞ্জামকে খুশি রাখার জন্য।
  4. বিমূর্ত শ্রেণিতে শর্তসাপেক্ষে আমদানি নির্দিষ্ট mobileএবং এর সাথে এই স্টাব ফাইলটি আমদানি করুন web। তারপরে কারখানায় নির্ধারক নির্দিষ্ট প্রয়োগের উদাহরণটি ফিরিয়ে দিন। এটি সঠিকভাবে লিখিত হলে শর্তাধীন আমদানি দ্বারা স্বয়ংক্রিয়ভাবে পরিচালিত হবে।

পদক্ষেপ -1 এবং 4:

import 'key_finder_stub.dart'
    // ignore: uri_does_not_exist
    if (dart.library.io) 'package:flutter_conditional_dependencies_example/storage/shared_pref_key_finder.dart'
    // ignore: uri_does_not_exist
    if (dart.library.html) 'package:flutter_conditional_dependencies_example/storage/web_key_finder.dart';

abstract class KeyFinder {

  // some generic methods to be exposed.

  /// returns a value based on the key
  String getKeyValue(String key) {
    return "I am from the interface";
  }

  /// stores a key value pair in the respective storage.
  void setKeyValue(String key, String value) {}

  /// factory constructor to return the correct implementation.
  factory KeyFinder() => getKeyFinder();
}

পদক্ষেপ -২.১: ওয়েব কী সন্ধানকারী

import 'dart:html';

import 'package:flutter_conditional_dependencies_example/storage/key_finder_interface.dart';

Window windowLoc;

class WebKeyFinder implements KeyFinder {

  WebKeyFinder() {
    windowLoc = window;
    print("Widnow is initialized");
    // storing something initially just to make sure it works. :)
    windowLoc.localStorage["MyKey"] = "I am from web local storage";
  }

  String getKeyValue(String key) {
    return windowLoc.localStorage[key];
  }

  void setKeyValue(String key, String value) {
    windowLoc.localStorage[key] = value;
  }  
}

KeyFinder getKeyFinder() => WebKeyFinder();

পদক্ষেপ -২.২: মোবাইল কী অনুসন্ধানকারী

import 'package:flutter_conditional_dependencies_example/storage/key_finder_interface.dart';
import 'package:shared_preferences/shared_preferences.dart';

class SharedPrefKeyFinder implements KeyFinder {
  SharedPreferences _instance;

  SharedPrefKeyFinder() {
    SharedPreferences.getInstance().then((SharedPreferences instance) {
      _instance = instance;
      // Just initializing something so that it can be fetched.
      _instance.setString("MyKey", "I am from Shared Preference");
    });
  }

  String getKeyValue(String key) {
    return _instance?.getString(key) ??
        'shared preference is not yet initialized';
  }

  void setKeyValue(String key, String value) {
    _instance?.setString(key, value);
  }

}

KeyFinder getKeyFinder() => SharedPrefKeyFinder();

ধাপ 3:

import 'key_finder_interface.dart';

KeyFinder getKeyFinder() => throw UnsupportedError(
    'Cannot create a keyfinder without the packages dart:html or package:shared_preferences');

তারপরে আপনার main.dartব্যবহারে KeyFinderবিমূর্ত শ্রেণিটি যেন এটি একটি জেনেরিক বাস্তবায়ন। এটি কিছুটা অ্যাডাপ্টারের প্যাটার্নের মতো

main.dart

import 'package:flutter/material.dart';
import 'package:flutter_conditional_dependencies_example/storage/key_finder_interface.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    KeyFinder keyFinder = KeyFinder();
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: SafeArea(
        child: KeyValueWidget(
          keyFinder: keyFinder,
        ),
      ),
    );
  }
}

class KeyValueWidget extends StatefulWidget {
  final KeyFinder keyFinder;

  KeyValueWidget({this.keyFinder});
  @override
  _KeyValueWidgetState createState() => _KeyValueWidgetState();
}

class _KeyValueWidgetState extends State<KeyValueWidget> {
  String key = "MyKey";
  TextEditingController _keyTextController = TextEditingController();
  TextEditingController _valueTextController = TextEditingController();
  @override
  Widget build(BuildContext context) {
    return Material(
      child: Container(
        width: 200.0,
        child: Column(
          children: <Widget>[
            Expanded(
              child: Text(
                '$key / ${widget.keyFinder.getKeyValue(key)}',
                style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),
              ),
            ),
            Expanded(
              child: TextFormField(
                decoration: InputDecoration(
                  labelText: "Key",
                  border: OutlineInputBorder(),
                ),
                controller: _keyTextController,
              ),
            ),
            Expanded(
              child: TextFormField(
                decoration: InputDecoration(
                  labelText: "Value",
                  border: OutlineInputBorder(),
                ),
                controller: _valueTextController,
              ),
            ),
            RaisedButton(
              child: Text('Save new Key/Value Pair'),
              onPressed: () {
                widget.keyFinder.setKeyValue(
                  _keyTextController.text,
                  _valueTextController.text,
                );
                setState(() {
                  key = _keyTextController.text;
                });
              },
            )
          ],
        ),
      ),
    );
  }
}

কিছু স্ক্রিন শট

ওয়েব এখানে চিত্র বর্ণনা লিখুন এখানে চিত্র বর্ণনা লিখুন

মুঠোফোন এখানে চিত্র বর্ণনা লিখুন


2
এই বিশাল প্রচেষ্টার জন্য ধন্যবাদ! সাবাশ. আমি ইতিমধ্যে একই পথে ছিলাম (পাশাপাশি HTTP প্যাকেজটিতেও যা মজার বিষয় :))। অনেক ধন্যবাদ!
জিওভান্নি

1
আশা করি এটি অন্যকেও সহায়তা করবে। আমরা সকলেই সমাধান করে শিখি .. :-)
অভিলাষ চন্দ্রন

হাই আপনার কোড চেষ্টা করে! TY। আমি তখন গ্লোবাল বুলেটিয়ান কিআইসওয়েব সম্পর্কে জানতে পেরেছিলাম যা ওয়েবে চালানোর জন্য অ্যাপটি সংকলিত হয়েছিল কিনা তা আপনাকে বলতে পারে। ডকুমেন্টেশন: api.flutter.dev/flutter/foundation/kIsWeb-constant.html PS- আমি যদি কিছু বাস্তবায়ন উপেক্ষা করে থাকি তবে অগ্রিম ক্ষমা চাওয়ার নতুন আপনি যদি এটি ব্যবহার করেন তবে
শমিক চোদনঙ্কার

2
@ সামিকচোডানকার আপনি ঠিক বলেছেন এই বুলিয়ান পতাকা নির্দিষ্ট যৌক্তিক সিদ্ধান্তের জন্য সহায়ক হবে। ওপিও এই বিকল্পটি চেষ্টা করে। তবে সমস্যাটি হ'ল, আমরা যদি dart:html' and একই ফাংশনে উভয় ভাগ করে নেওয়া সংজ্ঞা ব্যবহার করি তবে সংকলকটি ত্রুটিগুলি উত্পন্ন করবে কারণ এটি dart:htmlকোনও মোবাইল ডিভাইসের বিরুদ্ধে সংকলন করার সময় জানতে পারে না এবং বিপরীতে এটি sharedpreferencesযখন তার লেখকরা ব্যতীত ওয়েবের বিরুদ্ধে সংকলন করার সময় তা জানতে পারে না unless এটি অভ্যন্তরীণভাবে পরিচালনা করুন। এই পতাকাটি ব্যবহার করে যদি আপনার কাছে কার্যকারী উদাহরণ থাকে তবে দয়া করে ভাগ করুন। আমি তোলপাড় করতেও নতুন am
অভিলাষ চন্দ্রন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.