jaguar-examples/flutter_webview

iOS error

Opened this issue · 29 comments

Why can't be opened on IOS

white screen?

Will test it and fix it today or tomorrow.

@Kleak Can you try this?

I have the same problem

@tejainece Me too... white screen on latest on IOS.
trying to see whats wrong..

I dont have an iOS setup currently. I will fix it when I get home later today or tomorrow. Meanwhile, PRs are welcome.

@tejainece thanks. Will see what i can also do here...

@tejainece been messing around with using the fluuer webview example code with jaguar server.
Still does exactly the same error. Blank white screen.
I think its something to do the with async at the start, but not sure

Looking into it.

i took their example and put your jaguar code with it.
I still get the white screen on IOS.
On Android its working.
SO it cant be the async issue as i suggested...

Its a good idea to use their example i think as it shows off what it can do...

Any still working on this myself too to find the bug

here is the main.dart

import 'dart:async';

import 'package:flutter/material.dart';

import 'package:jaguar/jaguar.dart';
import 'package:jaguar_flutter_asset/jaguar_flutter_asset.dart';

import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';

const kAndroidUserAgent =
    'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Mobile Safari/537.36';

String selectedUrl = 'https://flutter.io';

//String selectedUrl = 'https://localhost:8080';

void main() async{

  final server = Jaguar();
  server.addRoute(serveFlutterAssets());
  await server.serve(logRequests: true);

  server.log.onRecord.listen((r) => print(r));

  runApp(MyApp());


  //runApp(new MyApp());
}

/*
main() async {
  final server = Jaguar();
  server.addRoute(serveFlutterAssets());
  await server.serve(logRequests: true);

  server.log.onRecord.listen((r) => print(r));

  runApp(MyApp());
}
*/

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter WebView Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      routes: {
        '/': (_) => const MyHomePage(title: 'Flutter WebView Demo'),
        '/widget': (_) => new WebviewScaffold(
              url: selectedUrl,
              appBar: new AppBar(
                title: const Text('Widget webview'),
              ),
              withZoom: true,
              withLocalStorage: true,
            )
      },
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // Instance of WebView plugin
  final flutterWebviewPlugin = new FlutterWebviewPlugin();

  // On destroy stream
  StreamSubscription _onDestroy;

  // On urlChanged stream
  StreamSubscription<String> _onUrlChanged;

  // On urlChanged stream
  StreamSubscription<WebViewStateChanged> _onStateChanged;

  StreamSubscription<WebViewHttpError> _onHttpError;

  StreamSubscription<double> _onScrollYChanged;

  StreamSubscription<double> _onScrollXChanged;

  final _urlCtrl = new TextEditingController(text: selectedUrl);

  final _codeCtrl =
      new TextEditingController(text: 'window.navigator.userAgent');

  final _scaffoldKey = new GlobalKey<ScaffoldState>();

  final _history = [];

  @override
  void initState() {
    super.initState();

    flutterWebviewPlugin.close();

    _urlCtrl.addListener(() {
      selectedUrl = _urlCtrl.text;
    });

    // Add a listener to on destroy WebView, so you can make came actions.
    _onDestroy = flutterWebviewPlugin.onDestroy.listen((_) {
      if (mounted) {
        // Actions like show a info toast.
        _scaffoldKey.currentState.showSnackBar(
          const SnackBar(content: const Text('Webview Destroyed')));
      }
    });

    // Add a listener to on url changed
    _onUrlChanged = flutterWebviewPlugin.onUrlChanged.listen((String url) {
      if (mounted) {
        setState(() {
          _history.add('onUrlChanged: $url');
        });
      }
    });

    _onScrollYChanged =
        flutterWebviewPlugin.onScrollYChanged.listen((double y) {
      if (mounted) {
        setState(() {
          _history.add("Scroll in  Y Direction: $y");
        });
      }
    });

    _onScrollXChanged =
        flutterWebviewPlugin.onScrollXChanged.listen((double x) {
      if (mounted) {
        setState(() {
          _history.add("Scroll in  X Direction: $x");
        });
      }
    });

    _onStateChanged =
        flutterWebviewPlugin.onStateChanged.listen((WebViewStateChanged state) {
      if (mounted) {
        setState(() {
          _history.add('onStateChanged: ${state.type} ${state.url}');
        });
      }
    });

    _onHttpError =
        flutterWebviewPlugin.onHttpError.listen((WebViewHttpError error) {
      if (mounted) {
        setState(() {
          _history.add('onHttpError: ${error.code} ${error.url}');
        });
      }
    });
  }

  @override
  void dispose() {
    // Every listener should be canceled, the same should be done with this stream.
    _onDestroy.cancel();
    _onUrlChanged.cancel();
    _onStateChanged.cancel();
    _onHttpError.cancel();
    _onScrollXChanged.cancel();
    _onScrollYChanged.cancel();

    flutterWebviewPlugin.dispose();

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      key: _scaffoldKey,
      appBar: new AppBar(
        title: const Text('Plugin example app'),
      ),
      body: new Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          new Container(
            padding: const EdgeInsets.all(24.0),
            child: new TextField(controller: _urlCtrl),
          ),
          new RaisedButton(
            onPressed: () {
              flutterWebviewPlugin.launch(selectedUrl,
                  rect: new Rect.fromLTWH(
                      0.0, 0.0, MediaQuery.of(context).size.width, 300.0),
                  userAgent: kAndroidUserAgent);
            },
            child: const Text('Open Webview (rect)'),
          ),
          new RaisedButton(
            onPressed: () {
              flutterWebviewPlugin.launch(selectedUrl, hidden: true);
            },
            child: const Text('Open "hidden" Webview'),
          ),
          new RaisedButton(
            onPressed: () {
              flutterWebviewPlugin.launch(selectedUrl);
            },
            child: const Text('Open Fullscreen Webview'),
          ),
          new RaisedButton(
            onPressed: () {
              Navigator.of(context).pushNamed('/widget');
            },
            child: const Text('Open widget webview'),
          ),
          new Container(
            padding: const EdgeInsets.all(24.0),
            child: new TextField(controller: _codeCtrl),
          ),
          new RaisedButton(
            onPressed: () {
              final future =
                  flutterWebviewPlugin.evalJavascript(_codeCtrl.text);
              future.then((String result) {
                setState(() {
                  _history.add('eval: $result');
                });
              });
            },
            child: const Text('Eval some javascript'),
          ),
          new RaisedButton(
            onPressed: () {
              setState(() {
                _history.clear();
              });
              flutterWebviewPlugin.close();
            },
            child: const Text('Close'),
          ),
          new RaisedButton(
            onPressed: () {
              flutterWebviewPlugin.getCookies().then((m) {
                setState(() {
                  _history.add('cookies: $m');
                });
              });
            },
            child: const Text('Cookies'),
          ),
          new Text(_history.join('\n'))
        ],
      ),
    );
  }
}

I have setup my Mac yesterday for Flutter development. I will check this today evening.

One suggestion is to check that Jaguar serves the requests using normal http client (package:http, dart:io or package:jaguar_resty).

ah good point. Will keep trying.. Am a dart newbie, so its slow going :)

Thanks a lot!

Sorry, but I had found a solution to the problem in IOS and I forgot to comment it,
simply replace 'https://localhost:8080' with 'http://127.0.0.1:8080/'.
I hope this helps you.

@lgArlequin Glad I found your solution, I almost gave up! Thanks!

Is this also working for android?

I will fix this in the example or PRs are welcome.

@allandaleho Yes! its work in android.

wow such a simple obvious change.
tested and works for me !!

The change from localhost to 127.0.0.1 worked for me

However, I have been experiencing a situation where the blank screen gets reintroduced:

  1. Have a button open a webview on iOS that is served up from assets
  2. Navigate back to the original screen without the webview
  3. Click out of the app, lock your iPhone screen, and then unlock it
  4. Try hitting the button to take you to the webview again .. and this time it will be a blank screen

(AFAICT this doesn't happen on android)

It is probably a problem with flutter_webview_plugin, not a Jaguar problem. Can you try anyother web view plugin?

However, I have been experiencing a situation where the blank screen gets reintroduced:

  1. Have a button open a webview on iOS that is served up from assets
  2. Navigate back to the original screen without the webview
  3. Click out of the app, lock your iPhone screen, and then unlock it
  4. Try hitting the button to take you to the webview again .. and this time it will be a blank screen

(AFAICT this doesn't happen on android)

Have you resolved this problem? I have this problem now and do not know how to reslove.

@zhouxting I have not resolved this issue yet, but I also haven't taken the advice above to try another webview plugin yet.

@gadfly361 I am using the webview_flutter plugin and it has the same issue!

@zhouxting Can you please post a small reproducible on github, so I can debug it?

@tejainece
body: WebView( initialUrl: "http://127.0.0.1:8080/index.html", javascriptMode: JavascriptMode.unrestricted, onWebViewCreated: (WebViewController webViewController){ _controller.complete(webViewController); }, javascriptChannels: <JavascriptChannel>[ _getDataJSChannel(), _hideProgressJSChannel() ].toSet(), )
On ios,
1.Let the application runs in background for a period of time.
2.Then open the application from background, the webviewpage will return a blank screen.

white screen?

can you patse console.log information ?

final server = Jaguar();

发现端口被占用会出现白屏的情况,更换下启动服务的端口试下,例如:final server = Jaguar(port: 8484);

@xujiehui 换端口也不行,你把程序退到后台,然后关闭屏幕,大约5分钟以后再打开就是白屏。