Hello, and welcome back to "Route 85," our road
trip of knowledge for iOS developers
where we don't have rest stops, we have great points.
And part three on our little series
on opening a link in Chrome iOS.
Now as you recall from last time-- which you should watch
if you haven't yet-- we were able to open
a link from our app directly in Google Chrome
and add a button in Chrome that goes back
to our app using this giant URL that takes advantage
of the x-callback URL format.
But there's one little problem here--
it turns out that if you have a very old version of Chrome,
like you haven't updated it in over two years,
and you tried to open this URL, it wouldn't work.
You see, Chrome didn't add support for the x-callback URL
stack until like November of 2012.
But because this URL still begins with the Google Chrome
scheme our UI applications can open
URL method would evaluate to "true" or "yes."
It's only once our old version of Chrome
receives this URL that it barfs, so we
have no way of knowing whether or not our version of Chrome
is recent enough to handle this x-callback URL.
Or do we?
Dun, dun dun.
You see, what the Google Chrome team did--
which I think is kind of clever--
is they added a third URL scheme called
Google Chrome x-callback.
This was added at the same time that the team added support
for x-callback URL, which means that you can check and see
if Google Chrome supports x-callback URL by asking if it
can open a URL that begins with the Google Chrome
x-callback scheme.
Now if it can't, then that's OK-- you just
revert back to the basic Google Chrome URL.
But if it can, then you just pass in the full URL as is.
So let's go back to our sample application
here and put this into action.
Here I am back in my ViewController.m file
and what I'm going to do here is I'm
going to change my callback URL so that instead of beginning
with googlechrome-s, it's going to begin
with googlechrome-x-callback.
I'm running out of space here, so let's put this
on another line.
Great.
And so now I have three URLs that I can use.
I've got my callback URL for modern versions of Chrome,
my basic Chrome URL for fairly old versions of Chrome,
and my plain old Safari URL.
So now let's go into my "if" clause here.
So first I'm going to check and see,
can I open my fancy callback URL?
If I can, then I know my version of Chrome
supports the x-callback URL scheme
and can therefore handle this URL that
points back to my application.
If it can't, then I'm going to add another check here and see,
well, at the very least can you open
the URL that is my Chrome URL?
If so, then I know that I have a version of Chrome installed,
albeit a fairly old one.
But still, I can have my UI application,
shared application, open URL, or Chrome URL.
And otherwise if it can't open either of those,
I know I don't have Chrome installed at all
and I will fall back to use Safari.
So there we go.
If we open this app again on my device,
we can see that clicking on this button will bring up Chrome.
And the fact that Chrome has this back button pointing back
to my app means that we passed along the x-callback version
of the URL and not the basic Chrome one.
And that's because I have a version of Chrome
that is less than two years old.
I actually can't show you this working on a really old version
of Chrome-- I'm not quite sure where to get it--
but I guess you'll just have to trust me
that that would work too.
So this is all fine and dandy, but I have now
expanded my simple code to open a URL from one
or two lines to, like, what-- 12?
And we did a bunch of manual URL escaping in the process.
So it seems like I probably want to abstract this logic out
into a separate class or something, right?
Well as luck would have it, Google
has already done the work for us.
So let's take a look at that next.
So let's go visit the OpenInChrome GitHub page over
at GitHub.com/Googl eChrome/OpenInChrome.
Now you can go ahead and grab these files however you'd like.
You can download the ZIP or clone the repository locally.
I think I am just going to grab the ZIP file here.
And then once it's done, I'm going to open up my ZIP file.
And within here are the two files
you're going to need-- OpenInChromeController.h
and OpenInChromeController.m.
So I'm just going to drag these two directly
into my project in Xcode here.
I'm going to say, yes, let's copy these.
And you can go ahead and check out these files if you want.
If you've been following these lessons up until this point,
most of this code should look pretty familiar to you.
They're just being a little more robust and a little more
bulletproof than our sample code.
So go ahead and check these out.
You can check out most importantly the .h file,
which is the actual public interface of this class.
You could see that basically it's a singleton.
We have a nice Boolean, IsChromeInstalled,
and we can either open a URL in Chrome or open a URL in Chrome
with a callback URL.
So let's go back to my ViewController
here and go back to my "Open In Web Page" method.
And basically, let's just delete all of this.
All that hard work-- gone.
So I'm going to go ahead and define two URLs here.
The first is the URL that I actually want to open.
We'll call it pageToOpen, it'll be an NSURL, URL with string,
and this can be just a plain old URL
that opens up www.google.com.
Then let's add a second URL, which is our callback URL.
And this is going to become 'googleOpenInChromeExample;'.
Again, note the colon at the end there,
and clearly you should make this specific to your app.
Now the code to open this up is much simpler.
First, let me go ahead and import
my OpenInChromeController.h.
And I'm just going to add an "if" clause
that says if OpenInChromeController shared
instance is Chrome-installed-- well, if that's the case, then
let's just open it in Chrome.
And I can do that by calling the method OpenInChromeCont
rollerSharedInstance.
OpenInChrome-- for this URL, I'm going
to make it the page to open.
With callback URL, can be our callback URL.
And create a new tab-- it's probably not necessary,
so I'll say "No" here.
Format this nicely.
And otherwise, user doesn't have Chrome installed.
So we'll just fall back to opening up this link in Safari.
And this is our plain old UI application/ shared application
open URL method.
And the nice thing here is that the OpenInChromeController
is doing all the heavy lifting in converting my ordinary URL
into an x-callback URL with all that percent escape information
all over the place.
In fact, let's go into this controller here
and we'll add a little NSLog statement that
shows what URL it actually ends up trying to open.
So right here, I'm going to add a little NSLog that says,
I am attempting to open-- and we'll
look at our Chrome URL absolute string.
So we can give this a try now by running it.
And just like always, I have a button.
I can click on it, takes me into Chrome,
and there's a Back button that once again takes me back
to my application.
And we go back to our console and we
look at what's been generated here.
We can see that yes, it has taken our very simple URL
and converted it into the giant x-callback URL that is required
to open this in Chrome with the Back button.
So we'll stop this.
And so now I'm sure you can see we have some logic that
is really easy to convert to a more general purpose method.
Now maybe in a real application, when the user starts up
the app, you can check and see if they have Chrome installed.
If they do have Google Chrome installed, then maybe
the first time the user clicks on a link,
you can bring up an alert view or an action sheet that
lets them select their default browser.
Save that information in NS User Defaults,
remember that choice in the future.
And then you could write a simple "open URLs
in preferred browser" method that takes a URL
and makes the appropriate call to open it.
And there you go.
I now have an application that opens up
links in the user's browser of choice, whatever it might be.
And in case you're wondering, do extensions in iOS 8
make this entire system obsolete?
The answer would appear to be no.
iOS 8 does support a number of actions with extensions.
And I suspect that there are some use cases of URL schemes
that could now be better handled by extensions.
However, opening up a web page isn't currently one of them.
So now at this point, we're basically
done with our main goal of showing you
how to open up a link in Chrome on iOS,
but we can still have a little more fun
with that x-callback URL and see how
we can take advantage of the link
that Chrome is using to send the user back to our app.
And I'll show you how to do that in the next lesson.
So stay tuned.
[ROCK MUSIC PLAYING]