I'm developing an application with Xamarin.Forms for Android and iOS. When I enter into an url that's like http://app.myapp.io/user/reset-password/{some_hash}
I open the app in a special screen that allows the user to set a new password for his account.
In Android I achieve this by using custom intent filters, setting the scheme to http
and the host to app.myapp.io
. I want to do the same in iOS. But AFAIK when you register the app linking in iOS the way to do it is registering in your Info.plist
file, the custom scheme. This is my custom scheme in my Info.plist
file.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>
<integer>2</integer>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>MinimumOSVersion</key>
<string>6.0</string>
<key>CFBundleDisplayName</key>
<string>MyApp</string>
<key>CFBundleIdentifier</key>
<string>com.company.app</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>CFBundleIconFiles</key>
<array>
<string>Icon-60@2x</string>
<string>Icon-60@3x</string>
<string>Icon-76</string>
<string>Icon-76@2x</string>
<string>Default</string>
<string>Default@2x</string>
<string>Default-568h@2x</string>
<string>Default-Portrait</string>
<string>Default-Portrait@2x</string>
<string>Icon-Small-40</string>
<string>Icon-Small-40@2x</string>
<string>Icon-Small-40@3x</string>
<string>Icon-Small</string>
<string>Icon-Small@2x</string>
<string>Icon-Small@3x</string>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>CFBundleName</key>
<string>Halligan</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.company.app</string>
<key>CFBundleURLSchemes</key>
<array>
<string>http</string>
</array>
</dict>
</array>
</dict>
</plist>
Here's my AppDelegate.cs
{
// The UIApplicationDelegate for the application. This class is responsible for launching the
// User Interface of the application, as well as listening (and optionally responding) to
// application events from iOS.
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate, IDeviceStorage
{
const string HOCKEYAPP_APPID = "ef71d53e56044baa813c2381b291c355";
#region IDeviceStorage implementation
public string LoadString(string key, string def = null)
{
string value = NSUserDefaults.StandardUserDefaults.StringForKey(key);
if (value == null)
return def;
else
return value;
}
public void SaveString(string key, string value)
{
NSUserDefaults.StandardUserDefaults.SetString(value, key);
NSUserDefaults.StandardUserDefaults.Synchronize();
}
#endregion
//
// This method is invoked when the application has loaded and is ready to run. In this
// method you should instantiate the window, load the UI into it and then make the window
// visible.
//
// You have 17 seconds to return from this method, or iOS will terminate your application.
//
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
if (!Resolver.IsSet) SetIoc();
global::Xamarin.Forms.Forms.Init();
SvgImageRenderer.Init ();
LoadApplication(new App());
return base.FinishedLaunching(app, options);
}
public override bool OpenUrl (UIApplication app, NSUrl url, string sourceApp, NSObject annotation)
{
var resetLinkHash = string.Empty;
if (url.BaseUrl.Host.Equals ("app.myapp.io")) {
if (!Resolver.IsSet) SetIoc();
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App(url.LastPathComponent));
return true;
}
LoadApplication(new App(url.LastPathComponent));
return true;
}
private void SetIoc()
{
TinyIoCContainer.Current.AutoRegister ();
var container = TinyIoCContainer.Current;
container.Register<IDeviceStorage>(this);
container.Register<IXFormsApp> (new XFormsAppiOS ());
container.Register<ISecureStorage, SecureStorage> ();
Resolver.SetResolver(new XLabs.Ioc.TinyIOC.TinyResolver(container));
}
}
}
And here's my Main.cs
{
public class Application
{
// This is the main entry point of the application.
static void Main(string[] args)
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main(args, null, "AppDelegate");
}
}
}
And well, for now this doesn't work on iOS, trying with or without http at the begining.
If someone can point me out in the right direction, I'd appreciate it. It's very important to me launching the app by matching the url, doing something like adding some <meta/>
tags to the page html will not work because I don't have any access to the server.