Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

App crashed on iOS - Lost connection to device #174

Closed
boozy-ph opened this issue Oct 16, 2019 · 16 comments
Closed

App crashed on iOS - Lost connection to device #174

boozy-ph opened this issue Oct 16, 2019 · 16 comments

Comments

@boozy-ph
Copy link

Hi, I've been encountering this issue where the app crashes on iOS simulator and leaves Lost connection to device error message. I haven't tested it on a real iOS device yet.

Podfile

# Using a CDN with CocoaPods 1.7.2 or later can save a lot of time on pod installation, but it's experimental rather than the default.
# source 'https://cdn.cocoapods.org/'

# Uncomment this line to define a global platform for your project
# platform :ios, '9.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

project 'Runner', {
  'Debug' => :debug,
  'Profile' => :release,
  'Release' => :release,
}

def parse_KV_file(file, separator='=')
  file_abs_path = File.expand_path(file)
  if !File.exists? file_abs_path
    return [];
  end
  pods_ary = []
  skip_line_start_symbols = ["#", "/"]
  File.foreach(file_abs_path) { |line|
      next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
      plugin = line.split(pattern=separator)
      if plugin.length == 2
        podname = plugin[0].strip()
        path = plugin[1].strip()
        podpath = File.expand_path("#{path}", file_abs_path)
        pods_ary.push({:name => podname, :path => podpath});
      else
        puts "Invalid plugin specification: #{line}"
      end
  }
  return pods_ary
end

target 'Runner' do
  use_frameworks!

  # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
  # referring to absolute paths on developers' machines.
  system('rm -rf .symlinks')
  system('mkdir -p .symlinks/plugins')

  # Flutter Pods
  generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig')
  if generated_xcode_build_settings.empty?
    puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first."
  end
  generated_xcode_build_settings.map { |p|
    if p[:name] == 'FLUTTER_FRAMEWORK_DIR'
      symlink = File.join('.symlinks', 'flutter')
      File.symlink(File.dirname(p[:path]), symlink)
      pod 'Flutter', :path => File.join(symlink, File.basename(p[:path]))
    end
  }

  # Plugin Pods
  plugin_pods = parse_KV_file('../.flutter-plugins')
  plugin_pods.map { |p|
    symlink = File.join('.symlinks', 'plugins', p[:name])
    File.symlink(p[:path], symlink)
    pod p[:name], :path => File.join(symlink, 'ios')
  }
end

# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.
install! 'cocoapods', :disable_input_output_paths => true

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['ENABLE_BITCODE'] = 'NO'
      config.build_settings['SWIFT_VERSION'] = '4.0'
    end
  end
end

pubspec.yaml

environment:
  sdk: ">=2.3.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  
  carousel_slider: ^1.3.0
  cached_network_image: ^1.1.1
  flutter_money_formatter: ^0.8.3
  graphql_flutter: ^2.1.0
  rxdart: ^0.22.2
  get_it: ^3.0.1
  rx_widgets: ^2.2.0+1
  rx_command: ^4.3.2+1
  flushbar: ^1.9.0
  flutter_inappbrowser: ^1.2.1
  cupertino_icons: ^0.1.2

dev_dependencies:
  flutter_test:
    sdk: flutter

flutter:
  uses-material-design: true
  assets:
    - assets/images/

Flutter Doctor result:
[✓] Flutter (Channel dev, v1.10.14, on Mac OS X 10.13.6 17G65, locale en-PH)

