androidiosfluttercross-platform

How to Detect Platform at Runtime in Flutter for Platform-Specific Storage Solutions?


I am developping a project that should work both as an app and a web page. I am using flutter_secure_storage to store local data for the app, but I need a different approach for web. Is there a way I can find out what platform I am on at runtime, and choose the correct read-write functions accordingly?


Solution

  • I don't think this question has been properly answered. So for anyone who finds themselves here, as I did ... When the code runs on the Web platform you must not use the Platform.X APIs first or the app will crash. Instead you should use the kIsWeb and TargetPlatform APIs to determine the OS that the Web browser is running on, then you can use the Platform.X APIs if you have determined that you are not running in a browser. Here are some examples:

    //  platform.dart
    
    import 'dart:io';
    
    import 'package:flutter/foundation.dart' show TargetPlatform, defaultTargetPlatform, kIsWeb;
    
    bool isDesktop() {
      if (kIsWeb) {
        return (defaultTargetPlatform != TargetPlatform.iOS && defaultTargetPlatform != TargetPlatform.android);
      } else {
        return Platform.isMacOS || Platform.isWindows || Platform.isLinux;
      }
    }
    
    bool isMobile() => !isDesktop();
    
    bool isAppleOS() {
      if (kIsWeb) {
        return (defaultTargetPlatform == TargetPlatform.iOS || defaultTargetPlatform == TargetPlatform.macOS);
      } else {
        return Platform.isMacOS || Platform.isIOS;
      }
    }
    

    To fully answer the OPs question. You have to use named conditional package imports in order to use the correct storage API. Here is an example for Web session storage. First create a window_service.dart file:

    //  window_service.dart
    
    Window window = Window();
    
    class Window {
      Map<String, String> sessionStorage = <String, String>{};
    }
    

    Now you can conditionally use this in preference to html.window.sessionStorage when not running on the Web by using conditional imports:

    import 'package:your/path/window_service.dart' if (kIsWeb) 'dart:html';
    
    ...
    
    window.sessionStorage[key] = value;
    

    In this way you can switch between session storage in the Web app, and some other custom storage, for non-Web Apps. You would need to build that out in the window_service.dart file above. The same strategy could be applied to Web localStorage.

    These were a couple of vital pieces of the puzzle for me, so I hope this helps.