Xamarin.Forms - iOS 链接到 http 方案 url 的应用程序不起作用

Xamarin.Forms - iOS app linking to an http scheme url doesn't work

我正在为 Android 和 iOS 使用 Xamarin.Forms 开发一个应用程序。当我输入类似于 http://app.myapp.io/user/reset-password/{some_hash} 的 url 时,我会在一个特殊屏幕中打开该应用程序,该屏幕允许用户为其帐户设置新密码。

在 Android 中,我通过使用自定义意图过滤器实现了这一点,将方案设置为 http 并将主机设置为 app.myapp.io。我想在 iOS 中做同样的事情。但是据我所知,当您在 iOS 中注册应用程序链接时,方法是在您的 Info.plist 文件中注册自定义方案。这是我 Info.plist 文件中的自定义方案。

<?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>

这是我的 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));
        }
    }
}

这是我的 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");
        }
    }
}

好吧,现在这在 iOS 上不起作用,请尝试在开始时使用或不使用 http。

如果有人能指出正确的方向,我将不胜感激。通过匹配 url 来启动应用程序对我来说非常重要,做一些像向页面 html 添加一些 <meta/> 标签这样的事情将不起作用,因为我没有任何服务器访问权限.

与 Android 不同,iOS 上的 URL 方案只能注册到单个应用程序。这对您不起作用的原因是因为 http 不是可用的 URL 方案,您的应用程序可以自行注册以在 iOS.

上使用

实现此功能的方法是 Universal Links, which is a new iOS 9+ feature. This allows you to register your app for http/https URLs on a specific domain only. However, you'll need access to the server for this, because you need to make some server-side changes to prove that you control the domain in question. If this is impossible, consider using a free service like Branch.io(完全披露:我是团队成员)来处理您的链接。