[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[✓] Xcode - develop for iOS and macOS (Xcode 10.1)
[✓] Android Studio (version 3.5)
[✓] VS Code (version 1.39.1)
[✓] Connected device (1 available)

This project was not created via flutter create -i swift, hope someone could help me on this. This is the only webview plugin that works really great on our app on Android.

@TimothyY
Copy link

I'm encountering the same issue. When compiled using xcode i get these errors:
Error on iPhone 6 (real device) - ios 12.4.2
Error on iPhone 8 (simulator) - ios 13.1

Fatal error: Unexpectedly found nil while unwrapping an Optional value: file /Users/user/development/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_inappbrowser-1.2.1/ios/Classes/FlutterWebViewFactory.swift, line 25
2019-10-22 17:44:48.289006+0700 Runner[360:13751] Fatal error: Unexpectedly found nil while unwrapping an Optional value: file /Users/user/development/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_inappbrowser-1.2.1/ios/Classes/FlutterWebViewFactory.swift, line 25

@TimothyY
Copy link

TimothyY commented Oct 23, 2019

i found the main problem in my project.

In my case,
flutter_inappbrowser (this plugin) is in conflict with flutter_downloader when calling await FlutterDownloader.initialize(); before runApp(MyApp()); on main.dart

this might be unique to my project though.

My solution is using older version of flutter_downloader which doesn't use such code (i'm using 1.2.2)

@boozy-ph
Copy link
Author

In my case,
flutter_inappbrowser (this plugin) is in conflict with flutter_downloader when calling await FlutterDownloader.initialize(); before runApp(MyApp()); on main.dart

@TimothyY how did you know that there is a conflict?

@TimothyY
Copy link

TimothyY commented Oct 25, 2019

When I take out the inappbrowser plugin the flutter_downloader runs normal.
Same is true when I take out the flutter_downloader and let the inappbrowser runs.

the code line I highlight is just recently added on flutter_downloader 1.3.x version

I also open an issue on the flutter_downloader github, because their older version works.

Are you using that plugin too? or have you tried compiling with xcode to see if there is extra error recognized by xcode for your case?

@boozy-ph
Copy link
Author

I'm not using flutter_downloader.

I'm new to flutter that's why I'm not familiar with xcode compiling. Would you please guide me or send me some links on how to do it?

@TimothyY
Copy link

  1. Open your project with android studio
  2. On your project structure, search for ios folder
  3. Inside the ios folder, search for runner folder
  4. Search for appdelegate.swift /appdelegate.c /appdelegate.h and open it.
  5. When the file is opened in android studio, look at the upper right section of your android studio, there should be something like "open in xcode". Click it.
  6. Your xcode will open the ios module of your project and you can run it from your xcode.
  7. Sometimes your xcode will ask for sign certificate, make sure you have it configured on xcode > your project structure > runner > sign and capabilities

@boozy-ph
Copy link
Author

Thanks @TimothyY, I will try this later and will post the progress here.

@pichillilorenzo
Copy link
Owner

Try the latest version of the plugin. However, this plugin changed its name to flutter_inappwebview. The current latest version now is 2.1.0+1. So, you can change your dependency influtter_inappwebview: ^2.1.0+1.
Also, change config.build_settings['SWIFT_VERSION'] = '4.0' to config.build_settings['SWIFT_VERSION'] = '5.0'

@koteezy
Copy link

koteezy commented Dec 17, 2019

@pichillilorenzo Should i create new issue, or, just post post messages here? I have same issue, on last ( ^2.1.0+1 ) version.

@pichillilorenzo
Copy link
Owner

@koteezy could you explain your use case for which this happens?? Post all useful information such as Xcode version and iOS version. Also, post the Xcode error logs you get. Thanks!

@koteezy
Copy link

koteezy commented Dec 17, 2019

@koteezy could you explain your use case for which this happens?? Post all useful information such as Xcode version and iOS version. Also, post the Xcode error logs you get. Thanks!

Alright, i found scenario when i got this error.

If i call flutter_inappwebview.callHandler to fast, like that:

flutter_inappwebview.callHandler('tracks', '[]');

I got crash, with these errors

Log
2019-12-17 22:45:12.185530+0300 Runner[31568:3738796] flutter: ok. go!
2019-12-17 22:45:12.409090+0300 Runner[31568:3738796] flutter: 

