I am using shared_preferences
in my Flutter application for iOS and Android. On the web I am using the http:dart
dependency (window.localStorage
) itself. Since Flutter for web was merged into the Flutter repo, I want to create a cross platform solution.
This means I need to import two seperate API's. This seems not to be very good supported in Dart yet, but this is what I did:
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';
In my preference_utils_stub.dart
file, I implemented all classes/variables which need to be visible during compile time:
Window window;
class SharedPreferences {
static Future<SharedPreferences> get getInstance async {}
setString(String key, String value) {}
getString(String key) {}
}
class Window {
Map<String, String> localStorage;
}
This gets rid of all errors before compilation. Now I implemented some method which checks if the application is using the web or not:
static Future<String> getString(String key) async {
if (kIsWeb) {
return window.localStorage[key];
}
SharedPreferences preferences = await SharedPreferences.getInstance;
return preferences.getString(key);
}
However, this gives loads of errors:
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];
And so on. How can one use different methods/classes depending on the platform without these errors? Note that I am using more dependencies this way, not just preferences. Thanks!
Best Answer
Here is my approach to your issue. This is based on the implementations from
http
package as in here.The core idea is as follows.
web
andandroid
dependencies which extends this abstract class.mobile
andweb
. Then in its factory constructor return the instance of the specific implementation. This will be handled automatically by conditional import if written correctly.Step-1 and 4:
Step-2.1: Web Key finder
Step-2.2: Mobile Key finder
Step-3:
Then in your
main.dart
use theKeyFinder
abstract class as if its a generic implementation. This is somewhat like an adapter pattern.main.dart
some screen shots
Web
mobile