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

时间:2016-05-23 18:32:55

标签: ios iphone xamarin.ios applinks

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

在Android中,我通过使用自定义意图过滤器实现此目的,将方案设置为http,将主机设置为app.myapp.io。我想在iOS中做同样的事情。但是当您在iOS中注册应用程序链接时,AFAIK会在您的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。

如果有人可以指出我正确的方向,我会很感激。对我来说,通过匹配网址来启动应用程序非常重要,例如在网页上添加一些<meta/>标签,html将无法正常工作,因为我无法访问服务器。

1 个答案:

答案 0 :(得分:0)

与Android不同,iOS上的URL方案只能注册到一个应用程序。这不适合您的原因是因为http不是您的应用可以注册自己在iOS上使用的可用网址方案。

实现此功能的方法是Universal Links,这是一项新的iOS 9+功能。这允许您仅在特定域上为http / https URL注册您的应用程序。但是,您需要访问服务器,因为您需要进行一些服务器端更改以证明您控制了相关域。如果这是不可能的,请考虑使用免费服务,例如Branch.io(完全披露:我是团队)来处理您的链接。