Browser Created!
2019-12-17 22:45:15.438394+0300 Runner[31568:3738796] flutter: 

Stopped!! 
2019-12-17 22:45:15.506786+0300 Runner[31568:3738796] flutter: We got args.
Fatal error: Unexpectedly found nil while unwrapping an Optional value: file /Users/uebanchik/.pub-cache/hosted/pub.dartlang.org/flutter_inappwebview-2.1.0+1/ios/Classes/InAppWebView.swift, line 1242
2019-12-17 22:45:15.508742+0300 Runner[31568:3738044] Fatal error: Unexpectedly found nil while unwrapping an Optional value: file /Users/uebanchik/.pub-cache/hosted/pub.dartlang.org/flutter_inappwebview-2.1.0+1/ios/Classes/InAppWebView.swift, line 1242
2019-12-17 22:46:06.339925+0300 Runner[31568:3738796] flutter: [{"tracks": []}]
(lldb)

But, if i will use something like this:

setTimeout(() => {
        flutter_inappwebview.callHandler('tracks', '[]');
 }, 1000);

I will got result, and everything will works fine.

Yea, i know what You say what we need use something like this, and i know that is right:

window.addEventListener("flutterInAppWebViewPlatformReady", function (event) {
   flutter_inappwebview.callHandler('tracks',  '[]');
});

But, how i say here, that listener just not called. ( i use injectJavascriptFileFromAsset )

Flutter doctor
[✓] Flutter (Channel stable, v1.12.13+hotfix.5, on Mac OS X 10.15.1 19B88, locale ru-RU)
    • Flutter version 1.12.13+hotfix.5 at /Users/uebanchik/development/flutter
    • Framework revision 27321ebbad (7 days ago), 2019-12-10 18:15:01 -0800
    • Engine revision 2994f7e1e6
    • Dart version 2.7.0

[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
    • Android SDK at /Users/uebanchik/Library/Android/sdk
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-29, build-tools 29.0.2
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 11.2.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 11.2.1, Build version 11B500
    • CocoaPods version 1.8.4

[✓] Android Studio (version 3.5)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 42.0.1
    • Dart plugin version 191.8593
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)

[✓] VS Code (version 1.41.0)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.7.1

[✓] Connected device (1 available)
    • iPhone 11 Pro Max • 92CEB5FD-320B-4EF6-B8C3-84C45803D21A • ios • com.apple.CoreSimulator.SimRuntime.iOS-13-2 (simulator)

• No issues found!

Plugin version: ^2.1.0+1

@pichillilorenzo
Copy link
Owner

@koteezy if you use injectJavascriptFileFromAsset on onLoadStop then it should be ok without using window.addEventListener("flutterInAppWebViewPlatformReady") because that event is already called before you load the javascript file. So, you can use directly flutter_inappwebview.callHandler('tracks', '[]'); in your javascript code.

About the crash, it has been fixed in the next major release.

I tested this code and it works as expected without errors:

import 'dart:async';

import 'package:flutter/material.dart';

import 'package:flutter_inappwebview/flutter_inappwebview.dart';

Future main() async {
  runApp(new MyApp());
}

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

class _MyAppState extends State<MyApp> {

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

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: InAppWebViewPage()
    );
  }
}

class InAppWebViewPage extends StatefulWidget {
  @override
  _InAppWebViewPageState createState() => new _InAppWebViewPageState();
}

