Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Open the youtube app from flutter app on iOS

I basically want to open a specific youtube video from my app, when a button is pressed. If the youtube app is installed on the user's device, then the video should be opened in the youtube app (and not in the browser or a separate webview).

I used the url_launcher package for that, and it works fine on android. However on iOS the youtube app is not opened even if it is installed, instead a separate web window is opened, where the corresponding youtube url is shown as a webpage.

I thought, that I could override this behaviour like so:

_launchURL() async {
  if (Platform.isIOS) {
    if (await canLaunch('youtube://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw')) {
      await launch('youtube://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw');
    } else {
      if (await canLaunch('https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw')) {
        await launch('https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw');
      } else {
        throw 'Could not launch https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw';
      }
    }
  } else {
    const url = 'https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw';
    if (await canLaunch(url)) {
      await launch(url);
    } else {
      throw 'Could not launch $url';
    }
  }
}

but it didn’t work. In case you wonder, I use the following imports:

import 'dart:io' show Platform;
import 'package:url_launcher/url_launcher.dart';

I am pretty sure, the youtube:// URL-Scheme works (launches the YouTube app), because I tested it on third party apps (Launch Center Pro and Pythonista).

The last thing I was not able to test, is if the Platform.isIOS is really true on my IPhone.

Is there a working way, to open the YouTube App from flutter?

like image 442
frankenapps Avatar asked May 02 '19 12:05

frankenapps


2 Answers

I fixed it. I had to set forceSafariVC: false, because it is true on default, which causes the url to be opened inside a sort of webview inside the app.

_launchURL() async {
  if (Platform.isIOS) {
    if (await canLaunch('youtube://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw')) {
      await launch('youtube://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw', forceSafariVC: false);
    } else {
      if (await canLaunch('https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw')) {
        await launch('https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw');
      } else {
        throw 'Could not launch https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw';
      }
    }
  } else {
    const url = 'https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw';
    if (await canLaunch(url)) {
      await launch(url);
    } else {
      throw 'Could not launch $url';
    }
}

This is actually documented in the url_launcher docs, but somewhat hidden...

like image 55
frankenapps Avatar answered Nov 16 '22 00:11

frankenapps


You don't have to have all that if/else clauses. The most important thing to take into consideration is that whether the device has the YouTube app or not, regardless of the O.S (and remember to define your function as Future because of the async):

Future<void> _launchYoutubeVideo(String _youtubeUrl) async {
if (_youtubeUrl != null && _youtubeUrl.isNotEmpty) {
  if (await canLaunch(_youtubeUrl)) {
    final bool _nativeAppLaunchSucceeded = await launch(
      _youtubeUrl,
      forceSafariVC: false,
      universalLinksOnly: true,
    );
    if (!_nativeAppLaunchSucceeded) {
      await launch(_youtubeUrl, forceSafariVC: true);
    }
  }
 }
}

The thing to highlight here to avoid several if/else si the attribute universalLinksOnly set to true.

like image 43
Carlos Daniel Avatar answered Nov 16 '22 01:11

Carlos Daniel