llfbandit / app_links

Android App Links, Deep Links, iOs Universal Links and Custom URL schemes handler for Flutter.
https://pub.dev/packages/app_links
Apache License 2.0
176 stars 68 forks source link

Not working with Flutter add-to-app in iOS #70

Closed samarthagarwal closed 6 months ago

samarthagarwal commented 11 months ago

I am using Flutter add-to-app to add flutter as a module to an iOS app. I have used the plugin to get the initial link and the stream updates as well. Here is the basic code.

Future<void> initUniLinks() async {
    final _appLinks = AppLinks();
    final initialLink = await _appLinks.getInitialAppLinkString();

    print('initialLink: ${initialLink ?? "no initial link"}');
    _streamController.add(initialLink ?? "/");
    // Attach a listener to the stream
    _sub = _appLinks.allStringLinkStream.listen((String? link) {
      print(link ?? "no link");
      _streamController.add(link ?? "/");
    }, onError: (err) {
      print(err);
    });
  }

I am using the allStringLinkStream method to listen to the new links but I never get any updates. The app launches but the link is never received so the app stays on the root URL.

Here is some of my iOS code that I am using to render the Flutter app inside the iOS SwiftUI app.

class AppDelegate: FlutterAppDelegate, ObservableObject {
  let flutterEngine = FlutterEngine(name: "my flutter engine")

  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
      // Runs the default Dart entrypoint with a default Flutter route.
      flutterEngine.run();
      // Used to connect plugins (only if you have plugins with iOS platform code).
      GeneratedPluginRegistrant.register(with: self.flutterEngine);
      return true;
    }
}

@main
struct MyApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    var body: some Scene {
        WindowGroup {
             ContentView()
        }
    }
}

struct ContentView: View {

    @EnvironmentObject var appDelegate: AppDelegate

  // Button is created to call the showFlutter function when pressed.
  var body: some View {
    Button("Show Flutter!") {
      showFlutter()
    }
  }

func showFlutter() {
    // Get the RootViewController.
    guard
      let windowScene = UIApplication.shared.connectedScenes
        .first(where: { $0.activationState == .foregroundActive && $0 is UIWindowScene }) as? UIWindowScene,
      let window = windowScene.windows.first(where: \.isKeyWindow),
      let rootViewController = window.rootViewController
    else { return }

    // Create the FlutterViewController.
    let flutterViewController = FlutterViewController(
      engine: appDelegate.flutterEngine,
      nibName: nil,
      bundle: nil)
    flutterViewController.modalPresentationStyle = .overCurrentContext
    flutterViewController.isViewOpaque = false

    rootViewController.present(flutterViewController, animated: true)
  }
}

I have also added the required entries to info.plist file as well and the custom scheme is registered. Whenever I try to open a custom scheme url, it launches the app but never receives the link information in the Flutter code.

llfbandit commented 9 months ago

Thanks for the report. I bet that overriding application(launchOptions:) conflicts with the plugin.

Depending of what type of link you use here's a sample code that should fix your situation:

    // Custom URL
    if let url = launchOptions?[UIApplication.LaunchOptionsKey.url] as? URL {
       // add eventually a check for your scheme before the lines below
        super.application(application, didFinishLaunchingWithOptions: launchOptions)
        // force return true so that it is handled in application(_:open:options:)
        return true
    }
    // Universal link
    else if let activityDictionary = launchOptions?[UIApplication.LaunchOptionsKey.userActivityDictionary] as? [AnyHashable: Any] { 
        for key in activityDictionary.keys {
            if let userActivity = activityDictionary[key] as? NSUserActivity {
                if let url = userActivity.webpageURL {
                  // add logic for universal link
                }
            }
        }
    }

    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
llfbandit commented 7 months ago

This should be somehow available in app_links 3.5.0-beta.1. Please have a look to the README file. Feedback appreciated!

llfbandit commented 6 months ago

Released in v3.5.0. Update your specifics to catch links.