class _InAppWebViewPageState extends State<InAppWebViewPage> {
  InAppWebViewController webView;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
            title: Text("InAppWebView")
        ),
        body: Container(
            child: Column(children: <Widget>[
              Expanded(
                child: Container(
                  child: InAppWebView(
                    initialFile: "assets/index.html",
                    initialHeaders: {},
                    initialOptions: InAppWebViewWidgetOptions(
                      inAppWebViewOptions: InAppWebViewOptions(
                        debuggingEnabled: true,
                      ),
                    ),
                    onWebViewCreated: (InAppWebViewController controller) {
                      webView = controller;

                      controller.addJavaScriptHandler(handlerName: "tracks", callback: (args) {
                        print(args);
                      });
                    },
                    onLoadStart: (InAppWebViewController controller, String url) {

                    },
                    onLoadStop: (InAppWebViewController controller, String url) {
                      controller.injectJavascriptFileFromAsset(assetFilePath: "assets/js/script.js");
                    },
                  ),
                ),
              ),
            ]))
    );
  }
}

where assets/index.html contains this simple HTML code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Flutter InAppWebView</title>
</head>
<body>
    <p>Hi</p>
</body>
</html>

and assets/js/script.js contains only:

var tracks = [1,2,3,4];
flutter_inappwebview.callHandler('tracks', tracks);

Xcode logs:

flutter: [[1, 2, 3, 4]]

@koteezy
Copy link

koteezy commented Dec 18, 2019

@pichillilorenzo I will wait, thanks!

@pichillilorenzo
Copy link
Owner

@koteezy my code example is working for you?

@koteezy
Copy link

koteezy commented Dec 18, 2019

@koteezy my code example is working for you?

No.. On android, everything okay, except, specific models like that one, on ios have same issue as i show above, if it help, here my browser:

class MyInAppBrowser extends InAppBrowser {
  Service service;
  Function callback;

  MyInAppBrowser(this.service, this.callback) {
    final options =
        InAppBrowserClassOptions(
          inAppBrowserOptions: InAppBrowserOptions(),
          inAppWebViewWidgetOptions: InAppWebViewWidgetOptions(
            inAppWebViewOptions: InAppWebViewOptions(
              debuggingEnabled: true
            )
          )
      );

    this.open(
      url: this.service.url,
      options: options,
    );
  }

  @override
  Future onBrowserCreated() {
    print("\n\nBrowser Created!\n\n");

    this.webViewController.addJavaScriptHandler(
        handlerName: "tracks",
        callback: (args) async {
          print("We got args.");
          print(args);
          this.callback(BrowserParsingCallback(service, json.decode(args[0])));

          this.close();
        });
  }

  @override
  Future onLoadStart(String url) async {
    // print("\n\nStarted $url\n\n");
  }

  @override
  Future onLoadStop(String url) async {
    print("\n\nStopped!! $url\n\n");

    this
        .webViewController
        .injectJavascriptFileFromAsset(assetFilePath: service.parserPath());
  }

  @override
  void onLoadError(String url, int code, String message) {
    print("Can't load $url.. Error: $message");
  }

  @override
  void onProgressChanged(int progress) {
    // 
  }

  @override
  void onExit() {
   //
  }

  @override
  void onLoadResource(LoadedResource response) {
   //
  }

  @override
  void onConsoleMessage(ConsoleMessage consoleMessage) {
    // 
  }
}

It works fine only if i use callHandler with delay, like:

setTimeout(() => {
        flutter_inappwebview.callHandler('tracks', '[]');
 }, 1000);

@ositano
Copy link

ositano commented Dec 19, 2019

@pichillilorenzo still shows lost connection to device like @koteezy said or else its added a setTimeout(). I got this error when i run via xcode

2019-12-19 05:35:04.895948+0100 Runner[14278:77343] flutter: Observatory listening on http://127.0.0.1:53075/gpsJXD8j4xw=/ Fatal error: Unexpectedly found nil while unwrapping an Optional value: file /Library/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_inappwebview-2.1.0+1/ios/Classes/InAppWebView.swift, line 1242 2019-12-19 05:35:07.142995+0100 Runner[14278:76915] Fatal error: Unexpectedly found nil while unwrapping an Optional value: file /Library/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_inappwebview-2.1.0+1/ios/Classes/InAppWebView.swift, line 1242 (lldb)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants