One thing that's not quite obvious from the documentation of turbolinks-ios, is how to pass the user's device token to your Rails backend in the case that you want to send push notifications. Read on for two options to get the user's device token from the device to your Rails app.
One: Pass via URL parameters
First in your AppDelegate.swift, you need to tell your app to register for remote notifications. Implement your applicationDidFinishLaunchingWithOptions as follows:
Then, also in your AppDelegate.swift add the callback method where you can receive the device token and do something with it. Implement the applicationDidRegisterForRemoteNotificationsWithDeviceToken like so:
This piece of code saves the device token in the user settings of your app.
Now we can write some code that reads the deviceToken from your user settings and passes it onto your Rails app via URL params.
First, lets change the standard presentVisitableForSession method to use a custom URL method to load the actual URL passed in. For example:
Then implement the URLWithToken method as follows:
In this method, we take the URLToken stored in the user defaults for the app. Then we remove the special characters and spaces so it can be sent correctly via URL param. The second half of the method makes sure that we:
- Do not send a token when it's not present
- Set the deviceToken as the primary URL parameter when the URL doesn't contain other parameters yet
- Add the deviceToken as a URL parameter when other parameters are already present in the URL.
At the Rails end, you can have a before_action in your ApplicationController that checks for this parameter and updates on the current user, like so:
Passing the device token via URL is the first option we tried. It's a good implementation that does the job. However, a downside is that it clutters every Turbolinks request that is made by your app, and another downside is that you need to sanitize the token before appending it to the URL.
Lately, I have been trying the next option - option two - in the new iOS app for Sporzer, a mobile fitness community that we're building.
Two: Pass via UserAgent string
This option passes the device token in the UserAgent string of your Turbolinks iOS webview client. I like this approach since it's similar to passing custom HTTP headers and you don't need to override the URLs throughout your app.
First - just like option one - update AppDelegate.swift so it registers for remote notifications and stores the device token in the user defaults for your app.
Then, in the UINavigationController that makes your Turbolinks requests happen, set up your custom WKWebViewConfiguration like so:
This code grabs the device token from the user defaults and then appends it to the application name in the user agent string. This way the Turbolinks webview will pass this to your Ruby on Rails app.
At the Ruby on Rails end, you do the following in your ApplicationController's before_action:
Done! That's it. With either option, you can store the device token of your user's iOS device in your app. With the device token stored, you can use a gem like Houston, to start sending push notifications to your users. Awesome!