This guide will walk you through creating a minimal Turbolinks for iOS application.
We’ll use the demo app’s bundled server in our examples, which runs at http://localhost:9292/
, but you can adjust the URL and hostname below to point to your own application. See Running the Demo for instructions on starting the demo server.
Note that for the sake of brevity, these examples use a UINavigationController and implement everything inside the AppDelegate. In a real application, you may not want to use a navigation controller, and you should consider factoring these responsibilities out of the AppDelegate and into separate classes.
Create a new Xcode project using the Single View Application template. Then, open AppDelegate.swift
and replace it with the following to create a UINavigationController and make it the window’s root view controller:
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var navigationController = UINavigationController()
func applicationDidFinishLaunching(_ application: UIApplication) {
window?.rootViewController = navigationController
}
}
Add Turbolinks to your project. Install the Turbolinks framework using Carthage, CocoaPods, or manually by building Turbolinks.framework
and linking it to your Xcode project. See Installation for more instructions.
Configure NSAppTransportSecurity for the demo server. By default, iOS versions 9 and later restrict access to unencrypted HTTP connections. In order for your application to connect to the demo server, you must configure it to allow insecure HTTP requests to localhost
.
Run the following command with the path to your application’s Info.plist
file:
plutil -insert NSAppTransportSecurity -json \
'{"NSExceptionDomains":{"localhost":{"NSExceptionAllowsInsecureHTTPLoads":true}}}' \
MyApp/Info.plist
See Apple’s property list documentation for more information about NSAppTransportSecurity.
A Turbolinks Session manages a WKWebView instance and moves it between Visitable view controllers when you navigate. Your application is responsible for displaying a Visitable view controller, giving it a URL, and telling the Session to visit it. See Understanding Turbolinks Concepts for details.
In your AppDelegate, create and retain a Session. Then, create a VisitableViewController with the demo server’s URL, and push it onto the navigation stack. Finally, call session.visit()
with your view controller to perform the visit.
import UIKit
import Turbolinks
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var navigationController = UINavigationController()
var session = Session()
func applicationDidFinishLaunching(_ application: UIApplication) {
window?.rootViewController = navigationController
startApplication()
}
func startApplication() {
visit(URL: URL(string: "http://localhost:9292")!)
}
func visit(URL: URL) {
let visitableViewController = VisitableViewController(url: URL)
navigationController.pushViewController(visitableViewController, animated: true)
session.visit(visitableViewController)
}
}
To handle link taps and initiate a Turbolinks visit, you must configure the Session’s delegate.
The Session notifies its delegate by proposing a visit whenever you tap a link. It also notifies its delegate when a visit request fails. The Session’s delegate is responsible for handling these events and deciding how to proceed. See Creating a Session for details.
First, assign the Session’s delegate
property. For demonstration purposes, we’ll make AppDelegate the Session’s delegate.
class AppDelegate: UIResponder, UIApplicationDelegate {
// ...
func startApplication() {
session.delegate = self
visit(URL: URL(string: "http://localhost:9292")!)
}
}
Next, implement the SessionDelegate protocol to handle proposed and failed visits by adding the following class extension just after the last closing brace in the file:
extension AppDelegate: SessionDelegate {
func session(_ session: Session, didProposeVisitToURL URL: URL, withAction action: Action) {
visit(URL: URL)
}
func session(_ session: Session, didFailRequestForVisitable visitable: Visitable, withError error: NSError) {
let alert = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
navigationController.present(alert, animated: true, completion: nil)
}
}
We handle a proposed visit in the same way as the initial visit: by creating a VisitableViewController, pushing it onto the navigation stack, and visiting it with the Session. When a visit request fails, we display an alert.
A real application will want to customize the view controller, respond to different visit actions, and gracefully handle errors. See Building Your Turbolinks Application for detailed instructions.