简体   繁体   English

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

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

I'm developing an application with Xamarin.Forms for Android and iOS. 我正在使用Xamarin.Forms开发适用于Android和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. 当我输入类似http://app.myapp.io/user/reset-password/{some_hash}的网址时,我会在一个特殊的屏幕中打开该应用程序,该屏幕允许用户为其帐户设置新密码。

In Android I achieve this by using custom intent filters, setting the scheme to http and the host to app.myapp.io . 在Android中,我可以通过使用自定义意图过滤器,将方案设置为http并将主机设置为app.myapp.ioapp.myapp.io I want to do the same in iOS. 我想在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. 但是,当您在iOS中注册链接的应用程序时,AFAIK的实现方式是在自定义方案Info.plist文件中注册。 This is my custom scheme in my Info.plist file. 这是我的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>

Here's my AppDelegate.cs 这是我的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 这是我的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. 而且,目前,这在iOS上不起作用,一开始尝试使用http或不使用http。

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. 对我来说,通过匹配url来启动应用程序非常重要,因为无法访问服务器,因此在html页面中添加一些<meta/>标签之类的操作将不起作用。

Unlike Android, URL schemes on iOS can only be registered to a single app. 与Android不同,iOS上的URL方案只能注册到一个应用程序。 The reason this doesn't work for you is because http isn't an available URL scheme that your app can register itself to use on iOS. 这对您不起作用的原因是因为http不是您的应用可以注册以在iOS上使用的可用URL方案。

The way to get this working is Universal Links , which is a new iOS 9+ feature. 实现此功能的方法是Universal Links ,它是iOS 9+的新功能。 This allows you to register your app for http/https URLs on a specific domain only. 这样,您就可以仅在特定域上为http / https URL注册应用。 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 (full disclosure: I'm the team) to handle your links. 如果这不可能,请考虑使用Branch.io之类的免费服务(完整披露:我是团队)来处理您的链接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM